Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name proto.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/mit-krb5 -isystem /usr/include/lua5.5 -isystem /usr/include/libxml2 -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-06-07-100346-3530-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <[email protected]>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30#include <wsutil/filesystem.h>
31#ifdef HAVE_UNISTD_H1
32#include <unistd.h>
33#endif
34
35#include <ftypes/ftypes.h>
36#include <ftypes/ftypes-int.h>
37
38#include <epan/packet.h>
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include "charsets.h"
50#include "column-info.h"
51#include "to_str.h"
52#include "osi-utils.h"
53#include "expert.h"
54#include "show_exception.h"
55#include "in_cksum.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 int cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 unsigned offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @return NULL if 'tree' is null */
95#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97
98/** See inlined comments.
99 @param length the length of this item
100 @param cleanup_block a code block to call to free resources if this returns
101 @return NULL if 'length' is lower -1 or equal 0 */
102#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
103 if (length < -1 || length == 0 ) { \
104 cleanup_block; \
105 return NULL((void*)0); \
106 }
107
108/** See inlined comments.
109 @param length the length of this item
110 @return NULL if 'length' is lower -1 or equal 0 */
111#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
112 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
113
114/** See inlined comments.
115 @param tree the tree to append this item to
116 @param hfindex field index
117 @param hfinfo header_field
118 @param free_block a code block to call to free resources if this returns
119 @return the header field matching 'hfinfo' */
120#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
121 /* If the tree is not visible and this item is not referenced \
122 we don't have to do much work at all but we should still \
123 return a node so that referenced field items below this node \
124 (think proto_item_add_subtree()) will still have somewhere \
125 to attach to or else filtering will not work (they would be \
126 ignored since tree would be NULL). \
127 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 because that means we can change its length or repr, and we \
129 don't want to do so with calls intended for this faked new \
130 item, so this item needs a new (hidden) child node. \
131 We fake FT_PROTOCOL unless some clients have requested us \
132 not to do so. \
133 */ \
134 PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 135, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
136 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 free_block; \
138 if (wireshark_abort_on_too_many_items) \
139 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
140 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
141 /* Let the exception handler add items to the tree */ \
142 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
144 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
145 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
146 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
147 } \
148 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 && (hfinfo->type != FT_PROTOCOL || \
153 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 free_block; \
155 /* return fake node with no field info */\
156 return proto_tree_add_fake_node(tree, hfinfo); \
157 } \
158 } \
159 }
160
161/** See inlined comments.
162 @param tree the tree to append this item to
163 @param hfindex field index
164 @param hfinfo header_field
165 @return the header field matching 'hfinfo' */
166#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
167 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
168
169
170/** See inlined comments.
171 @param pi the created protocol item we're about to return */
172#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 172, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
173 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
174 if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 return pi; \
176 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 /* If the tree (GUI) or item isn't visible it's pointless for \
179 * us to generate the protocol item's string representation */ \
180 return pi; \
181 }
182/* Same as above but returning void */
183#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
184 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 return; \
186 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 /* If the tree (GUI) or item isn't visible it's pointless for \
189 * us to generate the protocol item's string representation */ \
190 return; \
191 }
192/* Similar to above, but allows a NULL tree */
193#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
194 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 /* If the tree (GUI) or item isn't visible it's pointless for \
197 * us to generate the protocol item's string representation */ \
198 return pi; \
199 }
200
201#ifdef ENABLE_CHECK_FILTER
202#define CHECK_HF_VALUE(type, spec, start_values) \
203{ \
204 const type *current; \
205 int n, m; \
206 current = start_values; \
207 for (n=0; current; n++, current++) { \
208 /* Drop out if we reached the end. */ \
209 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 break; \
211 } \
212 /* Check value against all previous */ \
213 for (m=0; m < n; m++) { \
214 /* There are lots of duplicates with the same string, \
215 so only report if different... */ \
216 if ((start_values[m].value == current->value) && \
217 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
219 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
220 hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
221 current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221
, __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %"
spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo
->abbrev, current->value, m, start_values[m].strptr, n,
current->strptr)
; \
222 } \
223 } \
224 } \
225}
226#endif
227
228/* The longest NUMBER-like field label we have is for BASE_OUI, which
229 * can have up to 64 bytes for the manufacturer name if resolved plus
230 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 */
232#define NUMBER_LABEL_LENGTH80 80
233
234static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238static int hfinfo_bitoffset(const header_field_info *hfinfo);
239static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241
242#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244
245static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247
248static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255
256static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272
273static void proto_cleanup_base(void);
274
275static proto_item *
276proto_tree_add_node(proto_tree *tree, field_info *fi);
277
278static proto_item *
279proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280
281static void
282get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
283 int *item_length, const unsigned encoding);
284
285static void
286get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 unsigned* item_length, const unsigned encoding);
288
289static int
290get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
291 int length, unsigned item_length, const int encoding);
292
293static field_info *
294new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 const int start, const int item_length);
296
297static proto_item *
298proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 int start, int *length);
300
301static void
302proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
303static void
304proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
305
306static void
307proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
308static void
309proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
310static void
311proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
312static void
313proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
314static void
315proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
316static void
317proto_tree_set_string(field_info *fi, const char* value);
318static void
319proto_tree_set_ax25(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_vines(field_info *fi, const uint8_t* value);
324static void
325proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
326static void
327proto_tree_set_ether(field_info *fi, const uint8_t* value);
328static void
329proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
330static void
331proto_tree_set_ipxnet(field_info *fi, uint32_t value);
332static void
333proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
334static void
335proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
336static void
337proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
338static void
339proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
340static void
341proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
342static void
343proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
344static void
345proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
346static void
347proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348static void
349proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
350static void
351proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
352static void
353proto_tree_set_boolean(field_info *fi, uint64_t value);
354static void
355proto_tree_set_float(field_info *fi, float value);
356static void
357proto_tree_set_double(field_info *fi, double value);
358static void
359proto_tree_set_uint(field_info *fi, uint32_t value);
360static void
361proto_tree_set_int(field_info *fi, int32_t value);
362static void
363proto_tree_set_uint64(field_info *fi, uint64_t value);
364static void
365proto_tree_set_int64(field_info *fi, int64_t value);
366static void
367proto_tree_set_eui64(field_info *fi, const uint64_t value);
368static void
369proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
370
371/* Handle type length mismatch (now filterable) expert info */
372static int proto_type_length_mismatch;
373static expert_field ei_type_length_mismatch_error;
374static expert_field ei_type_length_mismatch_warn;
375static void register_type_length_mismatch(void);
376
377/* Handle byte array string decoding errors with expert info */
378static int proto_byte_array_string_decoding_error;
379static expert_field ei_byte_array_string_decoding_failed_error;
380static void register_byte_array_string_decodinws_error(void);
381
382/* Handle date and time string decoding errors with expert info */
383static int proto_date_time_string_decoding_error;
384static expert_field ei_date_time_string_decoding_failed_error;
385static void register_date_time_string_decodinws_error(void);
386
387/* Handle string errors expert info */
388static int proto_string_errors;
389static expert_field ei_string_trailing_characters;
390static void register_string_errors(void);
391
392static int proto_register_field_init(header_field_info *hfinfo, const int parent);
393
394/* special-case header field used within proto.c */
395static header_field_info hfi_text_only =
396 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
397int hf_text_only;
398
399/* Structure for information about a protocol */
400struct _protocol {
401 const char *name; /* long description */
402 const char *short_name; /* short description */
403 const char *filter_name; /* name of this protocol in filters */
404 GPtrArray *fields; /* fields for this protocol */
405 int proto_id; /* field ID for this protocol */
406 bool_Bool is_enabled; /* true if protocol is enabled */
407 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
408 bool_Bool can_toggle; /* true if is_enabled can be changed */
409 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
410 For dissectors that need a protocol name so they
411 can be added to a dissector table, but use the
412 parent_proto_id for things like enable/disable */
413 GList *heur_list; /* Heuristic dissectors associated with this protocol */
414};
415
416/* List of all protocols */
417static GList *protocols;
418
419/* Structure stored for deregistered g_slice */
420struct g_slice_data {
421 size_t block_size;
422 void *mem_block;
423};
424
425/* Deregistered fields */
426static GPtrArray *deregistered_fields;
427static GPtrArray *deregistered_data;
428static GPtrArray *deregistered_slice;
429
430/* indexed by prefix, contains initializers */
431static GHashTable* prefixes;
432
433/* Contains information about a field when a dissector calls
434 * proto_tree_add_item. */
435#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
436#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
437
438/* Contains the space for proto_nodes. */
439#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
440 node->first_child = NULL((void*)0); \
441 node->last_child = NULL((void*)0); \
442 node->next = NULL((void*)0);
443
444#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
445 wmem_free(pool, node)
446
447/* String space for protocol and field items for the GUI */
448#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
449 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
450 il->value_pos = 0; \
451 il->value_len = 0;
452#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
453 wmem_free(pool, il);
454
455#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 455, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
456 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
457 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 457
, __func__, "Unregistered hf! index=%d", hfindex)
; \
458 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 458, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
459 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
460 hfinfo = gpa_hfinfo.hfi[hfindex];
461
462#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
463
464/* List which stores protocols and fields that have been registered */
465typedef struct _gpa_hfinfo_t {
466 uint32_t len;
467 uint32_t allocated_len;
468 header_field_info **hfi;
469} gpa_hfinfo_t;
470
471static gpa_hfinfo_t gpa_hfinfo;
472
473/* Hash table of abbreviations and IDs */
474static wmem_map_t *gpa_name_map;
475static header_field_info *same_name_hfinfo;
476
477/* Hash table protocol aliases. const char * -> const char * */
478static GHashTable *gpa_protocol_aliases;
479
480/*
481 * We're called repeatedly with the same field name when sorting a column.
482 * Cache our last gpa_name_map hit for faster lookups.
483 */
484static char *last_field_name;
485static header_field_info *last_hfinfo;
486
487/* Points to the first element of an array of bits, indexed by
488 a subtree item type; that array element is true if subtrees of
489 an item of that type are to be expanded. */
490static uint32_t *tree_is_expanded;
491
492/* Number of elements in that array. The entry with index 0 is not used. */
493int num_tree_types = 1;
494
495/* Name hashtables for fast detection of duplicate names */
496static GHashTable* proto_names;
497static GHashTable* proto_short_names;
498static GHashTable* proto_filter_names;
499
500static const char * const reserved_filter_names[] = {
501 /* Display filter keywords. */
502 "eq",
503 "ne",
504 "all_eq",
505 "any_eq",
506 "all_ne",
507 "any_ne",
508 "gt",
509 "ge",
510 "lt",
511 "le",
512 "bitand",
513 "bitwise_and",
514 "contains",
515 "matches",
516 "not",
517 "and",
518 "or",
519 "xor",
520 "in",
521 "any",
522 "all",
523 "true",
524 "false",
525 "nan",
526 "inf",
527 "infinity",
528 NULL((void*)0)
529};
530
531static GHashTable *proto_reserved_filter_names;
532static GQueue* saved_dir_queue;
533
534static int
535proto_compare_name(const void *p1_arg, const void *p2_arg)
536{
537 const protocol_t *p1 = (const protocol_t *)p1_arg;
538 const protocol_t *p2 = (const protocol_t *)p2_arg;
539
540 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
541}
542
543static GSList *dissector_plugins;
544
545#ifdef HAVE_PLUGINS1
546void
547proto_register_plugin(const proto_plugin *plug)
548{
549 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
550}
551#else /* HAVE_PLUGINS */
552void
553proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
554{
555 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 555, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
556}
557#endif /* HAVE_PLUGINS */
558
559static void
560call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
561{
562 proto_plugin *plug = (proto_plugin *)data;
563
564 if (plug->register_protoinfo) {
565 plug->register_protoinfo();
566 }
567}
568
569static void
570call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
571{
572 proto_plugin *plug = (proto_plugin *)data;
573
574 if (plug->register_handoff) {
575 plug->register_handoff();
576 }
577}
578
579void proto_pre_init(void)
580{
581 saved_dir_queue = g_queue_new();
582
583 proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
584 proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
585 proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
586
587 proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
589 /* GHashTable has no key destructor so the cast is safe. */
590 g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
591 }
592
593 gpa_hfinfo.len = 0;
594 gpa_hfinfo.allocated_len = 0;
595 gpa_hfinfo.hfi = NULL((void*)0);
596 gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
597 wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
598 gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
599 deregistered_fields = g_ptr_array_new();
600 deregistered_data = g_ptr_array_new();
601 deregistered_slice = g_ptr_array_new();
602}
603
604/* initialize data structures and register protocols and fields */
605void
606proto_init(GSList *register_all_plugin_protocols_list,
607 GSList *register_all_plugin_handoffs_list,
608 register_entity_func register_func, register_entity_func handoff_func,
609 register_cb cb,
610 void *client_data)
611{
612 /* Initialize the ftype subsystem */
613 ftypes_initialize();
614
615 /* Initialize the address type subsystem */
616 address_types_initialize();
617
618 /* Register one special-case FT_TEXT_ONLY field for use when
619 converting wireshark to new-style proto_tree. These fields
620 are merely strings on the GUI tree; they are not filterable */
621 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
622
623 /* Register the pseudo-protocols used for exceptions. */
624 register_show_exception();
625 register_type_length_mismatch();
626 register_byte_array_string_decodinws_error();
627 register_date_time_string_decodinws_error();
628 register_string_errors();
629 ftypes_register_pseudofields();
630 col_register_protocol();
631
632 /* Have each built-in dissector register its protocols, fields,
633 dissector tables, and dissectors to be called through a
634 handle, and do whatever one-time initialization it needs to
635 do. */
636 if (register_func != NULL((void*)0))
637 register_func(cb, client_data);
638
639 /* Now call the registration routines for all epan plugins. */
640 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
641 ((void (*)(register_cb, void *))l->data)(cb, client_data);
642 }
643
644 /* Now call the registration routines for all dissector plugins. */
645 if (cb)
646 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
647 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
648
649 /* Now call the "handoff registration" routines of all built-in
650 dissectors; those routines register the dissector in other
651 dissectors' handoff tables, and fetch any dissector handles
652 they need. */
653 if (handoff_func != NULL((void*)0))
654 handoff_func(cb, client_data);
655
656 /* Now do the same with epan plugins. */
657 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
658 ((void (*)(register_cb, void *))l->data)(cb, client_data);
659 }
660
661 /* Now do the same with dissector plugins. */
662 if (cb)
663 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
664 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
665
666 /* sort the protocols by protocol name */
667 protocols = g_list_sort(protocols, proto_compare_name);
668
669 /* sort the dissector handles in dissector tables (for -G reports
670 * and -d error messages. The GUI sorts the handles itself.) */
671 packet_all_tables_sort_handles();
672
673 /* We've assigned all the subtree type values; allocate the array
674 for them, and zero it out. */
675 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
676}
677
678static void
679proto_cleanup_base(void)
680{
681 protocol_t *protocol;
682 header_field_info *hfinfo;
683
684 /* Free the abbrev/ID hash table */
685 if (gpa_name_map) {
686 // XXX - We don't have a wmem_map_destroy, but
687 // it does get cleaned up when epan scope is
688 // destroyed
689 //g_hash_table_destroy(gpa_name_map);
690 gpa_name_map = NULL((void*)0);
691 }
692 if (gpa_protocol_aliases) {
693 g_hash_table_destroy(gpa_protocol_aliases);
694 gpa_protocol_aliases = NULL((void*)0);
695 }
696 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
697 last_field_name = NULL((void*)0);
698
699 while (protocols) {
700 protocol = (protocol_t *)protocols->data;
701 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo)if((protocol->proto_id == 0 || (unsigned)protocol->proto_id
> gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 701
, __func__, "Unregistered hf! index=%d", protocol->proto_id
); ((void) ((protocol->proto_id > 0 && (unsigned
)protocol->proto_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 701, "protocol->proto_id > 0 && (unsigned)protocol->proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[protocol->
proto_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 701, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
702 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id)((void) ((protocol->proto_id == hfinfo->id) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 702, "protocol->proto_id == hfinfo->id"
))))
;
703
704 g_slice_free(header_field_info, hfinfo)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfinfo
)); else (void) ((header_field_info*) 0 == (hfinfo)); } while
(0)
;
705 if (protocol->parent_proto_id != -1) {
706 // pino protocol
707 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 707, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
708 DISSECTOR_ASSERT(protocol->heur_list == NULL)((void) ((protocol->heur_list == ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 708, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
709 } else {
710 if (protocol->fields) {
711 g_ptr_array_free(protocol->fields, true1);
712 }
713 g_list_free(protocol->heur_list);
714 }
715 protocols = g_list_remove(protocols, protocol);
716 g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized
(protocol, __builtin_object_size ((protocol), 0)) : (g_free)
(protocol)
;
717 }
718
719 if (proto_names) {
720 g_hash_table_destroy(proto_names);
721 proto_names = NULL((void*)0);
722 }
723
724 if (proto_short_names) {
725 g_hash_table_destroy(proto_short_names);
726 proto_short_names = NULL((void*)0);
727 }
728
729 if (proto_filter_names) {
730 g_hash_table_destroy(proto_filter_names);
731 proto_filter_names = NULL((void*)0);
732 }
733
734 if (proto_reserved_filter_names) {
735 g_hash_table_destroy(proto_reserved_filter_names);
736 proto_reserved_filter_names = NULL((void*)0);
737 }
738
739 if (gpa_hfinfo.allocated_len) {
740 gpa_hfinfo.len = 0;
741 gpa_hfinfo.allocated_len = 0;
742 g_free(gpa_hfinfo.hfi)(__builtin_object_size ((gpa_hfinfo.hfi), 0) != ((size_t) - 1
)) ? g_free_sized (gpa_hfinfo.hfi, __builtin_object_size ((gpa_hfinfo
.hfi), 0)) : (g_free) (gpa_hfinfo.hfi)
;
743 gpa_hfinfo.hfi = NULL((void*)0);
744 }
745
746 if (deregistered_fields) {
747 g_ptr_array_free(deregistered_fields, true1);
748 deregistered_fields = NULL((void*)0);
749 }
750
751 if (deregistered_data) {
752 g_ptr_array_free(deregistered_data, true1);
753 deregistered_data = NULL((void*)0);
754 }
755
756 if (deregistered_slice) {
757 g_ptr_array_free(deregistered_slice, true1);
758 deregistered_slice = NULL((void*)0);
759 }
760
761 g_free(tree_is_expanded)(__builtin_object_size ((tree_is_expanded), 0) != ((size_t) -
1)) ? g_free_sized (tree_is_expanded, __builtin_object_size (
(tree_is_expanded), 0)) : (g_free) (tree_is_expanded)
;
762 tree_is_expanded = NULL((void*)0);
763
764 if (prefixes)
765 g_hash_table_destroy(prefixes);
766
767 if (saved_dir_queue != NULL((void*)0)) {
768 g_queue_clear_full(saved_dir_queue, g_free);
769 g_queue_free(saved_dir_queue);
770 saved_dir_queue = NULL((void*)0);
771 }
772}
773
774void
775proto_cleanup(void)
776{
777 proto_free_deregistered_fields();
778 proto_cleanup_base();
779
780 g_slist_free(dissector_plugins);
781 dissector_plugins = NULL((void*)0);
782}
783
784static bool_Bool
785ws_pushd(const char* dir)
786{
787 //Save the current working directory
788 const char* save_wd = get_current_working_dir();
789 if (save_wd != NULL((void*)0))
790 g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
791
792 //Change to the new one
793#ifdef _WIN32
794 SetCurrentDirectory(utf_8to16(dir));
795 return true1;
796#else
797 return (chdir(dir) == 0);
798#endif
799}
800
801static bool_Bool
802ws_popd(void)
803{
804 int ret = 0;
805 char* saved_wd = g_queue_pop_head(saved_dir_queue);
806 if (saved_wd == NULL((void*)0))
807 return false0;
808
809 //Restore the previous one
810#ifdef _WIN32
811 SetCurrentDirectory(utf_8to16(saved_wd));
812#else
813 ret = chdir(saved_wd);
814#endif
815 g_free(saved_wd)(__builtin_object_size ((saved_wd), 0) != ((size_t) - 1)) ? g_free_sized
(saved_wd, __builtin_object_size ((saved_wd), 0)) : (g_free)
(saved_wd)
;
816 return (ret == 0);
817}
818
819void
820proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
821{
822 if (ws_pushd(dir))
823 {
824 func(param);
825 ws_popd();
826 }
827}
828
829static bool_Bool
830// NOLINTNEXTLINE(misc-no-recursion)
831proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
832 void *data)
833{
834 proto_node *pnode = tree;
835 proto_node *child;
836 proto_node *current;
837
838 if (func(pnode, data))
839 return true1;
840
841 child = pnode->first_child;
842 while (child != NULL((void*)0)) {
843 /*
844 * The routine we call might modify the child, e.g. by
845 * freeing it, so we get the child's successor before
846 * calling that routine.
847 */
848 current = child;
849 child = current->next;
850 // We recurse here, but we're limited by prefs.gui_max_tree_depth
851 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
852 return true1;
853 }
854
855 return false0;
856}
857
858void
859proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
860 void *data)
861{
862 proto_node *node = tree;
863 proto_node *current;
864
865 if (!node)
866 return;
867
868 node = node->first_child;
869 while (node != NULL((void*)0)) {
870 current = node;
871 node = current->next;
872 func((proto_tree *)current, data);
873 }
874}
875
876static void
877free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
878{
879 GPtrArray *ptrs = (GPtrArray *)value;
880 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
881 header_field_info *hfinfo;
882
883 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 883, __func__, "Unregistered hf! index=%d",
hfid); ((void) ((hfid > 0 && (unsigned)hfid < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 883, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 883, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
884 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
885 /* when a field is referenced by a filter this also
886 affects the refcount for the parent protocol so we need
887 to adjust the refcount for the parent as well
888 */
889 if (hfinfo->parent != -1) {
890 header_field_info *parent_hfinfo;
891 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 891
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 891, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 891, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
892 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
893 }
894 hfinfo->ref_type = HF_REF_TYPE_NONE;
895 }
896
897 g_ptr_array_free(ptrs, true1);
898}
899
900static void
901proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
902{
903 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
904
905 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
906
907 if (finfo) {
908 fvalue_free(finfo->value);
909 finfo->value = NULL((void*)0);
910 }
911}
912
913void
914proto_tree_reset(proto_tree *tree)
915{
916 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
917
918 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
919
920 /* free tree data */
921 if (tree_data->interesting_hfids) {
922 /* Free all the GPtrArray's in the interesting_hfids hash. */
923 g_hash_table_foreach(tree_data->interesting_hfids,
924 free_GPtrArray_value, NULL((void*)0));
925
926 /* And then remove all values. */
927 g_hash_table_remove_all(tree_data->interesting_hfids);
928 }
929
930 /* Reset track of the number of children */
931 tree_data->count = 0;
932
933 /* Reset our loop checks */
934 tree_data->idle_count_ds_tvb = NULL((void*)0);
935 tree_data->max_start = 0;
936 tree_data->start_idle_count = 0;
937
938 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
939}
940
941/* frees the resources that the dissection a proto_tree uses */
942void
943proto_tree_free(proto_tree *tree)
944{
945 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
946
947 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
948
949 /* free tree data */
950 if (tree_data->interesting_hfids) {
951 /* Free all the GPtrArray's in the interesting_hfids hash. */
952 g_hash_table_foreach(tree_data->interesting_hfids,
953 free_GPtrArray_value, NULL((void*)0));
954
955 /* And then destroy the hash. */
956 g_hash_table_destroy(tree_data->interesting_hfids);
957 }
958
959 g_slice_free(tree_data_t, tree_data)do { if (1) g_slice_free1 (sizeof (tree_data_t), (tree_data))
; else (void) ((tree_data_t*) 0 == (tree_data)); } while (0)
;
960
961 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
962}
963
964/* Is the parsing being done for a visible proto_tree or an invisible one?
965 * By setting this correctly, the proto_tree creation is sped up by not
966 * having to call vsnprintf and copy strings around.
967 */
968bool_Bool
969proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
970{
971 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
972
973 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
974
975 return old_visible;
976}
977
978void
979proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
980{
981 if (tree)
982 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
983}
984
985/* Assume dissector set only its protocol fields.
986 This function is called by dissectors and allows the speeding up of filtering
987 in wireshark; if this function returns false it is safe to reset tree to NULL
988 and thus skip calling most of the expensive proto_tree_add_...()
989 functions.
990 If the tree is visible we implicitly assume the field is referenced.
991*/
992bool_Bool
993proto_field_is_referenced(proto_tree *tree, int proto_id)
994{
995 register header_field_info *hfinfo;
996
997
998 if (!tree)
999 return false0;
1000
1001 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1002 return true1;
1003
1004 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo)if((proto_id == 0 || (unsigned)proto_id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1004, __func__, "Unregistered hf! index=%d"
, proto_id); ((void) ((proto_id > 0 && (unsigned)proto_id
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1004,
"proto_id > 0 && (unsigned)proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[proto_id]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1004, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
1005 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1006 return true1;
1007
1008 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1009 return true1;
1010
1011 return false0;
1012}
1013
1014
1015/* Finds a record in the hfinfo array by id. */
1016header_field_info *
1017proto_registrar_get_nth(unsigned hfindex)
1018{
1019 register header_field_info *hfinfo;
1020
1021 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1021, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1021,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1021, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
1022 return hfinfo;
1023}
1024
1025
1026/* Prefix initialization
1027 * this allows for a dissector to register a display filter name prefix
1028 * so that it can delay the initialization of the hf array as long as
1029 * possible.
1030 */
1031
1032/* compute a hash for the part before the dot of a display filter */
1033static unsigned
1034prefix_hash (const void *key) {
1035 /* end the string at the dot and compute its hash */
1036 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1037 char* c = copy;
1038 unsigned tmp;
1039
1040 for (; *c; c++) {
1041 if (*c == '.') {
1042 *c = 0;
1043 break;
1044 }
1045 }
1046
1047 tmp = wmem_str_hash(copy);
1048 g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized
(copy, __builtin_object_size ((copy), 0)) : (g_free) (copy)
;
1049 return tmp;
1050}
1051
1052/* are both strings equal up to the end or the dot? */
1053static gboolean
1054prefix_equal (const void *ap, const void *bp) {
1055 const char* a = (const char *)ap;
1056 const char* b = (const char *)bp;
1057
1058 do {
1059 char ac = *a++;
1060 char bc = *b++;
1061
1062 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1063
1064 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1065 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1066
1067 if (ac != bc) return FALSE(0);
1068 } while (1);
1069
1070 return FALSE(0);
1071}
1072
1073/* Register a new prefix for "delayed" initialization of field arrays */
1074void
1075proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1076 if (! prefixes ) {
1077 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1078 }
1079
1080 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1081}
1082
1083/* helper to call all prefix initializers */
1084static gboolean
1085initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1086 ((prefix_initializer_t)v)((const char *)k);
1087 return TRUE(!(0));
1088}
1089
1090/** Initialize every remaining uninitialized prefix. */
1091void
1092proto_initialize_all_prefixes(void) {
1093 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1094}
1095
1096/* Finds a record in the hfinfo array by name.
1097 * If it fails to find it in the already registered fields,
1098 * it tries to find and call an initializer in the prefixes
1099 * table and if so it looks again.
1100 */
1101
1102header_field_info *
1103proto_registrar_get_byname(const char *field_name)
1104{
1105 header_field_info *hfinfo;
1106 prefix_initializer_t pi;
1107
1108 if (!field_name)
1109 return NULL((void*)0);
1110
1111 if (g_strcmp0(field_name, last_field_name) == 0) {
1112 return last_hfinfo;
1113 }
1114
1115 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1116
1117 if (hfinfo) {
1118 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
1119 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1120 last_hfinfo = hfinfo;
1121 return hfinfo;
1122 }
1123
1124 if (!prefixes)
1125 return NULL((void*)0);
1126
1127 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1128 pi(field_name);
1129 g_hash_table_remove(prefixes, field_name);
1130 } else {
1131 return NULL((void*)0);
1132 }
1133
1134 hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1135
1136 if (hfinfo) {
1137 g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1
)) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name
), 0)) : (g_free) (last_field_name)
;
1138 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1139 last_hfinfo = hfinfo;
1140 }
1141 return hfinfo;
1142}
1143
1144header_field_info*
1145proto_registrar_get_byalias(const char *alias_name)
1146{
1147 if (!alias_name) {
1148 return NULL((void*)0);
1149 }
1150
1151 /* Find our aliased protocol. */
1152 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1153 char *dot = strchr(an_copy, '.');
1154 if (dot) {
1155 *dot = '\0';
1156 }
1157 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1158 if (!proto_pfx) {
1159 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1160 return NULL((void*)0);
1161 }
1162
1163 /* Construct our aliased field and look it up. */
1164 GString *filter_name = g_string_new(proto_pfx);
1165 if (dot) {
1166 g_string_append_printf(filter_name, ".%s", dot+1);
1167 }
1168 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1169 g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized
(an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) (
an_copy)
;
1170 g_string_free(filter_name, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(filter_name), ((!(0)))) : g_string_free_and_steal (filter_name
)) : (g_string_free) ((filter_name), ((!(0)))))
;
1171
1172 return hfinfo;
1173}
1174
1175int
1176proto_registrar_get_id_byname(const char *field_name)
1177{
1178 header_field_info *hfinfo;
1179
1180 hfinfo = proto_registrar_get_byname(field_name);
1181
1182 if (!hfinfo)
1183 return -1;
1184
1185 return hfinfo->id;
1186}
1187
1188static int
1189label_strcat_flags(const header_field_info *hfinfo)
1190{
1191 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1192 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1193
1194 return 0;
1195}
1196
1197static char *
1198format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1199 const uint8_t *bytes, unsigned length, size_t max_str_len)
1200{
1201 char *str = NULL((void*)0);
1202 const uint8_t *p;
1203 bool_Bool is_printable;
1204
1205 if (bytes) {
1206 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1207 /*
1208 * If all bytes are valid and printable UTF-8, show the
1209 * bytes as a string - in quotes to indicate that it's
1210 * a string.
1211 */
1212 if (isprint_utf8_string((const char*)bytes, length)) {
1213 str = wmem_strdup_printf(scope, "\"%.*s\"",
1214 (int)length, bytes);
1215 return str;
1216 }
1217 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1218 /*
1219 * Check whether all bytes are printable.
1220 */
1221 is_printable = true1;
1222 for (p = bytes; p < bytes+length; p++) {
1223 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1224 /* Not printable. */
1225 is_printable = false0;
1226 break;
1227 }
1228 }
1229
1230 /*
1231 * If all bytes are printable ASCII, show the bytes
1232 * as a string - in quotes to indicate that it's
1233 * a string.
1234 */
1235 if (is_printable) {
1236 str = wmem_strdup_printf(scope, "\"%.*s\"",
1237 (int)length, bytes);
1238 return str;
1239 }
1240 }
1241
1242 /*
1243 * Either it's not printable ASCII, or we don't care whether
1244 * it's printable ASCII; show it as hex bytes.
1245 */
1246 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1247 case SEP_DOT:
1248 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1249 break;
1250 case SEP_DASH:
1251 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1252 break;
1253 case SEP_COLON:
1254 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1255 break;
1256 case SEP_SPACE:
1257 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1258 break;
1259 case BASE_NONE:
1260 default:
1261 if (prefs.display_byte_fields_with_spaces) {
1262 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1263 } else {
1264 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1265 }
1266 break;
1267 }
1268 }
1269 else {
1270 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1271 str = wmem_strdup(scope, "<none>");
1272 } else {
1273 str = wmem_strdup(scope, "<MISSING>");
1274 }
1275 }
1276 return str;
1277}
1278
1279static char *
1280format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1281 const uint8_t *bytes, unsigned length)
1282{
1283 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1284}
1285
1286static void
1287ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1288{
1289 subtree_lvl *pushed_tree;
1290
1291 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER)((void) ((ptvc->pushed_tree_max <= 256 -8) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 1291, "ptvc->pushed_tree_max <= 256-8"))))
;
1292 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1293
1294 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1295 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1295, "pushed_tree != ((void*)0)"
))))
;
1296 ptvc->pushed_tree = pushed_tree;
1297}
1298
1299static void
1300ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1301{
1302 ptvc->pushed_tree = NULL((void*)0);
1303 ptvc->pushed_tree_max = 0;
1304 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0)((void) ((ptvc->pushed_tree_index == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1304, "ptvc->pushed_tree_index == 0"
))))
;
1305 ptvc->pushed_tree_index = 0;
1306}
1307
1308/* Allocates an initializes a ptvcursor_t with 3 variables:
1309 * proto_tree, tvbuff, and offset. */
1310ptvcursor_t *
1311ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1312{
1313 ptvcursor_t *ptvc;
1314
1315 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1316 ptvc->scope = scope;
1317 ptvc->tree = tree;
1318 ptvc->tvb = tvb;
1319 ptvc->offset = offset;
1320 ptvc->pushed_tree = NULL((void*)0);
1321 ptvc->pushed_tree_max = 0;
1322 ptvc->pushed_tree_index = 0;
1323 return ptvc;
1324}
1325
1326
1327/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1328void
1329ptvcursor_free(ptvcursor_t *ptvc)
1330{
1331 ptvcursor_free_subtree_levels(ptvc);
1332 wmem_free(ptvc->scope, ptvc);
1333}
1334
1335/* Returns tvbuff. */
1336tvbuff_t *
1337ptvcursor_tvbuff(ptvcursor_t *ptvc)
1338{
1339 return ptvc->tvb;
1340}
1341
1342/* Returns current offset. */
1343unsigned
1344ptvcursor_current_offset(ptvcursor_t *ptvc)
1345{
1346 return ptvc->offset;
1347}
1348
1349proto_tree *
1350ptvcursor_tree(ptvcursor_t *ptvc)
1351{
1352 if (!ptvc)
1353 return NULL((void*)0);
1354
1355 return ptvc->tree;
1356}
1357
1358void
1359ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1360{
1361 ptvc->tree = tree;
1362}
1363
1364/* creates a subtree, sets it as the working tree and pushes the old working tree */
1365proto_tree *
1366ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1367{
1368 subtree_lvl *subtree;
1369 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1370 ptvcursor_new_subtree_levels(ptvc);
1371
1372 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1373 subtree->tree = ptvc->tree;
1374 subtree->it= NULL((void*)0);
1375 ptvc->pushed_tree_index++;
1376 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1377}
1378
1379/* pops a subtree */
1380void
1381ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1382{
1383 subtree_lvl *subtree;
1384
1385 if (ptvc->pushed_tree_index <= 0)
1386 return;
1387
1388 ptvc->pushed_tree_index--;
1389 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1390 if (subtree->it != NULL((void*)0))
1391 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1392
1393 ptvc->tree = subtree->tree;
1394}
1395
1396/* saves the current tvb offset and the item in the current subtree level */
1397static void
1398ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1399{
1400 subtree_lvl *subtree;
1401
1402 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0)((void) ((ptvc->pushed_tree_index > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1402, "ptvc->pushed_tree_index > 0"
))))
;
1403
1404 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1405 subtree->it = it;
1406 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1407}
1408
1409/* Creates a subtree and adds it to the cursor as the working tree but does not
1410 * save the old working tree */
1411proto_tree *
1412ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1413{
1414 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1415 return ptvc->tree;
1416}
1417
1418static proto_tree *
1419ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1420{
1421 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1422 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1423 ptvcursor_subtree_set_item(ptvc, it);
1424 return ptvcursor_tree(ptvc);
1425}
1426
1427/* Add an item to the tree and create a subtree
1428 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1429 * In this case, when the subtree will be closed, the parent item length will
1430 * be equal to the advancement of the cursor since the creation of the subtree.
1431 */
1432proto_tree *
1433ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1434 const unsigned encoding, int ett_subtree)
1435{
1436 proto_item *it;
1437
1438 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1439 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1440}
1441
1442static proto_item *
1443proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1444
1445/* Add a text node to the tree and create a subtree
1446 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1447 * In this case, when the subtree will be closed, the item length will be equal
1448 * to the advancement of the cursor since the creation of the subtree.
1449 */
1450proto_tree *
1451ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1452 int ett_subtree, const char *format, ...)
1453{
1454 proto_item *pi;
1455 va_list ap;
1456 header_field_info *hfinfo;
1457 proto_tree *tree;
1458
1459 tree = ptvcursor_tree(ptvc);
1460
1461 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1462
1463 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1463
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1463, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1463, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1463, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1464
1465 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1466 ptvcursor_current_offset(ptvc), length);
1467
1468 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1468, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1469
1470 va_start(ap, format)__builtin_va_start(ap, format);
1471 proto_tree_set_representation(pi, format, ap);
1472 va_end(ap)__builtin_va_end(ap);
1473
1474 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1475}
1476
1477/* Add a text-only node, leaving it to our caller to fill the text in */
1478static proto_item *
1479proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1480{
1481 proto_item *pi;
1482
1483 if (tree == NULL((void*)0))
1484 return NULL((void*)0);
1485
1486 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1487
1488 return pi;
1489}
1490
1491/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1492proto_item *
1493proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1494 const char *format, ...)
1495{
1496 proto_item *pi;
1497 va_list ap;
1498 header_field_info *hfinfo;
1499
1500 if (length == -1) {
1501 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1502 } else {
1503 tvb_ensure_bytes_exist(tvb, start, length);
1504 }
1505
1506 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1507
1508 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1508
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1508, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1508, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1508, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1509
1510 pi = proto_tree_add_text_node(tree, tvb, start, length);
1511
1512 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1512, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1513
1514 va_start(ap, format)__builtin_va_start(ap, format);
1515 proto_tree_set_representation(pi, format, ap);
1516 va_end(ap)__builtin_va_end(ap);
1517
1518 return pi;
1519}
1520
1521/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1522proto_item *
1523proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1524 int length, const char *format, va_list ap)
1525{
1526 proto_item *pi;
1527 header_field_info *hfinfo;
1528
1529 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1530 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1531 * the length to be what's in the tvbuff if length is -1, and the
1532 * minimum of length and what's in the tvbuff if not.
1533 */
1534
1535 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1536
1537 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1537
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1537, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1537, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1537, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1538
1539 pi = proto_tree_add_text_node(tree, tvb, start, length);
1540
1541 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1541, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1542
1543 proto_tree_set_representation(pi, format, ap);
1544
1545 return pi;
1546}
1547
1548/* Add a text-only node that creates a subtree underneath.
1549 */
1550proto_tree *
1551proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1552{
1553 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1554}
1555
1556/* Add a text-only node that creates a subtree underneath.
1557 */
1558proto_tree *
1559proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1560{
1561 proto_tree *pt;
1562 proto_item *pi;
1563 va_list ap;
1564
1565 va_start(ap, format)__builtin_va_start(ap, format);
1566 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1567 va_end(ap)__builtin_va_end(ap);
1568
1569 if (tree_item != NULL((void*)0))
1570 *tree_item = pi;
1571
1572 pt = proto_item_add_subtree(pi, idx);
1573
1574 return pt;
1575}
1576
1577/* Add a text-only node for debugging purposes. The caller doesn't need
1578 * to worry about tvbuff, start, or length. Debug message gets sent to
1579 * STDOUT, too */
1580proto_item *
1581proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1582{
1583 proto_item *pi;
1584 va_list ap;
1585
1586 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1587
1588 if (pi) {
1589 va_start(ap, format)__builtin_va_start(ap, format);
1590 proto_tree_set_representation(pi, format, ap);
1591 va_end(ap)__builtin_va_end(ap);
1592 }
1593 va_start(ap, format)__builtin_va_start(ap, format);
1594 vprintf(format, ap);
1595 va_end(ap)__builtin_va_end(ap);
1596 printf("\n");
1597
1598 return pi;
1599}
1600
1601proto_item *
1602proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1603{
1604 proto_item *pi;
1605 header_field_info *hfinfo;
1606
1607 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1608
1609 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1609
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1609, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1609, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1609, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1610
1611 pi = proto_tree_add_text_node(tree, tvb, start, length);
1612
1613 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1613, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1614
1615 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1616
1617 return pi;
1618}
1619
1620proto_item *
1621proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1622{
1623 proto_item *pi;
1624 header_field_info *hfinfo;
1625 char *str;
1626
1627 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1628
1629 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1629
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1629, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1629, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1629, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1630
1631 pi = proto_tree_add_text_node(tree, tvb, start, length);
1632
1633 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1633, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1634
1635 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1636 proto_item_set_text(pi, "%s", str);
1637 wmem_free(NULL((void*)0), str);
1638
1639 return pi;
1640}
1641
1642void proto_report_dissector_bug(const char *format, ...)
1643{
1644 va_list args;
1645
1646 if (wireshark_abort_on_dissector_bug) {
1647 /*
1648 * Try to have the error message show up in the crash
1649 * information.
1650 */
1651 va_start(args, format)__builtin_va_start(args, format);
1652 ws_vadd_crash_info(format, args);
1653 va_end(args)__builtin_va_end(args);
1654
1655 /*
1656 * Print the error message.
1657 */
1658 va_start(args, format)__builtin_va_start(args, format);
1659 vfprintf(stderrstderr, format, args);
1660 va_end(args)__builtin_va_end(args);
1661 putc('\n', stderrstderr);
1662
1663 /*
1664 * And crash.
1665 */
1666 abort();
1667 } else {
1668 va_start(args, format)__builtin_va_start(args, format);
1669 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1670 va_end(args)__builtin_va_end(args);
1671 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1671
, __func__, "assertion \"not reached\" failed")
; /* GCC 12 with ASAN needs this. */
1672 }
1673}
1674
1675/* We could probably get away with changing is_error to a minimum length value. */
1676static void
1677report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1678{
1679 if (is_error) {
1680 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1681 } else {
1682 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1683 }
1684
1685 if (is_error) {
1686 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1687 }
1688}
1689
1690static uint32_t
1691get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1692{
1693 uint32_t value;
1694 bool_Bool length_error;
1695
1696 switch (length) {
1697
1698 case 1:
1699 value = tvb_get_uint8(tvb, offset);
1700 if (encoding & ENC_ZIGBEE0x40000000) {
1701 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1702 value = 0;
1703 }
1704 }
1705 break;
1706
1707 case 2:
1708 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1709 : tvb_get_ntohs(tvb, offset);
1710 if (encoding & ENC_ZIGBEE0x40000000) {
1711 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1712 value = 0;
1713 }
1714 }
1715 break;
1716
1717 case 3:
1718 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1719 : tvb_get_ntoh24(tvb, offset);
1720 break;
1721
1722 case 4:
1723 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1724 : tvb_get_ntohl(tvb, offset);
1725 break;
1726
1727 default:
1728 if (length < 1) {
1729 length_error = true1;
1730 value = 0;
1731 } else {
1732 length_error = false0;
1733 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1734 : tvb_get_ntohl(tvb, offset);
1735 }
1736 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1737 break;
1738 }
1739 return value;
1740}
1741
1742static inline uint64_t
1743get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1744{
1745 uint64_t value;
1746
1747 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1748
1749 if (length < 1 || length > 8) {
1750 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1751 }
1752
1753 return value;
1754}
1755
1756static int32_t
1757get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1758{
1759 int32_t value;
1760 bool_Bool length_error;
1761
1762 switch (length) {
1763
1764 case 1:
1765 value = tvb_get_int8(tvb, offset);
1766 break;
1767
1768 case 2:
1769 value = encoding ? tvb_get_letohis(tvb, offset)
1770 : tvb_get_ntohis(tvb, offset);
1771 break;
1772
1773 case 3:
1774 value = encoding ? tvb_get_letohi24(tvb, offset)
1775 : tvb_get_ntohi24(tvb, offset);
1776 break;
1777
1778 case 4:
1779 value = encoding ? tvb_get_letohil(tvb, offset)
1780 : tvb_get_ntohil(tvb, offset);
1781 break;
1782
1783 default:
1784 if (length < 1) {
1785 length_error = true1;
1786 value = 0;
1787 } else {
1788 length_error = false0;
1789 value = encoding ? tvb_get_letohil(tvb, offset)
1790 : tvb_get_ntohil(tvb, offset);
1791 }
1792 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1793 break;
1794 }
1795 return value;
1796}
1797
1798/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1799 * be cast-able as a int64_t. This is weird, but what the code has always done.
1800 */
1801static inline uint64_t
1802get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1803{
1804 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1805
1806 switch (length) {
1807 case 7:
1808 value = ws_sign_ext64(value, 56);
1809 break;
1810 case 6:
1811 value = ws_sign_ext64(value, 48);
1812 break;
1813 case 5:
1814 value = ws_sign_ext64(value, 40);
1815 break;
1816 case 4:
1817 value = ws_sign_ext64(value, 32);
1818 break;
1819 case 3:
1820 value = ws_sign_ext64(value, 24);
1821 break;
1822 case 2:
1823 value = ws_sign_ext64(value, 16);
1824 break;
1825 case 1:
1826 value = ws_sign_ext64(value, 8);
1827 break;
1828 }
1829
1830 return value;
1831}
1832
1833/* For FT_STRING */
1834static inline const uint8_t *
1835get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1836 int length, int *ret_length, const unsigned encoding)
1837{
1838 if (length == -1) {
1839 length = tvb_ensure_captured_length_remaining(tvb, start);
1840 }
1841 *ret_length = length;
1842 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1843}
1844
1845/* For FT_STRINGZ */
1846static inline const uint8_t *
1847get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1848 int start, int length, int *ret_length, const unsigned encoding)
1849{
1850 const uint8_t *value;
1851
1852 if (length < -1) {
1853 report_type_length_mismatch(tree, "a string", length, true1);
1854 }
1855
1856 /* XXX - Ideally, every "null-terminated string which fits into a
1857 * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1858 * as appropriate, not a FT_STRINGZ. If so, then we could always call
1859 * tvb_get_stringz_enc here. Failing that, we could treat length 0
1860 * as unknown length as well (since there is a trailing '\0', the real
1861 * length is never zero), allowing switching to unsigned lengths.
1862 */
1863 if (length == -1) {
1864 /* This can throw an exception */
1865 value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1866 } else {
1867 /* In this case, length signifies the length of the string.
1868 *
1869 * This could either be a null-padded string, which doesn't
1870 * necessarily have a '\0' at the end, or a null-terminated
1871 * string, with a trailing '\0'. (Yes, there are cases
1872 * where you have a string that's both counted and null-
1873 * terminated.)
1874 *
1875 * In the first case, we must allocate a buffer of length
1876 * "length+1", to make room for a trailing '\0'.
1877 *
1878 * In the second case, we don't assume that there is a
1879 * trailing '\0' there, as the packet might be malformed.
1880 * (XXX - should we throw an exception if there's no
1881 * trailing '\0'?) Therefore, we allocate a buffer of
1882 * length "length+1", and put in a trailing '\0', just to
1883 * be safe.
1884 *
1885 * (XXX - this would change if we made string values counted
1886 * rather than null-terminated.)
1887 */
1888 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1889 }
1890 *ret_length = length;
1891 return value;
1892}
1893
1894/* For FT_UINT_STRING */
1895static inline const uint8_t *
1896get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1897 tvbuff_t *tvb, int start, int length, int *ret_length,
1898 const unsigned encoding)
1899{
1900 uint32_t n;
1901 const uint8_t *value;
1902
1903 /* I believe it's ok if this is called with a NULL tree */
1904 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1905 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1906 length += n;
1907 *ret_length = length;
1908 return value;
1909}
1910
1911/* For FT_STRINGZPAD */
1912static inline const uint8_t *
1913get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1914 int length, int *ret_length, const unsigned encoding)
1915{
1916 /*
1917 * XXX - currently, string values are null-
1918 * terminated, so a "zero-padded" string
1919 * isn't special. If we represent string
1920 * values as something that includes a counted
1921 * array of bytes, we'll need to strip the
1922 * trailing NULs.
1923 */
1924 if (length == -1) {
1925 length = tvb_ensure_captured_length_remaining(tvb, start);
1926 }
1927 *ret_length = length;
1928 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1929}
1930
1931/* For FT_STRINGZTRUNC */
1932static inline const uint8_t *
1933get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1934 int length, int *ret_length, const unsigned encoding)
1935{
1936 /*
1937 * XXX - currently, string values are null-
1938 * terminated, so a "zero-truncated" string
1939 * isn't special. If we represent string
1940 * values as something that includes a counted
1941 * array of bytes, we'll need to strip everything
1942 * starting with the terminating NUL.
1943 */
1944 if (length == -1) {
1945 length = tvb_ensure_captured_length_remaining(tvb, start);
1946 }
1947 *ret_length = length;
1948 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1949}
1950
1951/*
1952 * Deltas between the epochs for various non-UN*X time stamp formats and
1953 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1954 * stamp format.
1955 */
1956
1957/*
1958 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1959 * XXX - if it's OK if this is unsigned, can we just use
1960 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1961 */
1962#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1963
1964/*
1965 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1966 */
1967#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1968
1969/* this can be called when there is no tree, so tree may be null */
1970static void
1971get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1972 const int length, const unsigned encoding, nstime_t *time_stamp,
1973 const bool_Bool is_relative)
1974{
1975 uint32_t tmpsecs;
1976 uint64_t tmp64secs;
1977 uint64_t todusecs;
1978
1979 switch (encoding) {
1980
1981 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1982 /*
1983 * If the length is 16, 8-byte seconds, followed
1984 * by 8-byte fractional time in nanoseconds,
1985 * both big-endian.
1986 *
1987 * If the length is 12, 8-byte seconds, followed
1988 * by 4-byte fractional time in nanoseconds,
1989 * both big-endian.
1990 *
1991 * If the length is 8, 4-byte seconds, followed
1992 * by 4-byte fractional time in nanoseconds,
1993 * both big-endian.
1994 *
1995 * For absolute times, the seconds are seconds
1996 * since the UN*X epoch.
1997 */
1998 if (length == 16) {
1999 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2000 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2001 } else if (length == 12) {
2002 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2003 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2004 } else if (length == 8) {
2005 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2006 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2007 } else if (length == 4) {
2008 /*
2009 * Backwards compatibility.
2010 * ENC_TIME_SECS_NSECS is 0; using
2011 * ENC_BIG_ENDIAN by itself with a 4-byte
2012 * time-in-seconds value was done in the
2013 * past.
2014 */
2015 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2016 time_stamp->nsecs = 0;
2017 } else {
2018 time_stamp->secs = 0;
2019 time_stamp->nsecs = 0;
2020 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2021 }
2022 break;
2023
2024 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2025 /*
2026 * If the length is 16, 8-byte seconds, followed
2027 * by 8-byte fractional time in nanoseconds,
2028 * both little-endian.
2029 *
2030 * If the length is 12, 8-byte seconds, followed
2031 * by 4-byte fractional time in nanoseconds,
2032 * both little-endian.
2033 *
2034 * If the length is 8, 4-byte seconds, followed
2035 * by 4-byte fractional time in nanoseconds,
2036 * both little-endian.
2037 *
2038 * For absolute times, the seconds are seconds
2039 * since the UN*X epoch.
2040 */
2041 if (length == 16) {
2042 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2043 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2044 } else if (length == 12) {
2045 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2046 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2047 } else if (length == 8) {
2048 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2049 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2050 } else if (length == 4) {
2051 /*
2052 * Backwards compatibility.
2053 * ENC_TIME_SECS_NSECS is 0; using
2054 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2055 * time-in-seconds value was done in the
2056 * past.
2057 */
2058 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2059 time_stamp->nsecs = 0;
2060 } else {
2061 time_stamp->secs = 0;
2062 time_stamp->nsecs = 0;
2063 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2064 }
2065 break;
2066
2067 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2068 /*
2069 * NTP time stamp, big-endian.
2070 * Only supported for absolute times.
2071 */
2072 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2072, "!is_relative"
))))
;
2073
2074 /* We need a temporary variable here so the unsigned math
2075 * works correctly (for years > 2036 according to RFC 2030
2076 * chapter 3).
2077 *
2078 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2079 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2080 * If bit 0 is not set, the time is in the range 2036-2104 and
2081 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2082 */
2083 tmpsecs = tvb_get_ntohl(tvb, start);
2084 if ((tmpsecs & 0x80000000) != 0)
2085 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2086 else
2087 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2088
2089 if (length == 8) {
2090 tmp64secs = tvb_get_ntoh64(tvb, start);
2091 if (tmp64secs == 0) {
2092 //This is "NULL" time
2093 time_stamp->secs = 0;
2094 time_stamp->nsecs = 0;
2095 } else {
2096 /*
2097 * Convert 1/2^32s of a second to
2098 * nanoseconds.
2099 */
2100 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2101 }
2102 } else if (length == 4) {
2103 /*
2104 * Backwards compatibility.
2105 */
2106 if (tmpsecs == 0) {
2107 //This is "NULL" time
2108 time_stamp->secs = 0;
2109 }
2110 time_stamp->nsecs = 0;
2111 } else {
2112 time_stamp->secs = 0;
2113 time_stamp->nsecs = 0;
2114 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2115 }
2116 break;
2117
2118 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2119 /*
2120 * NTP time stamp, little-endian.
2121 * Only supported for absolute times.
2122 *
2123 * NTP doesn't use this, because it's an Internet format
2124 * and hence big-endian. Any implementation must decide
2125 * whether the NTP timestamp is a 64-bit unsigned fixed
2126 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2127 * with a 32-bit unsigned seconds field followed by a
2128 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2129 * the previous two).
2130 *
2131 * XXX: We do the latter, but no dissector uses this format.
2132 * OTOH, ERF timestamps do the former, so perhaps we
2133 * should switch the interpretation so that packet-erf.c
2134 * could use this directly?
2135 */
2136 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2136, "!is_relative"
))))
;
2137
2138 /* We need a temporary variable here so the unsigned math
2139 * works correctly (for years > 2036 according to RFC 2030
2140 * chapter 3).
2141 *
2142 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2143 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2144 * If bit 0 is not set, the time is in the range 2036-2104 and
2145 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2146 */
2147 tmpsecs = tvb_get_letohl(tvb, start);
2148 if ((tmpsecs & 0x80000000) != 0)
2149 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2150 else
2151 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2152
2153 if (length == 8) {
2154 tmp64secs = tvb_get_letoh64(tvb, start);
2155 if (tmp64secs == 0) {
2156 //This is "NULL" time
2157 time_stamp->secs = 0;
2158 time_stamp->nsecs = 0;
2159 } else {
2160 /*
2161 * Convert 1/2^32s of a second to
2162 * nanoseconds.
2163 */
2164 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2165 }
2166 } else if (length == 4) {
2167 /*
2168 * Backwards compatibility.
2169 */
2170 if (tmpsecs == 0) {
2171 //This is "NULL" time
2172 time_stamp->secs = 0;
2173 }
2174 time_stamp->nsecs = 0;
2175 } else {
2176 time_stamp->secs = 0;
2177 time_stamp->nsecs = 0;
2178 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2179 }
2180 break;
2181
2182 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2183 /*
2184 * S/3x0 and z/Architecture TOD clock time stamp,
2185 * big-endian. The epoch is January 1, 1900,
2186 * 00:00:00 (proleptic?) UTC.
2187 *
2188 * Only supported for absolute times.
2189 */
2190 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2190, "!is_relative"
))))
;
2191 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2191, "length == 8"
))))
;
2192
2193 if (length == 8) {
2194 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2195 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2196 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2197 } else {
2198 time_stamp->secs = 0;
2199 time_stamp->nsecs = 0;
2200 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2201 }
2202 break;
2203
2204 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2205 /*
2206 * S/3x0 and z/Architecture TOD clock time stamp,
2207 * little-endian. The epoch is January 1, 1900,
2208 * 00:00:00 (proleptic?) UTC.
2209 *
2210 * Only supported for absolute times.
2211 */
2212 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2212, "!is_relative"
))))
;
2213
2214 if (length == 8) {
2215 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2216 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2217 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2218 } else {
2219 time_stamp->secs = 0;
2220 time_stamp->nsecs = 0;
2221 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2222 }
2223 break;
2224
2225 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2226 /*
2227 * Time stamp using the same seconds/fraction format
2228 * as NTP, but with the origin of the time stamp being
2229 * the UNIX epoch rather than the NTP epoch; big-
2230 * endian.
2231 *
2232 * Only supported for absolute times.
2233 */
2234 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2234, "!is_relative"
))))
;
2235
2236 if (length == 8) {
2237 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2238 /*
2239 * Convert 1/2^32s of a second to nanoseconds.
2240 */
2241 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2242 } else {
2243 time_stamp->secs = 0;
2244 time_stamp->nsecs = 0;
2245 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2246 }
2247 break;
2248
2249 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2250 /*
2251 * Time stamp using the same seconds/fraction format
2252 * as NTP, but with the origin of the time stamp being
2253 * the UNIX epoch rather than the NTP epoch; little-
2254 * endian.
2255 *
2256 * Only supported for absolute times.
2257 *
2258 * The RTPS specification explicitly supports Little
2259 * Endian encoding. In one place, it states that its
2260 * Time_t representation "is the one defined by ...
2261 * RFC 1305", but in another explicitly defines it as
2262 * a struct consisting of an 32 bit unsigned seconds
2263 * field and a 32 bit unsigned fraction field, not a 64
2264 * bit fixed point, so we do that here.
2265 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2266 */
2267 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2267, "!is_relative"
))))
;
2268
2269 if (length == 8) {
2270 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2271 /*
2272 * Convert 1/2^32s of a second to nanoseconds.
2273 */
2274 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2275 } else {
2276 time_stamp->secs = 0;
2277 time_stamp->nsecs = 0;
2278 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2279 }
2280 break;
2281
2282 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2283 /*
2284 * MIP6 time stamp, big-endian.
2285 * A 64-bit unsigned integer field containing a timestamp. The
2286 * value indicates the number of seconds since January 1, 1970,
2287 * 00:00 UTC, by using a fixed point format. In this format, the
2288 * integer number of seconds is contained in the first 48 bits of
2289 * the field, and the remaining 16 bits indicate the number of
2290 * 1/65536 fractions of a second.
2291
2292 * Only supported for absolute times.
2293 */
2294 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2294, "!is_relative"
))))
;
2295
2296 if (length == 8) {
2297 /* We need a temporary variable here so the casting and fractions
2298 * of a second work correctly.
2299 */
2300 tmp64secs = tvb_get_ntoh48(tvb, start);
2301 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2302 tmpsecs <<= 16;
2303
2304 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2305 //This is "NULL" time
2306 time_stamp->secs = 0;
2307 time_stamp->nsecs = 0;
2308 } else {
2309 time_stamp->secs = (time_t)tmp64secs;
2310 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2311 }
2312 } else {
2313 time_stamp->secs = 0;
2314 time_stamp->nsecs = 0;
2315 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2316 }
2317 break;
2318
2319 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2320 /*
2321 * If the length is 16, 8-byte seconds, followed
2322 * by 8-byte fractional time in microseconds,
2323 * both big-endian.
2324 *
2325 * If the length is 12, 8-byte seconds, followed
2326 * by 4-byte fractional time in microseconds,
2327 * both big-endian.
2328 *
2329 * If the length is 8, 4-byte seconds, followed
2330 * by 4-byte fractional time in microseconds,
2331 * both big-endian.
2332 *
2333 * For absolute times, the seconds are seconds
2334 * since the UN*X epoch.
2335 */
2336 if (length == 16) {
2337 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2338 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2339 } else if (length == 12) {
2340 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2341 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2342 } else if (length == 8) {
2343 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2344 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2345 } else {
2346 time_stamp->secs = 0;
2347 time_stamp->nsecs = 0;
2348 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2349 }
2350 break;
2351
2352 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2353 /*
2354 * If the length is 16, 8-byte seconds, followed
2355 * by 8-byte fractional time in microseconds,
2356 * both little-endian.
2357 *
2358 * If the length is 12, 8-byte seconds, followed
2359 * by 4-byte fractional time in microseconds,
2360 * both little-endian.
2361 *
2362 * If the length is 8, 4-byte seconds, followed
2363 * by 4-byte fractional time in microseconds,
2364 * both little-endian.
2365 *
2366 * For absolute times, the seconds are seconds
2367 * since the UN*X epoch.
2368 */
2369 if (length == 16) {
2370 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2371 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2372 } else if (length == 12) {
2373 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2374 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2375 } else if (length == 8) {
2376 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2377 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2378 } else {
2379 time_stamp->secs = 0;
2380 time_stamp->nsecs = 0;
2381 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2382 }
2383 break;
2384
2385 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2386 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2387 /*
2388 * Seconds, 1 to 8 bytes.
2389 * For absolute times, it's seconds since the
2390 * UN*X epoch.
2391 */
2392 if (length >= 1 && length <= 8) {
2393 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2394 time_stamp->nsecs = 0;
2395 } else {
2396 time_stamp->secs = 0;
2397 time_stamp->nsecs = 0;
2398 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2399 }
2400 break;
2401
2402 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2403 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2404 /*
2405 * Milliseconds, 1 to 8 bytes.
2406 * For absolute times, it's milliseconds since the
2407 * UN*X epoch.
2408 */
2409 if (length >= 1 && length <= 8) {
2410 uint64_t msecs;
2411
2412 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2413 time_stamp->secs = (time_t)(msecs / 1000);
2414 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2415 } else {
2416 time_stamp->secs = 0;
2417 time_stamp->nsecs = 0;
2418 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2419 }
2420 break;
2421
2422 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2423 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2424 /*
2425 * Microseconds, 1 to 8 bytes.
2426 * For absolute times, it's microseconds since the
2427 * UN*X epoch.
2428 */
2429 if (length >= 1 && length <= 8) {
2430 uint64_t usecs;
2431
2432 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2433 time_stamp->secs = (time_t)(usecs / 1000000);
2434 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2435 } else {
2436 time_stamp->secs = 0;
2437 time_stamp->nsecs = 0;
2438 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2439 }
2440 break;
2441
2442 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2443 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2444 /*
2445 * nanoseconds, 1 to 8 bytes.
2446 * For absolute times, it's nanoseconds since the
2447 * UN*X epoch.
2448 */
2449
2450 if (length >= 1 && length <= 8) {
2451 uint64_t nsecs;
2452
2453 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2454 time_stamp->secs = (time_t)(nsecs / 1000000000);
2455 time_stamp->nsecs = (int)(nsecs % 1000000000);
2456 } else {
2457 time_stamp->secs = 0;
2458 time_stamp->nsecs = 0;
2459 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2460 }
2461 break;
2462
2463 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2464 /*
2465 * 1/64ths of a second since the UN*X epoch,
2466 * big-endian.
2467 *
2468 * Only supported for absolute times.
2469 */
2470 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2470, "!is_relative"
))))
;
2471
2472 if (length == 8) {
2473 /*
2474 * The upper 48 bits are seconds since the
2475 * UN*X epoch.
2476 */
2477 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2478 /*
2479 * The lower 16 bits are 1/2^16s of a second;
2480 * convert them to nanoseconds.
2481 *
2482 * XXX - this may give the impression of higher
2483 * precision than you actually get.
2484 */
2485 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2486 } else {
2487 time_stamp->secs = 0;
2488 time_stamp->nsecs = 0;
2489 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2490 }
2491 break;
2492
2493 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2494 /*
2495 * 1/64ths of a second since the UN*X epoch,
2496 * little-endian.
2497 *
2498 * Only supported for absolute times.
2499 */
2500 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2500, "!is_relative"
))))
;
2501
2502 if (length == 8) {
2503 /*
2504 * XXX - this is assuming that, if anybody
2505 * were ever to use this format - RFC 3971
2506 * doesn't, because that's an Internet
2507 * protocol, and those use network byte
2508 * order, i.e. big-endian - they'd treat it
2509 * as a 64-bit count of 1/2^16s of a second,
2510 * putting the upper 48 bits at the end.
2511 *
2512 * The lower 48 bits are seconds since the
2513 * UN*X epoch.
2514 */
2515 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2516 /*
2517 * The upper 16 bits are 1/2^16s of a second;
2518 * convert them to nanoseconds.
2519 *
2520 * XXX - this may give the impression of higher
2521 * precision than you actually get.
2522 */
2523 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2524 } else {
2525 time_stamp->secs = 0;
2526 time_stamp->nsecs = 0;
2527 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2528 }
2529 break;
2530
2531 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2532 /*
2533 * NTP time stamp, with 1-second resolution (i.e.,
2534 * seconds since the NTP epoch), big-endian.
2535 * Only supported for absolute times.
2536 */
2537 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2537, "!is_relative"
))))
;
2538
2539 if (length == 4) {
2540 /*
2541 * We need a temporary variable here so the unsigned math
2542 * works correctly (for years > 2036 according to RFC 2030
2543 * chapter 3).
2544 *
2545 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2546 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2547 * If bit 0 is not set, the time is in the range 2036-2104 and
2548 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2549 */
2550 tmpsecs = tvb_get_ntohl(tvb, start);
2551 if ((tmpsecs & 0x80000000) != 0)
2552 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2553 else
2554 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2555 time_stamp->nsecs = 0;
2556 } else {
2557 time_stamp->secs = 0;
2558 time_stamp->nsecs = 0;
2559 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2560 }
2561 break;
2562
2563 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2564 /*
2565 * NTP time stamp, with 1-second resolution (i.e.,
2566 * seconds since the NTP epoch), little-endian.
2567 * Only supported for absolute times.
2568 */
2569 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2569, "!is_relative"
))))
;
2570
2571 /*
2572 * We need a temporary variable here so the unsigned math
2573 * works correctly (for years > 2036 according to RFC 2030
2574 * chapter 3).
2575 *
2576 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2577 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2578 * If bit 0 is not set, the time is in the range 2036-2104 and
2579 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2580 */
2581 if (length == 4) {
2582 tmpsecs = tvb_get_letohl(tvb, start);
2583 if ((tmpsecs & 0x80000000) != 0)
2584 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2585 else
2586 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2587 time_stamp->nsecs = 0;
2588 } else {
2589 time_stamp->secs = 0;
2590 time_stamp->nsecs = 0;
2591 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2592 }
2593 break;
2594
2595 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2596 /*
2597 * Milliseconds, 6 to 8 bytes.
2598 * For absolute times, it's milliseconds since the
2599 * NTP epoch.
2600 *
2601 * ETSI TS 129.274 8.119 defines this as:
2602 * "a 48 bit unsigned integer in network order format
2603 * ...encoded as the number of milliseconds since
2604 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2605 * rounded value of 1000 x the value of the 64-bit
2606 * timestamp (Seconds + (Fraction / (1<<32))) defined
2607 * in clause 6 of IETF RFC 5905."
2608 *
2609 * Taken literally, the part after "i.e." would
2610 * mean that the value rolls over before reaching
2611 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2612 * when the 64 bit timestamp rolls over, and we have
2613 * to pick an NTP Era equivalence class to support
2614 * (such as 1968-01-20 to 2104-02-06).
2615 *
2616 * OTOH, the extra room might be used to store Era
2617 * information instead, in which case times until
2618 * 10819-08-03 can be represented with 6 bytes without
2619 * ambiguity. We handle both implementations, and assume
2620 * that times before 1968-01-20 are not represented.
2621 *
2622 * Only 6 bytes or more makes sense as an absolute
2623 * time. 5 bytes or fewer could express a span of
2624 * less than 35 years, either 1900-1934 or 2036-2070.
2625 */
2626 if (length >= 6 && length <= 8) {
2627 uint64_t msecs;
2628
2629 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2630 tmp64secs = (msecs / 1000);
2631 /*
2632 * Assume that times in the first half of NTP
2633 * Era 0 really represent times in the NTP
2634 * Era 1.
2635 */
2636 if (tmp64secs >= 0x80000000)
2637 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2638 else
2639 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2640 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2641 }
2642 else {
2643 time_stamp->secs = 0;
2644 time_stamp->nsecs = 0;
2645 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2646 }
2647 break;
2648
2649 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2650 /*
2651 * MP4 file time stamps, big-endian.
2652 * Only supported for absolute times.
2653 */
2654 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2654, "!is_relative"
))))
;
2655
2656 if (length == 8) {
2657 tmp64secs = tvb_get_ntoh64(tvb, start);
2658 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2659 time_stamp->nsecs = 0;
2660 } else if (length == 4) {
2661 tmpsecs = tvb_get_ntohl(tvb, start);
2662 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2663 time_stamp->nsecs = 0;
2664 } else {
2665 time_stamp->secs = 0;
2666 time_stamp->nsecs = 0;
2667 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2668 }
2669 break;
2670
2671 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2672 /*
2673 * Zigbee ZCL time stamps, big-endian.
2674 * Only supported for absolute times.
2675 */
2676 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2676, "!is_relative"
))))
;
2677
2678 if (length == 8) {
2679 tmp64secs = tvb_get_ntoh64(tvb, start);
2680 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2681 time_stamp->nsecs = 0;
2682 } else if (length == 4) {
2683 tmpsecs = tvb_get_ntohl(tvb, start);
2684 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2685 time_stamp->nsecs = 0;
2686 } else {
2687 time_stamp->secs = 0;
2688 time_stamp->nsecs = 0;
2689 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2690 }
2691 break;
2692
2693 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2694 /*
2695 * Zigbee ZCL time stamps, little-endian.
2696 * Only supported for absolute times.
2697 */
2698 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2698, "!is_relative"
))))
;
2699
2700 if (length == 8) {
2701 tmp64secs = tvb_get_letoh64(tvb, start);
2702 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2703 time_stamp->nsecs = 0;
2704 } else if (length == 4) {
2705 tmpsecs = tvb_get_letohl(tvb, start);
2706 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2707 time_stamp->nsecs = 0;
2708 } else {
2709 time_stamp->secs = 0;
2710 time_stamp->nsecs = 0;
2711 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2712 }
2713 break;
2714
2715 default:
2716 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2716))
;
2717 break;
2718 }
2719}
2720
2721static void
2722tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2723{
2724 const header_field_info *hfinfo = fi->hfinfo;
2725
2726 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2727 GPtrArray *ptrs = NULL((void*)0);
2728
2729 if (tree_data->interesting_hfids == NULL((void*)0)) {
2730 /* Initialize the hash because we now know that it is needed */
2731 tree_data->interesting_hfids =
2732 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2733 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2734 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2735 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2736 }
2737
2738 if (!ptrs) {
2739 /* First element triggers the creation of pointer array */
2740 ptrs = g_ptr_array_new();
2741 g_hash_table_insert(tree_data->interesting_hfids,
2742 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2743 }
2744
2745 g_ptr_array_add(ptrs, fi);
2746 }
2747}
2748
2749
2750/*
2751 * Validates that field length bytes are available starting from
2752 * start (pos/neg). Throws an exception if they aren't.
2753 */
2754static void
2755test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2756 int start, int length, const unsigned encoding)
2757{
2758 int size = length;
2759
2760 if (!tvb)
2761 return;
2762
2763 if ((hfinfo->type == FT_STRINGZ) ||
2764 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2765 (FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
|| FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
))) {
2766 /* If we're fetching until the end of the TVB, only validate
2767 * that the offset is within range.
2768 */
2769 if (length == -1)
2770 size = 0;
2771 }
2772
2773 tvb_ensure_bytes_exist(tvb, start, size);
2774}
2775
2776static void
2777detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2778{
2779 bool_Bool found_stray_character = false0;
2780
2781 if (!string)
2782 return;
2783
2784 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2785 case ENC_ASCII0x00000000:
2786 case ENC_UTF_80x00000002:
2787 for (int i = (int)strlen(string); i < length; i++) {
2788 if (string[i] != '\0') {
2789 found_stray_character = true1;
2790 break;
2791 }
2792 }
2793 break;
2794
2795 default:
2796 break;
2797 }
2798
2799 if (found_stray_character) {
2800 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2801 }
2802}
2803
2804static void
2805free_fvalue_cb(void *data)
2806{
2807 fvalue_t *fv = (fvalue_t*)data;
2808 fvalue_free(fv);
2809}
2810
2811/* Add an item to a proto_tree, using the text label registered to that item;
2812 the item is extracted from the tvbuff handed to it. */
2813static proto_item *
2814proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2815 tvbuff_t *tvb, int start, int length,
2816 unsigned encoding)
2817{
2818 proto_item *pi;
2819 uint32_t value, n;
2820 uint64_t value64;
2821 ws_in4_addr ipv4_value;
2822 float floatval;
2823 double doubleval;
2824 const char *stringval = NULL((void*)0);
2825 nstime_t time_stamp;
2826 bool_Bool length_error;
2827
2828 /* Ensure that the newly created fvalue_t is freed if we throw an
2829 * exception before adding it to the tree. (gcc creates clobbering
2830 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2831 * XXX: Move the new_field_info() call inside here?
2832 */
2833 CLEANUP_PUSH(free_fvalue_cb, new_fi->value){ struct except_stacknode except_sn; struct except_cleanup except_cl
; except_setup_clean(&except_sn, &except_cl, (free_fvalue_cb
), (new_fi->value))
;
2834
2835 switch (new_fi->hfinfo->type) {
2836 case FT_NONE:
2837 /* no value to set for FT_NONE */
2838 break;
2839
2840 case FT_PROTOCOL:
2841 /* Set the protocol_tvb via the start offset, but include
2842 * rest of the ds_tvb so that if finfo_set_len is called
2843 * later it can be lengthened as much as possible. */
2844 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);
2845 break;
2846
2847 case FT_BYTES:
2848 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2849 break;
2850
2851 case FT_UINT_BYTES:
2852 n = get_uint_value(tree, tvb, start, length, encoding);
2853 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2854
2855 /* Instead of calling proto_item_set_len(), since we don't yet
2856 * have a proto_item, we set the field_info's length ourselves. */
2857 new_fi->length = n + length;
2858 break;
2859
2860 case FT_BOOLEAN:
2861 /*
2862 * Map all non-zero values to little-endian for
2863 * backwards compatibility.
2864 */
2865 if (encoding)
2866 encoding = ENC_LITTLE_ENDIAN0x80000000;
2867 proto_tree_set_boolean(new_fi,
2868 get_uint64_value(tree, tvb, start, length, encoding));
2869 break;
2870
2871 case FT_CHAR:
2872 /* XXX - make these just FT_UINT? */
2873 case FT_UINT8:
2874 case FT_UINT16:
2875 case FT_UINT24:
2876 case FT_UINT32:
2877 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2878 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2879 value = (uint32_t)value64;
2880 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2881 new_fi->flags |= FI_VARINT0x00040000;
2882 }
2883 }
2884 else {
2885 /*
2886 * Map all non-zero values to little-endian for
2887 * backwards compatibility.
2888 */
2889 if (encoding)
2890 encoding = ENC_LITTLE_ENDIAN0x80000000;
2891
2892 value = get_uint_value(tree, tvb, start, length, encoding);
2893 }
2894 proto_tree_set_uint(new_fi, value);
2895 break;
2896
2897 case FT_UINT40:
2898 case FT_UINT48:
2899 case FT_UINT56:
2900 case FT_UINT64:
2901 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2902 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2903 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2904 new_fi->flags |= FI_VARINT0x00040000;
2905 }
2906 }
2907 else {
2908 /*
2909 * Map all other non-zero values to little-endian for
2910 * backwards compatibility.
2911 */
2912 if (encoding)
2913 encoding = ENC_LITTLE_ENDIAN0x80000000;
2914
2915 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2916 }
2917 proto_tree_set_uint64(new_fi, value64);
2918 break;
2919
2920 /* XXX - make these just FT_INT? */
2921 case FT_INT8:
2922 case FT_INT16:
2923 case FT_INT24:
2924 case FT_INT32:
2925 /*
2926 * Map all non-zero values to little-endian for
2927 * backwards compatibility.
2928 */
2929 if (encoding)
2930 encoding = ENC_LITTLE_ENDIAN0x80000000;
2931 proto_tree_set_int(new_fi,
2932 get_int_value(tree, tvb, start, length, encoding));
2933 break;
2934
2935 case FT_INT40:
2936 case FT_INT48:
2937 case FT_INT56:
2938 case FT_INT64:
2939 /*
2940 * Map all non-zero values to little-endian for
2941 * backwards compatibility.
2942 */
2943 if (encoding)
2944 encoding = ENC_LITTLE_ENDIAN0x80000000;
2945 proto_tree_set_int64(new_fi,
2946 get_int64_value(tree, tvb, start, length, encoding));
2947 break;
2948
2949 case FT_IPv4:
2950 /*
2951 * Map all non-zero values to little-endian for
2952 * backwards compatibility.
2953 */
2954 if (encoding)
2955 encoding = ENC_LITTLE_ENDIAN0x80000000;
2956 if (length != FT_IPv4_LEN4) {
2957 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2958 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2959 }
2960 ipv4_value = tvb_get_ipv4(tvb, start);
2961 /*
2962 * NOTE: to support code written when
2963 * proto_tree_add_item() took a bool as its
2964 * last argument, with false meaning "big-endian"
2965 * and true meaning "little-endian", we treat any
2966 * non-zero value of "encoding" as meaning
2967 * "little-endian".
2968 */
2969 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);
2970 break;
2971
2972 case FT_IPXNET:
2973 if (length != FT_IPXNET_LEN4) {
2974 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2975 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2976 }
2977 proto_tree_set_ipxnet(new_fi,
2978 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2979 break;
2980
2981 case FT_IPv6:
2982 if (length != FT_IPv6_LEN16) {
2983 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2984 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2985 }
2986 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2987 break;
2988
2989 case FT_FCWWN:
2990 if (length != FT_FCWWN_LEN8) {
2991 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2992 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2993 }
2994 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2995 break;
2996
2997 case FT_AX25:
2998 if (length != 7) {
2999 length_error = length < 7 ? true1 : false0;
3000 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3001 }
3002 proto_tree_set_ax25_tvb(new_fi, tvb, start);
3003 break;
3004
3005 case FT_VINES:
3006 if (length != VINES_ADDR_LEN6) {
3007 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3008 report_type_length_mismatch(tree, "a Vines address", length, length_error);
3009 }
3010 proto_tree_set_vines_tvb(new_fi, tvb, start);
3011 break;
3012
3013 case FT_ETHER:
3014 if (length != FT_ETHER_LEN6) {
3015 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3016 report_type_length_mismatch(tree, "a MAC address", length, length_error);
3017 }
3018 proto_tree_set_ether_tvb(new_fi, tvb, start);
3019 break;
3020
3021 case FT_EUI64:
3022 /*
3023 * Map all non-zero values to little-endian for
3024 * backwards compatibility.
3025 */
3026 if (encoding)
3027 encoding = ENC_LITTLE_ENDIAN0x80000000;
3028 if (length != FT_EUI64_LEN8) {
3029 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3030 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3031 }
3032 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3033 break;
3034 case FT_GUID:
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_GUID_LEN16) {
3042 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3043 report_type_length_mismatch(tree, "a GUID", length, length_error);
3044 }
3045 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3046 break;
3047
3048 case FT_OID:
3049 case FT_REL_OID:
3050 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3051 break;
3052
3053 case FT_SYSTEM_ID:
3054 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3055 break;
3056
3057 case FT_FLOAT:
3058 /*
3059 * NOTE: to support code written when
3060 * proto_tree_add_item() took a bool as its
3061 * last argument, with false meaning "big-endian"
3062 * and true meaning "little-endian", we treat any
3063 * non-zero value of "encoding" as meaning
3064 * "little-endian".
3065 *
3066 * At some point in the future, we might
3067 * support non-IEEE-binary floating-point
3068 * formats in the encoding as well
3069 * (IEEE decimal, System/3x0, VAX).
3070 */
3071 if (encoding)
3072 encoding = ENC_LITTLE_ENDIAN0x80000000;
3073 if (length != 4) {
3074 length_error = length < 4 ? true1 : false0;
3075 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3076 }
3077 if (encoding)
3078 floatval = tvb_get_letohieee_float(tvb, start);
3079 else
3080 floatval = tvb_get_ntohieee_float(tvb, start);
3081 proto_tree_set_float(new_fi, floatval);
3082 break;
3083
3084 case FT_DOUBLE:
3085 /*
3086 * NOTE: to support code written when
3087 * proto_tree_add_item() took a bool as its
3088 * last argument, with false meaning "big-endian"
3089 * and true meaning "little-endian", we treat any
3090 * non-zero value of "encoding" as meaning
3091 * "little-endian".
3092 *
3093 * At some point in the future, we might
3094 * support non-IEEE-binary floating-point
3095 * formats in the encoding as well
3096 * (IEEE decimal, System/3x0, VAX).
3097 */
3098 if (encoding == true1)
3099 encoding = ENC_LITTLE_ENDIAN0x80000000;
3100 if (length != 8) {
3101 length_error = length < 8 ? true1 : false0;
3102 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3103 }
3104 if (encoding)
3105 doubleval = tvb_get_letohieee_double(tvb, start);
3106 else
3107 doubleval = tvb_get_ntohieee_double(tvb, start);
3108 proto_tree_set_double(new_fi, doubleval);
3109 break;
3110
3111 case FT_STRING:
3112 stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3113 tvb, start, length, &length, encoding);
3114 proto_tree_set_string(new_fi, stringval);
3115
3116 /* Instead of calling proto_item_set_len(), since we
3117 * don't yet have a proto_item, we set the
3118 * field_info's length ourselves.
3119 *
3120 * XXX - our caller can't use that length to
3121 * advance an offset unless they arrange that
3122 * there always be a protocol tree into which
3123 * we're putting this item.
3124 */
3125 new_fi->length = length;
3126 break;
3127
3128 case FT_STRINGZ:
3129 stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3130 tree, tvb, start, length, &length, encoding);
3131 proto_tree_set_string(new_fi, stringval);
3132
3133 /* Instead of calling proto_item_set_len(),
3134 * since we don't yet have a proto_item, we
3135 * set the field_info's length ourselves.
3136 *
3137 * XXX - our caller can't use that length to
3138 * advance an offset unless they arrange that
3139 * there always be a protocol tree into which
3140 * we're putting this item.
3141 */
3142 new_fi->length = length;
3143 break;
3144
3145 case FT_UINT_STRING:
3146 /*
3147 * NOTE: to support code written when
3148 * proto_tree_add_item() took a bool as its
3149 * last argument, with false meaning "big-endian"
3150 * and true meaning "little-endian", if the
3151 * encoding value is true, treat that as
3152 * ASCII with a little-endian length.
3153 *
3154 * This won't work for code that passes
3155 * arbitrary non-zero values; that code
3156 * will need to be fixed.
3157 */
3158 if (encoding == true1)
3159 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3160 stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3161 tree, tvb, start, length, &length, encoding);
3162 proto_tree_set_string(new_fi, stringval);
3163
3164 /* Instead of calling proto_item_set_len(), since we
3165 * don't yet have a proto_item, we set the
3166 * field_info's length ourselves.
3167 *
3168 * XXX - our caller can't use that length to
3169 * advance an offset unless they arrange that
3170 * there always be a protocol tree into which
3171 * we're putting this item.
3172 */
3173 new_fi->length = length;
3174 break;
3175
3176 case FT_STRINGZPAD:
3177 stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3178 tvb, start, length, &length, encoding);
3179 proto_tree_set_string(new_fi, stringval);
3180
3181 /* Instead of calling proto_item_set_len(), since we
3182 * don't yet have a proto_item, we set the
3183 * field_info's length ourselves.
3184 *
3185 * XXX - our caller can't use that length to
3186 * advance an offset unless they arrange that
3187 * there always be a protocol tree into which
3188 * we're putting this item.
3189 */
3190 new_fi->length = length;
3191 break;
3192
3193 case FT_STRINGZTRUNC:
3194 stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3195 tvb, start, length, &length, encoding);
3196 proto_tree_set_string(new_fi, stringval);
3197
3198 /* Instead of calling proto_item_set_len(), since we
3199 * don't yet have a proto_item, we set the
3200 * field_info's length ourselves.
3201 *
3202 * XXX - our caller can't use that length to
3203 * advance an offset unless they arrange that
3204 * there always be a protocol tree into which
3205 * we're putting this item.
3206 */
3207 new_fi->length = length;
3208 break;
3209
3210 case FT_ABSOLUTE_TIME:
3211 /*
3212 * Absolute times can be in any of a number of
3213 * formats, and they can be big-endian or
3214 * little-endian.
3215 *
3216 * Historically FT_TIMEs were only timespecs;
3217 * the only question was whether they were stored
3218 * in big- or little-endian format.
3219 *
3220 * For backwards compatibility, we interpret an
3221 * encoding of 1 as meaning "little-endian timespec",
3222 * so that passing true is interpreted as that.
3223 */
3224 if (encoding == true1)
3225 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3226
3227 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3228
3229 proto_tree_set_time(new_fi, &time_stamp);
3230 break;
3231
3232 case FT_RELATIVE_TIME:
3233 /*
3234 * Relative times can be in any of a number of
3235 * formats, and they can be big-endian or
3236 * little-endian.
3237 *
3238 * Historically FT_TIMEs were only timespecs;
3239 * the only question was whether they were stored
3240 * in big- or little-endian format.
3241 *
3242 * For backwards compatibility, we interpret an
3243 * encoding of 1 as meaning "little-endian timespec",
3244 * so that passing true is interpreted as that.
3245 */
3246 if (encoding == true1)
3247 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3248
3249 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3250
3251 proto_tree_set_time(new_fi, &time_stamp);
3252 break;
3253 case FT_IEEE_11073_SFLOAT:
3254 if (encoding)
3255 encoding = ENC_LITTLE_ENDIAN0x80000000;
3256 if (length != 2) {
3257 length_error = length < 2 ? true1 : false0;
3258 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3259 }
3260
3261 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3262
3263 break;
3264 case FT_IEEE_11073_FLOAT:
3265 if (encoding)
3266 encoding = ENC_LITTLE_ENDIAN0x80000000;
3267 if (length != 4) {
3268 length_error = length < 4 ? true1 : false0;
3269 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3270 }
3271 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3272
3273 break;
3274 default:
3275 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))
3276 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))
3277 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))
3278 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))
;
3279 break;
3280 }
3281 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)
;
3282
3283 /* Don't add new node to proto_tree until now so that any exceptions
3284 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3285 /* XXX. wouldn't be better to add this item to tree, with some special
3286 * flag (FI_EXCEPTION?) to know which item caused exception? For
3287 * strings and bytes, we would have to set new_fi->value to something
3288 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3289 * could handle NULL values. */
3290 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3291 pi = proto_tree_add_node(tree, new_fi);
3292
3293 switch (new_fi->hfinfo->type) {
3294
3295 case FT_STRING:
3296 /* XXX: trailing stray character detection should be done
3297 * _before_ conversion to UTF-8, because conversion can change
3298 * the length, or else get_string_length should return a value
3299 * for the "length in bytes of the string after conversion
3300 * including internal nulls." (Noting that we do, for other
3301 * reasons, still need the "length in bytes in the field",
3302 * especially for FT_STRINGZ.)
3303 *
3304 * This is true even for ASCII and UTF-8, because
3305 * substituting REPLACEMENT CHARACTERS for illegal characters
3306 * can also do so (and for UTF-8 possibly even make the
3307 * string _shorter_).
3308 */
3309 detect_trailing_stray_characters(encoding, stringval, length, pi);
3310 break;
3311
3312 default:
3313 break;
3314 }
3315
3316 return pi;
3317}
3318
3319proto_item *
3320proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3321 const int start, int length,
3322 const unsigned encoding, int32_t *retval)
3323{
3324 header_field_info *hfinfo;
3325 field_info *new_fi;
3326 int32_t value;
3327
3328 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", 3328, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3328,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3328, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3329
3330 switch (hfinfo->type) {
3331 case FT_INT8:
3332 case FT_INT16:
3333 case FT_INT24:
3334 case FT_INT32:
3335 break;
3336 case FT_INT64:
3337 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)
3338 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3339 default:
3340 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)
3341 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3342 }
3343
3344 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3345 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3346 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3347 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3348 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3349 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3350 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3351
3352 if (encoding & ENC_STRING0x07000000) {
3353 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3354 }
3355 /* I believe it's ok if this is called with a NULL tree */
3356 value = get_int_value(tree, tvb, start, length, encoding);
3357
3358 if (retval) {
3359 int no_of_bits;
3360 *retval = value;
3361 if (hfinfo->bitmask) {
3362 /* Mask out irrelevant portions */
3363 *retval &= (uint32_t)(hfinfo->bitmask);
3364 /* Shift bits */
3365 *retval >>= hfinfo_bitshift(hfinfo);
3366 }
3367 no_of_bits = ws_count_ones(hfinfo->bitmask);
3368 *retval = ws_sign_ext32(*retval, no_of_bits);
3369 }
3370
3371 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3372
3373 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", 3373
, __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", 3373, "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", 3373, "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", 3373, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3374
3375 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3376
3377 proto_tree_set_int(new_fi, value);
3378
3379 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3380
3381 return proto_tree_add_node(tree, new_fi);
3382}
3383
3384proto_item *
3385proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3386 const int start, int length,
3387 const unsigned encoding, uint32_t *retval)
3388{
3389 header_field_info *hfinfo;
3390 field_info *new_fi;
3391 uint32_t value;
3392
3393 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", 3393, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3393,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3393, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3394
3395 switch (hfinfo->type) {
3396 case FT_CHAR:
3397 case FT_UINT8:
3398 case FT_UINT16:
3399 case FT_UINT24:
3400 case FT_UINT32:
3401 break;
3402 default:
3403 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)
3404 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)
;
3405 }
3406
3407 if (length == 0) {
3408 if (retval) {
3409 *retval = 0;
3410 }
3411 return NULL((void*)0);
3412 }
3413
3414 if (encoding & ENC_STRING0x07000000) {
3415 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3416 }
3417 /* I believe it's ok if this is called with a NULL tree */
3418 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3419 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3420 uint64_t temp64;
3421 tvb_get_varint(tvb, start, length, &temp64, encoding);
3422 value = (uint32_t)temp64;
3423 } else {
3424 value = get_uint_value(tree, tvb, start, length, encoding);
3425 }
3426
3427 if (retval) {
3428 *retval = value;
3429 if (hfinfo->bitmask) {
3430 /* Mask out irrelevant portions */
3431 *retval &= (uint32_t)(hfinfo->bitmask);
3432 /* Shift bits */
3433 *retval >>= hfinfo_bitshift(hfinfo);
3434 }
3435 }
3436
3437 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3438
3439 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", 3439
, __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", 3439, "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", 3439, "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", 3439, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3440
3441 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3442
3443 proto_tree_set_uint(new_fi, value);
3444
3445 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3446 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3447 new_fi->flags |= FI_VARINT0x00040000;
3448 }
3449 return proto_tree_add_node(tree, new_fi);
3450}
3451
3452proto_item *
3453proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3454 const int start, int length,
3455 const unsigned encoding, uint32_t *retval)
3456{
3457 return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3458}
3459
3460proto_item *
3461proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3462 const int start, int length,
3463 const unsigned encoding, uint8_t *retval)
3464{
3465 /* TODO: further restrict by hfinfo->type ? */
3466 uint32_t val32;
3467 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3468 *retval = (uint8_t)val32;
3469 return item;
3470}
3471
3472proto_item *
3473proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3474 const int start, int length,
3475 const unsigned encoding, uint16_t *retval)
3476{
3477 /* TODO: further restrict by hfinfo->type ? */
3478 uint32_t val32;
3479 proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3480 *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3481 return item;
3482}
3483
3484
3485/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3486 * and returns proto_item* and uint value retrieved*/
3487proto_item *
3488ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3489 const unsigned encoding, uint32_t *retval)
3490{
3491 field_info *new_fi;
3492 header_field_info *hfinfo;
3493 unsigned item_length;
3494 unsigned offset;
3495 uint32_t value;
3496
3497 offset = ptvc->offset;
3498 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", 3498, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3498,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3498, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3499
3500 switch (hfinfo->type) {
3501 case FT_CHAR:
3502 case FT_UINT8:
3503 case FT_UINT16:
3504 case FT_UINT24:
3505 case FT_UINT32:
3506 break;
3507 default:
3508 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)
3509 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)
;
3510 }
3511
3512 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3513 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3514
3515 /* I believe it's ok if this is called with a NULL tree */
3516 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3517 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3518
3519 if (retval) {
3520 *retval = value;
3521 if (hfinfo->bitmask) {
3522 /* Mask out irrelevant portions */
3523 *retval &= (uint32_t)(hfinfo->bitmask);
3524 /* Shift bits */
3525 *retval >>= hfinfo_bitshift(hfinfo);
3526 }
3527 }
3528
3529 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3530
3531 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3532
3533 /* Coast clear. Try and fake it */
3534 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", 3534
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3534, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3534, "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", 3534, __func__, "Adding %s would put more than %d 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); } } }
;
3535
3536 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3537
3538 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3539 offset, length, encoding);
3540}
3541
3542/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3543 * and returns proto_item* and int value retrieved*/
3544proto_item *
3545ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3546 const unsigned encoding, int32_t *retval)
3547{
3548 field_info *new_fi;
3549 header_field_info *hfinfo;
3550 unsigned item_length;
3551 unsigned offset;
3552 uint32_t value;
3553
3554 offset = ptvc->offset;
3555 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", 3555, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3555,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3555, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3556
3557 switch (hfinfo->type) {
3558 case FT_INT8:
3559 case FT_INT16:
3560 case FT_INT24:
3561 case FT_INT32:
3562 break;
3563 default:
3564 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)
3565 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3566 }
3567
3568 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3569 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3570
3571 /* I believe it's ok if this is called with a NULL tree */
3572 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3573 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3574
3575 if (retval) {
3576 int no_of_bits;
3577 *retval = value;
3578 if (hfinfo->bitmask) {
3579 /* Mask out irrelevant portions */
3580 *retval &= (uint32_t)(hfinfo->bitmask);
3581 /* Shift bits */
3582 *retval >>= hfinfo_bitshift(hfinfo);
3583 }
3584 no_of_bits = ws_count_ones(hfinfo->bitmask);
3585 *retval = ws_sign_ext32(*retval, no_of_bits);
3586 }
3587
3588 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3589
3590 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3591
3592 /* Coast clear. Try and fake it */
3593 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", 3593
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3593, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3593, "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", 3593, __func__, "Adding %s would put more than %d 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); } } }
;
3594
3595 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3596
3597 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3598 offset, length, encoding);
3599}
3600
3601/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3602 * and returns proto_item* and string value retrieved */
3603proto_item*
3604ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3605{
3606 header_field_info *hfinfo;
3607 field_info *new_fi;
3608 const uint8_t *value;
3609 unsigned item_length;
3610 unsigned offset;
3611
3612 offset = ptvc->offset;
3613
3614 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", 3614
, __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", 3614, "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", 3614, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3615
3616 switch (hfinfo->type) {
3617 case FT_STRING:
3618 value = get_string_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3619 break;
3620 case FT_STRINGZ:
3621 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3622 break;
3623 case FT_UINT_STRING:
3624 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3625 break;
3626 case FT_STRINGZPAD:
3627 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3628 break;
3629 case FT_STRINGZTRUNC:
3630 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3631 break;
3632 default:
3633 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)
3634 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)
;
3635 }
3636
3637 if (retval)
3638 *retval = value;
3639
3640 ptvcursor_advance(ptvc, item_length);
3641
3642 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3643
3644 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", 3644, __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", 3644,
"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", 3644, "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", 3644
, __func__, "Adding %s would put more than %d 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); } } }
;
3645
3646 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3647
3648 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3649 offset, length, encoding);
3650}
3651
3652/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3653 * and returns proto_item* and boolean value retrieved */
3654proto_item*
3655ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3656{
3657 header_field_info *hfinfo;
3658 field_info *new_fi;
3659 unsigned item_length;
3660 unsigned offset;
3661 uint64_t value, bitval;
3662
3663 offset = ptvc->offset;
3664 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", 3664, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3664,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3664, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3665
3666 if (hfinfo->type != FT_BOOLEAN) {
3667 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)
3668 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3669 }
3670
3671 if (length == 0) {
3672 if (retval) {
3673 *retval = 0;
3674 }
3675 return NULL((void*)0);
3676 }
3677 if (encoding & ENC_STRING0x07000000) {
3678 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3679 }
3680
3681 get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3682 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3683
3684 /* I believe it's ok if this is called with a NULL tree */
3685 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3686
3687 if (retval) {
3688 bitval = value;
3689 if (hfinfo->bitmask) {
3690 /* Mask out irrelevant portions */
3691 bitval &= hfinfo->bitmask;
3692 }
3693 *retval = (bitval != 0);
3694 }
3695
3696 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3697
3698 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3699
3700 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", 3700, __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", 3700,
"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", 3700, "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", 3700
, __func__, "Adding %s would put more than %d 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); } } }
;
3701
3702 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3703
3704 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3705 offset, length, encoding);
3706}
3707
3708proto_item *
3709proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3710 const int start, int length, const unsigned encoding, uint64_t *retval)
3711{
3712 header_field_info *hfinfo;
3713 field_info *new_fi;
3714 uint64_t value;
3715
3716 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", 3716, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3716,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3716, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3717
3718 switch (hfinfo->type) {
3719 case FT_UINT40:
3720 case FT_UINT48:
3721 case FT_UINT56:
3722 case FT_UINT64:
3723 break;
3724 default:
3725 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)
3726 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3727 }
3728
3729 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3730 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3731 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3732 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3733 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3734 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3735 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3736
3737 if (encoding & ENC_STRING0x07000000) {
3738 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3739 }
3740 /* I believe it's ok if this is called with a NULL tree */
3741 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3742 tvb_get_varint(tvb, start, length, &value, encoding);
3743 } else {
3744 value = get_uint64_value(tree, tvb, start, length, encoding);
3745 }
3746
3747 if (retval) {
3748 *retval = value;
3749 if (hfinfo->bitmask) {
3750 /* Mask out irrelevant portions */
3751 *retval &= hfinfo->bitmask;
3752 /* Shift bits */
3753 *retval >>= hfinfo_bitshift(hfinfo);
3754 }
3755 }
3756
3757 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3758
3759 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", 3759
, __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", 3759, "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", 3759, "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", 3759, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3760
3761 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3762
3763 proto_tree_set_uint64(new_fi, value);
3764
3765 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3766 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3767 new_fi->flags |= FI_VARINT0x00040000;
3768 }
3769
3770 return proto_tree_add_node(tree, new_fi);
3771}
3772
3773proto_item *
3774proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3775 const int start, int length, const unsigned encoding, int64_t *retval)
3776{
3777 header_field_info *hfinfo;
3778 field_info *new_fi;
3779 int64_t value;
3780
3781 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", 3781, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3781,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3781, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3782
3783 switch (hfinfo->type) {
3784 case FT_INT40:
3785 case FT_INT48:
3786 case FT_INT56:
3787 case FT_INT64:
3788 break;
3789 default:
3790 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)
3791 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3792 }
3793
3794 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3795 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3796 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3797 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3798 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3799 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3800 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3801
3802 if (encoding & ENC_STRING0x07000000) {
3803 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3804 }
3805 /* I believe it's ok if this is called with a NULL tree */
3806 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3807 tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3808 }
3809 else {
3810 value = get_int64_value(tree, tvb, start, length, encoding);
3811 }
3812
3813 if (retval) {
3814 *retval = value;
3815 }
3816
3817 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3818
3819 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", 3819
, __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", 3819, "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", 3819, "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", 3819, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3820
3821 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3822
3823 proto_tree_set_int64(new_fi, value);
3824
3825 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3826 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3827 new_fi->flags |= FI_VARINT0x00040000;
3828 }
3829
3830 return proto_tree_add_node(tree, new_fi);
3831}
3832
3833proto_item *
3834proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3835 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3836{
3837 header_field_info *hfinfo;
3838 field_info *new_fi;
3839 uint64_t value;
3840
3841 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", 3841, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3841,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3841, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3842
3843 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
))
)) {
3844 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)
3845 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3846 }
3847
3848 /* length validation for native number encoding caught by get_uint64_value() */
3849 /* length has to be -1 or > 0 regardless of encoding */
3850 if (length == 0)
3851 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
3852 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3853
3854 if (encoding & ENC_STRING0x07000000) {
3855 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3856 }
3857
3858 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3859
3860 if (retval) {
3861 *retval = value;
3862 if (hfinfo->bitmask) {
3863 /* Mask out irrelevant portions */
3864 *retval &= hfinfo->bitmask;
3865 /* Shift bits */
3866 *retval >>= hfinfo_bitshift(hfinfo);
3867 }
3868 }
3869
3870 if (lenretval) {
3871 *lenretval = length;
3872 }
3873
3874 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3875
3876 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", 3876
, __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", 3876, "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", 3876, "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", 3876, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3877
3878 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3879
3880 proto_tree_set_uint64(new_fi, value);
3881
3882 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3883 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3884 new_fi->flags |= FI_VARINT0x00040000;
3885 }
3886
3887 return proto_tree_add_node(tree, new_fi);
3888
3889}
3890
3891proto_item *
3892proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3893 const int start, int length,
3894 const unsigned encoding, bool_Bool *retval)
3895{
3896 header_field_info *hfinfo;
3897 field_info *new_fi;
3898 uint64_t value, bitval;
3899
3900 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", 3900, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3900,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3900, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3901
3902 if (hfinfo->type != FT_BOOLEAN) {
3903 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)
3904 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3905 }
3906
3907 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3908 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3909 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3910 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3911 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3912 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3913 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3914
3915 if (encoding & ENC_STRING0x07000000) {
3916 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3917 }
3918 /* I believe it's ok if this is called with a NULL tree */
3919 value = get_uint64_value(tree, tvb, start, length, encoding);
3920
3921 if (retval) {
3922 bitval = value;
3923 if (hfinfo->bitmask) {
3924 /* Mask out irrelevant portions */
3925 bitval &= hfinfo->bitmask;
3926 }
3927 *retval = (bitval != 0);
3928 }
3929
3930 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3931
3932 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", 3932
, __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", 3932, "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", 3932, "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", 3932, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3933
3934 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3935
3936 proto_tree_set_boolean(new_fi, value);
3937
3938 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3939
3940 return proto_tree_add_node(tree, new_fi);
3941}
3942
3943proto_item *
3944proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3945 const int start, int length,
3946 const unsigned encoding, float *retval)
3947{
3948 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3949 field_info *new_fi;
3950 float value;
3951
3952 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", 3952,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3953
3954 if (hfinfo->type != FT_FLOAT) {
3955 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)
;
3956 }
3957
3958 if (length != 4) {
3959 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3960 }
3961
3962 /* treat any nonzero encoding as little endian for backwards compatibility */
3963 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3964 if (retval) {
3965 *retval = value;
3966 }
3967
3968 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3969
3970 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", 3970
, __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", 3970, "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", 3970, "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", 3970, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3971
3972 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3973 if (encoding) {
3974 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3975 }
3976
3977 proto_tree_set_float(new_fi, value);
3978
3979 return proto_tree_add_node(tree, new_fi);
3980}
3981
3982proto_item *
3983proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3984 const int start, int length,
3985 const unsigned encoding, double *retval)
3986{
3987 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3988 field_info *new_fi;
3989 double value;
3990
3991 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", 3991,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3992
3993 if (hfinfo->type != FT_DOUBLE) {
3994 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)
;
3995 }
3996
3997 if (length != 8) {
3998 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3999 }
4000
4001 /* treat any nonzero encoding as little endian for backwards compatibility */
4002 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4003 if (retval) {
4004 *retval = value;
4005 }
4006
4007 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4008
4009 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", 4009
, __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", 4009, "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", 4009, "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", 4009, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4010
4011 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4012 if (encoding) {
4013 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4014 }
4015
4016 proto_tree_set_double(new_fi, value);
4017
4018 return proto_tree_add_node(tree, new_fi);
4019}
4020
4021proto_item *
4022proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4023 const int start, int length,
4024 const unsigned encoding, ws_in4_addr *retval)
4025{
4026 header_field_info *hfinfo;
4027 field_info *new_fi;
4028 ws_in4_addr value;
4029
4030 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", 4030, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4030,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4030, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4031
4032 switch (hfinfo->type) {
4033 case FT_IPv4:
4034 break;
4035 default:
4036 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)
4037 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
4038 }
4039
4040 if (length != FT_IPv4_LEN4)
4041 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)
4042 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
4043
4044 if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4045 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4046 }
4047
4048 /*
4049 * NOTE: to support code written when proto_tree_add_item() took
4050 * a bool as its last argument, with false meaning "big-endian"
4051 * and true meaning "little-endian", we treat any non-zero value
4052 * of "encoding" as meaning "little-endian".
4053 */
4054 value = tvb_get_ipv4(tvb, start);
4055 if (encoding)
4056 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))))
;
4057
4058 if (retval) {
4059 *retval = value;
4060 }
4061
4062 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4063
4064 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", 4064
, __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", 4064, "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", 4064, "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", 4064, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4065
4066 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4067
4068 proto_tree_set_ipv4(new_fi, value);
4069
4070 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4071 return proto_tree_add_node(tree, new_fi);
4072}
4073
4074proto_item *
4075proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4076 const int start, int length,
4077 const unsigned encoding, ws_in6_addr *addr)
4078{
4079 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4080 field_info *new_fi;
4081
4082 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", 4082,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4083
4084 switch (hfinfo->type) {
4085 case FT_IPv6:
4086 break;
4087 default:
4088 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)
4089 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4090 }
4091
4092 if (length != FT_IPv6_LEN16)
4093 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)
4094 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4095
4096 if (encoding) {
4097 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"
)
;
4098 }
4099
4100 tvb_get_ipv6(tvb, start, addr);
4101
4102 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4103
4104 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4104
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4104, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4104, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4104, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4105
4106 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4107
4108 proto_tree_set_ipv6(new_fi, addr);
4109
4110 return proto_tree_add_node(tree, new_fi);
4111}
4112
4113proto_item *
4114proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4115 const int start, int length, const unsigned encoding, uint8_t *retval) {
4116
4117 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4118 field_info *new_fi;
4119
4120 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", 4120,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4121
4122 switch (hfinfo->type) {
4123 case FT_ETHER:
4124 break;
4125 default:
4126 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)
4127 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4128 }
4129
4130 if (length != FT_ETHER_LEN6)
4131 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)
4132 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4133
4134 if (encoding) {
4135 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"
)
;
4136 }
4137
4138 tvb_memcpy(tvb, retval, start, length);
4139
4140 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4141
4142 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", 4142
, __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", 4142, "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", 4142, "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", 4142, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4143
4144 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4145
4146 proto_tree_set_ether(new_fi, retval);
4147
4148 return proto_tree_add_node(tree, new_fi);
4149}
4150
4151
4152proto_item *
4153proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4154 tvbuff_t *tvb,
4155 const int start, int length,
4156 const unsigned encoding,
4157 wmem_allocator_t *scope,
4158 const uint8_t **retval,
4159 int *lenretval)
4160{
4161 proto_item *pi;
4162 header_field_info *hfinfo;
4163 field_info *new_fi;
4164 const uint8_t *value;
4165
4166 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", 4166, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4166,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4167
4168 switch (hfinfo->type) {
4169 case FT_STRING:
4170 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4171 break;
4172 case FT_STRINGZ:
4173 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4174 break;
4175 case FT_UINT_STRING:
4176 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4177 break;
4178 case FT_STRINGZPAD:
4179 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4180 break;
4181 case FT_STRINGZTRUNC:
4182 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4183 break;
4184 default:
4185 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)
4186 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)
;
4187 }
4188
4189 if (retval)
4190 *retval = value;
4191
4192 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4193
4194 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", 4194
, __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", 4194, "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", 4194, "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", 4194, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4195
4196 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4197
4198 proto_tree_set_string(new_fi, (const char*)value);
4199
4200 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4201
4202 pi = proto_tree_add_node(tree, new_fi);
4203
4204 switch (hfinfo->type) {
4205
4206 case FT_STRINGZ:
4207 case FT_STRINGZPAD:
4208 case FT_STRINGZTRUNC:
4209 case FT_UINT_STRING:
4210 break;
4211
4212 case FT_STRING:
4213 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4214 break;
4215
4216 default:
4217 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4217
, __func__, "assertion \"not reached\" failed")
;
4218 }
4219
4220 return pi;
4221}
4222
4223proto_item *
4224proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4225 const int start, int length,
4226 const unsigned encoding, wmem_allocator_t *scope,
4227 const uint8_t **retval)
4228{
4229 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4230 tvb, start, length, encoding, scope, retval, &length);
4231}
4232
4233proto_item *
4234proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4235 tvbuff_t *tvb,
4236 const int start, int length,
4237 const unsigned encoding,
4238 wmem_allocator_t *scope,
4239 char **retval,
4240 int *lenretval)
4241{
4242 proto_item *pi;
4243 header_field_info *hfinfo;
4244 field_info *new_fi;
4245 const uint8_t *value;
4246 uint32_t n = 0;
4247
4248 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", 4248, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4248,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4248, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4249
4250 switch (hfinfo->type) {
4251 case FT_STRING:
4252 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4253 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4254 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4255 break;
4256 case FT_STRINGZ:
4257 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4258 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4259 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4260 break;
4261 case FT_UINT_STRING:
4262 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4263 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4264 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4265 break;
4266 case FT_STRINGZPAD:
4267 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4268 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4269 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4270 break;
4271 case FT_STRINGZTRUNC:
4272 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4273 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4274 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4275 break;
4276 case FT_BYTES:
4277 tvb_ensure_bytes_exist(tvb, start, length);
4278 value = tvb_get_ptr(tvb, start, length);
4279 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4280 *lenretval = length;
4281 break;
4282 case FT_UINT_BYTES:
4283 n = get_uint_value(tree, tvb, start, length, encoding);
4284 tvb_ensure_bytes_exist(tvb, start + length, n);
4285 value = tvb_get_ptr(tvb, start + length, n);
4286 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4287 *lenretval = length + n;
4288 break;
4289 default:
4290 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)
4291 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)
;
4292 }
4293
4294 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4295
4296 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", 4296
, __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", 4296, "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", 4296, "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", 4296, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4297
4298 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4299
4300 switch (hfinfo->type) {
4301
4302 case FT_STRING:
4303 case FT_STRINGZ:
4304 case FT_UINT_STRING:
4305 case FT_STRINGZPAD:
4306 case FT_STRINGZTRUNC:
4307 proto_tree_set_string(new_fi, (const char*)value);
4308 break;
4309
4310 case FT_BYTES:
4311 proto_tree_set_bytes(new_fi, value, length);
4312 break;
4313
4314 case FT_UINT_BYTES:
4315 proto_tree_set_bytes(new_fi, value, n);
4316 break;
4317
4318 default:
4319 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4319
, __func__, "assertion \"not reached\" failed")
;
4320 }
4321
4322 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4323
4324 pi = proto_tree_add_node(tree, new_fi);
4325
4326 switch (hfinfo->type) {
4327
4328 case FT_STRINGZ:
4329 case FT_STRINGZPAD:
4330 case FT_STRINGZTRUNC:
4331 case FT_UINT_STRING:
4332 break;
4333
4334 case FT_STRING:
4335 detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4336 break;
4337
4338 case FT_BYTES:
4339 case FT_UINT_BYTES:
4340 break;
4341
4342 default:
4343 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4343
, __func__, "assertion \"not reached\" failed")
;
4344 }
4345
4346 return pi;
4347}
4348
4349proto_item *
4350proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4351 tvbuff_t *tvb,
4352 const int start, int length,
4353 const unsigned encoding,
4354 wmem_allocator_t *scope,
4355 char **retval)
4356{
4357 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4358 tvb, start, length, encoding, scope, retval, &length);
4359}
4360
4361proto_item *
4362proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4363 tvbuff_t *tvb,
4364 const int start, int length, const unsigned encoding,
4365 wmem_allocator_t *scope, char **retval)
4366{
4367 header_field_info *hfinfo;
4368 field_info *new_fi;
4369 nstime_t time_stamp;
4370 int flags;
4371
4372 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", 4372, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4372,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4372, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4373
4374 switch (hfinfo->type) {
4375 case FT_ABSOLUTE_TIME:
4376 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4377 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4378 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4379 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4380 }
4381 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4382 break;
4383 case FT_RELATIVE_TIME:
4384 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4385 *retval = rel_time_to_secs_str(scope, &time_stamp);
4386 break;
4387 default:
4388 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)
4389 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4390 }
4391
4392 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4393
4394 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", 4394
, __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", 4394, "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", 4394, "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", 4394, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4395
4396 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4397
4398 switch (hfinfo->type) {
4399
4400 case FT_ABSOLUTE_TIME:
4401 case FT_RELATIVE_TIME:
4402 proto_tree_set_time(new_fi, &time_stamp);
4403 break;
4404 default:
4405 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4405
, __func__, "assertion \"not reached\" failed")
;
4406 }
4407
4408 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4409
4410 return proto_tree_add_node(tree, new_fi);
4411}
4412
4413/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4414 and returns proto_item* */
4415proto_item *
4416ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4417 const unsigned encoding)
4418{
4419 field_info *new_fi;
4420 header_field_info *hfinfo;
4421 int item_length;
4422 unsigned offset;
4423
4424 offset = ptvc->offset;
4425 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", 4425, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4425,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4425, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4426 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4427 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4428
4429 ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4430
4431 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4432
4433 /* Coast clear. Try and fake it */
4434 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", 4434
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4434, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4434, "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", 4434, __func__, "Adding %s would put more than %d 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); } } }
;
4435
4436 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4437
4438 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4439 offset, length, encoding);
4440}
4441
4442/* Add an item to a proto_tree, using the text label registered to that item;
4443 the item is extracted from the tvbuff handed to it. */
4444proto_item *
4445proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4446 const int start, int length, const unsigned encoding)
4447{
4448 field_info *new_fi;
4449 int item_length;
4450
4451 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", 4451,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4452
4453 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4454 test_length(hfinfo, tvb, start, item_length, encoding);
4455
4456 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4457
4458 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", 4458
, __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", 4458, "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", 4458, "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", 4458, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4459
4460 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4461
4462 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4463}
4464
4465proto_item *
4466proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4467 const int start, int length, const unsigned encoding)
4468{
4469 register header_field_info *hfinfo;
4470
4471 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", 4471, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4471,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4471, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4472 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4473}
4474
4475/* Add an item to a proto_tree, using the text label registered to that item;
4476 the item is extracted from the tvbuff handed to it.
4477
4478 Return the length of the item through the pointer. */
4479proto_item *
4480proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4481 tvbuff_t *tvb, const int start,
4482 int length, const unsigned encoding,
4483 int *lenretval)
4484{
4485 field_info *new_fi;
4486 int item_length;
4487 proto_item *item;
4488
4489 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", 4489,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4490
4491 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4492 test_length(hfinfo, tvb, start, item_length, encoding);
4493
4494 if (!tree) {
4495 /*
4496 * We need to get the correct item length here.
4497 * That's normally done by proto_tree_new_item(),
4498 * but we won't be calling it.
4499 */
4500 *lenretval = get_full_length(hfinfo, tvb, start, length,
4501 item_length, encoding);
4502 return NULL((void*)0);
4503 }
4504
4505 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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4506 /*((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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4507 * 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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4508 * 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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4509 */((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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4510 *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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4511 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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4512 })((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", 4512
, __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", 4512, "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", 4512, "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", 4512
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
;
4513
4514 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4515
4516 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4517 *lenretval = new_fi->length;
4518 return item;
4519}
4520
4521proto_item *
4522proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4523 const int start, int length,
4524 const unsigned encoding, int *lenretval)
4525{
4526 register header_field_info *hfinfo;
4527
4528 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", 4528, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4528,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4528, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4529 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4530}
4531
4532/* which FT_ types can use proto_tree_add_bytes_item() */
4533static inline bool_Bool
4534validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4535{
4536 return (type == FT_BYTES ||
4537 type == FT_UINT_BYTES ||
4538 type == FT_OID ||
4539 type == FT_REL_OID ||
4540 type == FT_SYSTEM_ID );
4541}
4542
4543/* Note: this does no validation that the byte array of an FT_OID or
4544 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4545 so I think it's ok to continue not validating it?
4546 */
4547proto_item *
4548proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4549 const unsigned start, unsigned length,
4550 const unsigned encoding,
4551 GByteArray *retval, unsigned *endoff, int *err)
4552{
4553 field_info *new_fi;
4554 GByteArray *bytes = retval;
4555 GByteArray *created_bytes = NULL((void*)0);
4556 bool_Bool failed = false0;
4557 uint32_t n = 0;
4558 header_field_info *hfinfo;
4559 bool_Bool generate = (bytes || tree) ? true1 : false0;
4560
4561 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", 4561, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4561,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4561, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4562
4563 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", 4563,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4564
4565 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", 4566, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4566 "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", 4566, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4567
4568 if (length == 0) {
4569 return NULL((void*)0);
4570 }
4571
4572 if (encoding & ENC_STR_NUM0x01000000) {
4573 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"
)
;
4574 }
4575
4576 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4577 if (hfinfo->type == FT_UINT_BYTES) {
4578 /* can't decode FT_UINT_BYTES from strings */
4579 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")
4580 "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")
;
4581 }
4582
4583 unsigned hex_encoding = encoding;
4584 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4585 /* If none of the separator values are used,
4586 * assume no separator (the common case). */
4587 hex_encoding |= ENC_SEP_NONE0x00010000;
4588#if 0
4589 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")
4590 "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")
;
4591#endif
4592 }
4593
4594 if (!bytes) {
4595 /* caller doesn't care about return value, but we need it to
4596 call tvb_get_string_bytes() and set the tree later */
4597 bytes = created_bytes = g_byte_array_new();
4598 }
4599
4600 /*
4601 * bytes might be NULL after this, but can't add expert
4602 * error until later; if it's NULL, just note that
4603 * it failed.
4604 */
4605 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4606 if (bytes == NULL((void*)0))
4607 failed = true1;
4608 }
4609 else if (generate) {
4610 tvb_ensure_bytes_exist(tvb, start, length);
4611
4612 if (hfinfo->type == FT_UINT_BYTES) {
4613 n = length; /* n is now the "header" length */
4614 length = get_uint_value(tree, tvb, start, n, encoding);
4615 /* length is now the value's length; only store the value in the array */
4616 tvb_ensure_bytes_exist(tvb, start + n, length);
4617 if (!bytes) {
4618 /* caller doesn't care about return value, but
4619 * we may need it to set the tree later */
4620 bytes = created_bytes = g_byte_array_new();
4621 }
4622 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4623 }
4624 else if (length > 0) {
4625 if (!bytes) {
4626 /* caller doesn't care about return value, but
4627 * we may need it to set the tree later */
4628 bytes = created_bytes = g_byte_array_new();
4629 }
4630 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4631 }
4632
4633 if (endoff)
4634 *endoff = start + n + length;
4635 }
4636
4637 if (err)
4638 *err = failed ? EINVAL22 : 0;
4639
4640 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); }
4641 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4642 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); }
4643 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); }
4644 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); }
4645 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4646 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4647
4648 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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4649 {((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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4650 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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4651 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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4652 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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4653 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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4654 } )((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", 4654
, __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", 4654, "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", 4654, "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", 4654
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
;
4655
4656 /* n will be zero except when it's a FT_UINT_BYTES */
4657 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4658
4659 if (encoding & ENC_STRING0x07000000) {
4660 if (failed)
4661 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4662
4663 if (bytes)
4664 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4665 else
4666 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4667
4668 if (created_bytes)
4669 g_byte_array_free(created_bytes, true1);
4670 }
4671 else {
4672 /* n will be zero except when it's a FT_UINT_BYTES */
4673 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4674
4675 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4676 * use the byte array created above in this case.
4677 */
4678 if (created_bytes)
4679 g_byte_array_free(created_bytes, true1);
4680
4681 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4682 (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)
;
4683 }
4684
4685 return proto_tree_add_node(tree, new_fi);
4686}
4687
4688
4689proto_item *
4690proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4691 const unsigned start, const unsigned length,
4692 const unsigned encoding,
4693 nstime_t *retval, unsigned *endoff, int *err)
4694{
4695 field_info *new_fi;
4696 nstime_t time_stamp;
4697 int saved_err = 0;
4698 header_field_info *hfinfo;
4699
4700 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", 4700, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4700,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4700, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4701
4702 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", 4702,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4703
4704 if (length == 0) {
4705 if(retval) {
4706 nstime_set_zero(retval);
4707 }
4708 return NULL((void*)0);
4709 }
4710
4711 nstime_set_zero(&time_stamp);
4712
4713 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4714 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", 4714, ((hfinfo))->abbrev))))
;
4715 /* The only string format that could be a relative time is
4716 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4717 * relative to "now" currently.
4718 */
4719 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4720 saved_err = EINVAL22;
4721 }
4722 else {
4723 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", 4723, ((hfinfo))->abbrev))))
;
4724 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4725
4726 tvb_ensure_bytes_exist(tvb, start, length);
4727 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4728 if (endoff) *endoff = start + length;
4729 }
4730
4731 if (err) *err = saved_err;
4732
4733 if (retval) {
4734 retval->secs = time_stamp.secs;
4735 retval->nsecs = time_stamp.nsecs;
4736 }
4737
4738 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4739
4740 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", 4740
, __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", 4740, "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", 4740, "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", 4740, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4741
4742 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4743
4744 proto_tree_set_time(new_fi, &time_stamp);
4745
4746 if (encoding & ENC_STRING0x07000000) {
4747 if (saved_err)
4748 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4749 }
4750 else {
4751 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4752 (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)
;
4753 }
4754
4755 return proto_tree_add_node(tree, new_fi);
4756}
4757
4758/* Add a FT_NONE to a proto_tree */
4759proto_item *
4760proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4761 const int start, int length, const char *format,
4762 ...)
4763{
4764 proto_item *pi;
4765 va_list ap;
4766 header_field_info *hfinfo;
4767
4768 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4769
4770 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", 4770
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4770, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4770, "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", 4770, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4771
4772 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", 4772
, ((hfinfo))->abbrev))))
;
4773
4774 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4775
4776 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4776, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4777
4778 va_start(ap, format)__builtin_va_start(ap, format);
4779 proto_tree_set_representation(pi, format, ap);
4780 va_end(ap)__builtin_va_end(ap);
4781
4782 /* no value to set for FT_NONE */
4783 return pi;
4784}
4785
4786/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4787 * offset, and returns proto_item* */
4788proto_item *
4789ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4790 const unsigned encoding)
4791{
4792 proto_item *item;
4793
4794 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4795 length, encoding);
4796
4797 return item;
4798}
4799
4800/* Advance the ptvcursor's offset within its tvbuff without
4801 * adding anything to the proto_tree. */
4802void
4803ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4804{
4805 if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc
->offset))
) {
4806 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4807 }
4808}
4809
4810
4811static void
4812proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4813{
4814 ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full(
"Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4814, __func__, "assertion failed: %s"
, "length >= 0"); } while (0)
;
4815 fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4816}
4817
4818/* Add a FT_PROTOCOL to a proto_tree */
4819proto_item *
4820proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4821 int start, int length, const char *format, ...)
4822{
4823 proto_item *pi;
4824 field_info *new_fi;
4825 tvbuff_t *protocol_tvb;
4826 va_list ap;
4827 header_field_info *hfinfo;
4828 char* protocol_rep;
4829
4830 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4831
4832 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", 4832
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4832, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4832, "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", 4832, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4833
4834 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"
, 4834, ((hfinfo))->abbrev))))
;
4835
4836 /*
4837 * This can throw an exception when it calls get_hfi_length before
4838 * it allocates anything, if length is nonzero and start is past
4839 * the end of the tvb. Afterwards it can't throw an exception,
4840 * as length is clamped to the captured length remaining.
4841 */
4842 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4843 new_fi = PNODE_FINFO(pi)((pi)->finfo);
4844 /* Start the protocol_tvb at the correct start offset, but allow it
4845 * to be lengthened later via finfo_set_len. */
4846 protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4847
4848 va_start(ap, format)__builtin_va_start(ap, format);
4849 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4850 proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4851 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)
;
4852 va_end(ap)__builtin_va_end(ap);
4853
4854 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4854, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4855
4856 va_start(ap, format)__builtin_va_start(ap, format);
4857 proto_tree_set_representation(pi, format, ap);
4858 va_end(ap)__builtin_va_end(ap);
4859
4860 return pi;
4861}
4862
4863/* Add a FT_BYTES to a proto_tree */
4864proto_item *
4865proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4866 int length, const uint8_t *start_ptr)
4867{
4868 proto_item *pi;
4869 header_field_info *hfinfo;
4870 int item_length;
4871
4872 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", 4872, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4872,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4872, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4873 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4874 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4875
4876 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4877
4878 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", 4878
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4878, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4878, "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", 4878, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4879
4880 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",
4880, ((hfinfo))->abbrev))))
;
4881
4882 if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4883 start_ptr = tvb_get_ptr(tvb, start, length);
4884
4885 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4886 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4887
4888 return pi;
4889}
4890
4891/* Add a FT_BYTES to a proto_tree */
4892proto_item *
4893proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4894 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4895{
4896 proto_item *pi;
4897 header_field_info *hfinfo;
4898 int item_length;
4899
4900 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", 4900, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4900,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4900, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4901 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4902 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4903
4904 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4905
4906 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", 4906
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4906, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4906, "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", 4906, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4907
4908 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",
4908, ((hfinfo))->abbrev))))
;
4909
4910 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4911 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4912
4913 return pi;
4914}
4915
4916proto_item *
4917proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4918 int start, int length,
4919 const uint8_t *start_ptr,
4920 const char *format, ...)
4921{
4922 proto_item *pi;
4923 va_list ap;
4924
4925 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4926
4927 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; }
;
4928
4929 va_start(ap, format)__builtin_va_start(ap, format);
4930 proto_tree_set_representation_value(pi, format, ap);
4931 va_end(ap)__builtin_va_end(ap);
4932
4933 return pi;
4934}
4935
4936proto_item *
4937proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4938 int start, int length, const uint8_t *start_ptr,
4939 const char *format, ...)
4940{
4941 proto_item *pi;
4942 va_list ap;
4943
4944 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4945
4946 TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
;
4947
4948 va_start(ap, format)__builtin_va_start(ap, format);
4949 proto_tree_set_representation(pi, format, ap);
4950 va_end(ap)__builtin_va_end(ap);
4951
4952 return pi;
4953}
4954
4955static void
4956proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4957{
4958 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4958, "length >= 0"
))))
;
4959 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", 4959, "start_ptr != ((void*)0) || length == 0"
))))
;
4960
4961 fvalue_set_bytes_data(fi->value, start_ptr, length);
4962}
4963
4964
4965static void
4966proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4967{
4968 tvb_ensure_bytes_exist(tvb, offset, length);
4969 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4970}
4971
4972static void
4973proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4974{
4975 GByteArray *bytes;
4976
4977 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4977, "value != ((void*)0)"
))))
;
4978
4979 bytes = byte_array_dup(value);
4980
4981 fvalue_set_byte_array(fi->value, bytes);
4982}
4983
4984/* Add a FT_*TIME to a proto_tree */
4985proto_item *
4986proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4987 int length, const nstime_t *value_ptr)
4988{
4989 proto_item *pi;
4990 header_field_info *hfinfo;
4991
4992 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4993
4994 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", 4994
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4994, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4994, "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", 4994, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4995
4996 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", 4996, ((hfinfo))->abbrev))))
;
4997
4998 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4999 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5000
5001 return pi;
5002}
5003
5004proto_item *
5005proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5006 int start, int length, nstime_t *value_ptr,
5007 const char *format, ...)
5008{
5009 proto_item *pi;
5010 va_list ap;
5011
5012 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5013 if (pi != tree) {
5014 va_start(ap, format)__builtin_va_start(ap, format);
5015 proto_tree_set_representation_value(pi, format, ap);
5016 va_end(ap)__builtin_va_end(ap);
5017 }
5018
5019 return pi;
5020}
5021
5022proto_item *
5023proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5024 int start, int length, nstime_t *value_ptr,
5025 const char *format, ...)
5026{
5027 proto_item *pi;
5028 va_list ap;
5029
5030 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5031 if (pi != tree) {
5032 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5032, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5033
5034 va_start(ap, format)__builtin_va_start(ap, format);
5035 proto_tree_set_representation(pi, format, ap);
5036 va_end(ap)__builtin_va_end(ap);
5037 }
5038
5039 return pi;
5040}
5041
5042/* Set the FT_*TIME value */
5043static void
5044proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5045{
5046 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5046, "value_ptr != ((void*)0)"
))))
;
5047
5048 fvalue_set_time(fi->value, value_ptr);
5049}
5050
5051/* Add a FT_IPXNET to a proto_tree */
5052proto_item *
5053proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5054 int length, uint32_t value)
5055{
5056 proto_item *pi;
5057 header_field_info *hfinfo;
5058
5059 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5060
5061 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", 5061
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5061, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5061, "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", 5061, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5062
5063 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"
, 5063, ((hfinfo))->abbrev))))
;
5064
5065 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5066 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5067
5068 return pi;
5069}
5070
5071proto_item *
5072proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5073 int start, int length, uint32_t value,
5074 const char *format, ...)
5075{
5076 proto_item *pi;
5077 va_list ap;
5078
5079 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5080 if (pi != tree) {
5081 va_start(ap, format)__builtin_va_start(ap, format);
5082 proto_tree_set_representation_value(pi, format, ap);
5083 va_end(ap)__builtin_va_end(ap);
5084 }
5085
5086 return pi;
5087}
5088
5089proto_item *
5090proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5091 int start, int length, uint32_t value,
5092 const char *format, ...)
5093{
5094 proto_item *pi;
5095 va_list ap;
5096
5097 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5098 if (pi != tree) {
5099 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5099, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5100
5101 va_start(ap, format)__builtin_va_start(ap, format);
5102 proto_tree_set_representation(pi, format, ap);
5103 va_end(ap)__builtin_va_end(ap);
5104 }
5105
5106 return pi;
5107}
5108
5109/* Set the FT_IPXNET value */
5110static void
5111proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5112{
5113 fvalue_set_uinteger(fi->value, value);
5114}
5115
5116/* Add a FT_IPv4 to a proto_tree */
5117proto_item *
5118proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5119 int length, ws_in4_addr value)
5120{
5121 proto_item *pi;
5122 header_field_info *hfinfo;
5123
5124 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5125
5126 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", 5126
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5126, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5126, "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", 5126, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5127
5128 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", 5128
, ((hfinfo))->abbrev))))
;
5129
5130 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5131 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5132
5133 return pi;
5134}
5135
5136proto_item *
5137proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5138 int start, int length, ws_in4_addr value,
5139 const char *format, ...)
5140{
5141 proto_item *pi;
5142 va_list ap;
5143
5144 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5145 if (pi != tree) {
5146 va_start(ap, format)__builtin_va_start(ap, format);
5147 proto_tree_set_representation_value(pi, format, ap);
5148 va_end(ap)__builtin_va_end(ap);
5149 }
5150
5151 return pi;
5152}
5153
5154proto_item *
5155proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5156 int start, int length, ws_in4_addr value,
5157 const char *format, ...)
5158{
5159 proto_item *pi;
5160 va_list ap;
5161
5162 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5163 if (pi != tree) {
5164 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5164, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5165
5166 va_start(ap, format)__builtin_va_start(ap, format);
5167 proto_tree_set_representation(pi, format, ap);
5168 va_end(ap)__builtin_va_end(ap);
5169 }
5170
5171 return pi;
5172}
5173
5174/* Set the FT_IPv4 value */
5175static void
5176proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5177{
5178 ipv4_addr_and_mask ipv4;
5179 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5180 fvalue_set_ipv4(fi->value, &ipv4);
5181}
5182
5183/* Add a FT_IPv6 to a proto_tree */
5184proto_item *
5185proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5186 int length, const ws_in6_addr *value)
5187{
5188 proto_item *pi;
5189 header_field_info *hfinfo;
5190
5191 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5192
5193 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", 5193
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5193, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5193, "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", 5193, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5194
5195 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", 5195
, ((hfinfo))->abbrev))))
;
5196
5197 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5198 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5199
5200 return pi;
5201}
5202
5203proto_item *
5204proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5205 int start, int length,
5206 const ws_in6_addr *value_ptr,
5207 const char *format, ...)
5208{
5209 proto_item *pi;
5210 va_list ap;
5211
5212 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5213 if (pi != tree) {
5214 va_start(ap, format)__builtin_va_start(ap, format);
5215 proto_tree_set_representation_value(pi, format, ap);
5216 va_end(ap)__builtin_va_end(ap);
5217 }
5218
5219 return pi;
5220}
5221
5222proto_item *
5223proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5224 int start, int length,
5225 const ws_in6_addr *value_ptr,
5226 const char *format, ...)
5227{
5228 proto_item *pi;
5229 va_list ap;
5230
5231 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5232 if (pi != tree) {
5233 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5233, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5234
5235 va_start(ap, format)__builtin_va_start(ap, format);
5236 proto_tree_set_representation(pi, format, ap);
5237 va_end(ap)__builtin_va_end(ap);
5238 }
5239
5240 return pi;
5241}
5242
5243/* Set the FT_IPv6 value */
5244static void
5245proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5246{
5247 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5247, "value != ((void*)0)"
))))
;
5248 ipv6_addr_and_prefix ipv6;
5249 ipv6.addr = *value;
5250 ipv6.prefix = 128;
5251 fvalue_set_ipv6(fi->value, &ipv6);
5252}
5253
5254static void
5255proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5256{
5257 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5258}
5259
5260/* Set the FT_FCWWN value */
5261static void
5262proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5263{
5264 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5264, "value_ptr != ((void*)0)"
))))
;
5265 fvalue_set_fcwwn(fi->value, value_ptr);
5266}
5267
5268static void
5269proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5270{
5271 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5272}
5273
5274/* Add a FT_GUID to a proto_tree */
5275proto_item *
5276proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5277 int length, const e_guid_t *value_ptr)
5278{
5279 proto_item *pi;
5280 header_field_info *hfinfo;
5281
5282 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5283
5284 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", 5284
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5284, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5284, "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", 5284, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5285
5286 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", 5286
, ((hfinfo))->abbrev))))
;
5287
5288 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5289 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5290
5291 return pi;
5292}
5293
5294proto_item *
5295proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5296 int start, int length,
5297 const e_guid_t *value_ptr,
5298 const char *format, ...)
5299{
5300 proto_item *pi;
5301 va_list ap;
5302
5303 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5304 if (pi != tree) {
5305 va_start(ap, format)__builtin_va_start(ap, format);
5306 proto_tree_set_representation_value(pi, format, ap);
5307 va_end(ap)__builtin_va_end(ap);
5308 }
5309
5310 return pi;
5311}
5312
5313proto_item *
5314proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5315 int start, int length, const e_guid_t *value_ptr,
5316 const char *format, ...)
5317{
5318 proto_item *pi;
5319 va_list ap;
5320
5321 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5322 if (pi != tree) {
5323 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5323, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5324
5325 va_start(ap, format)__builtin_va_start(ap, format);
5326 proto_tree_set_representation(pi, format, ap);
5327 va_end(ap)__builtin_va_end(ap);
5328 }
5329
5330 return pi;
5331}
5332
5333/* Set the FT_GUID value */
5334static void
5335proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5336{
5337 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5337, "value_ptr != ((void*)0)"
))))
;
5338 fvalue_set_guid(fi->value, value_ptr);
5339}
5340
5341static void
5342proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5343 const unsigned encoding)
5344{
5345 e_guid_t guid;
5346
5347 tvb_get_guid(tvb, start, &guid, encoding);
5348 proto_tree_set_guid(fi, &guid);
5349}
5350
5351/* Add a FT_OID to a proto_tree */
5352proto_item *
5353proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5354 int length, const uint8_t* value_ptr)
5355{
5356 proto_item *pi;
5357 header_field_info *hfinfo;
5358
5359 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5360
5361 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", 5361
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5361, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5361, "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", 5361, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5362
5363 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", 5363
, ((hfinfo))->abbrev))))
;
5364
5365 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5366 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5367
5368 return pi;
5369}
5370
5371proto_item *
5372proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5373 int start, int length,
5374 const uint8_t* value_ptr,
5375 const char *format, ...)
5376{
5377 proto_item *pi;
5378 va_list ap;
5379
5380 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5381 if (pi != tree) {
5382 va_start(ap, format)__builtin_va_start(ap, format);
5383 proto_tree_set_representation_value(pi, format, ap);
5384 va_end(ap)__builtin_va_end(ap);
5385 }
5386
5387 return pi;
5388}
5389
5390proto_item *
5391proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5392 int start, int length, const uint8_t* value_ptr,
5393 const char *format, ...)
5394{
5395 proto_item *pi;
5396 va_list ap;
5397
5398 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5399 if (pi != tree) {
5400 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5400, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5401
5402 va_start(ap, format)__builtin_va_start(ap, format);
5403 proto_tree_set_representation(pi, format, ap);
5404 va_end(ap)__builtin_va_end(ap);
5405 }
5406
5407 return pi;
5408}
5409
5410/* Set the FT_OID value */
5411static void
5412proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5413{
5414 GByteArray *bytes;
5415
5416 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", 5416, "value_ptr != ((void*)0) || length == 0"
))))
;
5417
5418 bytes = g_byte_array_new();
5419 if (length > 0) {
5420 g_byte_array_append(bytes, value_ptr, length);
5421 }
5422 fvalue_set_byte_array(fi->value, bytes);
5423}
5424
5425static void
5426proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5427{
5428 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5429}
5430
5431/* Set the FT_SYSTEM_ID value */
5432static void
5433proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5434{
5435 GByteArray *bytes;
5436
5437 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", 5437, "value_ptr != ((void*)0) || length == 0"
))))
;
5438
5439 bytes = g_byte_array_new();
5440 if (length > 0) {
5441 g_byte_array_append(bytes, value_ptr, length);
5442 }
5443 fvalue_set_byte_array(fi->value, bytes);
5444}
5445
5446static void
5447proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5448{
5449 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5450}
5451
5452/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5453 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5454 * is destroyed. */
5455proto_item *
5456proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5457 int length, const char* value)
5458{
5459 proto_item *pi;
5460 header_field_info *hfinfo;
5461 int item_length;
5462
5463 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", 5463, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5463,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5463, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5464 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5465 /*
5466 * Special case - if the length is 0, skip the test, so that
5467 * we can have an empty string right after the end of the
5468 * packet. (This handles URL-encoded forms where the last field
5469 * has no value so the form ends right after the =.)
5470 *
5471 * XXX - length zero makes sense for FT_STRING, and more or less
5472 * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5473 * for FT_STRINGZ (except that a number of fields that should be
5474 * one of the others are actually registered as FT_STRINGZ.)
5475 */
5476 if (item_length != 0)
5477 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5478
5479 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5480
5481 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", 5481
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5481, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5481, "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", 5481, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5482
5483 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", 5483, ((hfinfo))->abbrev))))
;
5484
5485 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5486 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5486, "length >= 0"
))))
;
5487
5488 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", 5488, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5489 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5490
5491 return pi;
5492}
5493
5494proto_item *
5495proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5496 int start, int length, const char* value,
5497 const char *format,
5498 ...)
5499{
5500 proto_item *pi;
5501 va_list ap;
5502
5503 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5504 if (pi != tree) {
5505 va_start(ap, format)__builtin_va_start(ap, format);
5506 proto_tree_set_representation_value(pi, format, ap);
5507 va_end(ap)__builtin_va_end(ap);
5508 }
5509
5510 return pi;
5511}
5512
5513proto_item *
5514proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5515 int start, int length, const char* value,
5516 const char *format, ...)
5517{
5518 proto_item *pi;
5519 va_list ap;
5520
5521 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5522 if (pi != tree) {
5523 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5523, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5524
5525 va_start(ap, format)__builtin_va_start(ap, format);
5526 proto_tree_set_representation(pi, format, ap);
5527 va_end(ap)__builtin_va_end(ap);
5528 }
5529
5530 return pi;
5531}
5532
5533/* Set the FT_STRING value */
5534static void
5535proto_tree_set_string(field_info *fi, const char* value)
5536{
5537 if (value) {
5538 fvalue_set_string(fi->value, value);
5539 } else {
5540 /*
5541 * XXX - why is a null value for a string field
5542 * considered valid?
5543 */
5544 fvalue_set_string(fi->value, "[ Null ]");
5545 }
5546}
5547
5548/* Set the FT_AX25 value */
5549static void
5550proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5551{
5552 fvalue_set_ax25(fi->value, value);
5553}
5554
5555static void
5556proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5557{
5558 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5559}
5560
5561/* Set the FT_VINES value */
5562static void
5563proto_tree_set_vines(field_info *fi, const uint8_t* value)
5564{
5565 fvalue_set_vines(fi->value, value);
5566}
5567
5568static void
5569proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5570{
5571 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5572}
5573
5574/* Add a FT_ETHER to a proto_tree */
5575proto_item *
5576proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5577 int length, const uint8_t* value)
5578{
5579 proto_item *pi;
5580 header_field_info *hfinfo;
5581
5582 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5583
5584 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", 5584
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5584, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5584, "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", 5584, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5585
5586 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",
5586, ((hfinfo))->abbrev))))
;
5587
5588 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5589 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5590
5591 return pi;
5592}
5593
5594proto_item *
5595proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5596 int start, int length, const uint8_t* value,
5597 const char *format, ...)
5598{
5599 proto_item *pi;
5600 va_list ap;
5601
5602 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5603 if (pi != tree) {
5604 va_start(ap, format)__builtin_va_start(ap, format);
5605 proto_tree_set_representation_value(pi, format, ap);
5606 va_end(ap)__builtin_va_end(ap);
5607 }
5608
5609 return pi;
5610}
5611
5612proto_item *
5613proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5614 int start, int length, const uint8_t* value,
5615 const char *format, ...)
5616{
5617 proto_item *pi;
5618 va_list ap;
5619
5620 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5621 if (pi != tree) {
5622 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5622, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5623
5624 va_start(ap, format)__builtin_va_start(ap, format);
5625 proto_tree_set_representation(pi, format, ap);
5626 va_end(ap)__builtin_va_end(ap);
5627 }
5628
5629 return pi;
5630}
5631
5632/* Set the FT_ETHER value */
5633static void
5634proto_tree_set_ether(field_info *fi, const uint8_t* value)
5635{
5636 fvalue_set_ether(fi->value, value);
5637}
5638
5639static void
5640proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5641{
5642 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5643}
5644
5645/* Add a FT_BOOLEAN to a proto_tree */
5646proto_item *
5647proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5648 int length, uint64_t value)
5649{
5650 proto_item *pi;
5651 header_field_info *hfinfo;
5652
5653 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5654
5655 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", 5655
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5655, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5655, "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", 5655, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5656
5657 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"
, 5657, ((hfinfo))->abbrev))))
;
5658
5659 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5660 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5661
5662 return pi;
5663}
5664
5665proto_item *
5666proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5667 tvbuff_t *tvb, int start, int length,
5668 uint64_t value, const char *format, ...)
5669{
5670 proto_item *pi;
5671 va_list ap;
5672
5673 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5674 if (pi != tree) {
5675 va_start(ap, format)__builtin_va_start(ap, format);
5676 proto_tree_set_representation_value(pi, format, ap);
5677 va_end(ap)__builtin_va_end(ap);
5678 }
5679
5680 return pi;
5681}
5682
5683proto_item *
5684proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5685 int start, int length, uint64_t value,
5686 const char *format, ...)
5687{
5688 proto_item *pi;
5689 va_list ap;
5690
5691 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5692 if (pi != tree) {
5693 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5693, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5694
5695 va_start(ap, format)__builtin_va_start(ap, format);
5696 proto_tree_set_representation(pi, format, ap);
5697 va_end(ap)__builtin_va_end(ap);
5698 }
5699
5700 return pi;
5701}
5702
5703/* Set the FT_BOOLEAN value */
5704static void
5705proto_tree_set_boolean(field_info *fi, uint64_t value)
5706{
5707 proto_tree_set_uint64(fi, value);
5708}
5709
5710/* Generate, into "buf", a string showing the bits of a bitfield.
5711 Return a pointer to the character after that string. */
5712static char *
5713other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5714{
5715 int i = 0;
5716 uint64_t bit;
5717 char *p;
5718
5719 p = buf;
5720
5721 /* This is a devel error. It is safer to stop here. */
5722 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5722, "width >= 1"
))))
;
5723
5724 bit = UINT64_C(1)1UL << (width - 1);
5725 for (;;) {
5726 if (mask & bit) {
5727 /* This bit is part of the field. Show its value. */
5728 if (val & bit)
5729 *p++ = '1';
5730 else
5731 *p++ = '0';
5732 } else {
5733 /* This bit is not part of the field. */
5734 *p++ = '.';
5735 }
5736 bit >>= 1;
5737 i++;
5738 if (i >= width)
5739 break;
5740 if (i % 4 == 0)
5741 *p++ = ' ';
5742 }
5743 *p = '\0';
5744 return p;
5745}
5746
5747static char *
5748decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5749{
5750 char *p;
5751
5752 p = other_decode_bitfield_value(buf, val, mask, width);
5753 p = g_stpcpy(p, " = ");
5754
5755 return p;
5756}
5757
5758static char *
5759other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5760{
5761 int i = 0;
5762 uint64_t bit;
5763 char *p;
5764
5765 p = buf;
5766
5767 /* This is a devel error. It is safer to stop here. */
5768 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5768, "width >= 1"
))))
;
5769
5770 bit = UINT64_C(1)1UL << (width - 1);
5771 for (;;) {
5772 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5773 (mask & bit)) {
5774 /* This bit is part of the field. Show its value. */
5775 if (val & bit)
5776 *p++ = '1';
5777 else
5778 *p++ = '0';
5779 } else {
5780 /* This bit is not part of the field. */
5781 *p++ = '.';
5782 }
5783 bit >>= 1;
5784 i++;
5785 if (i >= width)
5786 break;
5787 if (i % 4 == 0)
5788 *p++ = ' ';
5789 }
5790
5791 *p = '\0';
5792 return p;
5793}
5794
5795static char *
5796decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5797{
5798 char *p;
5799
5800 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5801 p = g_stpcpy(p, " = ");
5802
5803 return p;
5804}
5805
5806/* Add a FT_FLOAT to a proto_tree */
5807proto_item *
5808proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5809 int length, float value)
5810{
5811 proto_item *pi;
5812 header_field_info *hfinfo;
5813
5814 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5815
5816 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", 5816
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5816, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5816, "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", 5816, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5817
5818 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",
5818, ((hfinfo))->abbrev))))
;
5819
5820 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5821 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5822
5823 return pi;
5824}
5825
5826proto_item *
5827proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5828 int start, int length, float value,
5829 const char *format, ...)
5830{
5831 proto_item *pi;
5832 va_list ap;
5833
5834 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5835 if (pi != tree) {
5836 va_start(ap, format)__builtin_va_start(ap, format);
5837 proto_tree_set_representation_value(pi, format, ap);
5838 va_end(ap)__builtin_va_end(ap);
5839 }
5840
5841 return pi;
5842}
5843
5844proto_item *
5845proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5846 int start, int length, float value,
5847 const char *format, ...)
5848{
5849 proto_item *pi;
5850 va_list ap;
5851
5852 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5853 if (pi != tree) {
5854 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5854, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5855
5856 va_start(ap, format)__builtin_va_start(ap, format);
5857 proto_tree_set_representation(pi, format, ap);
5858 va_end(ap)__builtin_va_end(ap);
5859 }
5860
5861 return pi;
5862}
5863
5864/* Set the FT_FLOAT value */
5865static void
5866proto_tree_set_float(field_info *fi, float value)
5867{
5868 fvalue_set_floating(fi->value, value);
5869}
5870
5871/* Add a FT_DOUBLE to a proto_tree */
5872proto_item *
5873proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5874 int length, double value)
5875{
5876 proto_item *pi;
5877 header_field_info *hfinfo;
5878
5879 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5880
5881 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", 5881
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5881, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5881, "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", 5881, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5882
5883 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"
, 5883, ((hfinfo))->abbrev))))
;
5884
5885 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5886 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5887
5888 return pi;
5889}
5890
5891proto_item *
5892proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5893 int start, int length, double value,
5894 const char *format, ...)
5895{
5896 proto_item *pi;
5897 va_list ap;
5898
5899 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5900 if (pi != tree) {
5901 va_start(ap, format)__builtin_va_start(ap, format);
5902 proto_tree_set_representation_value(pi, format, ap);
5903 va_end(ap)__builtin_va_end(ap);
5904 }
5905
5906 return pi;
5907}
5908
5909proto_item *
5910proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5911 int start, int length, double value,
5912 const char *format, ...)
5913{
5914 proto_item *pi;
5915 va_list ap;
5916
5917 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5918 if (pi != tree) {
5919 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5919, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5920
5921 va_start(ap, format)__builtin_va_start(ap, format);
5922 proto_tree_set_representation(pi, format, ap);
5923 va_end(ap)__builtin_va_end(ap);
5924 }
5925
5926 return pi;
5927}
5928
5929/* Set the FT_DOUBLE value */
5930static void
5931proto_tree_set_double(field_info *fi, double value)
5932{
5933 fvalue_set_floating(fi->value, value);
5934}
5935
5936/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5937proto_item *
5938proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5939 int length, uint32_t value)
5940{
5941 proto_item *pi = NULL((void*)0);
5942 header_field_info *hfinfo;
5943
5944 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5945
5946 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", 5946
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5946, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5946, "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", 5946, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5947
5948 switch (hfinfo->type) {
5949 case FT_CHAR:
5950 case FT_UINT8:
5951 case FT_UINT16:
5952 case FT_UINT24:
5953 case FT_UINT32:
5954 case FT_FRAMENUM:
5955 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5956 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5957 break;
5958
5959 default:
5960 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)
5961 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)
;
5962 }
5963
5964 return pi;
5965}
5966
5967proto_item *
5968proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5969 int start, int length, uint32_t value,
5970 const char *format, ...)
5971{
5972 proto_item *pi;
5973 va_list ap;
5974
5975 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5976 if (pi != tree) {
5977 va_start(ap, format)__builtin_va_start(ap, format);
5978 proto_tree_set_representation_value(pi, format, ap);
5979 va_end(ap)__builtin_va_end(ap);
5980 }
5981
5982 return pi;
5983}
5984
5985proto_item *
5986proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5987 int start, int length, uint32_t value,
5988 const char *format, ...)
5989{
5990 proto_item *pi;
5991 va_list ap;
5992
5993 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5994 if (pi != tree) {
5995 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5995, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5996
5997 va_start(ap, format)__builtin_va_start(ap, format);
5998 proto_tree_set_representation(pi, format, ap);
5999 va_end(ap)__builtin_va_end(ap);
6000 }
6001
6002 return pi;
6003}
6004
6005/* Set the FT_UINT{8,16,24,32} value */
6006static void
6007proto_tree_set_uint(field_info *fi, uint32_t value)
6008{
6009 const header_field_info *hfinfo;
6010 uint32_t integer;
6011
6012 hfinfo = fi->hfinfo;
6013 integer = value;
6014
6015 if (hfinfo->bitmask) {
6016 /* Mask out irrelevant portions */
6017 integer &= (uint32_t)(hfinfo->bitmask);
6018
6019 /* Shift bits */
6020 integer >>= hfinfo_bitshift(hfinfo);
6021
6022 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6023 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)
;
6024 }
6025
6026 fvalue_set_uinteger(fi->value, integer);
6027}
6028
6029/* Add FT_UINT{40,48,56,64} to a proto_tree */
6030proto_item *
6031proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6032 int length, uint64_t value)
6033{
6034 proto_item *pi = NULL((void*)0);
6035 header_field_info *hfinfo;
6036
6037 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6038
6039 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", 6039
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6039, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6039, "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", 6039, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6040
6041 switch (hfinfo->type) {
6042 case FT_UINT40:
6043 case FT_UINT48:
6044 case FT_UINT56:
6045 case FT_UINT64:
6046 case FT_FRAMENUM:
6047 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6048 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6049 break;
6050
6051 default:
6052 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)
6053 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)
;
6054 }
6055
6056 return pi;
6057}
6058
6059proto_item *
6060proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6061 int start, int length, uint64_t value,
6062 const char *format, ...)
6063{
6064 proto_item *pi;
6065 va_list ap;
6066
6067 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6068 if (pi != tree) {
6069 va_start(ap, format)__builtin_va_start(ap, format);
6070 proto_tree_set_representation_value(pi, format, ap);
6071 va_end(ap)__builtin_va_end(ap);
6072 }
6073
6074 return pi;
6075}
6076
6077proto_item *
6078proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6079 int start, int length, uint64_t value,
6080 const char *format, ...)
6081{
6082 proto_item *pi;
6083 va_list ap;
6084
6085 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6086 if (pi != tree) {
6087 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6087, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6088
6089 va_start(ap, format)__builtin_va_start(ap, format);
6090 proto_tree_set_representation(pi, format, ap);
6091 va_end(ap)__builtin_va_end(ap);
6092 }
6093
6094 return pi;
6095}
6096
6097/* Set the FT_UINT{40,48,56,64} value */
6098static void
6099proto_tree_set_uint64(field_info *fi, uint64_t value)
6100{
6101 const header_field_info *hfinfo;
6102 uint64_t integer;
6103
6104 hfinfo = fi->hfinfo;
6105 integer = value;
6106
6107 if (hfinfo->bitmask) {
6108 /* Mask out irrelevant portions */
6109 integer &= hfinfo->bitmask;
6110
6111 /* Shift bits */
6112 integer >>= hfinfo_bitshift(hfinfo);
6113
6114 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6115 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)
;
6116 }
6117
6118 fvalue_set_uinteger64(fi->value, integer);
6119}
6120
6121/* Add FT_INT{8,16,24,32} to a proto_tree */
6122proto_item *
6123proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6124 int length, int32_t value)
6125{
6126 proto_item *pi = NULL((void*)0);
6127 header_field_info *hfinfo;
6128
6129 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6130
6131 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", 6131
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6131, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6131, "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", 6131, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6132
6133 switch (hfinfo->type) {
6134 case FT_INT8:
6135 case FT_INT16:
6136 case FT_INT24:
6137 case FT_INT32:
6138 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6139 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6140 break;
6141
6142 default:
6143 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)
6144 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6145 }
6146
6147 return pi;
6148}
6149
6150proto_item *
6151proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6152 int start, int length, int32_t value,
6153 const char *format, ...)
6154{
6155 proto_item *pi;
6156 va_list ap;
6157
6158 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6159 if (pi != tree) {
6160 va_start(ap, format)__builtin_va_start(ap, format);
6161 proto_tree_set_representation_value(pi, format, ap);
6162 va_end(ap)__builtin_va_end(ap);
6163 }
6164
6165 return pi;
6166}
6167
6168proto_item *
6169proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6170 int start, int length, int32_t value,
6171 const char *format, ...)
6172{
6173 proto_item *pi;
6174 va_list ap;
6175
6176 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6177 if (pi != tree) {
6178 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6178, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6179
6180 va_start(ap, format)__builtin_va_start(ap, format);
6181 proto_tree_set_representation(pi, format, ap);
6182 va_end(ap)__builtin_va_end(ap);
6183 }
6184
6185 return pi;
6186}
6187
6188/* Set the FT_INT{8,16,24,32} value */
6189static void
6190proto_tree_set_int(field_info *fi, int32_t value)
6191{
6192 const header_field_info *hfinfo;
6193 uint32_t integer;
6194 int no_of_bits;
6195
6196 hfinfo = fi->hfinfo;
6197 integer = (uint32_t) value;
6198
6199 if (hfinfo->bitmask) {
6200 /* Mask out irrelevant portions */
6201 integer &= (uint32_t)(hfinfo->bitmask);
6202
6203 /* Shift bits */
6204 integer >>= hfinfo_bitshift(hfinfo);
6205
6206 no_of_bits = ws_count_ones(hfinfo->bitmask);
6207 integer = ws_sign_ext32(integer, no_of_bits);
6208
6209 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6210 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)
;
6211 }
6212
6213 fvalue_set_sinteger(fi->value, integer);
6214}
6215
6216/* Add FT_INT{40,48,56,64} to a proto_tree */
6217proto_item *
6218proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6219 int length, int64_t value)
6220{
6221 proto_item *pi = NULL((void*)0);
6222 header_field_info *hfinfo;
6223
6224 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6225
6226 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", 6226
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6226, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6226, "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", 6226, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6227
6228 switch (hfinfo->type) {
6229 case FT_INT40:
6230 case FT_INT48:
6231 case FT_INT56:
6232 case FT_INT64:
6233 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6234 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6235 break;
6236
6237 default:
6238 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)
6239 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6240 }
6241
6242 return pi;
6243}
6244
6245proto_item *
6246proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6247 int start, int length, int64_t value,
6248 const char *format, ...)
6249{
6250 proto_item *pi;
6251 va_list ap;
6252
6253 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6254 if (pi != tree) {
6255 va_start(ap, format)__builtin_va_start(ap, format);
6256 proto_tree_set_representation_value(pi, format, ap);
6257 va_end(ap)__builtin_va_end(ap);
6258 }
6259
6260 return pi;
6261}
6262
6263/* Set the FT_INT{40,48,56,64} value */
6264static void
6265proto_tree_set_int64(field_info *fi, int64_t value)
6266{
6267 const header_field_info *hfinfo;
6268 uint64_t integer;
6269 int no_of_bits;
6270
6271 hfinfo = fi->hfinfo;
6272 integer = value;
6273
6274 if (hfinfo->bitmask) {
6275 /* Mask out irrelevant portions */
6276 integer &= hfinfo->bitmask;
6277
6278 /* Shift bits */
6279 integer >>= hfinfo_bitshift(hfinfo);
6280
6281 no_of_bits = ws_count_ones(hfinfo->bitmask);
6282 integer = ws_sign_ext64(integer, no_of_bits);
6283
6284 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6285 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)
;
6286 }
6287
6288 fvalue_set_sinteger64(fi->value, integer);
6289}
6290
6291proto_item *
6292proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6293 int start, int length, int64_t value,
6294 const char *format, ...)
6295{
6296 proto_item *pi;
6297 va_list ap;
6298
6299 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6300 if (pi != tree) {
6301 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6301, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6302
6303 va_start(ap, format)__builtin_va_start(ap, format);
6304 proto_tree_set_representation(pi, format, ap);
6305 va_end(ap)__builtin_va_end(ap);
6306 }
6307
6308 return pi;
6309}
6310
6311/* Add a FT_EUI64 to a proto_tree */
6312proto_item *
6313proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6314 int length, const uint64_t value)
6315{
6316 proto_item *pi;
6317 header_field_info *hfinfo;
6318
6319 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6320
6321 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", 6321
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6321, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6321, "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", 6321, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6322
6323 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",
6323, ((hfinfo))->abbrev))))
;
6324
6325 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6326 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6327
6328 return pi;
6329}
6330
6331proto_item *
6332proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6333 int start, int length, const uint64_t value,
6334 const char *format, ...)
6335{
6336 proto_item *pi;
6337 va_list ap;
6338
6339 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6340 if (pi != tree) {
6341 va_start(ap, format)__builtin_va_start(ap, format);
6342 proto_tree_set_representation_value(pi, format, ap);
6343 va_end(ap)__builtin_va_end(ap);
6344 }
6345
6346 return pi;
6347}
6348
6349proto_item *
6350proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6351 int start, int length, const uint64_t value,
6352 const char *format, ...)
6353{
6354 proto_item *pi;
6355 va_list ap;
6356
6357 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6358 if (pi != tree) {
6359 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6359, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6360
6361 va_start(ap, format)__builtin_va_start(ap, format);
6362 proto_tree_set_representation(pi, format, ap);
6363 va_end(ap)__builtin_va_end(ap);
6364 }
6365
6366 return pi;
6367}
6368
6369/* Set the FT_EUI64 value */
6370static void
6371proto_tree_set_eui64(field_info *fi, const uint64_t value)
6372{
6373 uint8_t v[FT_EUI64_LEN8];
6374 phtonu64(v, value);
6375 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6376}
6377
6378static void
6379proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6380{
6381 if (encoding)
6382 {
6383 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6384 } else {
6385 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6386 }
6387}
6388
6389proto_item *
6390proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6391 const mac_hf_list_t *list_generic,
6392 int idx, tvbuff_t *tvb,
6393 proto_tree *tree, int offset)
6394{
6395 uint8_t addr[6];
6396 const char *addr_name = NULL((void*)0);
6397 const char *oui_name = NULL((void*)0);
6398 proto_item *addr_item = NULL((void*)0);
6399 proto_tree *addr_tree = NULL((void*)0);
6400 proto_item *ret_val = NULL((void*)0);
6401
6402 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6403 return NULL((void*)0);
6404 }
6405
6406 /* Resolve what we can of the address */
6407 tvb_memcpy(tvb, addr, offset, sizeof addr);
6408 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6409 addr_name = get_ether_name(addr);
6410 }
6411 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6412 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6413 }
6414
6415 /* Add the item for the specific address type */
6416 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6417 if (idx >= 0) {
6418 addr_tree = proto_item_add_subtree(ret_val, idx);
6419 }
6420 else {
6421 addr_tree = tree;
6422 }
6423
6424 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6425 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6426 tvb, offset, 6, addr_name);
6427 proto_item_set_generated(addr_item);
6428 proto_item_set_hidden(addr_item);
6429 }
6430
6431 if (list_specific->hf_oui != NULL((void*)0)) {
6432 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6433 proto_item_set_generated(addr_item);
6434 proto_item_set_hidden(addr_item);
6435
6436 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6437 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6438 proto_item_set_generated(addr_item);
6439 proto_item_set_hidden(addr_item);
6440 }
6441 }
6442
6443 if (list_specific->hf_lg != NULL((void*)0)) {
6444 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6445 }
6446 if (list_specific->hf_ig != NULL((void*)0)) {
6447 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6448 }
6449
6450 /* Were we given a list for generic address fields? If not, stop here */
6451 if (list_generic == NULL((void*)0)) {
6452 return ret_val;
6453 }
6454
6455 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6456 proto_item_set_hidden(addr_item);
6457
6458 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6459 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6460 tvb, offset, 6, addr_name);
6461 proto_item_set_generated(addr_item);
6462 proto_item_set_hidden(addr_item);
6463 }
6464
6465 if (list_generic->hf_oui != NULL((void*)0)) {
6466 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6467 proto_item_set_generated(addr_item);
6468 proto_item_set_hidden(addr_item);
6469
6470 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6471 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6472 proto_item_set_generated(addr_item);
6473 proto_item_set_hidden(addr_item);
6474 }
6475 }
6476
6477 if (list_generic->hf_lg != NULL((void*)0)) {
6478 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6479 proto_item_set_hidden(addr_item);
6480 }
6481 if (list_generic->hf_ig != NULL((void*)0)) {
6482 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6483 proto_item_set_hidden(addr_item);
6484 }
6485 return ret_val;
6486}
6487
6488static proto_item *
6489proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6490{
6491 proto_node *pnode, *tnode, *sibling;
6492 field_info *tfi;
6493 unsigned depth = 1;
6494
6495 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6495, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6496
6497 /*
6498 * Restrict our depth. proto_tree_traverse_pre_order and
6499 * proto_tree_traverse_post_order (and possibly others) are recursive
6500 * so we need to be mindful of our stack size.
6501 */
6502 if (tree->first_child == NULL((void*)0)) {
6503 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6504 depth++;
6505 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6506 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__)), 6509)))
6507 "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__)), 6509)))
6508 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__)), 6509)))
6509 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__)), 6509)))
;
6510 }
6511 }
6512 }
6513
6514 /*
6515 * Make sure "tree" is ready to have subtrees under it, by
6516 * checking whether it's been given an ett_ value.
6517 *
6518 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6519 * node of the protocol tree. That node is not displayed,
6520 * so it doesn't need an ett_ value to remember whether it
6521 * was expanded.
6522 */
6523 tnode = tree;
6524 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6525 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6526 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"
, 6527)
6527 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"
, 6527)
;
6528 /* XXX - is it safe to continue here? */
6529 }
6530
6531 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6532 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6533 pnode->parent = tnode;
6534 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6535 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6536 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6537
6538 if (tnode->last_child != NULL((void*)0)) {
6539 sibling = tnode->last_child;
6540 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6540, "sibling->next == ((void*)0)"
))))
;
6541 sibling->next = pnode;
6542 } else
6543 tnode->first_child = pnode;
6544 tnode->last_child = pnode;
6545
6546 /* We should not be adding a fake node for an interesting field */
6547 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", 6547, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6548
6549 /* XXX - Should the proto_item have a header_field_info member, at least
6550 * for faked items, to know what hfi was faked? (Some dissectors look at
6551 * the tree items directly.)
6552 */
6553 return (proto_item *)pnode;
6554}
6555
6556/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6557static proto_item *
6558proto_tree_add_node(proto_tree *tree, field_info *fi)
6559{
6560 proto_node *pnode, *tnode, *sibling;
6561 field_info *tfi;
6562 unsigned depth = 1;
6563
6564 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6564, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6565
6566 /*
6567 * Restrict our depth. proto_tree_traverse_pre_order and
6568 * proto_tree_traverse_post_order (and possibly others) are recursive
6569 * so we need to be mindful of our stack size.
6570 */
6571 if (tree->first_child == NULL((void*)0)) {
6572 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6573 depth++;
6574 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6575 fvalue_free(fi->value);
6576 fi->value = NULL((void*)0);
6577 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__)), 6580)))
6578 "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__)), 6580)))
6579 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__)), 6580)))
6580 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__)), 6580)))
;
6581 }
6582 }
6583 }
6584
6585 /*
6586 * Make sure "tree" is ready to have subtrees under it, by
6587 * checking whether it's been given an ett_ value.
6588 *
6589 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6590 * node of the protocol tree. That node is not displayed,
6591 * so it doesn't need an ett_ value to remember whether it
6592 * was expanded.
6593 */
6594 tnode = tree;
6595 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6596 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6597 /* Since we are not adding fi to a node, its fvalue won't get
6598 * freed by proto_tree_free_node(), so free it now.
6599 */
6600 fvalue_free(fi->value);
6601 fi->value = NULL((void*)0);
6602 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", 6603)
6603 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", 6603)
;
6604 /* XXX - is it safe to continue here? */
6605 }
6606
6607 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6608 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6609 pnode->parent = tnode;
6610 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6611 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6612 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6613
6614 if (tnode->last_child != NULL((void*)0)) {
6615 sibling = tnode->last_child;
6616 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6616, "sibling->next == ((void*)0)"
))))
;
6617 sibling->next = pnode;
6618 } else
6619 tnode->first_child = pnode;
6620 tnode->last_child = pnode;
6621
6622 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6623
6624 return (proto_item *)pnode;
6625}
6626
6627
6628/* Generic way to allocate field_info and add to proto_tree.
6629 * Sets *pfi to address of newly-allocated field_info struct */
6630static proto_item *
6631proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6632 int *length)
6633{
6634 proto_item *pi;
6635 field_info *fi;
6636 int item_length;
6637
6638 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6639 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6640 pi = proto_tree_add_node(tree, fi);
6641
6642 return pi;
6643}
6644
6645
6646static void
6647get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6648 int *item_length, const unsigned encoding)
6649{
6650 int length_remaining;
6651
6652 /*
6653 * We only allow a null tvbuff if the item has a zero length,
6654 * i.e. if there's no data backing it.
6655 */
6656 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", 6656, "tvb != ((void*)0) || *length == 0"
))))
;
6657
6658 /*
6659 * XXX - in some protocols, there are 32-bit unsigned length
6660 * fields, so lengths in protocol tree and tvbuff routines
6661 * should really be unsigned. We should have, for those
6662 * field types for which "to the end of the tvbuff" makes sense,
6663 * additional routines that take no length argument and
6664 * add fields that run to the end of the tvbuff.
6665 */
6666 if (*length == -1) {
6667 /*
6668 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6669 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6670 * of -1 means "set the length to what remains in the
6671 * tvbuff".
6672 *
6673 * The assumption is either that
6674 *
6675 * 1) the length of the item can only be determined
6676 * by dissection (typically true of items with
6677 * subitems, which are probably FT_NONE or
6678 * FT_PROTOCOL)
6679 *
6680 * or
6681 *
6682 * 2) if the tvbuff is "short" (either due to a short
6683 * snapshot length or due to lack of reassembly of
6684 * fragments/segments/whatever), we want to display
6685 * what's available in the field (probably FT_BYTES
6686 * or FT_STRING) and then throw an exception later
6687 *
6688 * or
6689 *
6690 * 3) the field is defined to be "what's left in the
6691 * packet"
6692 *
6693 * so we set the length to what remains in the tvbuff so
6694 * that, if we throw an exception while dissecting, it
6695 * has what is probably the right value.
6696 *
6697 * For FT_STRINGZ, it means "the string is null-terminated,
6698 * not null-padded; set the length to the actual length
6699 * of the string", and if the tvbuff if short, we just
6700 * throw an exception.
6701 *
6702 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6703 * it means "find the end of the string",
6704 * and if the tvbuff if short, we just throw an exception.
6705 *
6706 * It's not valid for any other type of field. For those
6707 * fields, we treat -1 the same way we treat other
6708 * negative values - we assume the length is a Really
6709 * Big Positive Number, and throw a ReportedBoundsError
6710 * exception, under the assumption that the Really Big
6711 * Length would run past the end of the packet.
6712 */
6713 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
))
)) {
6714 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6715 /*
6716 * Leave the length as -1, so our caller knows
6717 * it was -1.
6718 */
6719 *item_length = *length;
6720 return;
6721 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6722 switch (tvb_get_uint8(tvb, start) >> 6)
6723 {
6724 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6725 *item_length = 1;
6726 break;
6727 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6728 *item_length = 2;
6729 break;
6730 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6731 *item_length = 4;
6732 break;
6733 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6734 *item_length = 8;
6735 break;
6736 }
6737 }
6738 }
6739
6740 switch (hfinfo->type) {
6741
6742 case FT_PROTOCOL:
6743 case FT_NONE:
6744 case FT_BYTES:
6745 case FT_STRING:
6746 case FT_STRINGZPAD:
6747 case FT_STRINGZTRUNC:
6748 /*
6749 * We allow FT_PROTOCOLs to be zero-length -
6750 * for example, an ONC RPC NULL procedure has
6751 * neither arguments nor reply, so the
6752 * payload for that protocol is empty.
6753 *
6754 * We also allow the others to be zero-length -
6755 * because that's the way the code has been for a
6756 * long, long time.
6757 *
6758 * However, we want to ensure that the start
6759 * offset is not *past* the byte past the end
6760 * of the tvbuff: we throw an exception in that
6761 * case.
6762 */
6763 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6764 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6764, "*length >= 0"
))))
;
6765 break;
6766
6767 case FT_STRINGZ:
6768 /*
6769 * Leave the length as -1, so our caller knows
6770 * it was -1.
6771 */
6772 break;
6773
6774 default:
6775 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6776 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6776))
;
6777 }
6778 *item_length = *length;
6779 } else {
6780 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6781 /*
6782 * These types are for interior nodes of the
6783 * tree, and don't have data associated with
6784 * them; if the length is negative (XXX - see
6785 * above) or goes past the end of the tvbuff,
6786 * cut it short at the end of the tvbuff.
6787 * That way, if this field is selected in
6788 * Wireshark, we don't highlight stuff past
6789 * the end of the data.
6790 *
6791 * If we don't have a tvb, then length must be zero,
6792 * per the DISSECTOR_ASSERT() above.
6793 *
6794 * If we do have a tvb, and the length requested is
6795 * nonzero, we want to ensure that the start offset
6796 * is not *past* the byte past the end of the tvbuff
6797 * data: we throw an exception in that case as above.
6798 */
6799 if (tvb && *length) {
6800 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6801 if (*length < 0 ||
6802 (*length > 0 &&
6803 (length_remaining < *length)))
6804 *length = length_remaining;
6805 }
6806 }
6807 *item_length = *length;
6808 if (*item_length < 0) {
6809 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6810 }
6811 }
6812}
6813
6814static void
6815get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6816 unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6817{
6818 unsigned length_remaining;
6819
6820 /*
6821 * We only allow a null tvbuff if the item has a zero length,
6822 * i.e. if there's no data backing it.
6823 */
6824 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", 6824, "tvb != ((void*)0) || *length == 0"
))))
;
6825
6826
6827 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6828 /*
6829 * These types are for interior nodes of the
6830 * tree, and don't have data associated with
6831 * them; if the length is negative (XXX - see
6832 * above) or goes past the end of the tvbuff,
6833 * cut it short at the end of the tvbuff.
6834 * That way, if this field is selected in
6835 * Wireshark, we don't highlight stuff past
6836 * the end of the data.
6837 *
6838 * If we don't have a tvb, then length must be zero,
6839 * per the DISSECTOR_ASSERT() above.
6840 *
6841 * If we do have a tvb, and the length requested is
6842 * nonzero, we want to ensure that the start offset
6843 * is not *past* the byte past the end of the tvbuff
6844 * data: we throw an exception in that case as above.
6845 * (If the length requested is zero, then it's quite
6846 * likely that the start offset is the byte past the
6847 * end, but that's ok.)
6848 */
6849 if (tvb && *length) {
6850 length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6851 if (length_remaining < *length) {
6852 *length = length_remaining;
6853 }
6854 }
6855 }
6856 *item_length = *length;
6857}
6858
6859static int
6860get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6861 int length, unsigned item_length, const int encoding)
6862{
6863 uint32_t n;
6864
6865 /*
6866 * We need to get the correct item length here.
6867 * That's normally done by proto_tree_new_item(),
6868 * but we won't be calling it.
6869 */
6870 switch (hfinfo->type) {
6871
6872 case FT_NONE:
6873 case FT_PROTOCOL:
6874 case FT_BYTES:
6875 /*
6876 * The length is the specified length.
6877 */
6878 break;
6879
6880 case FT_UINT_BYTES:
6881 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6882 item_length += n;
6883 if ((int)item_length < length) {
6884 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6885 }
6886 break;
6887
6888 /* XXX - make these just FT_UINT? */
6889 case FT_UINT8:
6890 case FT_UINT16:
6891 case FT_UINT24:
6892 case FT_UINT32:
6893 case FT_UINT40:
6894 case FT_UINT48:
6895 case FT_UINT56:
6896 case FT_UINT64:
6897 /* XXX - make these just FT_INT? */
6898 case FT_INT8:
6899 case FT_INT16:
6900 case FT_INT24:
6901 case FT_INT32:
6902 case FT_INT40:
6903 case FT_INT48:
6904 case FT_INT56:
6905 case FT_INT64:
6906 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6907 if (length < -1) {
6908 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6909 }
6910 if (length == -1) {
6911 uint64_t dummy;
6912 /* This can throw an exception */
6913 /* XXX - do this without fetching the varint? */
6914 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6915 if (length == 0) {
6916 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6917 }
6918 }
6919 item_length = length;
6920 break;
6921 }
6922
6923 /*
6924 * The length is the specified length.
6925 */
6926 break;
6927
6928 case FT_BOOLEAN:
6929 case FT_CHAR:
6930 case FT_IPv4:
6931 case FT_IPXNET:
6932 case FT_IPv6:
6933 case FT_FCWWN:
6934 case FT_AX25:
6935 case FT_VINES:
6936 case FT_ETHER:
6937 case FT_EUI64:
6938 case FT_GUID:
6939 case FT_OID:
6940 case FT_REL_OID:
6941 case FT_SYSTEM_ID:
6942 case FT_FLOAT:
6943 case FT_DOUBLE:
6944 case FT_STRING:
6945 /*
6946 * The length is the specified length.
6947 */
6948 break;
6949
6950 case FT_STRINGZ:
6951 if (length < -1) {
6952 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6953 }
6954 if (length == -1) {
6955 /* This can throw an exception */
6956 item_length = tvb_strsize_enc(tvb, start, encoding);
6957 }
6958 break;
6959
6960 case FT_UINT_STRING:
6961 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6962 item_length += n;
6963 if ((int)item_length < length) {
6964 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6965 }
6966 break;
6967
6968 case FT_STRINGZPAD:
6969 case FT_STRINGZTRUNC:
6970 case FT_ABSOLUTE_TIME:
6971 case FT_RELATIVE_TIME:
6972 case FT_IEEE_11073_SFLOAT:
6973 case FT_IEEE_11073_FLOAT:
6974 /*
6975 * The length is the specified length.
6976 */
6977 break;
6978
6979 default:
6980 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
))
6981 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
))
6982 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
))
6983 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
))
;
6984 break;
6985 }
6986 return item_length;
6987}
6988
6989// This was arbitrarily chosen, but if you're adding 50K items to the tree
6990// without advancing the offset you should probably take a long, hard look
6991// at what you're doing.
6992// We *could* make this a configurable option, but I (Gerald) would like to
6993// avoid adding yet another nerd knob.
6994# define PROTO_TREE_MAX_IDLE50000 50000
6995static field_info *
6996new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6997 const int start, const int item_length)
6998{
6999 field_info *fi;
7000
7001 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
7002
7003 fi->hfinfo = hfinfo;
7004 fi->start = start;
7005 fi->start += (tvb)?tvb_raw_offset(tvb):0;
7006 /* add the data source tvbuff */
7007 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7008
7009 // If our start offset hasn't advanced after adding many items it probably
7010 // means we're in a large or infinite loop.
7011 if (fi->start > 0) {
7012 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7013 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7014 if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7015 if (wireshark_abort_on_too_many_items) {
7016 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", 7017
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
7017 hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7017
, __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop"
, hfinfo->abbrev, 50000)
;
7018 }
7019 /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7020 * but if not, we should hit the max item error earlier,
7021 * so we shouldn't need to reset the tree count to
7022 * ensure that the exception handler can add the item. */
7023 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)))
7024 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)))
7025 "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)))
7026 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)))
;
7027 }
7028 } else {
7029 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7030 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7031 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7032 }
7033 }
7034 fi->length = item_length;
7035 fi->tree_type = -1;
7036 fi->flags = 0;
7037 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7038 /* If the tree is not visible, set the item hidden, unless we
7039 * need the representation or length and can't fake them.
7040 */
7041 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7042 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
7043 }
7044 }
7045 fi->value = fvalue_new(fi->hfinfo->type);
7046 fi->rep = NULL((void*)0);
7047
7048 fi->appendix_start = 0;
7049 fi->appendix_length = 0;
7050
7051 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7052 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7053
7054 return fi;
7055}
7056
7057static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7058{
7059 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7060 return 0;
7061 }
7062
7063 /* Search for field name */
7064 char *ptr = strstr(representation, hfinfo->name);
7065 if (!ptr) {
7066 return 0;
7067 }
7068
7069 /* Check if field name ends with the ": " delimiter */
7070 ptr += strlen(hfinfo->name);
7071 if (strncmp(ptr, ": ", 2) == 0) {
7072 ptr += 2;
7073 }
7074
7075 /* Return offset to after field name */
7076 return ptr - representation;
7077}
7078
7079static size_t label_find_name_pos(const item_label_t *rep)
7080{
7081 size_t name_pos = 0;
7082
7083 /* If the value_pos is too small or too large, we can't find the expected format */
7084 if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7085 return 0;
7086 }
7087
7088 /* Check if the format looks like "label: value", then set name_pos before ':'. */
7089 if (rep->representation[rep->value_pos-2] == ':') {
7090 name_pos = rep->value_pos - 2;
7091 }
7092
7093 return name_pos;
7094}
7095
7096/* If the protocol tree is to be visible, set the representation of a
7097 proto_tree entry with the name of the field for the item and with
7098 the value formatted with the supplied printf-style format and
7099 argument list. */
7100static void
7101proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7102{
7103 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 7103, __func__, "assertion failed: %s", "pi"
); } while (0)
;
7104
7105 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7106 * items string representation */
7107 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7108 size_t name_pos, ret = 0;
7109 char *str;
7110 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7111 const header_field_info *hf;
7112
7113 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7113, "fi"))))
;
7114
7115 hf = fi->hfinfo;
7116
7117 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;
;
7118 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))
)) {
7119 uint64_t val;
7120 char *p;
7121
7122 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)
)
7123 val = fvalue_get_uinteger(fi->value);
7124 else
7125 val = fvalue_get_uinteger64(fi->value);
7126
7127 val <<= hfinfo_bitshift(hf);
7128
7129 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7130 ret = (p - fi->rep->representation);
7131 }
7132
7133 /* put in the hf name */
7134 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)
;
7135
7136 ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const
uint8_t*)": ", 0)
;
7137 /* If possible, Put in the value of the string */
7138 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7139 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"
, 7139, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7140 fi->rep->value_pos = ret;
7141 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7142 if (ret >= ITEM_LABEL_LENGTH240) {
7143 /* Uh oh, we don't have enough room. Tell the user
7144 * that the field is truncated.
7145 */
7146 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7147 }
7148 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7149 }
7150}
7151
7152/* If the protocol tree is to be visible, set the representation of a
7153 proto_tree entry with the representation formatted with the supplied
7154 printf-style format and argument list. */
7155static void
7156proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7157{
7158 size_t ret; /*tmp return value */
7159 char *str;
7160 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7161
7162 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7162, "fi"))))
;
7163
7164 if (!proto_item_is_hidden(pi)) {
7165 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;
;
7166
7167 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7168 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"
, 7168, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7169 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7170 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7171 if (ret >= ITEM_LABEL_LENGTH240) {
7172 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7173 size_t name_pos = label_find_name_pos(fi->rep);
7174 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7175 }
7176 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7177 }
7178}
7179
7180static int
7181proto_strlcpy(char *dest, const char *src, size_t dest_size)
7182{
7183 if (dest_size == 0) return 0;
7184
7185 size_t res = g_strlcpy(dest, src, dest_size);
7186
7187 /* At most dest_size - 1 characters will be copied
7188 * (unless dest_size is 0). */
7189 if (res >= dest_size)
7190 res = dest_size - 1;
7191 return (int) res;
7192}
7193
7194static header_field_info *
7195hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7196{
7197 header_field_info *dup_hfinfo;
7198
7199 if (hfinfo->same_name_prev_id == -1)
7200 return NULL((void*)0);
7201 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", 7201
, __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", 7201, "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", 7201,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7202 return dup_hfinfo;
7203}
7204
7205static void
7206hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7207{
7208 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)
;
7209 last_field_name = NULL((void*)0);
7210
7211 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7212 /* No hfinfo with the same name */
7213 wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7214 return;
7215 }
7216
7217 if (hfinfo->same_name_next) {
7218 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7219 }
7220
7221 if (hfinfo->same_name_prev_id != -1) {
7222 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7223 same_name_prev->same_name_next = hfinfo->same_name_next;
7224 if (!hfinfo->same_name_next) {
7225 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7226 wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7227 }
7228 }
7229}
7230
7231int
7232proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7233{
7234 const header_field_info *hfinfo = finfo->hfinfo;
7235 int label_len = 0;
7236 char *tmp_str;
7237 const char *str;
7238 const uint8_t *bytes;
7239 uint32_t number;
7240 uint64_t number64;
7241 const char *hf_str_val;
7242 char number_buf[NUMBER_LABEL_LENGTH80];
7243 const char *number_out;
7244 address addr;
7245 const ipv4_addr_and_mask *ipv4;
7246 const ipv6_addr_and_prefix *ipv6;
7247
7248 switch (hfinfo->type) {
7249
7250 case FT_NONE:
7251 case FT_PROTOCOL:
7252 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7253
7254 case FT_UINT_BYTES:
7255 case FT_BYTES:
7256 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7257 hfinfo,
7258 fvalue_get_bytes_data(finfo->value),
7259 (unsigned)fvalue_length2(finfo->value),
7260 label_str_size);
7261 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7262 wmem_free(NULL((void*)0), tmp_str);
7263 break;
7264
7265 case FT_ABSOLUTE_TIME:
7266 {
7267 const nstime_t *value = fvalue_get_time(finfo->value);
7268 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7269 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7270 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7271 }
7272 if (hfinfo->strings) {
7273 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7274 if (time_string != NULL((void*)0)) {
7275 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7276 break;
7277 }
7278 }
7279 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7280 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7281 wmem_free(NULL((void*)0), tmp_str);
7282 break;
7283 }
7284
7285 case FT_RELATIVE_TIME:
7286 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7287 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7288 wmem_free(NULL((void*)0), tmp_str);
7289 break;
7290
7291 case FT_BOOLEAN:
7292 number64 = fvalue_get_uinteger64(finfo->value);
7293 label_len = proto_strlcpy(display_label_str,
7294 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7295 break;
7296
7297 case FT_CHAR:
7298 number = fvalue_get_uinteger(finfo->value);
7299
7300 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7301 char tmp[ITEM_LABEL_LENGTH240];
7302 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7303
7304 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7304, "fmtfunc"))))
;
7305 fmtfunc(tmp, number);
7306
7307 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7308
7309 } else if (hfinfo->strings) {
7310 number_out = hf_try_val_to_str(number, hfinfo);
7311
7312 if (!number_out) {
7313 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7314 }
7315
7316 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7317
7318 } else {
7319 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7320
7321 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7322 }
7323
7324 break;
7325
7326 /* XXX - make these just FT_NUMBER? */
7327 case FT_INT8:
7328 case FT_INT16:
7329 case FT_INT24:
7330 case FT_INT32:
7331 case FT_UINT8:
7332 case FT_UINT16:
7333 case FT_UINT24:
7334 case FT_UINT32:
7335 case FT_FRAMENUM:
7336 hf_str_val = NULL((void*)0);
7337 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
))
?
7338 (uint32_t) fvalue_get_sinteger(finfo->value) :
7339 fvalue_get_uinteger(finfo->value);
7340
7341 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7342 char tmp[ITEM_LABEL_LENGTH240];
7343 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7344
7345 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7345, "fmtfunc"))))
;
7346 fmtfunc(tmp, number);
7347
7348 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7349
7350 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7351 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7352 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7353 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7354 hf_str_val = hf_try_val_to_str(number, hfinfo);
7355 if (hf_str_val)
7356 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7357 } else {
7358 number_out = hf_try_val_to_str(number, hfinfo);
7359
7360 if (!number_out) {
7361 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7362 }
7363
7364 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7365 }
7366 } else {
7367 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7368
7369 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7370 }
7371
7372 break;
7373
7374 case FT_INT40:
7375 case FT_INT48:
7376 case FT_INT56:
7377 case FT_INT64:
7378 case FT_UINT40:
7379 case FT_UINT48:
7380 case FT_UINT56:
7381 case FT_UINT64:
7382 hf_str_val = NULL((void*)0);
7383 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
))
?
7384 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7385 fvalue_get_uinteger64(finfo->value);
7386
7387 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7388 char tmp[ITEM_LABEL_LENGTH240];
7389 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7390
7391 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7391, "fmtfunc64"
))))
;
7392 fmtfunc64(tmp, number64);
7393
7394 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7395 } else if (hfinfo->strings) {
7396 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7397 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7398 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7399 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7400 if (hf_str_val)
7401 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7402 } else {
7403 number_out = hf_try_val64_to_str(number64, hfinfo);
7404
7405 if (!number_out)
7406 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7407
7408 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7409 }
7410 } else {
7411 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7412
7413 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7414 }
7415
7416 break;
7417
7418 case FT_EUI64:
7419 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7420 tmp_str = address_to_display(NULL((void*)0), &addr);
7421 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7422 wmem_free(NULL((void*)0), tmp_str);
7423 break;
7424
7425 case FT_IPv4:
7426 ipv4 = fvalue_get_ipv4(finfo->value);
7427 //XXX: Should we ignore the mask?
7428 set_address_ipv4(&addr, ipv4);
7429 tmp_str = address_to_display(NULL((void*)0), &addr);
7430 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7431 wmem_free(NULL((void*)0), tmp_str);
7432 free_address(&addr);
7433 break;
7434
7435 case FT_IPv6:
7436 ipv6 = fvalue_get_ipv6(finfo->value);
7437 set_address_ipv6(&addr, ipv6);
7438 tmp_str = address_to_display(NULL((void*)0), &addr);
7439 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7440 wmem_free(NULL((void*)0), tmp_str);
7441 free_address(&addr);
7442 break;
7443
7444 case FT_FCWWN:
7445 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7446 tmp_str = address_to_display(NULL((void*)0), &addr);
7447 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7448 wmem_free(NULL((void*)0), tmp_str);
7449 break;
7450
7451 case FT_ETHER:
7452 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7453 tmp_str = address_to_display(NULL((void*)0), &addr);
7454 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7455 wmem_free(NULL((void*)0), tmp_str);
7456 break;
7457
7458 case FT_GUID:
7459 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7460 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7461 wmem_free(NULL((void*)0), tmp_str);
7462 break;
7463
7464 case FT_REL_OID:
7465 bytes = fvalue_get_bytes_data(finfo->value);
7466 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7467 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7468 wmem_free(NULL((void*)0), tmp_str);
7469 break;
7470
7471 case FT_OID:
7472 bytes = fvalue_get_bytes_data(finfo->value);
7473 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7474 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7475 wmem_free(NULL((void*)0), tmp_str);
7476 break;
7477
7478 case FT_SYSTEM_ID:
7479 bytes = fvalue_get_bytes_data(finfo->value);
7480 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7481 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7482 wmem_free(NULL((void*)0), tmp_str);
7483 break;
7484
7485 case FT_FLOAT:
7486 case FT_DOUBLE:
7487 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7488 break;
7489
7490 case FT_IEEE_11073_SFLOAT:
7491 case FT_IEEE_11073_FLOAT:
7492 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7493 break;
7494
7495 case FT_STRING:
7496 case FT_STRINGZ:
7497 case FT_UINT_STRING:
7498 case FT_STRINGZPAD:
7499 case FT_STRINGZTRUNC:
7500 str = fvalue_get_string(finfo->value);
7501 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7502 if (label_len >= label_str_size) {
7503 /* Truncation occurred. Get the real length
7504 * copied (not including '\0') */
7505 label_len = label_str_size ? label_str_size - 1 : 0;
7506 }
7507 break;
7508
7509 default:
7510 /* First try ftype string representation */
7511 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7512 if (!tmp_str) {
7513 /* Default to show as bytes */
7514 bytes = fvalue_get_bytes_data(finfo->value);
7515 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7516 }
7517 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7518 wmem_free(NULL((void*)0), tmp_str);
7519 break;
7520 }
7521 return label_len;
7522}
7523
7524const char *
7525proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7526 char *result, char *expr, const int size)
7527{
7528 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7529 GPtrArray *finfos;
7530 field_info *finfo = NULL((void*)0);
7531 header_field_info* hfinfo;
7532 const char *abbrev = NULL((void*)0);
7533
7534 char *str;
7535 col_custom_t *field_idx;
7536 int field_id;
7537 int ii = 0;
7538
7539 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7539, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7540 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7541 field_id = field_idx->field_id;
7542 if (field_id == 0) {
7543 GPtrArray *fvals = NULL((void*)0);
7544 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7545 if (fvals != NULL((void*)0)) {
7546
7547 // XXX - Handling occurrences is unusual when more
7548 // than one field is involved, e.g. there's four
7549 // results for tcp.port + tcp.port. We may really
7550 // want to apply it to the operands, not the output.
7551 // Note that occurrences are not quite the same as
7552 // the layer operator (should the grammar support
7553 // both?)
7554 /* Calculate single index or set outer boundaries */
7555 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7556 if (occurrence < 0) {
7557 i = occurrence + len;
7558 last = i;
7559 } else if (occurrence > 0) {
7560 i = occurrence - 1;
7561 last = i;
7562 } else {
7563 i = 0;
7564 last = len - 1;
7565 }
7566 if (i < 0 || i >= len) {
7567 g_ptr_array_unref(fvals);
7568 continue;
7569 }
7570 for (; i <= last; i++) {
7571 /* XXX - We could have a "resolved" result
7572 * for types where the value depends only
7573 * on the type, e.g. FT_IPv4, and not on
7574 * hfinfo->strings. Supporting the latter
7575 * requires knowing which hfinfo matched
7576 * if there are multiple with the same
7577 * abbreviation. In any case, we need to
7578 * know the expected return type of the
7579 * field expression.
7580 */
7581 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7582 if (offset_r && (offset_r < (size - 1)))
7583 result[offset_r++] = ',';
7584 if (offset_e && (offset_e < (size - 1)))
7585 expr[offset_e++] = ',';
7586 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7587 // col_{add,append,set}_* calls ws_label_strcpy
7588 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7589
7590 g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized
(str, __builtin_object_size ((str), 0)) : (g_free) (str)
;
7591 }
7592 g_ptr_array_unref(fvals);
7593 } else if (passed) {
7594 // XXX - Occurrence doesn't make sense for a test
7595 // output, it should be applied to the operands.
7596 if (offset_r && (offset_r < (size - 1)))
7597 result[offset_r++] = ',';
7598 if (offset_e && (offset_e < (size - 1)))
7599 expr[offset_e++] = ',';
7600 /* Prevent multiple check marks */
7601 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7602 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7603 } else {
7604 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7605 }
7606 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7607 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7608 } else {
7609 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7610 }
7611 }
7612 continue;
7613 }
7614 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", 7614
, __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", 7614,
"(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", 7614,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7615
7616 /* do we need to rewind ? */
7617 if (!hfinfo)
7618 return "";
7619
7620 if (occurrence < 0) {
7621 /* Search other direction */
7622 while (hfinfo->same_name_prev_id != -1) {
7623 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", 7623
, __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", 7623, "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", 7623,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7624 }
7625 }
7626
7627 prev_len = 0; /* Reset handled occurrences */
7628
7629 while (hfinfo) {
7630 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7631
7632 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7633 if (occurrence < 0) {
7634 hfinfo = hfinfo->same_name_next;
7635 } else {
7636 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7637 }
7638 continue;
7639 }
7640
7641 /* Are there enough occurrences of the field? */
7642 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7643 if (occurrence < 0) {
7644 hfinfo = hfinfo->same_name_next;
7645 } else {
7646 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7647 }
7648 prev_len += len;
7649 continue;
7650 }
7651
7652 /* Calculate single index or set outer boundaries */
7653 if (occurrence < 0) {
7654 i = occurrence + len + prev_len;
7655 last = i;
7656 } else if (occurrence > 0) {
7657 i = occurrence - 1 - prev_len;
7658 last = i;
7659 } else {
7660 i = 0;
7661 last = len - 1;
7662 }
7663
7664 prev_len += len; /* Count handled occurrences */
7665
7666 while (i <= last) {
7667 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7668
7669 if (offset_r && (offset_r < (size - 1)))
7670 result[offset_r++] = ',';
7671
7672 if (display_details) {
7673 char representation[ITEM_LABEL_LENGTH240];
7674 size_t offset = 0;
7675
7676 if (finfo->rep && finfo->rep->value_len) {
7677 (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7678 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7679 } else {
7680 proto_item_fill_label(finfo, representation, &offset);
7681 }
7682 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7683 } else {
7684 switch (hfinfo->type) {
7685
7686 case FT_NONE:
7687 case FT_PROTOCOL:
7688 /* Prevent multiple check marks */
7689 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7690 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7691 } else {
7692 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7693 }
7694 break;
7695
7696 default:
7697 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7698 break;
7699 }
7700 }
7701
7702 if (offset_e && (offset_e < (size - 1)))
7703 expr[offset_e++] = ',';
7704
7705 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
))
)) {
7706 const char *hf_str_val;
7707 /* Integer types with BASE_NONE never get the numeric value. */
7708 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7709 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7710 } 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
)
) {
7711 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7712 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7713 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7714 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7715 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7716 }
7717 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7718 offset_e = (int)strlen(expr);
7719 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7720 /* Prevent multiple check marks */
7721 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7722 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7723 } else {
7724 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7725 }
7726 } else {
7727 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7728 // col_{add,append,set}_* calls ws_label_strcpy
7729 offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7730 wmem_free(NULL((void*)0), str);
7731 }
7732 i++;
7733 }
7734
7735 /* XXX: Why is only the first abbreviation returned for a multifield
7736 * custom column? */
7737 if (!abbrev) {
7738 /* Store abbrev for return value */
7739 abbrev = hfinfo->abbrev;
7740 }
7741
7742 if (occurrence == 0) {
7743 /* Fetch next hfinfo with same name (abbrev) */
7744 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7745 } else {
7746 hfinfo = NULL((void*)0);
7747 }
7748 }
7749 }
7750
7751 if (offset_r >= (size - 1)) {
7752 mark_truncated(result, 0, size, NULL((void*)0));
7753 }
7754 if (offset_e >= (size - 1)) {
7755 mark_truncated(expr, 0, size, NULL((void*)0));
7756 }
7757 return abbrev ? abbrev : "";
7758}
7759
7760char *
7761proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7762{
7763 int len, prev_len, last, i;
7764 GPtrArray *finfos;
7765 field_info *finfo = NULL((void*)0);
7766 header_field_info* hfinfo;
7767
7768 char *filter = NULL((void*)0);
7769 GPtrArray *filter_array;
7770
7771 col_custom_t *col_custom;
7772 int field_id;
7773
7774 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7774, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7775 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7776 for (GSList *iter = field_ids; iter; iter = iter->next) {
7777 col_custom = (col_custom_t*)iter->data;
7778 field_id = col_custom->field_id;
7779 if (field_id == 0) {
7780 GPtrArray *fvals = NULL((void*)0);
7781 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7782 if (fvals != NULL((void*)0)) {
7783 // XXX - Handling occurrences is unusual when more
7784 // than one field is involved, e.g. there's four
7785 // results for tcp.port + tcp.port. We really
7786 // want to apply it to the operands, not the output.
7787 /* Calculate single index or set outer boundaries */
7788 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7789 if (occurrence < 0) {
7790 i = occurrence + len;
7791 last = i;
7792 } else if (occurrence > 0) {
7793 i = occurrence - 1;
7794 last = i;
7795 } else {
7796 i = 0;
7797 last = len - 1;
7798 }
7799 if (i < 0 || i >= len) {
7800 g_ptr_array_unref(fvals);
7801 continue;
7802 }
7803 for (; i <= last; i++) {
7804 /* XXX - Should multiple values for one
7805 * field use set membership to reduce
7806 * verbosity, here and below? */
7807 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7808 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7809 wmem_free(NULL((void*)0), str);
7810 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7811 g_ptr_array_add(filter_array, filter);
7812 }
7813 }
7814 g_ptr_array_unref(fvals);
7815 } else if (passed) {
7816 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7817 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7818 g_ptr_array_add(filter_array, filter);
7819 }
7820 } else {
7821 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7822 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7823 g_ptr_array_add(filter_array, filter);
7824 }
7825 }
7826 continue;
7827 }
7828
7829 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", 7829
, __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", 7829,
"(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", 7829,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7830
7831 /* do we need to rewind ? */
7832 if (!hfinfo)
7833 return NULL((void*)0);
7834
7835 if (occurrence < 0) {
7836 /* Search other direction */
7837 while (hfinfo->same_name_prev_id != -1) {
7838 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", 7838
, __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", 7838, "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", 7838,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7839 }
7840 }
7841
7842 prev_len = 0; /* Reset handled occurrences */
7843
7844 while (hfinfo) {
7845 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7846
7847 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7848 if (occurrence < 0) {
7849 hfinfo = hfinfo->same_name_next;
7850 } else {
7851 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7852 }
7853 continue;
7854 }
7855
7856 /* Are there enough occurrences of the field? */
7857 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7858 if (occurrence < 0) {
7859 hfinfo = hfinfo->same_name_next;
7860 } else {
7861 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7862 }
7863 prev_len += len;
7864 continue;
7865 }
7866
7867 /* Calculate single index or set outer boundaries */
7868 if (occurrence < 0) {
7869 i = occurrence + len + prev_len;
7870 last = i;
7871 } else if (occurrence > 0) {
7872 i = occurrence - 1 - prev_len;
7873 last = i;
7874 } else {
7875 i = 0;
7876 last = len - 1;
7877 }
7878
7879 prev_len += len; /* Count handled occurrences */
7880
7881 while (i <= last) {
7882 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7883
7884 filter = proto_construct_match_selected_string(finfo, edt);
7885 if (filter) {
7886 /* Only add the same expression once (especially for FT_PROTOCOL).
7887 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7888 */
7889 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7890 g_ptr_array_add(filter_array, filter);
7891 }
7892 }
7893 i++;
7894 }
7895
7896 if (occurrence == 0) {
7897 /* Fetch next hfinfo with same name (abbrev) */
7898 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7899 } else {
7900 hfinfo = NULL((void*)0);
7901 }
7902 }
7903 }
7904
7905 g_ptr_array_add(filter_array, NULL((void*)0));
7906
7907 /* XXX: Should this be || or && ? */
7908 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7909
7910 g_ptr_array_free(filter_array, true1);
7911
7912 return output;
7913}
7914
7915/* Set text of proto_item after having already been created. */
7916void
7917proto_item_set_text(proto_item *pi, const char *format, ...)
7918{
7919 field_info *fi = NULL((void*)0);
7920 va_list ap;
7921
7922 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7923
7924 fi = PITEM_FINFO(pi)((pi)->finfo);
7925 if (fi == NULL((void*)0))
7926 return;
7927
7928 if (fi->rep) {
7929 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7930 fi->rep = NULL((void*)0);
7931 }
7932
7933 va_start(ap, format)__builtin_va_start(ap, format);
7934 proto_tree_set_representation(pi, format, ap);
7935 va_end(ap)__builtin_va_end(ap);
7936}
7937
7938/* Append to text of proto_item after having already been created. */
7939void
7940proto_item_append_text(proto_item *pi, const char *format, ...)
7941{
7942 field_info *fi = NULL((void*)0);
7943 size_t curlen;
7944 char *str;
7945 va_list ap;
7946
7947 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7948
7949 fi = PITEM_FINFO(pi)((pi)->finfo);
7950 if (fi == NULL((void*)0)) {
7951 return;
7952 }
7953
7954 if (!proto_item_is_hidden(pi)) {
7955 /*
7956 * If we don't already have a representation,
7957 * generate the default representation.
7958 */
7959 if (fi->rep == NULL((void*)0)) {
7960 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;
;
7961 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7962 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7963 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7964 (strncmp(format, ": ", 2) == 0)) {
7965 fi->rep->value_pos += 2;
7966 }
7967 }
7968 if (fi->rep) {
7969 curlen = strlen(fi->rep->representation);
7970 /* curlen doesn't include the \0 byte.
7971 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7972 * the representation has already been truncated (of an up
7973 * to 4 byte UTF-8 character) or is just at the maximum length
7974 * unless we search for " [truncated]" (which may not be
7975 * at the start.)
7976 * It's safer to do nothing.
7977 */
7978 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7979 va_start(ap, format)__builtin_va_start(ap, format);
7980 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7981 va_end(ap)__builtin_va_end(ap);
7982 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"
, 7982, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7983 /* Keep fi->rep->value_pos */
7984 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7985 if (curlen >= ITEM_LABEL_LENGTH240) {
7986 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7987 size_t name_pos = label_find_name_pos(fi->rep);
7988 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7989 }
7990 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7991 }
7992 }
7993 }
7994}
7995
7996/* Prepend to text of proto_item after having already been created. */
7997void
7998proto_item_prepend_text(proto_item *pi, const char *format, ...)
7999{
8000 field_info *fi = NULL((void*)0);
8001 size_t pos;
8002 char representation[ITEM_LABEL_LENGTH240];
8003 char *str;
8004 va_list ap;
8005
8006 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
8007
8008 fi = PITEM_FINFO(pi)((pi)->finfo);
8009 if (fi == NULL((void*)0)) {
8010 return;
8011 }
8012
8013 if (!proto_item_is_hidden(pi)) {
8014 /*
8015 * If we don't already have a representation,
8016 * generate the default representation.
8017 */
8018 if (fi->rep == NULL((void*)0)) {
8019 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;
;
8020 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8021 } else
8022 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8023
8024 va_start(ap, format)__builtin_va_start(ap, format);
8025 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8026 va_end(ap)__builtin_va_end(ap);
8027 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"
, 8027, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
8028 fi->rep->value_pos += strlen(str);
8029 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8030 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8031 /* XXX: As above, if the old representation is close to the label
8032 * length, it might already be marked as truncated. */
8033 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8034 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8035 size_t name_pos = label_find_name_pos(fi->rep);
8036 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8037 }
8038 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8039 }
8040}
8041
8042static void
8043finfo_set_len(field_info *fi, const unsigned length)
8044{
8045 unsigned length_remaining;
8046
8047 length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8048 if (length > length_remaining)
8049 fi->length = length_remaining;
8050 else
8051 fi->length = length;
8052
8053 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8054 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8055 fvalue_set_protocol_length(fi->value, fi->length);
8056 }
8057
8058 /*
8059 * You cannot just make the "len" field of a GByteArray
8060 * larger, if there's no data to back that length;
8061 * you can only make it smaller.
8062 */
8063 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8064 GBytes *bytes = fvalue_get_bytes(fi->value);
8065 size_t size;
8066 const void *data = g_bytes_get_data(bytes, &size);
8067 if ((size_t)fi->length <= size) {
8068 fvalue_set_bytes_data(fi->value, data, fi->length);
8069 }
8070 g_bytes_unref(bytes);
8071 }
8072}
8073
8074void
8075proto_item_set_len(proto_item *pi, const unsigned length)
8076{
8077 field_info *fi;
8078
8079 if (pi == NULL((void*)0))
8080 return;
8081
8082 fi = PITEM_FINFO(pi)((pi)->finfo);
8083 if (fi == NULL((void*)0))
8084 return;
8085
8086 finfo_set_len(fi, length);
8087}
8088
8089/*
8090 * Sets the length of the item based on its start and on the specified
8091 * offset, which is the offset past the end of the item; as the start
8092 * in the item is relative to the beginning of the data source tvbuff,
8093 * we need to pass in a tvbuff - the end offset is relative to the beginning
8094 * of that tvbuff.
8095 */
8096void
8097proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8098{
8099 field_info *fi;
8100 unsigned length;
8101
8102 if (pi == NULL((void*)0))
8103 return;
8104
8105 fi = PITEM_FINFO(pi)((pi)->finfo);
8106 if (fi == NULL((void*)0))
8107 return;
8108
8109 if (G_LIKELY(tvb)(tvb)) {
8110 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"
, 8110, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8111 end += tvb_raw_offset(tvb);
8112 } else {
8113 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", 8113, "((void*)0) == fi->ds_tvb"
))))
;
8114 }
8115 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8115, "end >= fi->start"
))))
;
8116 length = end - fi->start;
8117
8118 finfo_set_len(fi, length);
8119}
8120
8121unsigned
8122proto_item_get_len(const proto_item *pi)
8123{
8124 /* XXX - The only use case where this is really guaranteed to work is
8125 * increasing the length of an item (which has no effect if the item
8126 * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8127 *
8128 * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8129 *
8130 * Should there be a macro or function to do that, and possibly this
8131 * be deprecated? As a bonus, we could handle overflow.
8132 */
8133 field_info *fi;
8134
8135 if (!pi)
8136 return 0;
8137 fi = PITEM_FINFO(pi)((pi)->finfo);
8138 if (fi) {
8139 return fi->length;
8140 }
8141 return 0;
8142}
8143
8144void
8145proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8146 if (!ti) {
8147 return;
8148 }
8149 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)
;
8150 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)
;
8151}
8152
8153char *
8154proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8155{
8156 field_info *fi;
8157
8158 if (!pi)
8159 return wmem_strdup(scope, "");
8160 fi = PITEM_FINFO(pi)((pi)->finfo);
8161 if (!fi)
8162 return wmem_strdup(scope, "");
8163 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8163, "fi->hfinfo != ((void*)0)"
))))
;
8164 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8165}
8166
8167proto_tree *
8168proto_tree_create_root(packet_info *pinfo)
8169{
8170 proto_node *pnode;
8171
8172 /* Initialize the proto_node */
8173 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof
(proto_tree) : 1)))
;
8174 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
8175 pnode->parent = NULL((void*)0);
8176 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8177 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)))
;
8178
8179 /* Make sure we can access pinfo everywhere */
8180 pnode->tree_data->pinfo = pinfo;
8181
8182 /* Don't initialize the tree_data_t. Wait until we know we need it */
8183 pnode->tree_data->interesting_hfids = NULL((void*)0);
8184
8185 /* Set the default to false so it's easier to
8186 * find errors; if we expect to see the protocol tree
8187 * but for some reason the default 'visible' is not
8188 * changed, then we'll find out very quickly. */
8189 pnode->tree_data->visible = false0;
8190
8191 /* Make sure that we fake protocols (if possible) */
8192 pnode->tree_data->fake_protocols = true1;
8193
8194 /* Keep track of the number of children */
8195 pnode->tree_data->count = 0;
8196
8197 /* Initialize our loop checks */
8198 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8199 pnode->tree_data->max_start = 0;
8200 pnode->tree_data->start_idle_count = 0;
8201
8202 return (proto_tree *)pnode;
8203}
8204
8205
8206/* "prime" a proto_tree with a single hfid that a dfilter
8207 * is interested in. */
8208void
8209proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8210{
8211 header_field_info *hfinfo;
8212
8213 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", 8213, __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", 8213, "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", 8213, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8214 /* this field is referenced by a filter so increase the refcount.
8215 also increase the refcount for the parent, i.e the protocol.
8216 Don't increase the refcount if we're already printing the
8217 type, as that is a superset of direct reference.
8218 */
8219 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8220 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8221 }
8222 /* only increase the refcount if there is a parent.
8223 if this is a protocol and not a field then parent will be -1
8224 and there is no parent to add any refcounting for.
8225 */
8226 if (hfinfo->parent != -1) {
8227 header_field_info *parent_hfinfo;
8228 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", 8228
, __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", 8228,
"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", 8228,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8229
8230 /* Mark parent as indirectly referenced unless it is already directly
8231 * referenced, i.e. the user has specified the parent in a filter.
8232 */
8233 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8234 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8235 }
8236}
8237
8238/* "prime" a proto_tree with a single hfid that a dfilter
8239 * is interested in. */
8240void
8241proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8242{
8243 header_field_info *hfinfo;
8244
8245 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", 8245, __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", 8245, "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", 8245, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8246 /* this field is referenced by an (output) filter so increase the refcount.
8247 also increase the refcount for the parent, i.e the protocol.
8248 */
8249 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8250 /* only increase the refcount if there is a parent.
8251 if this is a protocol and not a field then parent will be -1
8252 and there is no parent to add any refcounting for.
8253 */
8254 if (hfinfo->parent != -1) {
8255 header_field_info *parent_hfinfo;
8256 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", 8256
, __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", 8256,
"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", 8256,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8257
8258 /* Mark parent as indirectly referenced unless it is already directly
8259 * referenced, i.e. the user has specified the parent in a filter.
8260 */
8261 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8262 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8263 }
8264}
8265
8266proto_tree *
8267proto_item_add_subtree(proto_item *pi, const int idx) {
8268 field_info *fi;
8269
8270 if (!pi)
8271 return NULL((void*)0);
8272
8273 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", 8273, "idx >= 0 && idx < num_tree_types"
))))
;
8274
8275 fi = PITEM_FINFO(pi)((pi)->finfo);
8276 if (!fi)
8277 return (proto_tree *)pi;
8278
8279 fi->tree_type = idx;
8280
8281 return (proto_tree *)pi;
8282}
8283
8284proto_tree *
8285proto_item_get_subtree(proto_item *pi) {
8286 field_info *fi;
8287
8288 if (!pi)
8289 return NULL((void*)0);
8290 fi = PITEM_FINFO(pi)((pi)->finfo);
8291 if ( (fi) && (fi->tree_type == -1) )
8292 return NULL((void*)0);
8293 return (proto_tree *)pi;
8294}
8295
8296proto_item *
8297proto_item_get_parent(const proto_item *ti) {
8298 if (!ti)
8299 return NULL((void*)0);
8300 return ti->parent;
8301}
8302
8303proto_item *
8304proto_item_get_parent_nth(proto_item *ti, int gen) {
8305 if (!ti)
8306 return NULL((void*)0);
8307 while (gen--) {
8308 ti = ti->parent;
8309 if (!ti)
8310 return NULL((void*)0);
8311 }
8312 return ti;
8313}
8314
8315
8316proto_item *
8317proto_tree_get_parent(proto_tree *tree) {
8318 if (!tree)
8319 return NULL((void*)0);
8320 return (proto_item *)tree;
8321}
8322
8323proto_tree *
8324proto_tree_get_parent_tree(proto_tree *tree) {
8325 if (!tree)
8326 return NULL((void*)0);
8327
8328 /* we're the root tree, there's no parent
8329 return ourselves so the caller has at least a tree to attach to */
8330 if (!tree->parent)
8331 return tree;
8332
8333 return (proto_tree *)tree->parent;
8334}
8335
8336proto_tree *
8337proto_tree_get_root(proto_tree *tree) {
8338 if (!tree)
8339 return NULL((void*)0);
8340 while (tree->parent) {
8341 tree = tree->parent;
8342 }
8343 return tree;
8344}
8345
8346void
8347proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8348 proto_item *item_to_move)
8349{
8350 /* This function doesn't generate any values. It only reorganizes the protocol tree
8351 * so we can bail out immediately if it isn't visible. */
8352 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8353 return;
8354
8355 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", 8355, "item_to_move->parent == tree"
))))
;
8356 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", 8356, "fixed_item->parent == tree"
))))
;
8357
8358 /*** cut item_to_move out ***/
8359
8360 /* is item_to_move the first? */
8361 if (tree->first_child == item_to_move) {
8362 /* simply change first child to next */
8363 tree->first_child = item_to_move->next;
8364
8365 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", 8365, "tree->last_child != item_to_move"
))))
;
8366 } else {
8367 proto_item *curr_item;
8368 /* find previous and change it's next */
8369 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8370 if (curr_item->next == item_to_move) {
8371 break;
8372 }
8373 }
8374
8375 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8375, "curr_item"
))))
;
8376
8377 curr_item->next = item_to_move->next;
8378
8379 /* fix last_child if required */
8380 if (tree->last_child == item_to_move) {
8381 tree->last_child = curr_item;
8382 }
8383 }
8384
8385 /*** insert to_move after fixed ***/
8386 item_to_move->next = fixed_item->next;
8387 fixed_item->next = item_to_move;
8388 if (tree->last_child == fixed_item) {
8389 tree->last_child = item_to_move;
8390 }
8391}
8392
8393void
8394proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8395 const unsigned length)
8396{
8397 field_info *fi;
8398
8399 if (tree == NULL((void*)0))
8400 return;
8401
8402 fi = PTREE_FINFO(tree)((tree)->finfo);
8403 if (fi == NULL((void*)0))
8404 return;
8405
8406 /* We don't store a separate data source tvb for the appendix, so
8407 * it must be from the same data source. (XXX - Are there any
8408 * situations where it makes sense to have an appendix from a
8409 * different data source?) */
8410 if (G_LIKELY(tvb)(tvb)) {
8411 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"
, 8411, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))))
;
8412 start += tvb_raw_offset(tvb);
8413 } else {
8414 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", 8414, "((void*)0) == fi->ds_tvb"
))))
;
8415 }
8416
8417 /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8418 * main body? */
8419
8420 fi->appendix_start = start;
8421 fi->appendix_length = length;
8422}
8423
8424static void
8425check_protocol_filter_name_or_fail(const char *filter_name)
8426{
8427 /* Require at least two characters. */
8428 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8429 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)
;
8430 }
8431
8432 if (proto_check_field_name(filter_name) != '\0') {
8433 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)
8434 " 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)
8435 " 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)
;
8436 }
8437
8438 /* Check that it doesn't match some very common numeric forms. */
8439 if (filter_name[0] == '0' &&
8440 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8441 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8442 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])
8443 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])
;
8444 }
8445
8446 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8447
8448 /* Check that it contains at least one letter. */
8449 bool_Bool have_letter = false0;
8450 for (const char *s = filter_name; *s != '\0'; s++) {
8451 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8452 have_letter = true1;
8453 break;
8454 }
8455 }
8456 if (!have_letter) {
8457 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)
8458 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8459 }
8460
8461 /* Check for reserved keywords. */
8462 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8463 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)
8464 " 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)
;
8465 }
8466}
8467
8468int
8469proto_register_protocol(const char *name, const char *short_name,
8470 const char *filter_name)
8471{
8472 protocol_t *protocol;
8473 header_field_info *hfinfo;
8474
8475 check_protocol_filter_name_or_fail(filter_name);
8476
8477 /*
8478 * Add this protocol to the list of known protocols;
8479 * the list is sorted by protocol short name.
8480 */
8481 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8482 protocol->name = name;
8483 protocol->short_name = short_name;
8484 protocol->filter_name = filter_name;
8485 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8486 protocol->is_enabled = true1; /* protocol is enabled by default */
8487 protocol->enabled_by_default = true1; /* see previous comment */
8488 protocol->can_toggle = true1;
8489 protocol->parent_proto_id = -1;
8490 protocol->heur_list = NULL((void*)0);
8491
8492 /* List will be sorted later by name, when all protocols completed registering */
8493 protocols = g_list_prepend(protocols, protocol);
8494 /*
8495 * Make sure there's not already a protocol with any of those
8496 * names. Crash if there is, as that's an error in the code
8497 * or an inappropriate plugin.
8498 * This situation has to be fixed to not register more than one
8499 * protocol with the same name.
8500 */
8501 if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8502 /* ws_error will terminate the program */
8503 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)
8504 " 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)
;
8505 }
8506 if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8507 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)
8508 " 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)
;
8509 }
8510 if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8511 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)
8512 " 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)
;
8513 }
8514
8515 /* Here we allocate a new header_field_info struct */
8516 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8517 hfinfo->name = name;
8518 hfinfo->abbrev = filter_name;
8519 hfinfo->type = FT_PROTOCOL;
8520 hfinfo->display = BASE_NONE;
8521 hfinfo->strings = protocol;
8522 hfinfo->bitmask = 0;
8523 hfinfo->ref_type = HF_REF_TYPE_NONE;
8524 hfinfo->blurb = NULL((void*)0);
8525 hfinfo->parent = -1; /* This field differentiates protos and fields */
8526
8527 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8528 return protocol->proto_id;
8529}
8530
8531int
8532proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8533{
8534 protocol_t *protocol;
8535 header_field_info *hfinfo;
8536
8537 /*
8538 * Helper protocols don't need the strict rules as a "regular" protocol
8539 * Just register it in a list and make a hf_ field from it
8540 */
8541 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8542 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)
;
8543 }
8544
8545 if (parent_proto <= 0) {
8546 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)
8547 " 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)
;
8548 }
8549
8550 check_protocol_filter_name_or_fail(filter_name);
8551
8552 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8553 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8554 protocol->name = name;
8555 protocol->short_name = short_name;
8556 protocol->filter_name = filter_name;
8557 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8558
8559 /* Enabling and toggling is really determined by parent protocol,
8560 but provide default values here */
8561 protocol->is_enabled = true1;
8562 protocol->enabled_by_default = true1;
8563 protocol->can_toggle = true1;
8564
8565 protocol->parent_proto_id = parent_proto;
8566 protocol->heur_list = NULL((void*)0);
8567
8568 /* List will be sorted later by name, when all protocols completed registering */
8569 protocols = g_list_prepend(protocols, protocol);
8570
8571 /* Here we allocate a new header_field_info struct */
8572 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info
) > 0 ? sizeof (header_field_info) : 1)))
;
8573 hfinfo->name = name;
8574 hfinfo->abbrev = filter_name;
8575 hfinfo->type = field_type;
8576 hfinfo->display = BASE_NONE;
8577 if (field_type == FT_BYTES) {
8578 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8579 }
8580 hfinfo->strings = protocol;
8581 hfinfo->bitmask = 0;
8582 hfinfo->ref_type = HF_REF_TYPE_NONE;
8583 hfinfo->blurb = NULL((void*)0);
8584 hfinfo->parent = -1; /* This field differentiates protos and fields */
8585
8586 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8587 return protocol->proto_id;
8588}
8589
8590bool_Bool
8591proto_deregister_protocol(const char *short_name)
8592{
8593 protocol_t *protocol;
8594 header_field_info *hfinfo;
8595 int proto_id;
8596 unsigned i;
8597
8598 proto_id = proto_get_id_by_short_name(short_name);
8599 protocol = find_protocol_by_id(proto_id);
8600 if (protocol == NULL((void*)0))
8601 return false0;
8602
8603 g_hash_table_remove(proto_names, protocol->name);
8604 g_hash_table_remove(proto_short_names, (void *)short_name);
8605 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8606
8607 if (protocol->fields) {
8608 for (i = 0; i < protocol->fields->len; i++) {
8609 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8610 hfinfo_remove_from_gpa_name_map(hfinfo);
8611 expert_deregister_expertinfo(hfinfo->abbrev);
8612 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8613 }
8614 g_ptr_array_free(protocol->fields, true1);
8615 protocol->fields = NULL((void*)0);
8616 }
8617
8618 g_list_free(protocol->heur_list);
8619
8620 /* Remove this protocol from the list of known protocols */
8621 protocols = g_list_remove(protocols, protocol);
8622
8623 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8624 wmem_map_remove(gpa_name_map, protocol->filter_name);
8625
8626 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)
;
8627 last_field_name = NULL((void*)0);
8628
8629 return true1;
8630}
8631
8632void
8633proto_register_alias(const int proto_id, const char *alias_name)
8634{
8635 protocol_t *protocol;
8636
8637 protocol = find_protocol_by_id(proto_id);
8638 if (alias_name && protocol) {
8639 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8640 }
8641}
8642
8643/*
8644 * Routines to use to iterate over the protocols.
8645 * The argument passed to the iterator routines is an opaque cookie to
8646 * their callers; it's the GList pointer for the current element in
8647 * the list.
8648 * The ID of the protocol is returned, or -1 if there is no protocol.
8649 */
8650int
8651proto_get_first_protocol(void **cookie)
8652{
8653 protocol_t *protocol;
8654
8655 if (protocols == NULL((void*)0))
8656 return -1;
8657 *cookie = protocols;
8658 protocol = (protocol_t *)protocols->data;
8659 return protocol->proto_id;
8660}
8661
8662int
8663proto_get_data_protocol(void *cookie)
8664{
8665 GList *list_item = (GList *)cookie;
8666
8667 protocol_t *protocol = (protocol_t *)list_item->data;
8668 return protocol->proto_id;
8669}
8670
8671int
8672proto_get_next_protocol(void **cookie)
8673{
8674 GList *list_item = (GList *)*cookie;
8675 protocol_t *protocol;
8676
8677 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8678 if (list_item == NULL((void*)0))
8679 return -1;
8680 *cookie = list_item;
8681 protocol = (protocol_t *)list_item->data;
8682 return protocol->proto_id;
8683}
8684
8685header_field_info *
8686proto_get_first_protocol_field(const int proto_id, void **cookie)
8687{
8688 protocol_t *protocol = find_protocol_by_id(proto_id);
8689
8690 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8691 return NULL((void*)0);
8692
8693 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8694 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8695}
8696
8697header_field_info *
8698proto_get_next_protocol_field(const int proto_id, void **cookie)
8699{
8700 protocol_t *protocol = find_protocol_by_id(proto_id);
8701 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8702
8703 i++;
8704
8705 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8706 return NULL((void*)0);
8707
8708 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8709 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8710}
8711
8712protocol_t *
8713find_protocol_by_id(const int proto_id)
8714{
8715 header_field_info *hfinfo;
8716
8717 if (proto_id <= 0)
8718 return NULL((void*)0);
8719
8720 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", 8720, __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", 8720,
"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", 8720, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8721 if (hfinfo->type != FT_PROTOCOL) {
8722 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", 8722, "hfinfo->display & 0x00004000"
))))
;
8723 }
8724 return (protocol_t *)hfinfo->strings;
8725}
8726
8727int
8728proto_get_id(const protocol_t *protocol)
8729{
8730 return protocol->proto_id;
8731}
8732
8733bool_Bool
8734proto_name_already_registered(const char *name)
8735{
8736 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8736, "name", "No name present"))))
;
8737
8738 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8739 return true1;
8740 return false0;
8741}
8742
8743int
8744proto_get_id_by_filter_name(const char *filter_name)
8745{
8746 const protocol_t *protocol = NULL((void*)0);
8747
8748 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", 8748,
"filter_name", "No filter name present"))))
;
8749
8750 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8751
8752 if (protocol == NULL((void*)0))
8753 return -1;
8754 return protocol->proto_id;
8755}
8756
8757int
8758proto_get_id_by_short_name(const char *short_name)
8759{
8760 const protocol_t *protocol = NULL((void*)0);
8761
8762 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", 8762,
"short_name", "No short name present"))))
;
8763
8764 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8765
8766 if (protocol == NULL((void*)0))
8767 return -1;
8768 return protocol->proto_id;
8769}
8770
8771const char *
8772proto_get_protocol_name(const int proto_id)
8773{
8774 protocol_t *protocol;
8775
8776 protocol = find_protocol_by_id(proto_id);
8777
8778 if (protocol == NULL((void*)0))
8779 return NULL((void*)0);
8780 return protocol->name;
8781}
8782
8783const char *
8784proto_get_protocol_short_name(const protocol_t *protocol)
8785{
8786 if (protocol == NULL((void*)0))
8787 return "(none)";
8788 return protocol->short_name;
8789}
8790
8791const char *
8792proto_get_protocol_long_name(const protocol_t *protocol)
8793{
8794 if (protocol == NULL((void*)0))
8795 return "(none)";
8796 return protocol->name;
8797}
8798
8799const char *
8800proto_get_protocol_filter_name(const int proto_id)
8801{
8802 protocol_t *protocol;
8803
8804 protocol = find_protocol_by_id(proto_id);
8805 if (protocol == NULL((void*)0))
8806 return "(none)";
8807 return protocol->filter_name;
8808}
8809
8810void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8811{
8812 heur_dtbl_entry_t* heuristic_dissector;
8813
8814 if (protocol == NULL((void*)0))
8815 return;
8816
8817 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8818 if (heuristic_dissector != NULL((void*)0))
8819 {
8820 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8821 }
8822}
8823
8824void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8825{
8826 if (protocol == NULL((void*)0))
8827 return;
8828
8829 g_list_foreach(protocol->heur_list, func, user_data);
8830}
8831
8832void
8833proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8834 bool_Bool *is_tcp, bool_Bool *is_udp,
8835 bool_Bool *is_sctp, bool_Bool *is_tls,
8836 bool_Bool *is_rtp,
8837 bool_Bool *is_lte_rlc)
8838{
8839 wmem_list_frame_t *protos = wmem_list_head(layers);
8840 int proto_id;
8841 const char *proto_name;
8842
8843 /* Walk the list of a available protocols in the packet and
8844 attempt to find "major" ones. */
8845 /* It might make more sense to assemble and return a bitfield. */
8846 while (protos != NULL((void*)0))
8847 {
8848 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8849 proto_name = proto_get_protocol_filter_name(proto_id);
8850
8851 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8852 (!strcmp(proto_name, "ipv6")))) {
8853 *is_ip = true1;
8854 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8855 *is_tcp = true1;
8856 } else if (is_udp && !strcmp(proto_name, "udp")) {
8857 *is_udp = true1;
8858 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8859 *is_sctp = true1;
8860 } else if (is_tls && !strcmp(proto_name, "tls")) {
8861 *is_tls = true1;
8862 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8863 *is_rtp = true1;
8864 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8865 *is_lte_rlc = true1;
8866 }
8867
8868 protos = wmem_list_frame_next(protos);
8869 }
8870}
8871
8872bool_Bool
8873proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8874{
8875 wmem_list_frame_t *protos = wmem_list_head(layers);
8876 int proto_id;
8877 const char *name;
8878
8879 /* Walk the list of a available protocols in the packet and
8880 attempt to find the specified protocol. */
8881 while (protos != NULL((void*)0))
8882 {
8883 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8884 name = proto_get_protocol_filter_name(proto_id);
8885
8886 if (!strcmp(name, proto_name))
8887 {
8888 return true1;
8889 }
8890
8891 protos = wmem_list_frame_next(protos);
8892 }
8893
8894 return false0;
8895}
8896
8897char *
8898proto_list_layers(const packet_info *pinfo)
8899{
8900 wmem_strbuf_t *buf;
8901 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8902
8903 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8904
8905 /* Walk the list of layers in the packet and
8906 return a string of all entries. */
8907 while (layers != NULL((void*)0))
8908 {
8909 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8910
8911 layers = wmem_list_frame_next(layers);
8912 if (layers != NULL((void*)0)) {
8913 wmem_strbuf_append_c(buf, ':');
8914 }
8915 }
8916
8917 return wmem_strbuf_finalize(buf);
8918}
8919
8920uint8_t
8921proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8922{
8923 int *proto_layer_num_ptr;
8924
8925 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8926 if (proto_layer_num_ptr == NULL((void*)0)) {
8927 return 0;
8928 }
8929
8930 return (uint8_t)*proto_layer_num_ptr;
8931}
8932
8933bool_Bool
8934proto_is_pino(const protocol_t *protocol)
8935{
8936 return (protocol->parent_proto_id != -1);
8937}
8938
8939bool_Bool
8940// NOLINTNEXTLINE(misc-no-recursion)
8941proto_is_protocol_enabled(const protocol_t *protocol)
8942{
8943 if (protocol == NULL((void*)0))
8944 return false0;
8945
8946 //parent protocol determines enable/disable for helper dissectors
8947 if (proto_is_pino(protocol))
8948 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8949
8950 return protocol->is_enabled;
8951}
8952
8953bool_Bool
8954// NOLINTNEXTLINE(misc-no-recursion)
8955proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8956{
8957 //parent protocol determines enable/disable for helper dissectors
8958 if (proto_is_pino(protocol))
8959 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8960
8961 return protocol->enabled_by_default;
8962}
8963
8964bool_Bool
8965// NOLINTNEXTLINE(misc-no-recursion)
8966proto_can_toggle_protocol(const int proto_id)
8967{
8968 protocol_t *protocol;
8969
8970 protocol = find_protocol_by_id(proto_id);
8971 //parent protocol determines toggling for helper dissectors
8972 if (proto_is_pino(protocol))
8973 return proto_can_toggle_protocol(protocol->parent_proto_id);
8974
8975 return protocol->can_toggle;
8976}
8977
8978void
8979proto_disable_by_default(const int proto_id)
8980{
8981 protocol_t *protocol;
8982
8983 protocol = find_protocol_by_id(proto_id);
8984 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8984, "protocol->can_toggle"
))))
;
8985 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", 8985, "proto_is_pino(protocol) == 0"
))))
;
8986 protocol->is_enabled = false0;
8987 protocol->enabled_by_default = false0;
8988}
8989
8990void
8991proto_set_decoding(const int proto_id, const bool_Bool enabled)
8992{
8993 protocol_t *protocol;
8994
8995 protocol = find_protocol_by_id(proto_id);
8996 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8996, "protocol->can_toggle"
))))
;
8997 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", 8997, "proto_is_pino(protocol) == 0"
))))
;
8998 protocol->is_enabled = enabled;
8999}
9000
9001void
9002proto_disable_all(void)
9003{
9004 /* This doesn't explicitly disable heuristic protocols,
9005 * but the heuristic doesn't get called if the parent
9006 * protocol isn't enabled.
9007 */
9008 protocol_t *protocol;
9009 GList *list_item = protocols;
9010
9011 if (protocols == NULL((void*)0))
9012 return;
9013
9014 while (list_item) {
9015 protocol = (protocol_t *)list_item->data;
9016 if (protocol->can_toggle) {
9017 protocol->is_enabled = false0;
9018 }
9019 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9020 }
9021}
9022
9023static void
9024heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9025{
9026 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9027
9028 heur->enabled = heur->enabled_by_default;
9029}
9030
9031void
9032proto_reenable_all(void)
9033{
9034 protocol_t *protocol;
9035 GList *list_item = protocols;
9036
9037 if (protocols == NULL((void*)0))
9038 return;
9039
9040 while (list_item) {
9041 protocol = (protocol_t *)list_item->data;
9042 if (protocol->can_toggle)
9043 protocol->is_enabled = protocol->enabled_by_default;
9044 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9045 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
9046 }
9047}
9048
9049void
9050proto_set_cant_toggle(const int proto_id)
9051{
9052 protocol_t *protocol;
9053
9054 protocol = find_protocol_by_id(proto_id);
9055 protocol->can_toggle = false0;
9056}
9057
9058static int
9059proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9060{
9061 g_ptr_array_add(proto->fields, hfi);
9062
9063 return proto_register_field_init(hfi, parent);
9064}
9065
9066/* for use with static arrays only, since we don't allocate our own copies
9067of the header_field_info struct contained within the hf_register_info struct */
9068void
9069proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9070{
9071 hf_register_info *ptr = hf;
9072 protocol_t *proto;
9073 int i;
9074
9075 proto = find_protocol_by_id(parent);
9076
9077 /* if (proto == NULL) - error or return? */
9078
9079 if (proto->fields == NULL((void*)0)) {
9080 /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9081 * GLib introduced g_ptr_array_new_from_array, which might have
9082 * given a reason to actually use it. (#17774)
9083 */
9084 proto->fields = g_ptr_array_sized_new(num_records);
9085 }
9086
9087 for (i = 0; i < num_records; i++, ptr++) {
9088 /*
9089 * Make sure we haven't registered this yet.
9090 * Most fields have variables associated with them that
9091 * are initialized to 0; some are initialized to -1 (which
9092 * was the standard before 4.4).
9093 *
9094 * XXX - Since this is called almost 300000 times at startup,
9095 * it might be nice to compare to only 0 and require
9096 * dissectors to pass in zero for unregistered fields.
9097 */
9098 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9099 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
9100 "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)
9101 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
9102 return;
9103 }
9104
9105 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9106 }
9107}
9108
9109/* deregister already registered fields */
9110void
9111proto_deregister_field (const int parent, int hf_id)
9112{
9113 header_field_info *hfi;
9114 protocol_t *proto;
9115 unsigned i;
9116
9117 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)
;
9118 last_field_name = NULL((void*)0);
9119
9120 if (hf_id == -1 || hf_id == 0)
9121 return;
9122
9123 proto = find_protocol_by_id (parent);
9124 if (!proto || proto->fields == NULL((void*)0)) {
9125 return;
9126 }
9127
9128 for (i = 0; i < proto->fields->len; i++) {
9129 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9130 if (hfi->id == hf_id) {
9131 /* Found the hf_id in this protocol */
9132 wmem_map_remove(gpa_name_map, hfi->abbrev);
9133 g_ptr_array_remove_index_fast(proto->fields, i);
9134 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9135 return;
9136 }
9137 }
9138}
9139
9140/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9141void
9142proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9143{
9144 header_field_info *hfinfo;
9145 protocol_t *proto;
9146
9147 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)
;
9148 last_field_name = NULL((void*)0);
9149
9150 proto = find_protocol_by_id(parent);
9151 if (proto && proto->fields && proto->fields->len > 0) {
9152 unsigned i = proto->fields->len;
9153 do {
9154 i--;
9155
9156 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9157 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) )
) {
9158 hfinfo_remove_from_gpa_name_map(hfinfo);
9159 expert_deregister_expertinfo(hfinfo->abbrev);
9160 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9161 g_ptr_array_remove_index_fast(proto->fields, i);
9162 }
9163 } while (i > 0);
9164 }
9165}
9166
9167void
9168proto_add_deregistered_data (void *data)
9169{
9170 g_ptr_array_add(deregistered_data, data);
9171}
9172
9173void
9174proto_add_deregistered_slice (size_t block_size, void *mem_block)
9175{
9176 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)))
;
9177
9178 slice_data->block_size = block_size;
9179 slice_data->mem_block = mem_block;
9180
9181 g_ptr_array_add(deregistered_slice, slice_data);
9182}
9183
9184void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9185{
9186 if (field_strings == NULL((void*)0)) {
9187 return;
9188 }
9189
9190 switch (field_type) {
9191 case FT_FRAMENUM:
9192 /* This is just an integer represented as a pointer */
9193 break;
9194 case FT_PROTOCOL: {
9195 protocol_t *protocol = (protocol_t *)field_strings;
9196 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)
;
9197 break;
9198 }
9199 case FT_BOOLEAN: {
9200 true_false_string *tf = (true_false_string *)field_strings;
9201 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)
;
9202 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)
;
9203 break;
9204 }
9205 case FT_UINT40:
9206 case FT_INT40:
9207 case FT_UINT48:
9208 case FT_INT48:
9209 case FT_UINT56:
9210 case FT_INT56:
9211 case FT_UINT64:
9212 case FT_INT64: {
9213 if (field_display & BASE_UNIT_STRING0x00001000) {
9214 unit_name_string *unit = (unit_name_string *)field_strings;
9215 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)
;
9216 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)
;
9217 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9218 range_string *rs = (range_string *)field_strings;
9219 while (rs->strptr) {
9220 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
)
;
9221 rs++;
9222 }
9223 } else if (field_display & BASE_EXT_STRING0x00000200) {
9224 val64_string_ext *vse = (val64_string_ext *)field_strings;
9225 val64_string *vs = (val64_string *)vse->_vs_p;
9226 while (vs->strptr) {
9227 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
)
;
9228 vs++;
9229 }
9230 val64_string_ext_free(vse);
9231 field_strings = NULL((void*)0);
9232 } else if (field_display == BASE_CUSTOM) {
9233 /* this will be a pointer to a function, don't free that */
9234 field_strings = NULL((void*)0);
9235 } else {
9236 val64_string *vs64 = (val64_string *)field_strings;
9237 while (vs64->strptr) {
9238 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)
;
9239 vs64++;
9240 }
9241 }
9242 break;
9243 }
9244 case FT_CHAR:
9245 case FT_UINT8:
9246 case FT_INT8:
9247 case FT_UINT16:
9248 case FT_INT16:
9249 case FT_UINT24:
9250 case FT_INT24:
9251 case FT_UINT32:
9252 case FT_INT32:
9253 case FT_FLOAT:
9254 case FT_DOUBLE: {
9255 if (field_display & BASE_UNIT_STRING0x00001000) {
9256 unit_name_string *unit = (unit_name_string *)field_strings;
9257 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)
;
9258 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)
;
9259 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9260 range_string *rs = (range_string *)field_strings;
9261 while (rs->strptr) {
9262 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
)
;
9263 rs++;
9264 }
9265 } else if (field_display & BASE_EXT_STRING0x00000200) {
9266 value_string_ext *vse = (value_string_ext *)field_strings;
9267 value_string *vs = (value_string *)vse->_vs_p;
9268 while (vs->strptr) {
9269 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
)
;
9270 vs++;
9271 }
9272 value_string_ext_free(vse);
9273 field_strings = NULL((void*)0);
9274 } else if (field_display == BASE_CUSTOM) {
9275 /* this will be a pointer to a function, don't free that */
9276 field_strings = NULL((void*)0);
9277 } else {
9278 value_string *vs = (value_string *)field_strings;
9279 while (vs->strptr) {
9280 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
)
;
9281 vs++;
9282 }
9283 }
9284 break;
9285 default:
9286 break;
9287 }
9288 }
9289
9290 if (field_type != FT_FRAMENUM) {
9291 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
)
;
9292 }
9293}
9294
9295static void
9296free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9297{
9298 header_field_info *hfi = (header_field_info *) data;
9299 int hf_id = hfi->id;
9300
9301 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
)
;
9302 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
)
;
9303 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
)
;
9304
9305 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9306
9307 if (hfi->parent == -1)
9308 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)
;
9309
9310 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9311}
9312
9313static void
9314free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9315{
9316 g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized
(data, __builtin_object_size ((data), 0)) : (g_free) (data)
;
9317}
9318
9319static void
9320free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9321{
9322 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9323
9324 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9325 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)
;
9326}
9327
9328/* free deregistered fields and data */
9329void
9330proto_free_deregistered_fields (void)
9331{
9332 expert_free_deregistered_expertinfos();
9333
9334 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9335 g_ptr_array_free(deregistered_fields, true1);
9336 deregistered_fields = g_ptr_array_new();
9337
9338 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9339 g_ptr_array_free(deregistered_data, true1);
9340 deregistered_data = g_ptr_array_new();
9341
9342 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9343 g_ptr_array_free(deregistered_slice, true1);
9344 deregistered_slice = g_ptr_array_new();
9345}
9346
9347static const value_string hf_display[] = {
9348 { BASE_NONE, "BASE_NONE" },
9349 { BASE_DEC, "BASE_DEC" },
9350 { BASE_HEX, "BASE_HEX" },
9351 { BASE_OCT, "BASE_OCT" },
9352 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9353 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9354 { BASE_CUSTOM, "BASE_CUSTOM" },
9355 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9356 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9357 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9358 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9359 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9360 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9361 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9362 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9363 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9364 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9365 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9366 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9367 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9368 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9369 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9370 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9371 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9372 { BASE_PT_UDP, "BASE_PT_UDP" },
9373 { BASE_PT_TCP, "BASE_PT_TCP" },
9374 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9375 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9376 { BASE_OUI, "BASE_OUI" },
9377 { 0, NULL((void*)0) } };
9378
9379const char* proto_field_display_to_string(int field_display)
9380{
9381 return val_to_str_const(field_display, hf_display, "Unknown");
9382}
9383
9384static inline port_type
9385display_to_port_type(field_display_e e)
9386{
9387 switch (e) {
9388 case BASE_PT_UDP:
9389 return PT_UDP;
9390 case BASE_PT_TCP:
9391 return PT_TCP;
9392 case BASE_PT_DCCP:
9393 return PT_DCCP;
9394 case BASE_PT_SCTP:
9395 return PT_SCTP;
9396 default:
9397 break;
9398 }
9399 return PT_NONE;
9400}
9401
9402/* temporary function containing assert part for easier profiling */
9403static void
9404tmp_fld_check_assert(header_field_info *hfinfo)
9405{
9406 char* tmp_str;
9407
9408 /* The field must have a name (with length > 0) */
9409 if (!hfinfo->name || !hfinfo->name[0]) {
9410 if (hfinfo->abbrev)
9411 /* Try to identify the field */
9412 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)
9413 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9414 else
9415 /* Hum, no luck */
9416 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)"
)
;
9417 }
9418
9419 /* fields with an empty string for an abbreviation aren't filterable */
9420 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9421 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)
;
9422
9423 /* TODO: This check is a significant percentage of startup time (~10%),
9424 although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9425 It might be nice to have a way to disable this check when, e.g.,
9426 running TShark many times with the same configuration. */
9427 /* Check that the filter name (abbreviation) is legal;
9428 * it must contain only alphanumerics, '-', "_", and ".". */
9429 unsigned char c;
9430 c = module_check_valid_name(hfinfo->abbrev, false0);
9431 if (c) {
9432 if (c == '.') {
9433 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)
;
9434 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9435 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)
;
9436 } else {
9437 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)
;
9438 }
9439 }
9440
9441 /* These types of fields are allowed to have value_strings,
9442 * true_false_strings or a protocol_t struct
9443 */
9444 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9445 switch (hfinfo->type) {
9446
9447 /*
9448 * These types are allowed to support display value_strings,
9449 * value64_strings, the extended versions of the previous
9450 * two, range strings, or unit strings.
9451 */
9452 case FT_CHAR:
9453 case FT_UINT8:
9454 case FT_UINT16:
9455 case FT_UINT24:
9456 case FT_UINT32:
9457 case FT_UINT40:
9458 case FT_UINT48:
9459 case FT_UINT56:
9460 case FT_UINT64:
9461 case FT_INT8:
9462 case FT_INT16:
9463 case FT_INT24:
9464 case FT_INT32:
9465 case FT_INT40:
9466 case FT_INT48:
9467 case FT_INT56:
9468 case FT_INT64:
9469 case FT_BOOLEAN:
9470 case FT_PROTOCOL:
9471 break;
9472
9473 /*
9474 * This is allowed to have a value of type
9475 * enum ft_framenum_type to indicate what relationship
9476 * the frame in question has to the frame in which
9477 * the field is put.
9478 */
9479 case FT_FRAMENUM:
9480 break;
9481
9482 /*
9483 * These types are allowed to support only unit strings.
9484 */
9485 case FT_FLOAT:
9486 case FT_DOUBLE:
9487 case FT_IEEE_11073_SFLOAT:
9488 case FT_IEEE_11073_FLOAT:
9489 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9490 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))
9491 " (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))
9492 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))
;
9493 }
9494 break;
9495
9496 /*
9497 * These types are allowed to support display
9498 * time_value_strings.
9499 */
9500 case FT_ABSOLUTE_TIME:
9501 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9502 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9503 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9504 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9505 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))
9506 " (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))
9507 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))
;
9508 }
9509 break;
9510
9511 /*
9512 * This type is only allowed to support a string if it's
9513 * a protocol (for pinos).
9514 */
9515 case FT_BYTES:
9516 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9517 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))
9518 " (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))
9519 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))
;
9520 }
9521 break;
9522
9523 default:
9524 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))
9525 " (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))
9526 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))
;
9527 }
9528 }
9529
9530 /* TODO: This check may slow down startup, and output quite a few warnings.
9531 It would be good to be able to enable this (and possibly other checks?)
9532 in non-release builds. */
9533#ifdef ENABLE_CHECK_FILTER
9534 /* Check for duplicate value_string values.
9535 There are lots that have the same value *and* string, so for now only
9536 report those that have same value but different string. */
9537 if ((hfinfo->strings != NULL((void*)0)) &&
9538 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9539 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9540 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9541 (
9542 (hfinfo->type == FT_CHAR) ||
9543 (hfinfo->type == FT_UINT8) ||
9544 (hfinfo->type == FT_UINT16) ||
9545 (hfinfo->type == FT_UINT24) ||
9546 (hfinfo->type == FT_UINT32) ||
9547 (hfinfo->type == FT_INT8) ||
9548 (hfinfo->type == FT_INT16) ||
9549 (hfinfo->type == FT_INT24) ||
9550 (hfinfo->type == FT_INT32) )) {
9551
9552 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9553 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9554 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9555 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9556 } else {
9557 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9558 CHECK_HF_VALUE(value_string, "u", start_values);
9559 }
9560 } else {
9561 const value_string *start_values = (const value_string*)hfinfo->strings;
9562 CHECK_HF_VALUE(value_string, "u", start_values);
9563 }
9564 }
9565
9566 if (hfinfo->type == FT_BOOLEAN) {
9567 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9568 if (tfs) {
9569 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9570 ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9572
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9571 hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9572
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
9572 tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9572
, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string)
;
9573 }
9574 }
9575 }
9576
9577 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9578 const range_string *rs = (const range_string*)(hfinfo->strings);
9579 if (rs) {
9580 const range_string *this_it = rs;
9581
9582 do {
9583 if (this_it->value_max < this_it->value_min) {
9584 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"
, 9588, __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)
9585 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9588, __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)
9586 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9588, __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)
9587 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9588, __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)
9588 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9588, __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)
;
9589 ++this_it;
9590 continue;
9591 }
9592
9593 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9594 /* Not OK if this one is completely hidden by an earlier one! */
9595 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9596 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"
, 9602, __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)
9597 "(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"
, 9602, __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)
9598 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9602, __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)
9599 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9602, __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)
9600 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9602, __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)
9601 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9602, __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)
9602 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9602, __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)
;
9603 }
9604 }
9605 ++this_it;
9606 } while (this_it->strptr);
9607 }
9608 }
9609#endif
9610
9611 switch (hfinfo->type) {
9612
9613 case FT_CHAR:
9614 /* Require the char type to have BASE_HEX, BASE_OCT,
9615 * BASE_CUSTOM, or BASE_NONE as its base.
9616 *
9617 * If the display value is BASE_NONE and there is a
9618 * strings conversion then the dissector writer is
9619 * telling us that the field's numerical value is
9620 * meaningless; we'll avoid showing the value to the
9621 * user.
9622 */
9623 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9624 case BASE_HEX:
9625 case BASE_OCT:
9626 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9627 break;
9628 case BASE_NONE:
9629 if (hfinfo->strings == NULL((void*)0))
9630 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
))
9631 " 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
))
9632 " 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
))
9633 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
))
9634 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
))
;
9635 break;
9636 default:
9637 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9638 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)
9639 " 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)
9640 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)
9641 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)
;
9642 //wmem_free(NULL, tmp_str);
9643 }
9644 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9645 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
))
9646 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
))
9647 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
))
;
9648 }
9649 break;
9650 case FT_INT8:
9651 case FT_INT16:
9652 case FT_INT24:
9653 case FT_INT32:
9654 case FT_INT40:
9655 case FT_INT48:
9656 case FT_INT56:
9657 case FT_INT64:
9658 /* Hexadecimal and octal are, in printf() and everywhere
9659 * else, unsigned so don't allow dissectors to register a
9660 * signed field to be displayed unsigned. (Else how would
9661 * we display negative values?)
9662 */
9663 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9664 case BASE_HEX:
9665 case BASE_OCT:
9666 case BASE_DEC_HEX:
9667 case BASE_HEX_DEC:
9668 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9669 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)
9670 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)
9671 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)
;
9672 //wmem_free(NULL, tmp_str);
9673 }
9674 /* FALL THROUGH */
9675 case FT_UINT8:
9676 case FT_UINT16:
9677 case FT_UINT24:
9678 case FT_UINT32:
9679 case FT_UINT40:
9680 case FT_UINT48:
9681 case FT_UINT56:
9682 case FT_UINT64:
9683 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
))
) {
9684 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9685 if (hfinfo->type != FT_UINT16) {
9686 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))
9687 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))
9688 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))
;
9689 }
9690 if (hfinfo->strings != NULL((void*)0)) {
9691 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)
9692 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)
9693 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)
;
9694 }
9695 if (hfinfo->bitmask != 0) {
9696 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)
9697 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)
9698 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)
;
9699 }
9700 wmem_free(NULL((void*)0), tmp_str);
9701 break;
9702 }
9703
9704 if (hfinfo->display == BASE_OUI) {
9705 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9706 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) {
9707 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))
9708 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))
9709 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))
;
9710 }
9711 if (hfinfo->strings != NULL((void*)0)) {
9712 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)
9713 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)
9714 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)
;
9715 }
9716 /* It can be a FT_UINT24 with a 0 bitmask, or
9717 * larger with a bitmask with 24 bits set. */
9718 if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9719 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)
9720 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)
9721 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)
;
9722 }
9723 wmem_free(NULL((void*)0), tmp_str);
9724 break;
9725 }
9726
9727 /* Require integral types (other than frame number,
9728 * which is always displayed in decimal) to have a
9729 * number base.
9730 *
9731 * If the display value is BASE_NONE and there is a
9732 * strings conversion then the dissector writer is
9733 * telling us that the field's numerical value is
9734 * meaningless; we'll avoid showing the value to the
9735 * user.
9736 */
9737 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9738 case BASE_DEC:
9739 case BASE_HEX:
9740 case BASE_OCT:
9741 case BASE_DEC_HEX:
9742 case BASE_HEX_DEC:
9743 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9744 break;
9745 case BASE_NONE:
9746 if (hfinfo->strings == NULL((void*)0)) {
9747 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an integral value (%s)"proto_report_dissector_bug("Field '%s' (%s) is an integral value (%s)"
" but is being displayed as BASE_NONE but" " without a strings conversion"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9748 " 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
))
9749 " 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
))
9750 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
))
9751 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
))
;
9752 }
9753 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9754 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
))
9755 " 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
))
9756 " 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
))
9757 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
))
9758 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
))
;
9759 }
9760 break;
9761
9762 default:
9763 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9764 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)
9765 " 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)
9766 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)
9767 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)
;
9768 //wmem_free(NULL, tmp_str);
9769 }
9770 break;
9771 case FT_BYTES:
9772 case FT_UINT_BYTES:
9773 /* Require bytes to have a "display type" that could
9774 * add a character between displayed bytes.
9775 */
9776 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9777 case BASE_NONE:
9778 case SEP_DOT:
9779 case SEP_DASH:
9780 case SEP_COLON:
9781 case SEP_SPACE:
9782 break;
9783 default:
9784 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9785 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)
9786 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)
;
9787 //wmem_free(NULL, tmp_str);
9788 }
9789 if (hfinfo->bitmask != 0)
9790 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
))
9791 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
))
9792 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
))
;
9793 //allowed to support string if its a protocol (for pinos)
9794 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9795 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
))
9796 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
))
9797 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
))
;
9798 break;
9799
9800 case FT_PROTOCOL:
9801 case FT_FRAMENUM:
9802 if (hfinfo->display != BASE_NONE) {
9803 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9804 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)
9805 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)
9806 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)
;
9807 //wmem_free(NULL, tmp_str);
9808 }
9809 if (hfinfo->bitmask != 0)
9810 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
))
9811 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
))
9812 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
))
;
9813 break;
9814
9815 case FT_BOOLEAN:
9816 break;
9817
9818 case FT_ABSOLUTE_TIME:
9819 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9820 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9821 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)
9822 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)
;
9823 //wmem_free(NULL, tmp_str);
9824 }
9825 if (hfinfo->bitmask != 0)
9826 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9827 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9828 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9829 break;
9830
9831 case FT_STRING:
9832 case FT_STRINGZ:
9833 case FT_UINT_STRING:
9834 case FT_STRINGZPAD:
9835 case FT_STRINGZTRUNC:
9836 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9837 case BASE_NONE:
9838 case BASE_STR_WSP:
9839 break;
9840
9841 default:
9842 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9843 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)
9844 " 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)
9845 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)
9846 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)
;
9847 //wmem_free(NULL, tmp_str);
9848 }
9849
9850 if (hfinfo->bitmask != 0)
9851 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
))
9852 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
))
9853 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
))
;
9854 if (hfinfo->strings != NULL((void*)0))
9855 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
))
9856 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
))
9857 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
))
;
9858 break;
9859
9860 case FT_IPv4:
9861 switch (hfinfo->display) {
9862 case BASE_NONE:
9863 case BASE_NETMASK:
9864 break;
9865
9866 default:
9867 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9868 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)
9869 " 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)
9870 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)
9871 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)
;
9872 //wmem_free(NULL, tmp_str);
9873 break;
9874 }
9875 break;
9876 case FT_FLOAT:
9877 case FT_DOUBLE:
9878 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9879 case BASE_NONE:
9880 case BASE_DEC:
9881 case BASE_HEX:
9882 case BASE_EXP:
9883 case BASE_CUSTOM:
9884 break;
9885 default:
9886 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9887 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)
9888 " 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)
9889 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)
9890 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)
;
9891 //wmem_free(NULL, tmp_str);
9892 }
9893 if (hfinfo->bitmask != 0)
9894 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
))
9895 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
))
9896 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
))
;
9897 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9898 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
))
9899 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
))
9900 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
))
;
9901 break;
9902 case FT_IEEE_11073_SFLOAT:
9903 case FT_IEEE_11073_FLOAT:
9904 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9905 tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9906 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)
9907 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)
9908 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)
9909 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)
;
9910 //wmem_free(NULL, tmp_str);
9911 }
9912 if (hfinfo->bitmask != 0)
9913 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
))
9914 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
))
9915 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
))
;
9916 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9917 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
))
9918 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
))
9919 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
))
;
9920 break;
9921 default:
9922 if (hfinfo->display != BASE_NONE) {
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 %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)
9925 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)
9926 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)
9927 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)
;
9928 //wmem_free(NULL, tmp_str);
9929 }
9930 if (hfinfo->bitmask != 0)
9931 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
))
9932 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
))
9933 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
))
;
9934 if (hfinfo->strings != NULL((void*)0))
9935 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
))
9936 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
))
9937 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
))
;
9938 break;
9939 }
9940}
9941
9942static void
9943register_type_length_mismatch(void)
9944{
9945 static ei_register_info ei[] = {
9946 { &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)}}
}},
9947 { &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)}}
}},
9948 };
9949
9950 expert_module_t* expert_type_length_mismatch;
9951
9952 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9953
9954 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9955 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9956
9957 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9958 disabling them makes no sense. */
9959 proto_set_cant_toggle(proto_type_length_mismatch);
9960}
9961
9962static void
9963register_byte_array_string_decodinws_error(void)
9964{
9965 static ei_register_info ei[] = {
9966 { &ei_byte_array_string_decoding_failed_error,
9967 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9968 "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)}}
9969 }
9970 },
9971 };
9972
9973 expert_module_t* expert_byte_array_string_decoding_error;
9974
9975 proto_byte_array_string_decoding_error =
9976 proto_register_protocol("Byte Array-String Decoding Error",
9977 "Byte Array-string decoding error",
9978 "_ws.byte_array_string.decoding_error");
9979
9980 expert_byte_array_string_decoding_error =
9981 expert_register_protocol(proto_byte_array_string_decoding_error);
9982 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9983
9984 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9985 disabling them makes no sense. */
9986 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9987}
9988
9989static void
9990register_date_time_string_decodinws_error(void)
9991{
9992 static ei_register_info ei[] = {
9993 { &ei_date_time_string_decoding_failed_error,
9994 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9995 "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)}}
9996 }
9997 },
9998 };
9999
10000 expert_module_t* expert_date_time_string_decoding_error;
10001
10002 proto_date_time_string_decoding_error =
10003 proto_register_protocol("Date and Time-String Decoding Error",
10004 "Date and Time-string decoding error",
10005 "_ws.date_time_string.decoding_error");
10006
10007 expert_date_time_string_decoding_error =
10008 expert_register_protocol(proto_date_time_string_decoding_error);
10009 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10010
10011 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10012 disabling them makes no sense. */
10013 proto_set_cant_toggle(proto_date_time_string_decoding_error);
10014}
10015
10016static void
10017register_string_errors(void)
10018{
10019 static ei_register_info ei[] = {
10020 { &ei_string_trailing_characters,
10021 { "_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)}}
}
10022 },
10023 };
10024
10025 expert_module_t* expert_string_errors;
10026
10027 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10028
10029 expert_string_errors = expert_register_protocol(proto_string_errors);
10030 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10031
10032 /* "String Errors" isn't really a protocol, it's an error indication;
10033 disabling them makes no sense. */
10034 proto_set_cant_toggle(proto_string_errors);
10035}
10036
10037static int
10038proto_register_field_init(header_field_info *hfinfo, const int parent)
10039{
10040
10041 tmp_fld_check_assert(hfinfo);
10042
10043 hfinfo->parent = parent;
10044 hfinfo->same_name_next = NULL((void*)0);
10045 hfinfo->same_name_prev_id = -1;
10046
10047 /* if we always add and never delete, then id == len - 1 is correct */
10048 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10049 if (!gpa_hfinfo.hfi) {
10050 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10051 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10052 /* The entry with index 0 is not used. */
10053 gpa_hfinfo.hfi[0] = NULL((void*)0);
10054 gpa_hfinfo.len = 1;
10055 } else {
10056 gpa_hfinfo.allocated_len += 1000;
10057 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10058 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10059 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10060 }
10061 }
10062 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10063 gpa_hfinfo.len++;
10064 hfinfo->id = gpa_hfinfo.len - 1;
10065
10066 /* if we have real names, enter this field in the name tree */
10067 /* Already checked in tmp_fld_check_assert */
10068 /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10069 {
10070
10071 header_field_info *same_name_next_hfinfo;
10072
10073 /* We allow multiple hfinfo's to be registered under the same
10074 * abbreviation. This was done for X.25, as, depending
10075 * on whether it's modulo-8 or modulo-128 operation,
10076 * some bitfield fields may be in different bits of
10077 * a byte, and we want to be able to refer to that field
10078 * with one name regardless of whether the packets
10079 * are modulo-8 or modulo-128 packets. */
10080
10081 /* wmem_map_insert - if key is already present the previous
10082 * hfinfo with the same key/name is returned, otherwise NULL */
10083 same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10084 if (same_name_hfinfo) {
10085 /* There's already a field with this name.
10086 * Put the current field *before* that field
10087 * in the list of fields with this name, Thus,
10088 * we end up with an effectively
10089 * doubly-linked-list of same-named hfinfo's,
10090 * with the head of the list (stored in the
10091 * hash) being the last seen hfinfo.
10092 */
10093 same_name_next_hfinfo =
10094 same_name_hfinfo->same_name_next;
10095
10096 hfinfo->same_name_next = same_name_next_hfinfo;
10097 if (same_name_next_hfinfo)
10098 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10099
10100 same_name_hfinfo->same_name_next = hfinfo;
10101 hfinfo->same_name_prev_id = same_name_hfinfo->id;
10102#ifdef ENABLE_CHECK_FILTER
10103 while (same_name_hfinfo) {
10104 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10105 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", 10105
, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type))
;
10106 same_name_hfinfo = same_name_hfinfo->same_name_next;
10107 }
10108#endif
10109 }
10110 }
10111
10112 return hfinfo->id;
10113}
10114
10115void
10116proto_register_subtree_array(int * const *indices, const int num_indices)
10117{
10118 int i;
10119 int *const *ptr = indices;
10120
10121 /*
10122 * If we've already allocated the array of tree types, expand
10123 * it; this lets plugins such as mate add tree types after
10124 * the initial startup. (If we haven't already allocated it,
10125 * we don't allocate it; on the first pass, we just assign
10126 * ett values and keep track of how many we've assigned, and
10127 * when we're finished registering all dissectors we allocate
10128 * the array, so that we do only one allocation rather than
10129 * wasting CPU time and memory by growing the array for each
10130 * dissector that registers ett values.)
10131 */
10132 if (tree_is_expanded != NULL((void*)0)) {
10133 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10134
10135 /* set new items to 0 */
10136 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10137 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10138 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10139 }
10140
10141 /*
10142 * Assign "num_indices" subtree numbers starting at "num_tree_types",
10143 * returning the indices through the pointers in the array whose
10144 * first element is pointed to by "indices", and update
10145 * "num_tree_types" appropriately.
10146 */
10147 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10148 if (**ptr != -1 && **ptr != 0) {
10149 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.")
10150 " 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.")
10151 " 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.")
10152 " 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.")
;
10153 }
10154 **ptr = num_tree_types;
10155 }
10156}
10157
10158static void
10159mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10160{
10161 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10162 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10163 char *last_char;
10164
10165 /* ..... field_name: dataaaaaaaaaaaaa
10166 * |
10167 * ^^^^^ name_pos
10168 *
10169 * ..... field_name […]: dataaaaaaaaaaaaa
10170 *
10171 * name_pos==0 means that we have only data or only a field_name
10172 */
10173
10174 ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10174, __func__, "assertion failed: %s"
, "size > trunc_len"); } while (0)
;
10175
10176 if (name_pos >= size - trunc_len) {
10177 /* No room for trunc_str after the field_name, put it first. */
10178 name_pos = 0;
10179 }
10180
10181 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10182 if (name_pos == 0) {
10183 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10184 memcpy(label_str, trunc_str + 1, trunc_len);
10185 } else {
10186 memcpy(label_str + name_pos, trunc_str, trunc_len);
10187 }
10188 /* in general, label_str is UTF-8
10189 we can truncate it only at the beginning of a new character
10190 we go backwards from the byte right after our buffer and
10191 find the next starting byte of a UTF-8 character, this is
10192 where we cut
10193 there's no need to use g_utf8_find_prev_char(), the search
10194 will always succeed since we copied trunc_str into the
10195 buffer */
10196 /* g_utf8_prev_char does not deference the memory address
10197 * passed in (until after decrementing it, so it is perfectly
10198 * legal to pass in a pointer one past the last element.
10199 */
10200 last_char = g_utf8_prev_char(label_str + size);
10201 *last_char = '\0';
10202 /* This is unnecessary (above always terminates), but try to
10203 * convince Coverity to avoid dozens of false positives. */
10204 label_str[size - 1] = '\0';
10205
10206 if (value_pos && *value_pos > 0) {
10207 if (name_pos == 0) {
10208 *value_pos += trunc_len;
10209 } else {
10210 /* Move one back to include trunc_str in the value. */
10211 *value_pos -= 1;
10212 }
10213 }
10214
10215 /* Check if value_pos is past label_str. */
10216 if (value_pos && *value_pos >= size) {
10217 *value_pos = size - 1;
10218 }
10219}
10220
10221static void
10222label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10223{
10224 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10225}
10226
10227static size_t
10228label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10229{
10230 size_t name_pos;
10231
10232 /* "%s: %s", hfinfo->name, text */
10233 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)
;
10234 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10235 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10236 if (value_pos) {
10237 *value_pos = pos;
10238 }
10239 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10240 }
10241
10242 if (pos >= ITEM_LABEL_LENGTH240) {
10243 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10244 label_mark_truncated(label_str, name_pos, value_pos);
10245 }
10246
10247 return pos;
10248}
10249
10250static size_t
10251label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10252{
10253 size_t name_pos;
10254
10255 /* "%s: %s (%s)", hfinfo->name, text, descr */
10256 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)
;
10257 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10258 pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10259 if (value_pos) {
10260 *value_pos = pos;
10261 }
10262 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10263 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)
;
10264 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)
;
10265 } else {
10266 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)
;
10267 pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10268 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)
;
10269 pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10270 }
10271 }
10272
10273 if (pos >= ITEM_LABEL_LENGTH240) {
10274 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10275 label_mark_truncated(label_str, name_pos, value_pos);
10276 }
10277
10278 return pos;
10279}
10280
10281void
10282proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10283{
10284 const header_field_info *hfinfo;
10285 const char *str;
10286 const uint8_t *bytes;
10287 uint32_t integer;
10288 const ipv4_addr_and_mask *ipv4;
10289 const ipv6_addr_and_prefix *ipv6;
10290 const e_guid_t *guid;
10291 char *name;
10292 address addr;
10293 char *addr_str;
10294 char *tmp;
10295
10296 if (!label_str) {
10297 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10297, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10298 return;
10299 }
10300
10301 label_str[0]= '\0';
10302
10303 if (!fi) {
10304 return;
10305 }
10306
10307 hfinfo = fi->hfinfo;
10308
10309 switch (hfinfo->type) {
10310 case FT_NONE:
10311 case FT_PROTOCOL:
10312 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10313 if (value_pos) {
10314 *value_pos = strlen(hfinfo->name);
10315 }
10316 break;
10317
10318 case FT_BOOLEAN:
10319 fill_label_boolean(fi, label_str, value_pos);
10320 break;
10321
10322 case FT_BYTES:
10323 case FT_UINT_BYTES:
10324 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10325 fvalue_get_bytes_data(fi->value),
10326 (unsigned)fvalue_length2(fi->value));
10327 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10328 wmem_free(NULL((void*)0), tmp);
10329 break;
10330
10331 case FT_CHAR:
10332 if (hfinfo->bitmask) {
10333 fill_label_bitfield_char(fi, label_str, value_pos);
10334 } else {
10335 fill_label_char(fi, label_str, value_pos);
10336 }
10337 break;
10338
10339 /* Four types of integers to take care of:
10340 * Bitfield, with val_string
10341 * Bitfield, w/o val_string
10342 * Non-bitfield, with val_string
10343 * Non-bitfield, w/o val_string
10344 */
10345 case FT_UINT8:
10346 case FT_UINT16:
10347 case FT_UINT24:
10348 case FT_UINT32:
10349 if (hfinfo->bitmask) {
10350 fill_label_bitfield(fi, label_str, value_pos, false0);
10351 } else {
10352 fill_label_number(fi, label_str, value_pos, false0);
10353 }
10354 break;
10355
10356 case FT_FRAMENUM:
10357 fill_label_number(fi, label_str, value_pos, false0);
10358 break;
10359
10360 case FT_UINT40:
10361 case FT_UINT48:
10362 case FT_UINT56:
10363 case FT_UINT64:
10364 if (hfinfo->bitmask) {
10365 fill_label_bitfield64(fi, label_str, value_pos, false0);
10366 } else {
10367 fill_label_number64(fi, label_str, value_pos, false0);
10368 }
10369 break;
10370
10371 case FT_INT8:
10372 case FT_INT16:
10373 case FT_INT24:
10374 case FT_INT32:
10375 if (hfinfo->bitmask) {
10376 fill_label_bitfield(fi, label_str, value_pos, true1);
10377 } else {
10378 fill_label_number(fi, label_str, value_pos, true1);
10379 }
10380 break;
10381
10382 case FT_INT40:
10383 case FT_INT48:
10384 case FT_INT56:
10385 case FT_INT64:
10386 if (hfinfo->bitmask) {
10387 fill_label_bitfield64(fi, label_str, value_pos, true1);
10388 } else {
10389 fill_label_number64(fi, label_str, value_pos, true1);
10390 }
10391 break;
10392
10393 case FT_FLOAT:
10394 case FT_DOUBLE:
10395 fill_label_float(fi, label_str, value_pos);
10396 break;
10397
10398 case FT_ABSOLUTE_TIME:
10399 {
10400 const nstime_t *value = fvalue_get_time(fi->value);
10401 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10402 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10403 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10404 }
10405 if (hfinfo->strings) {
10406 /*
10407 * Table of time valus to be displayed
10408 * specially.
10409 */
10410 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10411 if (time_string != NULL((void*)0)) {
10412 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10413 break;
10414 }
10415 }
10416 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10417 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10418 wmem_free(NULL((void*)0), tmp);
10419 break;
10420 }
10421 case FT_RELATIVE_TIME:
10422 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10423 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10424 wmem_free(NULL((void*)0), tmp);
10425 break;
10426
10427 case FT_IPXNET:
10428 integer = fvalue_get_uinteger(fi->value);
10429 tmp = get_ipxnet_name(NULL((void*)0), integer);
10430 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10431 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10432 wmem_free(NULL((void*)0), tmp);
10433 wmem_free(NULL((void*)0), addr_str);
10434 break;
10435
10436 case FT_VINES:
10437 addr.type = AT_VINES;
10438 addr.len = VINES_ADDR_LEN6;
10439 addr.data = fvalue_get_bytes_data(fi->value);
10440
10441 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10442 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10443 wmem_free(NULL((void*)0), addr_str);
10444 break;
10445
10446 case FT_ETHER:
10447 bytes = fvalue_get_bytes_data(fi->value);
10448
10449 addr.type = AT_ETHER;
10450 addr.len = 6;
10451 addr.data = bytes;
10452
10453 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10454 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10455 wmem_free(NULL((void*)0), addr_str);
10456 break;
10457
10458 case FT_IPv4:
10459 ipv4 = fvalue_get_ipv4(fi->value);
10460 set_address_ipv4(&addr, ipv4);
10461
10462 if (hfinfo->display == BASE_NETMASK) {
10463 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10464 } else {
10465 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10466 }
10467 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10468 wmem_free(NULL((void*)0), addr_str);
10469 free_address(&addr);
10470 break;
10471
10472 case FT_IPv6:
10473 ipv6 = fvalue_get_ipv6(fi->value);
10474 set_address_ipv6(&addr, ipv6);
10475
10476 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10477 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10478 wmem_free(NULL((void*)0), addr_str);
10479 free_address(&addr);
10480 break;
10481
10482 case FT_FCWWN:
10483 bytes = fvalue_get_bytes_data(fi->value);
10484 addr.type = AT_FCWWN;
10485 addr.len = FCWWN_ADDR_LEN8;
10486 addr.data = bytes;
10487
10488 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10489 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10490 wmem_free(NULL((void*)0), addr_str);
10491 break;
10492
10493 case FT_GUID:
10494 guid = fvalue_get_guid(fi->value);
10495 tmp = guid_to_str(NULL((void*)0), guid);
10496 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10497 wmem_free(NULL((void*)0), tmp);
10498 break;
10499
10500 case FT_OID:
10501 bytes = fvalue_get_bytes_data(fi->value);
10502 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10503 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10504 if (name) {
10505 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10506 wmem_free(NULL((void*)0), name);
10507 } else {
10508 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10509 }
10510 wmem_free(NULL((void*)0), tmp);
10511 break;
10512
10513 case FT_REL_OID:
10514 bytes = fvalue_get_bytes_data(fi->value);
10515 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10516 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10517 if (name) {
10518 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10519 wmem_free(NULL((void*)0), name);
10520 } else {
10521 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10522 }
10523 wmem_free(NULL((void*)0), tmp);
10524 break;
10525
10526 case FT_SYSTEM_ID:
10527 bytes = fvalue_get_bytes_data(fi->value);
10528 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10529 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10530 wmem_free(NULL((void*)0), tmp);
10531 break;
10532
10533 case FT_EUI64:
10534 bytes = fvalue_get_bytes_data(fi->value);
10535 addr.type = AT_EUI64;
10536 addr.len = EUI64_ADDR_LEN8;
10537 addr.data = bytes;
10538
10539 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10540 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10541 wmem_free(NULL((void*)0), addr_str);
10542 break;
10543 case FT_STRING:
10544 case FT_STRINGZ:
10545 case FT_UINT_STRING:
10546 case FT_STRINGZPAD:
10547 case FT_STRINGZTRUNC:
10548 case FT_AX25:
10549 str = fvalue_get_string(fi->value);
10550 label_fill(label_str, 0, hfinfo, str, value_pos);
10551 break;
10552
10553 case FT_IEEE_11073_SFLOAT:
10554 case FT_IEEE_11073_FLOAT:
10555 fill_label_ieee_11073_float(fi, label_str, value_pos);
10556 break;
10557
10558 default:
10559 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
))
10560 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
))
10561 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
))
10562 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
))
;
10563 break;
10564 }
10565}
10566
10567static void
10568fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10569{
10570 char *p;
10571 int bitfield_byte_length = 0, bitwidth;
10572 uint64_t unshifted_value;
10573 uint64_t value;
10574
10575 const header_field_info *hfinfo = fi->hfinfo;
10576
10577 value = fvalue_get_uinteger64(fi->value);
10578 if (hfinfo->bitmask) {
10579 /* Figure out the bit width */
10580 bitwidth = hfinfo_container_bitwidth(hfinfo);
10581
10582 /* Un-shift bits */
10583 unshifted_value = value;
10584 unshifted_value <<= hfinfo_bitshift(hfinfo);
10585
10586 /* Create the bitfield first */
10587 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10588 bitfield_byte_length = (int) (p - label_str);
10589 }
10590
10591 /* Fill in the textual info */
10592 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10593}
10594
10595static const char *
10596hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10597{
10598 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10599 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10600
10601 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10602 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10603 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10604 else
10605 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10606 }
10607
10608 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10609 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10610
10611 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10612 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10613
10614 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10615}
10616
10617static const char *
10618hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10619{
10620 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10621 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10622 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10623 else
10624 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10625 }
10626
10627 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10628 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10629
10630 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10631 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10632
10633 /* If this is reached somebody registered a 64-bit field with a 32-bit
10634 * value-string, which isn't right. */
10635 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)
10636 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10637
10638 /* This is necessary to squelch MSVC errors; is there
10639 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10640 never returns? */
10641 return NULL((void*)0);
10642}
10643
10644static const char *
10645hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10646{
10647 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10648 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10649
10650 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)
;
10651
10652 /* This is necessary to squelch MSVC errors; is there
10653 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10654 never returns? */
10655 return NULL((void*)0);
10656}
10657
10658static const char *
10659hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10660{
10661 const char *str = hf_try_val_to_str(value, hfinfo);
10662
10663 return (str) ? str : unknown_str;
10664}
10665
10666static const char *
10667hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10668{
10669 const char *str = hf_try_val64_to_str(value, hfinfo);
10670
10671 return (str) ? str : unknown_str;
10672}
10673
10674/* Fills data for bitfield chars with val_strings */
10675static void
10676fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10677{
10678 char *p;
10679 int bitfield_byte_length, bitwidth;
10680 uint32_t unshifted_value;
10681 uint32_t value;
10682
10683 char buf[32];
10684 const char *out;
10685
10686 const header_field_info *hfinfo = fi->hfinfo;
10687
10688 /* Figure out the bit width */
10689 bitwidth = hfinfo_container_bitwidth(hfinfo);
10690
10691 /* Un-shift bits */
10692 value = fvalue_get_uinteger(fi->value);
10693
10694 unshifted_value = value;
10695 if (hfinfo->bitmask) {
10696 unshifted_value <<= hfinfo_bitshift(hfinfo);
10697 }
10698
10699 /* Create the bitfield first */
10700 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10701 bitfield_byte_length = (int) (p - label_str);
10702
10703 /* Fill in the textual info using stored (shifted) value */
10704 if (hfinfo->display == BASE_CUSTOM) {
10705 char tmp[ITEM_LABEL_LENGTH240];
10706 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10707
10708 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10708, "fmtfunc"))))
;
10709 fmtfunc(tmp, value);
10710 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10711 }
10712 else if (hfinfo->strings) {
10713 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10714
10715 out = hfinfo_char_vals_format(hfinfo, buf, value);
10716 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10717 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10718 else
10719 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10720 }
10721 else {
10722 out = hfinfo_char_value_format(hfinfo, buf, value);
10723
10724 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10725 }
10726}
10727
10728/* Fills data for bitfield ints with val_strings */
10729static void
10730fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10731{
10732 char *p;
10733 int bitfield_byte_length, bitwidth;
10734 uint32_t value, unshifted_value;
10735 char buf[NUMBER_LABEL_LENGTH80];
10736 const char *out;
10737
10738 const header_field_info *hfinfo = fi->hfinfo;
10739
10740 /* Figure out the bit width */
10741 if (fi->flags & FI_VARINT0x00040000)
10742 bitwidth = fi->length*8;
10743 else
10744 bitwidth = hfinfo_container_bitwidth(hfinfo);
10745
10746 /* Un-shift bits */
10747 if (is_signed)
10748 value = fvalue_get_sinteger(fi->value);
10749 else
10750 value = fvalue_get_uinteger(fi->value);
10751
10752 unshifted_value = value;
10753 if (hfinfo->bitmask) {
10754 unshifted_value <<= hfinfo_bitshift(hfinfo);
10755 }
10756
10757 /* Create the bitfield first */
10758 if (fi->flags & FI_VARINT0x00040000)
10759 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10760 else
10761 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10762 bitfield_byte_length = (int) (p - label_str);
10763
10764 /* Fill in the textual info using stored (shifted) value */
10765 if (hfinfo->display == BASE_CUSTOM) {
10766 char tmp[ITEM_LABEL_LENGTH240];
10767 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10768
10769 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10769, "fmtfunc"))))
;
10770 fmtfunc(tmp, value);
10771 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10772 }
10773 else if (hfinfo->strings) {
10774 const char *val_str = hf_try_val_to_str(value, hfinfo);
10775
10776 out = hfinfo_number_vals_format(hfinfo, buf, value);
10777 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10778 /*
10779 * Unique values only display value_string string
10780 * if there is a match. Otherwise it's just a number
10781 */
10782 if (val_str) {
10783 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10784 } else {
10785 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10786 }
10787 } else {
10788 if (val_str == NULL((void*)0))
10789 val_str = "Unknown";
10790
10791 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10792 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10793 else
10794 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10795 }
10796 }
10797 else {
10798 out = hfinfo_number_value_format(hfinfo, buf, value);
10799
10800 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10801 }
10802}
10803
10804static void
10805fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10806{
10807 char *p;
10808 int bitfield_byte_length, bitwidth;
10809 uint64_t value, unshifted_value;
10810 char buf[NUMBER_LABEL_LENGTH80];
10811 const char *out;
10812
10813 const header_field_info *hfinfo = fi->hfinfo;
10814
10815 /* Figure out the bit width */
10816 if (fi->flags & FI_VARINT0x00040000)
10817 bitwidth = fi->length*8;
10818 else
10819 bitwidth = hfinfo_container_bitwidth(hfinfo);
10820
10821 /* Un-shift bits */
10822 if (is_signed)
10823 value = fvalue_get_sinteger64(fi->value);
10824 else
10825 value = fvalue_get_uinteger64(fi->value);
10826
10827 unshifted_value = value;
10828 if (hfinfo->bitmask) {
10829 unshifted_value <<= hfinfo_bitshift(hfinfo);
10830 }
10831
10832 /* Create the bitfield first */
10833 if (fi->flags & FI_VARINT0x00040000)
10834 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10835 else
10836 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10837 bitfield_byte_length = (int) (p - label_str);
10838
10839 /* Fill in the textual info using stored (shifted) value */
10840 if (hfinfo->display == BASE_CUSTOM) {
10841 char tmp[ITEM_LABEL_LENGTH240];
10842 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10843
10844 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10844, "fmtfunc64"
))))
;
10845 fmtfunc64(tmp, value);
10846 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10847 }
10848 else if (hfinfo->strings) {
10849 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10850
10851 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10852 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10853 /*
10854 * Unique values only display value_string string
10855 * if there is a match. Otherwise it's just a number
10856 */
10857 if (val_str) {
10858 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10859 } else {
10860 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10861 }
10862 } else {
10863 if (val_str == NULL((void*)0))
10864 val_str = "Unknown";
10865
10866 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10867 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10868 else
10869 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10870 }
10871 }
10872 else {
10873 out = hfinfo_number_value_format64(hfinfo, buf, value);
10874
10875 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10876 }
10877}
10878
10879static void
10880fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10881{
10882 const header_field_info *hfinfo = fi->hfinfo;
10883 uint32_t value;
10884
10885 char buf[32];
10886 const char *out;
10887
10888 value = fvalue_get_uinteger(fi->value);
10889
10890 /* Fill in the textual info */
10891 if (hfinfo->display == BASE_CUSTOM) {
10892 char tmp[ITEM_LABEL_LENGTH240];
10893 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10894
10895 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10895, "fmtfunc"))))
;
10896 fmtfunc(tmp, value);
10897 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10898 }
10899 else if (hfinfo->strings) {
10900 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10901
10902 out = hfinfo_char_vals_format(hfinfo, buf, value);
10903 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10904 }
10905 else {
10906 out = hfinfo_char_value_format(hfinfo, buf, value);
10907
10908 label_fill(label_str, 0, hfinfo, out, value_pos);
10909 }
10910}
10911
10912static void
10913fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10914{
10915 const header_field_info *hfinfo = fi->hfinfo;
10916 uint32_t value;
10917
10918 char buf[NUMBER_LABEL_LENGTH80];
10919 const char *out;
10920
10921 if (is_signed)
10922 value = fvalue_get_sinteger(fi->value);
10923 else
10924 value = fvalue_get_uinteger(fi->value);
10925
10926 /* Fill in the textual info */
10927 if (hfinfo->display == BASE_CUSTOM) {
10928 char tmp[ITEM_LABEL_LENGTH240];
10929 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10930
10931 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10931, "fmtfunc"))))
;
10932 fmtfunc(tmp, value);
10933 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10934 }
10935 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10936 /*
10937 * It makes no sense to have a value-string table for a
10938 * frame-number field - they're just integers giving
10939 * the ordinal frame number.
10940 */
10941 const char *val_str = hf_try_val_to_str(value, hfinfo);
10942
10943 out = hfinfo_number_vals_format(hfinfo, buf, value);
10944 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10945 /*
10946 * Unique values only display value_string string
10947 * if there is a match. Otherwise it's just a number
10948 */
10949 if (val_str) {
10950 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10951 } else {
10952 label_fill(label_str, 0, hfinfo, out, value_pos);
10953 }
10954 } else {
10955 if (val_str == NULL((void*)0))
10956 val_str = "Unknown";
10957
10958 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10959 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10960 else
10961 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10962 }
10963 }
10964 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
))
) {
10965 char tmp[ITEM_LABEL_LENGTH240];
10966
10967 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10968 display_to_port_type((field_display_e)hfinfo->display), value);
10969 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10970 }
10971 else {
10972 out = hfinfo_number_value_format(hfinfo, buf, value);
10973
10974 label_fill(label_str, 0, hfinfo, out, value_pos);
10975 }
10976}
10977
10978static void
10979fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10980{
10981 const header_field_info *hfinfo = fi->hfinfo;
10982 uint64_t value;
10983
10984 char buf[NUMBER_LABEL_LENGTH80];
10985 const char *out;
10986
10987 if (is_signed)
10988 value = fvalue_get_sinteger64(fi->value);
10989 else
10990 value = fvalue_get_uinteger64(fi->value);
10991
10992 /* Fill in the textual info */
10993 if (hfinfo->display == BASE_CUSTOM) {
10994 char tmp[ITEM_LABEL_LENGTH240];
10995 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10996
10997 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10997, "fmtfunc64"
))))
;
10998 fmtfunc64(tmp, value);
10999 label_fill(label_str, 0, hfinfo, tmp, value_pos);
11000 }
11001 else if (hfinfo->strings) {
11002 const char *val_str = hf_try_val64_to_str(value, hfinfo);
11003
11004 out = hfinfo_number_vals_format64(hfinfo, buf, value);
11005 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11006 /*
11007 * Unique values only display value_string string
11008 * if there is a match. Otherwise it's just a number
11009 */
11010 if (val_str) {
11011 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11012 } else {
11013 label_fill(label_str, 0, hfinfo, out, value_pos);
11014 }
11015 } else {
11016 if (val_str == NULL((void*)0))
11017 val_str = "Unknown";
11018
11019 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11020 label_fill(label_str, 0, hfinfo, val_str, value_pos);
11021 else
11022 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11023 }
11024 }
11025 else {
11026 out = hfinfo_number_value_format64(hfinfo, buf, value);
11027
11028 label_fill(label_str, 0, hfinfo, out, value_pos);
11029 }
11030}
11031
11032static size_t
11033fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11034{
11035 int display;
11036 int n;
11037 double value;
11038
11039 if (label_str_size < 12) {
11040 /* Not enough room to write an entire floating point value. */
11041 return 0;
11042 }
11043
11044 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11045 value = fvalue_get_floating(fi->value);
11046
11047 if (display == BASE_CUSTOM) {
11048 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11049 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 11049, "fmtfunc"))))
;
11050 fmtfunc(label_str, value);
11051 return strlen(label_str);
11052 }
11053
11054 switch (display) {
11055 case BASE_NONE:
11056 if (fi->hfinfo->type == FT_FLOAT) {
11057 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11058 } else {
11059 n = (int)strlen(dtoa_g_fmt(label_str, value));
11060 }
11061 break;
11062 case BASE_DEC:
11063 n = snprintf(label_str, label_str_size, "%f", value);
11064 break;
11065 case BASE_HEX:
11066 n = snprintf(label_str, label_str_size, "%a", value);
11067 break;
11068 case BASE_EXP:
11069 n = snprintf(label_str, label_str_size, "%e", value);
11070 break;
11071 default:
11072 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11072
, __func__, "assertion \"not reached\" failed")
;
11073 }
11074 if (n < 0) {
11075 return 0; /* error */
11076 }
11077 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11078 const char *hf_str_val;
11079 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11080 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11081 }
11082 if (n > label_str_size) {
11083 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11083, __func__, "label length too small"); } } while (0)
;
11084 return strlen(label_str);
11085 }
11086
11087 return n;
11088}
11089
11090void
11091fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11092{
11093 char tmp[ITEM_LABEL_LENGTH240];
11094
11095 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11096 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11097}
11098
11099static size_t
11100fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11101{
11102 int display;
11103 size_t pos = 0;
11104 double value;
11105 char* tmp_str;
11106
11107 if (label_str_size < 12) {
11108 /* Not enough room to write an entire floating point value. */
11109 return 0;
11110 }
11111
11112 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11113 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11114 pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str,
0)
;
11115 wmem_free(NULL((void*)0), tmp_str);
11116
11117 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11118 const char *hf_str_val;
11119 fvalue_to_double(fi->value, &value);
11120 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11121 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)
;
11122 }
11123 if ((int)pos > label_str_size) {
11124 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11124, __func__, "label length too small"); } } while (0)
;
11125 return strlen(label_str);
11126 }
11127
11128 return pos;
11129}
11130
11131void
11132fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11133{
11134 char tmp[ITEM_LABEL_LENGTH240];
11135
11136 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11137 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11138}
11139
11140int
11141hfinfo_bitshift(const header_field_info *hfinfo)
11142{
11143 return ws_ctz(hfinfo->bitmask);
11144}
11145
11146
11147static int
11148hfinfo_bitoffset(const header_field_info *hfinfo)
11149{
11150 if (!hfinfo->bitmask) {
11151 return 0;
11152 }
11153
11154 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11155 * as the first bit */
11156 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11157}
11158
11159static int
11160hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11161{
11162 if (!hfinfo->bitmask) {
11163 return 0;
11164 }
11165
11166 /* ilog2 = first set bit, ctz = last set bit */
11167 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11168}
11169
11170static int
11171hfinfo_type_bitwidth(enum ftenum type)
11172{
11173 int bitwidth = 0;
11174
11175 switch (type) {
11176 case FT_CHAR:
11177 case FT_UINT8:
11178 case FT_INT8:
11179 bitwidth = 8;
11180 break;
11181 case FT_UINT16:
11182 case FT_INT16:
11183 bitwidth = 16;
11184 break;
11185 case FT_UINT24:
11186 case FT_INT24:
11187 bitwidth = 24;
11188 break;
11189 case FT_UINT32:
11190 case FT_INT32:
11191 bitwidth = 32;
11192 break;
11193 case FT_UINT40:
11194 case FT_INT40:
11195 bitwidth = 40;
11196 break;
11197 case FT_UINT48:
11198 case FT_INT48:
11199 bitwidth = 48;
11200 break;
11201 case FT_UINT56:
11202 case FT_INT56:
11203 bitwidth = 56;
11204 break;
11205 case FT_UINT64:
11206 case FT_INT64:
11207 bitwidth = 64;
11208 break;
11209 default:
11210 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 11210))
;
11211 ;
11212 }
11213 return bitwidth;
11214}
11215
11216
11217static int
11218hfinfo_container_bitwidth(const header_field_info *hfinfo)
11219{
11220 if (!hfinfo->bitmask) {
11221 return 0;
11222 }
11223
11224 if (hfinfo->type == FT_BOOLEAN) {
11225 return hfinfo->display; /* hacky? :) */
11226 }
11227
11228 return hfinfo_type_bitwidth(hfinfo->type);
11229}
11230
11231static int
11232hfinfo_hex_digits(const header_field_info *hfinfo)
11233{
11234 int bitwidth;
11235
11236 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11237 * appropriate to determine the number of hex digits for the field.
11238 * So instead, we compute it from the bitmask.
11239 */
11240 if (hfinfo->bitmask != 0) {
11241 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11242 } else {
11243 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11244 }
11245
11246 /* Divide by 4, rounding up, to get number of hex digits. */
11247 return (bitwidth + 3) / 4;
11248}
11249
11250const char *
11251hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11252{
11253 char *ptr = &buf[6];
11254 static const char hex_digits[16] =
11255 { '0', '1', '2', '3', '4', '5', '6', '7',
11256 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11257
11258 *ptr = '\0';
11259 *(--ptr) = '\'';
11260 /* Properly format value */
11261 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11262 /*
11263 * Printable, so just show the character, and, if it needs
11264 * to be escaped, escape it.
11265 */
11266 *(--ptr) = value;
11267 if (value == '\\' || value == '\'')
11268 *(--ptr) = '\\';
11269 } else {
11270 /*
11271 * Non-printable; show it as an escape sequence.
11272 */
11273 switch (value) {
11274
11275 case '\0':
11276 /*
11277 * Show a NUL with only one digit.
11278 */
11279 *(--ptr) = '0';
11280 break;
11281
11282 case '\a':
11283 case '\b':
11284 case '\f':
11285 case '\n':
11286 case '\r':
11287 case '\t':
11288 case '\v':
11289 *(--ptr) = value - '\a' + 'a';
11290 break;
11291
11292 default:
11293 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11294
11295 case BASE_OCT:
11296 *(--ptr) = (value & 0x7) + '0';
11297 value >>= 3;
11298 *(--ptr) = (value & 0x7) + '0';
11299 value >>= 3;
11300 *(--ptr) = (value & 0x7) + '0';
11301 break;
11302
11303 case BASE_HEX:
11304 *(--ptr) = hex_digits[value & 0x0F];
11305 value >>= 4;
11306 *(--ptr) = hex_digits[value & 0x0F];
11307 *(--ptr) = 'x';
11308 break;
11309
11310 default:
11311 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11312 }
11313 }
11314 *(--ptr) = '\\';
11315 }
11316 *(--ptr) = '\'';
11317 return ptr;
11318}
11319
11320static const char *
11321hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11322{
11323 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11324 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
))
;
11325
11326 *ptr = '\0';
11327 /* Properly format value */
11328 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11329 case BASE_DEC:
11330 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11331
11332 case BASE_DEC_HEX:
11333 *(--ptr) = ')';
11334 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11335 *(--ptr) = '(';
11336 *(--ptr) = ' ';
11337 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11338 return ptr;
11339
11340 case BASE_OCT:
11341 return oct_to_str_back(ptr, value);
11342
11343 case BASE_HEX:
11344 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11345
11346 case BASE_HEX_DEC:
11347 *(--ptr) = ')';
11348 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11349 *(--ptr) = '(';
11350 *(--ptr) = ' ';
11351 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11352 return ptr;
11353
11354 case BASE_PT_UDP:
11355 case BASE_PT_TCP:
11356 case BASE_PT_DCCP:
11357 case BASE_PT_SCTP:
11358 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11359 display_to_port_type((field_display_e)display), value);
11360 return buf;
11361 case BASE_OUI:
11362 {
11363 uint8_t p_oui[3];
11364 const char *manuf_name;
11365
11366 p_oui[0] = value >> 16 & 0xFF;
11367 p_oui[1] = value >> 8 & 0xFF;
11368 p_oui[2] = value & 0xFF;
11369
11370 /* Attempt an OUI lookup. */
11371 manuf_name = uint_get_manuf_name_if_known(value);
11372 if (manuf_name == NULL((void*)0)) {
11373 /* Could not find an OUI. */
11374 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11375 }
11376 else {
11377 /* Found an address string. */
11378 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11379 }
11380 return buf;
11381 }
11382
11383 default:
11384 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11385 }
11386 return ptr;
11387}
11388
11389static const char *
11390hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11391{
11392 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11393 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
))
;
11394
11395 *ptr = '\0';
11396 /* Properly format value */
11397 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11398 case BASE_DEC:
11399 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11400
11401 case BASE_DEC_HEX:
11402 *(--ptr) = ')';
11403 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11404 *(--ptr) = '(';
11405 *(--ptr) = ' ';
11406 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11407 return ptr;
11408
11409 case BASE_OCT:
11410 return oct64_to_str_back(ptr, value);
11411
11412 case BASE_HEX:
11413 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11414
11415 case BASE_HEX_DEC:
11416 *(--ptr) = ')';
11417 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11418 *(--ptr) = '(';
11419 *(--ptr) = ' ';
11420 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11421 return ptr;
11422
11423 default:
11424 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11425 }
11426
11427 return ptr;
11428}
11429
11430static const char *
11431hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11432{
11433 int display = hfinfo->display;
11434
11435 if (hfinfo->type == FT_FRAMENUM) {
11436 /*
11437 * Frame numbers are always displayed in decimal.
11438 */
11439 display = BASE_DEC;
11440 }
11441
11442 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11443}
11444
11445static const char *
11446hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11447{
11448 int display = hfinfo->display;
11449
11450 if (hfinfo->type == FT_FRAMENUM) {
11451 /*
11452 * Frame numbers are always displayed in decimal.
11453 */
11454 display = BASE_DEC;
11455 }
11456
11457 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11458}
11459
11460static const char *
11461hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11462{
11463 /* Get the underlying BASE_ value */
11464 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11465
11466 return hfinfo_char_value_format_display(display, buf, value);
11467}
11468
11469static const char *
11470hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11471{
11472 /* Get the underlying BASE_ value */
11473 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11474
11475 if (hfinfo->type == FT_FRAMENUM) {
11476 /*
11477 * Frame numbers are always displayed in decimal.
11478 */
11479 display = BASE_DEC;
11480 }
11481
11482 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11483 display = BASE_DEC;
11484 } else if (display == BASE_OUI) {
11485 display = BASE_HEX;
11486 }
11487
11488 switch (display) {
11489 case BASE_NONE:
11490 /* case BASE_DEC: */
11491 case BASE_DEC_HEX:
11492 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11493 case BASE_CUSTOM:
11494 display = BASE_DEC;
11495 break;
11496
11497 /* case BASE_HEX: */
11498 case BASE_HEX_DEC:
11499 display = BASE_HEX;
11500 break;
11501 }
11502
11503 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11504}
11505
11506static const char *
11507hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11508{
11509 /* Get the underlying BASE_ value */
11510 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11511
11512 if (hfinfo->type == FT_FRAMENUM) {
11513 /*
11514 * Frame numbers are always displayed in decimal.
11515 */
11516 display = BASE_DEC;
11517 }
11518
11519 switch (display) {
11520 case BASE_NONE:
11521 /* case BASE_DEC: */
11522 case BASE_DEC_HEX:
11523 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11524 case BASE_CUSTOM:
11525 display = BASE_DEC;
11526 break;
11527
11528 /* case BASE_HEX: */
11529 case BASE_HEX_DEC:
11530 display = BASE_HEX;
11531 break;
11532 }
11533
11534 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11535}
11536
11537static const char *
11538hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11539{
11540 /* Get the underlying BASE_ value */
11541 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11542
11543 return hfinfo_char_value_format_display(display, buf, value);
11544}
11545
11546static const char *
11547hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11548{
11549 /* Get the underlying BASE_ value */
11550 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11551
11552 if (display == BASE_NONE)
11553 return NULL((void*)0);
11554
11555 if (display == BASE_DEC_HEX)
11556 display = BASE_DEC;
11557 if (display == BASE_HEX_DEC)
11558 display = BASE_HEX;
11559
11560 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11561}
11562
11563static const char *
11564hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11565{
11566 /* Get the underlying BASE_ value */
11567 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11568
11569 if (display == BASE_NONE)
11570 return NULL((void*)0);
11571
11572 if (display == BASE_DEC_HEX)
11573 display = BASE_DEC;
11574 if (display == BASE_HEX_DEC)
11575 display = BASE_HEX;
11576
11577 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11578}
11579
11580const char *
11581proto_registrar_get_name(const int n)
11582{
11583 header_field_info *hfinfo;
11584
11585 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", 11585
, __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", 11585
, "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", 11585, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11586 return hfinfo->name;
11587}
11588
11589const char *
11590proto_registrar_get_abbrev(const int n)
11591{
11592 header_field_info *hfinfo;
11593
11594 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", 11594
, __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", 11594
, "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", 11594, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11595 return hfinfo->abbrev;
11596}
11597
11598enum ftenum
11599proto_registrar_get_ftype(const int n)
11600{
11601 header_field_info *hfinfo;
11602
11603 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", 11603
, __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", 11603
, "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", 11603, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11604 return hfinfo->type;
11605}
11606
11607int
11608proto_registrar_get_parent(const int n)
11609{
11610 header_field_info *hfinfo;
11611
11612 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", 11612
, __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", 11612
, "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", 11612, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11613 return hfinfo->parent;
11614}
11615
11616bool_Bool
11617proto_registrar_is_protocol(const int n)
11618{
11619 header_field_info *hfinfo;
11620
11621 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", 11621
, __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", 11621
, "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", 11621, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11622 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11623}
11624
11625/* Returns length of field in packet (not necessarily the length
11626 * in our internal representation, as in the case of IPv4).
11627 * 0 means undeterminable at time of registration
11628 * -1 means the field is not registered. */
11629int
11630proto_registrar_get_length(const int n)
11631{
11632 header_field_info *hfinfo;
11633
11634 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11634
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11634
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11634, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11635 return ftype_wire_size(hfinfo->type);
11636}
11637
11638size_t
11639proto_registrar_get_count(struct proto_registrar_stats *stats)
11640{
11641 header_field_info *hfinfo;
11642
11643 // Index zero is not used. We have to skip it.
11644 size_t total_count = gpa_hfinfo.len - 1;
11645 if (stats == NULL((void*)0)) {
11646 return total_count;
11647 }
11648 for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11649 if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11650 stats->deregistered_count++;
11651 continue; /* This is a deregistered protocol or header field */
11652 }
11653
11654 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", 11654
, __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", 11654, "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", 11654, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[id];
;
11655
11656 if (proto_registrar_is_protocol(id))
11657 stats->protocol_count++;
11658
11659 if (hfinfo->same_name_prev_id != -1)
11660 stats->same_name_count++;
11661 }
11662
11663 return total_count;
11664}
11665
11666/* Looks for a protocol or a field in a proto_tree. Returns true if
11667 * it exists anywhere, or false if it exists nowhere. */
11668bool_Bool
11669proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11670{
11671 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11672
11673 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11674 return true1;
11675 }
11676 else {
11677 return false0;
11678 }
11679}
11680
11681/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11682 * This only works if the hfindex was "primed" before the dissection
11683 * took place, as we just pass back the already-created GPtrArray*.
11684 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11685 * handles that. */
11686GPtrArray *
11687proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11688{
11689 if (!tree)
11690 return NULL((void*)0);
11691
11692 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11693 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11694 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11695 else
11696 return NULL((void*)0);
11697}
11698
11699bool_Bool
11700proto_tracking_interesting_fields(const proto_tree *tree)
11701{
11702 GHashTable *interesting_hfids;
11703
11704 if (!tree)
11705 return false0;
11706
11707 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11708
11709 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11710}
11711
11712/* Helper struct for proto_find_info() and proto_all_finfos() */
11713typedef struct {
11714 GPtrArray *array;
11715 int id;
11716} ffdata_t;
11717
11718/* Helper function for proto_find_info() */
11719static bool_Bool
11720find_finfo(proto_node *node, void * data)
11721{
11722 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11723 if (fi && fi->hfinfo) {
11724 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11725 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11726 }
11727 }
11728
11729 /* Don't stop traversing. */
11730 return false0;
11731}
11732
11733/* Helper function for proto_find_first_info() */
11734static bool_Bool
11735find_first_finfo(proto_node *node, void *data)
11736{
11737 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11738 if (fi && fi->hfinfo) {
11739 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11740 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11741
11742 /* Stop traversing. */
11743 return true1;
11744 }
11745 }
11746
11747 /* Continue traversing. */
11748 return false0;
11749}
11750
11751/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11752* This works on any proto_tree, primed or unprimed, but actually searches
11753* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11754* The caller does need to free the returned GPtrArray with
11755* g_ptr_array_free(<array>, true).
11756*/
11757GPtrArray *
11758proto_find_finfo(proto_tree *tree, const int id)
11759{
11760 ffdata_t ffdata;
11761
11762 ffdata.array = g_ptr_array_new();
11763 ffdata.id = id;
11764
11765 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11766
11767 return ffdata.array;
11768}
11769
11770/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11771* This works on any proto_tree, primed or unprimed, but actually searches
11772* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11773* The caller does need to free the returned GPtrArray with
11774* g_ptr_array_free(<array>, true).
11775*/
11776GPtrArray *
11777proto_find_first_finfo(proto_tree *tree, const int id)
11778{
11779 ffdata_t ffdata;
11780
11781 ffdata.array = g_ptr_array_new();
11782 ffdata.id = id;
11783
11784 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11785
11786 return ffdata.array;
11787}
11788
11789/* Helper function for proto_all_finfos() */
11790static bool_Bool
11791every_finfo(proto_node *node, void * data)
11792{
11793 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11794 if (fi && fi->hfinfo) {
11795 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11796 }
11797
11798 /* Don't stop traversing. */
11799 return false0;
11800}
11801
11802/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11803 * The caller does need to free the returned GPtrArray with
11804 * g_ptr_array_free(<array>, true).
11805 */
11806GPtrArray *
11807proto_all_finfos(proto_tree *tree)
11808{
11809 ffdata_t ffdata;
11810
11811 /* Pre allocate enough space to hold all fields in most cases */
11812 ffdata.array = g_ptr_array_sized_new(512);
11813 ffdata.id = 0;
11814
11815 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11816
11817 return ffdata.array;
11818}
11819
11820
11821typedef struct {
11822 unsigned offset;
11823 field_info *finfo;
11824 tvbuff_t *tvb;
11825} offset_search_t;
11826
11827static bool_Bool
11828check_for_offset(proto_node *node, void * data)
11829{
11830 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11831 offset_search_t *offsearch = (offset_search_t *)data;
11832
11833 /* !fi == the top most container node which holds nothing */
11834 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11835 if (offsearch->offset >= (unsigned) fi->start &&
11836 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11837
11838 offsearch->finfo = fi;
11839 return false0; /* keep traversing */
11840 }
11841 }
11842 return false0; /* keep traversing */
11843}
11844
11845/* Search a proto_tree backwards (from leaves to root) looking for the field
11846 * whose start/length occupies 'offset' */
11847/* XXX - I couldn't find an easy way to search backwards, so I search
11848 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11849 * the one I want to return to the user. This algorithm is inefficient
11850 * and could be re-done, but I'd have to handle all the children and
11851 * siblings of each node myself. When I have more time I'll do that.
11852 * (yeah right) */
11853field_info *
11854proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11855{
11856 offset_search_t offsearch;
11857
11858 offsearch.offset = offset;
11859 offsearch.finfo = NULL((void*)0);
11860 offsearch.tvb = tvb;
11861
11862 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11863
11864 return offsearch.finfo;
11865}
11866
11867typedef struct {
11868 unsigned length;
11869 char *buf;
11870} decoded_data_t;
11871
11872static bool_Bool
11873check_for_undecoded(proto_node *node, void * data)
11874{
11875 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11876 decoded_data_t* decoded = (decoded_data_t*)data;
11877 unsigned i;
11878 unsigned byte;
11879 unsigned bit;
11880
11881 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11882 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11883 byte = i / 8;
11884 bit = i % 8;
11885 decoded->buf[byte] |= (1 << bit);
11886 }
11887 }
11888
11889 return false0;
11890}
11891
11892char*
11893proto_find_undecoded_data(proto_tree *tree, unsigned length)
11894{
11895 decoded_data_t decoded;
11896 decoded.length = length;
11897 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11898
11899 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11900 return decoded.buf;
11901}
11902
11903/* Dumps the protocols in the registration database to stdout. An independent
11904 * program can take this output and format it into nice tables or HTML or
11905 * whatever.
11906 *
11907 * There is one record per line. The fields are tab-delimited.
11908 *
11909 * Field 1 = protocol name
11910 * Field 2 = protocol short name
11911 * Field 3 = protocol filter name
11912 * Field 4 = protocol enabled
11913 * Field 5 = protocol enabled by default
11914 * Field 6 = protocol can toggle
11915 */
11916void
11917proto_registrar_dump_protocols(void)
11918{
11919 protocol_t *protocol;
11920 int i;
11921 void *cookie = NULL((void*)0);
11922
11923
11924 i = proto_get_first_protocol(&cookie);
11925 while (i != -1) {
11926 protocol = find_protocol_by_id(i);
11927 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11928 protocol->name,
11929 protocol->short_name,
11930 protocol->filter_name,
11931 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11932 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11933 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11934 i = proto_get_next_protocol(&cookie);
11935 }
11936}
11937
11938/* Dumps the value_strings, extended value string headers, range_strings
11939 * or true/false strings for fields that have them.
11940 * There is one record per line. Fields are tab-delimited.
11941 * There are four types of records: Value String, Extended Value String Header,
11942 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11943 * the type of record.
11944 *
11945 * Note that a record will be generated only if the value_string,... is referenced
11946 * in a registered hfinfo entry.
11947 *
11948 *
11949 * Value Strings
11950 * -------------
11951 * Field 1 = 'V'
11952 * Field 2 = Field abbreviation to which this value string corresponds
11953 * Field 3 = Integer value
11954 * Field 4 = String
11955 *
11956 * Extended Value String Headers
11957 * -----------------------------
11958 * Field 1 = 'E'
11959 * Field 2 = Field abbreviation to which this extended value string header corresponds
11960 * Field 3 = Extended Value String "Name"
11961 * Field 4 = Number of entries in the associated value_string array
11962 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11963 *
11964 * Range Strings
11965 * -------------
11966 * Field 1 = 'R'
11967 * Field 2 = Field abbreviation to which this range string corresponds
11968 * Field 3 = Integer value: lower bound
11969 * Field 4 = Integer value: upper bound
11970 * Field 5 = String
11971 *
11972 * True/False Strings
11973 * ------------------
11974 * Field 1 = 'T'
11975 * Field 2 = Field abbreviation to which this true/false string corresponds
11976 * Field 3 = True String
11977 * Field 4 = False String
11978 */
11979void
11980proto_registrar_dump_values(void)
11981{
11982 header_field_info *hfinfo;
11983 int i, len, vi;
11984 const value_string *vals;
11985 const val64_string *vals64;
11986 const range_string *range;
11987 const true_false_string *tfs;
11988 const unit_name_string *units;
11989
11990 len = gpa_hfinfo.len;
11991 for (i = 1; i < len ; i++) {
11992 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11993 continue; /* This is a deregistered protocol or field */
11994
11995 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", 11995
, __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", 11995
, "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", 11995, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11996
11997 if (hfinfo->id == hf_text_only) {
11998 continue;
11999 }
12000
12001 /* ignore protocols */
12002 if (proto_registrar_is_protocol(i)) {
12003 continue;
12004 }
12005 /* process header fields */
12006#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12007 /*
12008 * If this field isn't at the head of the list of
12009 * fields with this name, skip this field - all
12010 * fields with the same name are really just versions
12011 * of the same field stored in different bits, and
12012 * should have the same type/radix/value list, and
12013 * just differ in their bit masks. (If a field isn't
12014 * a bitfield, but can be, say, 1 or 2 bytes long,
12015 * it can just be made FT_UINT16, meaning the
12016 * *maximum* length is 2 bytes, and be used
12017 * for all lengths.)
12018 */
12019 if (hfinfo->same_name_prev_id != -1)
12020 continue;
12021#endif
12022 vals = NULL((void*)0);
12023 vals64 = NULL((void*)0);
12024 range = NULL((void*)0);
12025 tfs = NULL((void*)0);
12026 units = NULL((void*)0);
12027
12028 if (hfinfo->strings != NULL((void*)0)) {
12029 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12030 (hfinfo->type == FT_CHAR ||
12031 hfinfo->type == FT_UINT8 ||
12032 hfinfo->type == FT_UINT16 ||
12033 hfinfo->type == FT_UINT24 ||
12034 hfinfo->type == FT_UINT32 ||
12035 hfinfo->type == FT_UINT40 ||
12036 hfinfo->type == FT_UINT48 ||
12037 hfinfo->type == FT_UINT56 ||
12038 hfinfo->type == FT_UINT64 ||
12039 hfinfo->type == FT_INT8 ||
12040 hfinfo->type == FT_INT16 ||
12041 hfinfo->type == FT_INT24 ||
12042 hfinfo->type == FT_INT32 ||
12043 hfinfo->type == FT_INT40 ||
12044 hfinfo->type == FT_INT48 ||
12045 hfinfo->type == FT_INT56 ||
12046 hfinfo->type == FT_INT64 ||
12047 hfinfo->type == FT_FLOAT ||
12048 hfinfo->type == FT_DOUBLE)) {
12049
12050 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12051 range = (const range_string *)hfinfo->strings;
12052 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12053 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12054 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12055 } else {
12056 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12057 }
12058 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12059 vals64 = (const val64_string *)hfinfo->strings;
12060 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12061 units = (const unit_name_string *)hfinfo->strings;
12062 } else {
12063 vals = (const value_string *)hfinfo->strings;
12064 }
12065 }
12066 else if (hfinfo->type == FT_BOOLEAN) {
12067 tfs = (const struct true_false_string *)hfinfo->strings;
12068 }
12069 }
12070
12071 /* Print value strings? */
12072 if (vals) {
12073 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12074 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12075 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12076 if (!val64_string_ext_validate(vse_p)) {
12077 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12077, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12078 continue;
12079 }
12080 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12081 printf("E\t%s\t%u\t%s\t%s\n",
12082 hfinfo->abbrev,
12083 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12084 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12085 val64_string_ext_match_type_str(vse_p));
12086 } else {
12087 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12088 if (!value_string_ext_validate(vse_p)) {
12089 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 12089, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
12090 continue;
12091 }
12092 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12093 printf("E\t%s\t%u\t%s\t%s\n",
12094 hfinfo->abbrev,
12095 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12096 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12097 value_string_ext_match_type_str(vse_p));
12098 }
12099 }
12100 vi = 0;
12101 while (vals[vi].strptr) {
12102 /* Print in the proper base */
12103 if (hfinfo->type == FT_CHAR) {
12104 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
12105 printf("V\t%s\t'%c'\t%s\n",
12106 hfinfo->abbrev,
12107 vals[vi].value,
12108 vals[vi].strptr);
12109 } else {
12110 if (hfinfo->display == BASE_HEX) {
12111 printf("V\t%s\t'\\x%02x'\t%s\n",
12112 hfinfo->abbrev,
12113 vals[vi].value,
12114 vals[vi].strptr);
12115 }
12116 else {
12117 printf("V\t%s\t'\\%03o'\t%s\n",
12118 hfinfo->abbrev,
12119 vals[vi].value,
12120 vals[vi].strptr);
12121 }
12122 }
12123 } else {
12124 if (hfinfo->display == BASE_HEX) {
12125 printf("V\t%s\t0x%x\t%s\n",
12126 hfinfo->abbrev,
12127 vals[vi].value,
12128 vals[vi].strptr);
12129 }
12130 else {
12131 printf("V\t%s\t%u\t%s\n",
12132 hfinfo->abbrev,
12133 vals[vi].value,
12134 vals[vi].strptr);
12135 }
12136 }
12137 vi++;
12138 }
12139 }
12140 else if (vals64) {
12141 vi = 0;
12142 while (vals64[vi].strptr) {
12143 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12144 hfinfo->abbrev,
12145 vals64[vi].value,
12146 vals64[vi].strptr);
12147 vi++;
12148 }
12149 }
12150
12151 /* print range strings? */
12152 else if (range) {
12153 vi = 0;
12154 while (range[vi].strptr) {
12155 /* Print in the proper base */
12156 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12157 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12158 hfinfo->abbrev,
12159 range[vi].value_min,
12160 range[vi].value_max,
12161 range[vi].strptr);
12162 }
12163 else {
12164 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12165 hfinfo->abbrev,
12166 range[vi].value_min,
12167 range[vi].value_max,
12168 range[vi].strptr);
12169 }
12170 vi++;
12171 }
12172 }
12173
12174 /* Print true/false strings? */
12175 else if (tfs) {
12176 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12177 tfs->true_string, tfs->false_string);
12178 }
12179 /* Print unit strings? */
12180 else if (units) {
12181 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12182 units->singular, units->plural ? units->plural : "(no plural)");
12183 }
12184 }
12185}
12186
12187/* Prints the number of registered fields.
12188 * Useful for determining an appropriate value for
12189 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12190 *
12191 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12192 * the number of fields, true otherwise.
12193 */
12194bool_Bool
12195proto_registrar_dump_fieldcount(void)
12196{
12197 struct proto_registrar_stats stats = {0, 0, 0};
12198 size_t total_count = proto_registrar_get_count(&stats);
12199
12200 printf("There are %zu header fields registered, of which:\n"
12201 "\t%zu are deregistered\n"
12202 "\t%zu are protocols\n"
12203 "\t%zu have the same name as another field\n\n",
12204 total_count, stats.deregistered_count, stats.protocol_count,
12205 stats.same_name_count);
12206
12207 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12208 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12209 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12210 "\n");
12211
12212 printf("The header field table consumes %u KiB of memory.\n",
12213 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12214 printf("The fields themselves consume %u KiB of memory.\n",
12215 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12216
12217 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12218}
12219
12220static void
12221elastic_add_base_mapping(json_dumper *dumper)
12222{
12223 json_dumper_set_member_name(dumper, "index_patterns");
12224 json_dumper_begin_array(dumper);
12225 // The index names from write_json_index() in print.c
12226 json_dumper_value_string(dumper, "packets-*");
12227 json_dumper_end_array(dumper);
12228
12229 json_dumper_set_member_name(dumper, "settings");
12230 json_dumper_begin_object(dumper);
12231 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12232 json_dumper_value_anyf(dumper, "%d", 1000000);
12233 json_dumper_end_object(dumper);
12234}
12235
12236static char*
12237ws_type_to_elastic(unsigned type)
12238{
12239 switch(type) {
12240 case FT_INT8:
12241 return "byte";
12242 case FT_UINT8:
12243 case FT_INT16:
12244 return "short";
12245 case FT_UINT16:
12246 case FT_INT32:
12247 case FT_UINT24:
12248 case FT_INT24:
12249 return "integer";
12250 case FT_FRAMENUM:
12251 case FT_UINT32:
12252 case FT_UINT40:
12253 case FT_UINT48:
12254 case FT_UINT56:
12255 case FT_INT40:
12256 case FT_INT48:
12257 case FT_INT56:
12258 case FT_INT64:
12259 return "long";
12260 case FT_UINT64:
12261 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12262 case FT_FLOAT:
12263 return "float";
12264 case FT_DOUBLE:
12265 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12266 return "double";
12267 case FT_IPv6:
12268 case FT_IPv4:
12269 return "ip";
12270 case FT_ABSOLUTE_TIME:
12271 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12272 case FT_BOOLEAN:
12273 return "boolean";
12274 default:
12275 return NULL((void*)0);
12276 }
12277}
12278
12279static char*
12280dot_to_underscore(char* str)
12281{
12282 unsigned i;
12283 for (i = 0; i < strlen(str); i++) {
12284 if (str[i] == '.')
12285 str[i] = '_';
12286 }
12287 return str;
12288}
12289
12290/* Dumps a mapping file for ElasticSearch
12291 * This is the v1 (legacy) _template API.
12292 * At some point it may need to be updated with the composable templates
12293 * introduced in Elasticsearch 7.8 (_index_template)
12294 */
12295void
12296proto_registrar_dump_elastic(const char* filter)
12297{
12298 header_field_info *hfinfo;
12299 header_field_info *parent_hfinfo;
12300 unsigned i;
12301 bool_Bool open_object = true1;
12302 const char* prev_proto = NULL((void*)0);
12303 char* str;
12304 char** protos = NULL((void*)0);
12305 char* proto;
12306 bool_Bool found;
12307 unsigned j;
12308 char* type;
12309 char* prev_item = NULL((void*)0);
12310
12311 /* We have filtering protocols. Extract them. */
12312 if (filter) {
12313 protos = g_strsplit(filter, ",", -1);
12314 }
12315
12316 /*
12317 * To help tracking down the json tree, objects have been appended with a comment:
12318 * n.label -> where n is the indentation level and label the name of the object
12319 */
12320
12321 json_dumper dumper = {
12322 .output_file = stdoutstdout,
12323 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12324 };
12325 json_dumper_begin_object(&dumper); // 1.root
12326 elastic_add_base_mapping(&dumper);
12327
12328 json_dumper_set_member_name(&dumper, "mappings");
12329 json_dumper_begin_object(&dumper); // 2.mappings
12330
12331 json_dumper_set_member_name(&dumper, "properties");
12332 json_dumper_begin_object(&dumper); // 3.properties
12333 json_dumper_set_member_name(&dumper, "timestamp");
12334 json_dumper_begin_object(&dumper); // 4.timestamp
12335 json_dumper_set_member_name(&dumper, "type");
12336 json_dumper_value_string(&dumper, "date");
12337 json_dumper_end_object(&dumper); // 4.timestamp
12338
12339 json_dumper_set_member_name(&dumper, "layers");
12340 json_dumper_begin_object(&dumper); // 4.layers
12341 json_dumper_set_member_name(&dumper, "properties");
12342 json_dumper_begin_object(&dumper); // 5.properties
12343
12344 for (i = 1; i < gpa_hfinfo.len; i++) {
12345 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12346 continue; /* This is a deregistered protocol or header field */
12347
12348 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", 12348
, __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", 12348
, "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", 12348, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12349
12350 /*
12351 * Skip the pseudo-field for "proto_tree_add_text()" since
12352 * we don't want it in the list of filterable protocols.
12353 */
12354 if (hfinfo->id == hf_text_only)
12355 continue;
12356
12357 if (!proto_registrar_is_protocol(i)) {
12358 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", 12358
, __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", 12358
, "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", 12358
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12359
12360 /*
12361 * Skip the field if filter protocols have been set and this one's
12362 * parent is not listed.
12363 */
12364 if (protos) {
12365 found = false0;
12366 j = 0;
12367 proto = protos[0];
12368 while(proto) {
12369 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12370 found = true1;
12371 break;
12372 }
12373 j++;
12374 proto = protos[j];
12375 }
12376 if (!found)
12377 continue;
12378 }
12379
12380 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12381 json_dumper_end_object(&dumper); // 7.properties
12382 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12383 open_object = true1;
12384 }
12385
12386 prev_proto = parent_hfinfo->abbrev;
12387
12388 if (open_object) {
12389 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12390 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12391 json_dumper_set_member_name(&dumper, "properties");
12392 json_dumper_begin_object(&dumper); // 7.properties
12393 open_object = false0;
12394 }
12395 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12396 type = ws_type_to_elastic(hfinfo->type);
12397 /* when type is NULL, we have the default mapping: string */
12398 if (type) {
12399 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12400 dot_to_underscore(str);
12401 if (g_strcmp0(prev_item, str)) {
12402 json_dumper_set_member_name(&dumper, str);
12403 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12404 json_dumper_set_member_name(&dumper, "type");
12405 json_dumper_value_string(&dumper, type);
12406 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12407 }
12408 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)
;
12409 prev_item = str;
12410 }
12411 }
12412 }
12413 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)
;
12414
12415 if (prev_proto) {
12416 json_dumper_end_object(&dumper); // 7.properties
12417 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12418 }
12419
12420 json_dumper_end_object(&dumper); // 5.properties
12421 json_dumper_end_object(&dumper); // 4.layers
12422 json_dumper_end_object(&dumper); // 3.properties
12423 json_dumper_end_object(&dumper); // 2.mappings
12424 json_dumper_end_object(&dumper); // 1.root
12425 bool_Bool ret = json_dumper_finish(&dumper);
12426 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12426, "ret"))))
;
12427
12428 g_strfreev(protos);
12429}
12430
12431/* Dumps the contents of the registration database to stdout. An independent
12432 * program can take this output and format it into nice tables or HTML or
12433 * whatever.
12434 *
12435 * There is one record per line. Each record is either a protocol or a header
12436 * field, differentiated by the first field. The fields are tab-delimited.
12437 *
12438 * Protocols
12439 * ---------
12440 * Field 1 = 'P'
12441 * Field 2 = descriptive protocol name
12442 * Field 3 = protocol abbreviation
12443 *
12444 * Header Fields
12445 * -------------
12446 * Field 1 = 'F'
12447 * Field 2 = descriptive field name
12448 * Field 3 = field abbreviation
12449 * Field 4 = type ( textual representation of the ftenum type )
12450 * Field 5 = parent protocol abbreviation
12451 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12452 * Field 7 = bitmask: format: hex: 0x....
12453 * Field 8 = blurb describing field
12454 */
12455void
12456proto_registrar_dump_fields(void)
12457{
12458 header_field_info *hfinfo, *parent_hfinfo;
12459 int i, len;
12460 const char *enum_name;
12461 const char *base_name;
12462 const char *blurb;
12463 char width[5];
12464
12465 len = gpa_hfinfo.len;
12466 for (i = 1; i < len ; i++) {
12467 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12468 continue; /* This is a deregistered protocol or header field */
12469
12470 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", 12470
, __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", 12470
, "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", 12470, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12471
12472 /*
12473 * Skip the pseudo-field for "proto_tree_add_text()" since
12474 * we don't want it in the list of filterable fields.
12475 */
12476 if (hfinfo->id == hf_text_only)
12477 continue;
12478
12479 /* format for protocols */
12480 if (proto_registrar_is_protocol(i)) {
12481 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12482 }
12483 /* format for header fields */
12484 else {
12485 /*
12486 * If this field isn't at the head of the list of
12487 * fields with this name, skip this field - all
12488 * fields with the same name are really just versions
12489 * of the same field stored in different bits, and
12490 * should have the same type/radix/value list, and
12491 * just differ in their bit masks. (If a field isn't
12492 * a bitfield, but can be, say, 1 or 2 bytes long,
12493 * it can just be made FT_UINT16, meaning the
12494 * *maximum* length is 2 bytes, and be used
12495 * for all lengths.)
12496 */
12497 if (hfinfo->same_name_prev_id != -1)
12498 continue;
12499
12500 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", 12500
, __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", 12500
, "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", 12500
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12501
12502 enum_name = ftype_name(hfinfo->type);
12503 base_name = "";
12504
12505 if (hfinfo->type == FT_CHAR ||
12506 hfinfo->type == FT_UINT8 ||
12507 hfinfo->type == FT_UINT16 ||
12508 hfinfo->type == FT_UINT24 ||
12509 hfinfo->type == FT_UINT32 ||
12510 hfinfo->type == FT_UINT40 ||
12511 hfinfo->type == FT_UINT48 ||
12512 hfinfo->type == FT_UINT56 ||
12513 hfinfo->type == FT_UINT64 ||
12514 hfinfo->type == FT_INT8 ||
12515 hfinfo->type == FT_INT16 ||
12516 hfinfo->type == FT_INT24 ||
12517 hfinfo->type == FT_INT32 ||
12518 hfinfo->type == FT_INT40 ||
12519 hfinfo->type == FT_INT48 ||
12520 hfinfo->type == FT_INT56 ||
12521 hfinfo->type == FT_INT64) {
12522
12523 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12524 case BASE_NONE:
12525 case BASE_DEC:
12526 case BASE_HEX:
12527 case BASE_OCT:
12528 case BASE_DEC_HEX:
12529 case BASE_HEX_DEC:
12530 case BASE_CUSTOM:
12531 case BASE_PT_UDP:
12532 case BASE_PT_TCP:
12533 case BASE_PT_DCCP:
12534 case BASE_PT_SCTP:
12535 case BASE_OUI:
12536 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12537 break;
12538 default:
12539 base_name = "????";
12540 break;
12541 }
12542 } else if (hfinfo->type == FT_BOOLEAN) {
12543 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12544 snprintf(width, sizeof(width), "%d", hfinfo->display);
12545 base_name = width;
12546 }
12547
12548 blurb = hfinfo->blurb;
12549 if (blurb == NULL((void*)0))
12550 blurb = "";
12551 else if (strlen(blurb) == 0)
12552 blurb = "\"\"";
12553
12554 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12555 hfinfo->name, hfinfo->abbrev, enum_name,
12556 parent_hfinfo->abbrev, base_name,
12557 hfinfo->bitmask, blurb);
12558 }
12559 }
12560}
12561
12562/* Dumps all abbreviated field and protocol completions of the given string to
12563 * stdout. An independent program may use this for command-line tab completion
12564 * of fields.
12565 */
12566bool_Bool
12567proto_registrar_dump_field_completions(const char *prefix)
12568{
12569 header_field_info *hfinfo;
12570 int i, len;
12571 size_t prefix_len;
12572 bool_Bool matched = false0;
12573
12574 prefix_len = strlen(prefix);
12575 len = gpa_hfinfo.len;
12576 for (i = 1; i < len ; i++) {
12577 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12578 continue; /* This is a deregistered protocol or header field */
12579
12580 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", 12580
, __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", 12580
, "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", 12580, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12581
12582 /*
12583 * Skip the pseudo-field for "proto_tree_add_text()" since
12584 * we don't want it in the list of filterable fields.
12585 */
12586 if (hfinfo->id == hf_text_only)
12587 continue;
12588
12589 /* format for protocols */
12590 if (proto_registrar_is_protocol(i)) {
12591 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12592 matched = true1;
12593 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12594 }
12595 }
12596 /* format for header fields */
12597 else {
12598 /*
12599 * If this field isn't at the head of the list of
12600 * fields with this name, skip this field - all
12601 * fields with the same name are really just versions
12602 * of the same field stored in different bits, and
12603 * should have the same type/radix/value list, and
12604 * just differ in their bit masks. (If a field isn't
12605 * a bitfield, but can be, say, 1 or 2 bytes long,
12606 * it can just be made FT_UINT16, meaning the
12607 * *maximum* length is 2 bytes, and be used
12608 * for all lengths.)
12609 */
12610 if (hfinfo->same_name_prev_id != -1)
12611 continue;
12612
12613 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12614 matched = true1;
12615 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12616 }
12617 }
12618 }
12619 return matched;
12620}
12621
12622/* Dumps field types and descriptive names to stdout. An independent
12623 * program can take this output and format it into nice tables or HTML or
12624 * whatever.
12625 *
12626 * There is one record per line. The fields are tab-delimited.
12627 *
12628 * Field 1 = field type name, e.g. FT_UINT8
12629 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12630 */
12631void
12632proto_registrar_dump_ftypes(void)
12633{
12634 int fte;
12635
12636 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12637 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12638 }
12639}
12640
12641/* This function indicates whether it's possible to construct a
12642 * "match selected" display filter string for the specified field,
12643 * returns an indication of whether it's possible, and, if it's
12644 * possible and "filter" is non-null, constructs the filter and
12645 * sets "*filter" to point to it.
12646 * You do not need to [g_]free() this string since it will be automatically
12647 * freed once the next packet is dissected.
12648 */
12649static bool_Bool
12650construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12651 char **filter)
12652{
12653 const header_field_info *hfinfo;
12654 int start, length, length_remaining;
12655
12656 if (!finfo)
12657 return false0;
12658
12659 hfinfo = finfo->hfinfo;
12660 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12660, "hfinfo"))))
;
12661
12662 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12663 * then "the numeric value ... is not used when preparing
12664 * filters for the field in question." If it's any other
12665 * base, we'll generate the filter normally (which will
12666 * be numeric, even though the human-readable string does
12667 * work for filtering.)
12668 *
12669 * XXX - It might be nice to use fvalue_to_string_repr() in
12670 * "proto_item_fill_label()" as well, although, there, you'd
12671 * have to deal with the base *and* with resolved values for
12672 * addresses.
12673 *
12674 * Perhaps in addition to taking the repr type (DISPLAY
12675 * or DFILTER) and the display (base), fvalue_to_string_repr()
12676 * should have the the "strings" values in the header_field_info
12677 * structure for the field as a parameter, so it can have
12678 * if the field is Boolean or an enumerated integer type,
12679 * the tables used to generate human-readable values.
12680 */
12681 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12682 const char *str = NULL((void*)0);
12683
12684 switch (hfinfo->type) {
12685
12686 case FT_INT8:
12687 case FT_INT16:
12688 case FT_INT24:
12689 case FT_INT32:
12690 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12691 break;
12692
12693 case FT_CHAR:
12694 case FT_UINT8:
12695 case FT_UINT16:
12696 case FT_UINT24:
12697 case FT_UINT32:
12698 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12699 break;
12700
12701 default:
12702 break;
12703 }
12704
12705 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12706 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12707 return true1;
12708 }
12709 }
12710
12711 switch (hfinfo->type) {
12712
12713 case FT_PROTOCOL:
12714 if (filter != NULL((void*)0))
12715 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12716 break;
12717
12718 case FT_NONE:
12719 /*
12720 * If the length is 0, just match the name of the
12721 * field.
12722 *
12723 * (Also check for negative values, just in case,
12724 * as we'll cast it to an unsigned value later.)
12725 */
12726 length = finfo->length;
12727 if (length == 0) {
12728 if (filter != NULL((void*)0))
12729 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12730 break;
12731 }
12732 if (length < 0)
12733 return false0;
12734
12735 /*
12736 * This doesn't have a value, so we'd match
12737 * on the raw bytes at this address.
12738 *
12739 * Should we be allowed to access to the raw bytes?
12740 * If "edt" is NULL, the answer is "no".
12741 */
12742 if (edt == NULL((void*)0))
12743 return false0;
12744
12745 /*
12746 * Is this field part of the raw frame tvbuff?
12747 * If not, we can't use "frame[N:M]" to match
12748 * it.
12749 *
12750 * XXX - should this be frame-relative, or
12751 * protocol-relative?
12752 *
12753 * XXX - does this fallback for non-registered
12754 * fields even make sense?
12755 */
12756 if (finfo->ds_tvb != edt->tvb)
12757 return false0; /* you lose */
12758
12759 /*
12760 * Don't go past the end of that tvbuff.
12761 */
12762 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12763 if (length > length_remaining)
12764 length = length_remaining;
12765 if (length <= 0)
12766 return false0;
12767
12768 if (filter != NULL((void*)0)) {
12769 start = finfo->start;
12770 char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12771 *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12772 wmem_free(NULL((void*)0), str);
12773 }
12774 break;
12775
12776 /* By default, use the fvalue's "to_string_repr" method. */
12777 default:
12778 if (filter != NULL((void*)0)) {
12779 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12780 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12781 wmem_free(NULL((void*)0), str);
12782 }
12783 break;
12784 }
12785
12786 return true1;
12787}
12788
12789/*
12790 * Returns true if we can do a "match selected" on the field, false
12791 * otherwise.
12792 */
12793bool_Bool
12794proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12795{
12796 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12797}
12798
12799/* This function attempts to construct a "match selected" display filter
12800 * string for the specified field; if it can do so, it returns a pointer
12801 * to the string, otherwise it returns NULL.
12802 *
12803 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12804 */
12805char *
12806proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12807{
12808 char *filter = NULL((void*)0);
12809
12810 if (!construct_match_selected_string(finfo, edt, &filter))
12811 {
12812 wmem_free(NULL((void*)0), filter);
12813 return NULL((void*)0);
12814 }
12815 return filter;
12816}
12817
12818/* This function is common code for all proto_tree_add_bitmask... functions.
12819 */
12820
12821static bool_Bool
12822proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12823 const int len, const int ett, int * const *fields,
12824 const int flags, bool_Bool first,
12825 bool_Bool use_parent_tree,
12826 proto_tree* tree, uint64_t value)
12827{
12828 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12829 uint64_t bitmask = 0;
12830 uint64_t tmpval;
12831 header_field_info *hf;
12832 uint32_t integer32;
12833 int bit_offset;
12834 int no_of_bits;
12835
12836 if (!*fields)
12837 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"
)
;
12838
12839 if (len < 0 || len > 8)
12840 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12841 /**
12842 * packet-frame.c uses len=0 since the value is taken from the packet
12843 * metadata, not the packet bytes. In that case, assume that all bits
12844 * in the provided value are valid.
12845 */
12846 if (len > 0) {
12847 available_bits >>= (8 - (unsigned)len)*8;
12848 }
12849
12850 if (use_parent_tree == false0)
12851 tree = proto_item_add_subtree(item, ett);
12852
12853 while (*fields) {
12854 uint64_t present_bits;
12855 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", 12855, __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", 12855
, "**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", 12855, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12856 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", 12856
, "hf->bitmask != 0", hf->abbrev))))
;
12857
12858 bitmask |= hf->bitmask;
12859
12860 /* Skip fields that aren't fully present */
12861 present_bits = available_bits & hf->bitmask;
12862 if (present_bits != hf->bitmask) {
12863 fields++;
12864 continue;
12865 }
12866
12867 switch (hf->type) {
12868 case FT_CHAR:
12869 case FT_UINT8:
12870 case FT_UINT16:
12871 case FT_UINT24:
12872 case FT_UINT32:
12873 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12874 break;
12875
12876 case FT_INT8:
12877 case FT_INT16:
12878 case FT_INT24:
12879 case FT_INT32:
12880 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12881 break;
12882
12883 case FT_UINT40:
12884 case FT_UINT48:
12885 case FT_UINT56:
12886 case FT_UINT64:
12887 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12888 break;
12889
12890 case FT_INT40:
12891 case FT_INT48:
12892 case FT_INT56:
12893 case FT_INT64:
12894 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12895 break;
12896
12897 case FT_BOOLEAN:
12898 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12899 break;
12900
12901 default:
12902 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))
12903 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))
12904 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))
12905 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))
;
12906 break;
12907 }
12908 if (flags & BMT_NO_APPEND0x01) {
12909 fields++;
12910 continue;
12911 }
12912 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12913
12914 /* XXX: README.developer and the comments have always defined
12915 * BMT_NO_INT as "only boolean flags are added to the title /
12916 * don't add non-boolean (integral) fields", but the
12917 * implementation has always added BASE_CUSTOM and fields with
12918 * value_strings, though not fields with unit_strings.
12919 * Possibly this is because some dissectors use a FT_UINT8
12920 * with a value_string for fields that should be a FT_BOOLEAN.
12921 */
12922 switch (hf->type) {
12923 case FT_CHAR:
12924 if (hf->display == BASE_CUSTOM) {
12925 char lbl[ITEM_LABEL_LENGTH240];
12926 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12927
12928 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12928, "fmtfunc"))))
;
12929 fmtfunc(lbl, (uint32_t) tmpval);
12930 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12931 hf->name, lbl);
12932 first = false0;
12933 }
12934 else if (hf->strings) {
12935 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12936 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12937 first = false0;
12938 }
12939 else if (!(flags & BMT_NO_INT0x02)) {
12940 char buf[32];
12941 const char *out;
12942
12943 if (!first) {
12944 proto_item_append_text(item, ", ");
12945 }
12946
12947 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12948 proto_item_append_text(item, "%s: %s", hf->name, out);
12949 first = false0;
12950 }
12951
12952 break;
12953
12954 case FT_UINT8:
12955 case FT_UINT16:
12956 case FT_UINT24:
12957 case FT_UINT32:
12958 if (hf->display == BASE_CUSTOM) {
12959 char lbl[ITEM_LABEL_LENGTH240];
12960 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12961
12962 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12962, "fmtfunc"))))
;
12963 fmtfunc(lbl, (uint32_t) tmpval);
12964 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12965 hf->name, lbl);
12966 first = false0;
12967 }
12968 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12969 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12970 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12971 first = false0;
12972 }
12973 else if (!(flags & BMT_NO_INT0x02)) {
12974 char buf[NUMBER_LABEL_LENGTH80];
12975 const char *out = NULL((void*)0);
12976
12977 if (!first) {
12978 proto_item_append_text(item, ", ");
12979 }
12980
12981 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12982 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12983 }
12984 if (out == NULL((void*)0)) {
12985 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12986 }
12987 proto_item_append_text(item, "%s: %s", hf->name, out);
12988 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12989 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12990 }
12991 first = false0;
12992 }
12993
12994 break;
12995
12996 case FT_INT8:
12997 case FT_INT16:
12998 case FT_INT24:
12999 case FT_INT32:
13000 integer32 = (uint32_t) tmpval;
13001 if (hf->bitmask) {
13002 no_of_bits = ws_count_ones(hf->bitmask);
13003 integer32 = ws_sign_ext32(integer32, no_of_bits);
13004 }
13005 if (hf->display == BASE_CUSTOM) {
13006 char lbl[ITEM_LABEL_LENGTH240];
13007 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13008
13009 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13009, "fmtfunc"))))
;
13010 fmtfunc(lbl, (int32_t) integer32);
13011 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13012 hf->name, lbl);
13013 first = false0;
13014 }
13015 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13016 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13017 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13018 first = false0;
13019 }
13020 else if (!(flags & BMT_NO_INT0x02)) {
13021 char buf[NUMBER_LABEL_LENGTH80];
13022 const char *out = NULL((void*)0);
13023
13024 if (!first) {
13025 proto_item_append_text(item, ", ");
13026 }
13027
13028 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13029 out = hf_try_val_to_str((int32_t) integer32, hf);
13030 }
13031 if (out == NULL((void*)0)) {
13032 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13033 }
13034 proto_item_append_text(item, "%s: %s", hf->name, out);
13035 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13036 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13037 }
13038 first = false0;
13039 }
13040
13041 break;
13042
13043 case FT_UINT40:
13044 case FT_UINT48:
13045 case FT_UINT56:
13046 case FT_UINT64:
13047 if (hf->display == BASE_CUSTOM) {
13048 char lbl[ITEM_LABEL_LENGTH240];
13049 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13050
13051 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 13051, "fmtfunc"))))
;
13052 fmtfunc(lbl, tmpval);
13053 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13054 hf->name, lbl);
13055 first = false0;
13056 }
13057 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13058 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13059 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13060 first = false0;
13061 }
13062 else if (!(flags & BMT_NO_INT0x02)) {
13063 char buf[NUMBER_LABEL_LENGTH80];
13064 const char *out = NULL((void*)0);
13065
13066 if (!first) {
13067 proto_item_append_text(item, ", ");
13068 }
13069
13070 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13071 out = hf_try_val64_to_str(tmpval, hf);
13072 }
13073 if (out == NULL((void*)0)) {
13074 out = hfinfo_number_value_format64(hf, buf, tmpval);
13075 }
13076 proto_item_append_text(item, "%s: %s", hf->name, out);
13077 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13078 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13079 }
13080 first = false0;
13081 }
13082
13083 break;
13084
13085 case FT_INT40:
13086 case FT_INT48:
13087 case FT_INT56:
13088 case FT_INT64:
13089 if (hf->bitmask) {
13090 no_of_bits = ws_count_ones(hf->bitmask);
13091 tmpval = ws_sign_ext64(tmpval, no_of_bits);
13092 }
13093 if (hf->display == BASE_CUSTOM) {
13094 char lbl[ITEM_LABEL_LENGTH240];
13095 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_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, (int64_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) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13104 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13105 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13106 first = false0;
13107 }
13108 else if (!(flags & BMT_NO_INT0x02)) {
13109 char buf[NUMBER_LABEL_LENGTH80];
13110 const char *out = NULL((void*)0);
13111
13112 if (!first) {
13113 proto_item_append_text(item, ", ");
13114 }
13115
13116 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13117 out = hf_try_val64_to_str((int64_t) tmpval, hf);
13118 }
13119 if (out == NULL((void*)0)) {
13120 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13121 }
13122 proto_item_append_text(item, "%s: %s", hf->name, out);
13123 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13124 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13125 }
13126 first = false0;
13127 }
13128
13129 break;
13130
13131 case FT_BOOLEAN:
13132 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13133 /* If we have true/false strings, emit full - otherwise messages
13134 might look weird */
13135 const struct true_false_string *tfs =
13136 (const struct true_false_string *)hf->strings;
13137
13138 if (tmpval) {
13139 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13140 hf->name, tfs->true_string);
13141 first = false0;
13142 } else if (!(flags & BMT_NO_FALSE0x04)) {
13143 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13144 hf->name, tfs->false_string);
13145 first = false0;
13146 }
13147 } else if (hf->bitmask & value) {
13148 /* If the flag is set, show the name */
13149 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13150 first = false0;
13151 }
13152 break;
13153 default:
13154 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))
13155 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))
13156 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))
13157 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))
;
13158 break;
13159 }
13160
13161 fields++;
13162 }
13163
13164 /* XXX: We don't pass the hfi into this function. Perhaps we should,
13165 * but then again most dissectors don't set the bitmask field for
13166 * the higher level bitmask hfi, so calculate the bitmask from the
13167 * fields present. */
13168 if (item) {
13169 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13170 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13171 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)
;
13172 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)
;
13173 }
13174 return first;
13175}
13176
13177/* This function will dissect a sequence of bytes that describe a
13178 * bitmask and supply the value of that sequence through a pointer.
13179 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13180 * to be dissected.
13181 * This field will form an expansion under which the individual fields of the
13182 * bitmask is dissected and displayed.
13183 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13184 *
13185 * fields is an array of pointers to int that lists all the fields of the
13186 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13187 * or another integer of the same type/size as hf_hdr with a mask specified.
13188 * This array is terminated by a NULL entry.
13189 *
13190 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13191 * FT_integer fields that have a value_string attached will have the
13192 * matched string displayed on the expansion line.
13193 */
13194proto_item *
13195proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13196 const unsigned offset, const int hf_hdr,
13197 const int ett, int * const *fields,
13198 const unsigned encoding, uint64_t *retval)
13199{
13200 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);
13201}
13202
13203/* This function will dissect a sequence of bytes that describe a
13204 * bitmask.
13205 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13206 * to be dissected.
13207 * This field will form an expansion under which the individual fields of the
13208 * bitmask is dissected and displayed.
13209 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13210 *
13211 * fields is an array of pointers to int that lists all the fields of the
13212 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13213 * or another integer of the same type/size as hf_hdr with a mask specified.
13214 * This array is terminated by a NULL entry.
13215 *
13216 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13217 * FT_integer fields that have a value_string attached will have the
13218 * matched string displayed on the expansion line.
13219 */
13220proto_item *
13221proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13222 const unsigned offset, const int hf_hdr,
13223 const int ett, int * const *fields,
13224 const unsigned encoding)
13225{
13226 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13227}
13228
13229/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13230 * what data is appended to the header.
13231 */
13232proto_item *
13233proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13234 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13235 uint64_t *retval)
13236{
13237 proto_item *item = NULL((void*)0);
13238 header_field_info *hf;
13239 int len;
13240 uint64_t value;
13241
13242 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", 13242, __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", 13242
, "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", 13242, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13243 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", 13243, (hf)->abbrev)))
;
13244 len = ftype_wire_size(hf->type);
13245 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13246
13247 if (parent_tree) {
13248 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13249 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13250 flags, false0, false0, NULL((void*)0), value);
13251 }
13252
13253 *retval = value;
13254 if (hf->bitmask) {
13255 /* Mask out irrelevant portions */
13256 *retval &= hf->bitmask;
13257 /* Shift bits */
13258 *retval >>= hfinfo_bitshift(hf);
13259 }
13260
13261 return item;
13262}
13263
13264/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13265 * what data is appended to the header.
13266 */
13267proto_item *
13268proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13269 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13270{
13271 proto_item *item = NULL((void*)0);
13272 header_field_info *hf;
13273 int len;
13274 uint64_t value;
13275
13276 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", 13276, __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", 13276
, "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", 13276, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13277 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", 13277, (hf)->abbrev)))
;
13278
13279 if (parent_tree) {
13280 len = ftype_wire_size(hf->type);
13281 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13282 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13283 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13284 flags, false0, false0, NULL((void*)0), value);
13285 }
13286
13287 return item;
13288}
13289
13290/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13291 can't be retrieved directly from tvb) */
13292proto_item *
13293proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13294 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13295{
13296 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13297 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13298}
13299
13300/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13301WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13302proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13303 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13304{
13305 proto_item *item = NULL((void*)0);
13306 header_field_info *hf;
13307 int len;
13308
13309 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", 13309, __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", 13309
, "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", 13309, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13310 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", 13310, (hf)->abbrev)))
;
13311 /* the proto_tree_add_uint/_uint64() calls below
13312 will fail if tvb==NULL and len!=0 */
13313 len = tvb ? ftype_wire_size(hf->type) : 0;
13314
13315 if (parent_tree) {
13316 if (len <= 4)
13317 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13318 else
13319 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13320
13321 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13322 flags, false0, false0, NULL((void*)0), value);
13323 }
13324
13325 return item;
13326}
13327
13328/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13329void
13330proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13331 const int len, int * const *fields, const unsigned encoding)
13332{
13333 uint64_t value;
13334
13335 if (tree) {
13336 value = get_uint64_value(tree, tvb, offset, len, encoding);
13337 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13338 BMT_NO_APPEND0x01, false0, true1, tree, value);
13339 }
13340}
13341
13342WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13343proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13344 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13345{
13346 uint64_t value;
13347
13348 value = get_uint64_value(tree, tvb, offset, len, encoding);
13349 if (tree) {
13350 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13351 BMT_NO_APPEND0x01, false0, true1, tree, value);
13352 }
13353 if (retval) {
13354 *retval = value;
13355 }
13356}
13357
13358WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13359proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13360 const int len, int * const *fields, const uint64_t value)
13361{
13362 if (tree) {
13363 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13364 BMT_NO_APPEND0x01, false0, true1, tree, value);
13365 }
13366}
13367
13368
13369/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13370 * This is intended to support bitmask fields whose lengths can vary, perhaps
13371 * as the underlying standard evolves over time.
13372 * With this API there is the possibility of being called to display more or
13373 * less data than the dissector was coded to support.
13374 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13375 * Thus when presented with "too much" or "too little" data, MSbits will be
13376 * ignored or MSfields sacrificed.
13377 *
13378 * Only fields for which all defined bits are available are displayed.
13379 */
13380proto_item *
13381proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13382 const unsigned offset, const unsigned len, const int hf_hdr,
13383 const int ett, int * const *fields, struct expert_field* exp,
13384 const unsigned encoding)
13385{
13386 proto_item *item = NULL((void*)0);
13387 header_field_info *hf;
13388 unsigned decodable_len;
13389 unsigned decodable_offset;
13390 uint32_t decodable_value;
13391 uint64_t value;
13392
13393 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", 13393, __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", 13393
, "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", 13393, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13394 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", 13394, (hf)->abbrev)))
;
13395
13396 decodable_offset = offset;
13397 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13398
13399 /* If we are ftype_wire_size-limited,
13400 * make sure we decode as many LSBs as possible.
13401 */
13402 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13403 decodable_offset += (len - decodable_len);
13404 }
13405
13406 if (parent_tree) {
13407 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13408 decodable_len, encoding);
13409
13410 /* The root item covers all the bytes even if we can't decode them all */
13411 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13412 decodable_value);
13413 }
13414
13415 if (decodable_len < len) {
13416 /* Dissector likely requires updating for new protocol revision */
13417 expert_add_info_format(NULL((void*)0), item, exp,
13418 "Only least-significant %d of %d bytes decoded",
13419 decodable_len, len);
13420 }
13421
13422 if (item) {
13423 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13424 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13425 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13426 }
13427
13428 return item;
13429}
13430
13431/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13432proto_item *
13433proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13434 const unsigned offset, const unsigned len,
13435 const char *name, const char *fallback,
13436 const int ett, int * const *fields,
13437 const unsigned encoding, const int flags)
13438{
13439 proto_item *item = NULL((void*)0);
13440 uint64_t value;
13441
13442 if (parent_tree) {
13443 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13444 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13445 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13446 flags, true1, false0, NULL((void*)0), value) && fallback) {
13447 /* Still at first item - append 'fallback' text if any */
13448 proto_item_append_text(item, "%s", fallback);
13449 }
13450 }
13451
13452 return item;
13453}
13454
13455proto_item *
13456proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13457 const unsigned bit_offset, const int no_of_bits,
13458 const unsigned encoding)
13459{
13460 header_field_info *hfinfo;
13461 int octet_length;
13462 int octet_offset;
13463
13464 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", 13464, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13464
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13464, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13465
13466 if (no_of_bits < 0) {
13467 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13468 }
13469 octet_length = (no_of_bits + 7) >> 3;
13470 octet_offset = bit_offset >> 3;
13471 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13472
13473 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13474 * but only after doing a bunch more work (which we can, in the common
13475 * case, shortcut here).
13476 */
13477 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13478 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", 13478
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13478, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13478, "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", 13478, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13479
13480 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13481}
13482
13483/*
13484 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13485 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13486 * Offset should be given in bits from the start of the tvb.
13487 */
13488
13489static proto_item *
13490_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13491 const unsigned bit_offset, const int no_of_bits,
13492 uint64_t *return_value, const unsigned encoding)
13493{
13494 int offset;
13495 unsigned length;
13496 uint8_t tot_no_bits;
13497 char *bf_str;
13498 char lbl_str[ITEM_LABEL_LENGTH240];
13499 uint64_t value = 0;
13500 uint8_t *bytes = NULL((void*)0);
13501 size_t bytes_length = 0;
13502
13503 proto_item *pi;
13504 header_field_info *hf_field;
13505
13506 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13507 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", 13507, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13507
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13507, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13508
13509 if (hf_field->bitmask != 0) {
13510 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)
13511 " 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)
13512 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)
;
13513 }
13514
13515 if (no_of_bits < 0) {
13516 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13517 } else if (no_of_bits == 0) {
13518 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)
13519 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)
;
13520 }
13521
13522 /* Byte align offset */
13523 offset = bit_offset>>3;
13524
13525 /*
13526 * Calculate the number of octets used to hold the bits
13527 */
13528 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13529 length = (tot_no_bits + 7) >> 3;
13530
13531 if (no_of_bits < 65) {
13532 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13533 } else if (hf_field->type != FT_BYTES) {
13534 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)
13535 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)
;
13536 return NULL((void*)0);
13537 }
13538
13539 /* Sign extend for signed types */
13540 switch (hf_field->type) {
13541 case FT_INT8:
13542 case FT_INT16:
13543 case FT_INT24:
13544 case FT_INT32:
13545 case FT_INT40:
13546 case FT_INT48:
13547 case FT_INT56:
13548 case FT_INT64:
13549 value = ws_sign_ext64(value, no_of_bits);
13550 break;
13551
13552 default:
13553 break;
13554 }
13555
13556 if (return_value) {
13557 *return_value = value;
13558 }
13559
13560 /* Coast clear. Try and fake it */
13561 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13562 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", 13562
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13562, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13562, "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", 13562, __func__, "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); } } }
;
13563
13564 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13565
13566 switch (hf_field->type) {
13567 case FT_BOOLEAN:
13568 /* Boolean field */
13569 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13570 "%s = %s: %s",
13571 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13572 break;
13573
13574 case FT_CHAR:
13575 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13576 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13577 break;
13578
13579 case FT_UINT8:
13580 case FT_UINT16:
13581 case FT_UINT24:
13582 case FT_UINT32:
13583 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13584 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13585 break;
13586
13587 case FT_INT8:
13588 case FT_INT16:
13589 case FT_INT24:
13590 case FT_INT32:
13591 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13592 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13593 break;
13594
13595 case FT_UINT40:
13596 case FT_UINT48:
13597 case FT_UINT56:
13598 case FT_UINT64:
13599 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13600 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13601 break;
13602
13603 case FT_INT40:
13604 case FT_INT48:
13605 case FT_INT56:
13606 case FT_INT64:
13607 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13608 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13609 break;
13610
13611 case FT_BYTES:
13612 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13613 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13614 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13615 proto_item_set_text(pi, "%s", lbl_str);
13616 return pi;
13617
13618 /* TODO: should handle FT_UINT_BYTES ? */
13619
13620 default:
13621 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))
13622 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))
13623 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))
13624 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))
;
13625 return NULL((void*)0);
13626 }
13627
13628 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13629 return pi;
13630}
13631
13632proto_item *
13633proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13634 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13635 uint64_t *return_value)
13636{
13637 proto_item *pi;
13638 int no_of_bits;
13639 int octet_offset;
13640 unsigned mask_initial_bit_offset;
13641 unsigned mask_greatest_bit_offset;
13642 unsigned octet_length;
13643 uint8_t i;
13644 char bf_str[256];
13645 char lbl_str[ITEM_LABEL_LENGTH240];
13646 uint64_t value;
13647 uint64_t composite_bitmask;
13648 uint64_t composite_bitmap;
13649
13650 header_field_info *hf_field;
13651
13652 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13653 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", 13653, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13653
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13653, "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
13654
13655 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13656 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)
13657 " 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)
13658 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)
;
13659 }
13660
13661 mask_initial_bit_offset = bit_offset % 8;
13662
13663 no_of_bits = 0;
13664 value = 0;
13665 i = 0;
13666 mask_greatest_bit_offset = 0;
13667 composite_bitmask = 0;
13668 composite_bitmap = 0;
13669
13670 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
13671 uint64_t crumb_mask, crumb_value;
13672 uint8_t crumb_end_bit_offset;
13673
13674 crumb_value = tvb_get_bits64(tvb,
13675 bit_offset + crumb_spec[i].crumb_bit_offset,
13676 crumb_spec[i].crumb_bit_length,
13677 ENC_BIG_ENDIAN0x00000000);
13678 value += crumb_value;
13679 no_of_bits += crumb_spec[i].crumb_bit_length;
13680 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", 13680
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13681
13682 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13683 octet containing the initial offset.
13684 If the mask is beyond 32 bits, then give up on bit map display.
13685 This could be improved in future, probably showing a table
13686 of 32 or 64 bits per row */
13687 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13688 crumb_end_bit_offset = mask_initial_bit_offset
13689 + crumb_spec[i].crumb_bit_offset
13690 + crumb_spec[i].crumb_bit_length;
13691 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'
13692
13693 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13694 mask_greatest_bit_offset = crumb_end_bit_offset;
13695 }
13696 /* Currently the bitmap of the crumbs are only shown if
13697 * smaller than 32 bits. Do not bother calculating the
13698 * mask if it is larger than that. */
13699 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13700 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'
13701 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13702 }
13703 }
13704 /* Shift left for the next segment */
13705 value <<= crumb_spec[++i].crumb_bit_length;
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 default:
13721 break;
13722 }
13723
13724 if (return_value) {
13725 *return_value = value;
13726 }
13727
13728 /* Coast clear. Try and fake it */
13729 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13730 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", 13730
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13730, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13730, "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", 13730, __func__, "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); } } }
;
13731
13732 /* initialise the format string */
13733 bf_str[0] = '\0';
13734
13735 octet_offset = bit_offset >> 3;
13736
13737 /* Round up mask length to nearest octet */
13738 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13739 mask_greatest_bit_offset = octet_length << 3;
13740
13741 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13742 It would be a useful enhancement to eliminate this restriction. */
13743 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13744 other_decode_bitfield_value(bf_str,
13745 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13746 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13747 mask_greatest_bit_offset);
13748 } else {
13749 /* If the bitmask is too large, try to describe its contents. */
13750 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13751 }
13752
13753 switch (hf_field->type) {
13754 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13755 /* Boolean field */
13756 return proto_tree_add_boolean_format(tree, hfindex,
13757 tvb, octet_offset, octet_length, value,
13758 "%s = %s: %s",
13759 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13760 break;
13761
13762 case FT_CHAR:
13763 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13764 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13765 break;
13766
13767 case FT_UINT8:
13768 case FT_UINT16:
13769 case FT_UINT24:
13770 case FT_UINT32:
13771 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13772 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13773 break;
13774
13775 case FT_INT8:
13776 case FT_INT16:
13777 case FT_INT24:
13778 case FT_INT32:
13779 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13780 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13781 break;
13782
13783 case FT_UINT40:
13784 case FT_UINT48:
13785 case FT_UINT56:
13786 case FT_UINT64:
13787 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13788 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13789 break;
13790
13791 case FT_INT40:
13792 case FT_INT48:
13793 case FT_INT56:
13794 case FT_INT64:
13795 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13796 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13797 break;
13798
13799 default:
13800 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))
13801 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))
13802 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))
13803 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))
;
13804 return NULL((void*)0);
13805 }
13806 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13807 return pi;
13808}
13809
13810void
13811proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13812 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13813{
13814 header_field_info *hfinfo;
13815 int start = bit_offset >> 3;
13816 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13817
13818 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13819 * so that we can use the tree's memory scope in calculating the string */
13820 if (length == -1) {
13821 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13822 } else {
13823 tvb_ensure_bytes_exist(tvb, start, length);
13824 }
13825 if (!tree) return;
13826
13827 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", 13827, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13827
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13827, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13828 proto_tree_add_text_internal(tree, tvb, start, length,
13829 "%s crumb %d of %s (decoded above)",
13830 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13831 tvb_get_bits32(tvb,
13832 bit_offset,
13833 crumb_spec[crumb_index].crumb_bit_length,
13834 ENC_BIG_ENDIAN0x00000000),
13835 ENC_BIG_ENDIAN0x00000000),
13836 crumb_index,
13837 hfinfo->name);
13838}
13839
13840proto_item *
13841proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13842 const unsigned bit_offset, const int no_of_bits,
13843 uint64_t *return_value, const unsigned encoding)
13844{
13845 proto_item *item;
13846
13847 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13848 bit_offset, no_of_bits,
13849 return_value, encoding))) {
13850 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)
;
13851 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)
;
13852 }
13853 return item;
13854}
13855
13856static proto_item *
13857_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13858 tvbuff_t *tvb, const unsigned bit_offset,
13859 const int no_of_bits, void *value_ptr,
13860 const unsigned encoding, char *value_str)
13861{
13862 int offset;
13863 unsigned length;
13864 uint8_t tot_no_bits;
13865 char *str;
13866 uint64_t value = 0;
13867 header_field_info *hf_field;
13868
13869 /* We do not have to return a value, try to fake it as soon as possible */
13870 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13871 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", 13871
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13871, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13871, "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", 13871, __func__, "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); } } }
;
13872
13873 if (hf_field->bitmask != 0) {
13874 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)
13875 " 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)
13876 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)
;
13877 }
13878
13879 if (no_of_bits < 0) {
13880 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13881 } else if (no_of_bits == 0) {
13882 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)
13883 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)
;
13884 }
13885
13886 /* Byte align offset */
13887 offset = bit_offset>>3;
13888
13889 /*
13890 * Calculate the number of octets used to hold the bits
13891 */
13892 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13893 length = tot_no_bits>>3;
13894 /* If we are using part of the next octet, increase length by 1 */
13895 if (tot_no_bits & 0x07)
13896 length++;
13897
13898 if (no_of_bits < 65) {
13899 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13900 } else {
13901 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)
13902 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)
;
13903 return NULL((void*)0);
13904 }
13905
13906 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13907
13908 (void) g_strlcat(str, " = ", 256+64);
13909 (void) g_strlcat(str, hf_field->name, 256+64);
13910
13911 /*
13912 * This function does not receive an actual value but a dimensionless pointer to that value.
13913 * For this reason, the type of the header field is examined in order to determine
13914 * what kind of value we should read from this address.
13915 * The caller of this function must make sure that for the specific header field type the address of
13916 * a compatible value is provided.
13917 */
13918 switch (hf_field->type) {
13919 case FT_BOOLEAN:
13920 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13921 "%s: %s", str, value_str);
13922 break;
13923
13924 case FT_CHAR:
13925 case FT_UINT8:
13926 case FT_UINT16:
13927 case FT_UINT24:
13928 case FT_UINT32:
13929 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13930 "%s: %s", str, value_str);
13931 break;
13932
13933 case FT_UINT40:
13934 case FT_UINT48:
13935 case FT_UINT56:
13936 case FT_UINT64:
13937 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13938 "%s: %s", str, value_str);
13939 break;
13940
13941 case FT_INT8:
13942 case FT_INT16:
13943 case FT_INT24:
13944 case FT_INT32:
13945 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13946 "%s: %s", str, value_str);
13947 break;
13948
13949 case FT_INT40:
13950 case FT_INT48:
13951 case FT_INT56:
13952 case FT_INT64:
13953 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13954 "%s: %s", str, value_str);
13955 break;
13956
13957 case FT_FLOAT:
13958 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13959 "%s: %s", str, value_str);
13960 break;
13961
13962 default:
13963 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))
13964 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))
13965 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))
13966 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))
;
13967 return NULL((void*)0);
13968 }
13969}
13970
13971static proto_item *
13972proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13973 tvbuff_t *tvb, const unsigned bit_offset,
13974 const int no_of_bits, void *value_ptr,
13975 const unsigned encoding, char *value_str)
13976{
13977 proto_item *item;
13978
13979 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13980 tvb, bit_offset, no_of_bits,
13981 value_ptr, encoding, value_str))) {
13982 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)
;
13983 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)
;
13984 }
13985 return item;
13986}
13987
13988#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);
\
13989 va_start(ap, format)__builtin_va_start(ap, format); \
13990 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13991 va_end(ap)__builtin_va_end(ap);
13992
13993proto_item *
13994proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13995 tvbuff_t *tvb, const unsigned bit_offset,
13996 const int no_of_bits, uint32_t value,
13997 const unsigned encoding,
13998 const char *format, ...)
13999{
14000 va_list ap;
14001 char *dst;
14002 header_field_info *hf_field;
14003
14004 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14005
14006 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", 14006
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14006, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14006, "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", 14006, __func__, "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); } } }
;
14007
14008 switch (hf_field->type) {
14009 case FT_UINT8:
14010 case FT_UINT16:
14011 case FT_UINT24:
14012 case FT_UINT32:
14013 break;
14014
14015 default:
14016 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)
14017 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)
;
14018 return NULL((void*)0);
14019 }
14020
14021 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);
;
14022
14023 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14024}
14025
14026proto_item *
14027proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14028 tvbuff_t *tvb, const unsigned bit_offset,
14029 const int no_of_bits, uint64_t value,
14030 const unsigned encoding,
14031 const char *format, ...)
14032{
14033 va_list ap;
14034 char *dst;
14035 header_field_info *hf_field;
14036
14037 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14038
14039 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", 14039
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14039, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14039, "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", 14039, __func__, "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); } } }
;
14040
14041 switch (hf_field->type) {
14042 case FT_UINT40:
14043 case FT_UINT48:
14044 case FT_UINT56:
14045 case FT_UINT64:
14046 break;
14047
14048 default:
14049 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)
14050 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)
;
14051 return NULL((void*)0);
14052 }
14053
14054 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);
;
14055
14056 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14057}
14058
14059proto_item *
14060proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14061 tvbuff_t *tvb, const unsigned bit_offset,
14062 const int no_of_bits, float value,
14063 const unsigned encoding,
14064 const char *format, ...)
14065{
14066 va_list ap;
14067 char *dst;
14068 header_field_info *hf_field;
14069
14070 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14071
14072 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", 14072
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14072, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14072, "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", 14072, __func__, "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); } } }
;
14073
14074 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",
14074, ((hf_field))->abbrev))))
;
14075
14076 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);
;
14077
14078 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14079}
14080
14081proto_item *
14082proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14083 tvbuff_t *tvb, const unsigned bit_offset,
14084 const int no_of_bits, int32_t value,
14085 const unsigned encoding,
14086 const char *format, ...)
14087{
14088 va_list ap;
14089 char *dst;
14090 header_field_info *hf_field;
14091
14092 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14093
14094 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", 14094
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14094, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14094, "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", 14094, __func__, "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); } } }
;
14095
14096 switch (hf_field->type) {
14097 case FT_INT8:
14098 case FT_INT16:
14099 case FT_INT24:
14100 case FT_INT32:
14101 break;
14102
14103 default:
14104 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)
14105 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)
;
14106 return NULL((void*)0);
14107 }
14108
14109 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);
;
14110
14111 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14112}
14113
14114proto_item *
14115proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14116 tvbuff_t *tvb, const unsigned bit_offset,
14117 const int no_of_bits, int64_t value,
14118 const unsigned encoding,
14119 const char *format, ...)
14120{
14121 va_list ap;
14122 char *dst;
14123 header_field_info *hf_field;
14124
14125 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14126
14127 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", 14127
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14127, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14127, "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", 14127, __func__, "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); } } }
;
14128
14129 switch (hf_field->type) {
14130 case FT_INT40:
14131 case FT_INT48:
14132 case FT_INT56:
14133 case FT_INT64:
14134 break;
14135
14136 default:
14137 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)
14138 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)
;
14139 return NULL((void*)0);
14140 }
14141
14142 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);
;
14143
14144 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14145}
14146
14147proto_item *
14148proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14149 tvbuff_t *tvb, const unsigned bit_offset,
14150 const int no_of_bits, uint64_t value,
14151 const unsigned encoding,
14152 const char *format, ...)
14153{
14154 va_list ap;
14155 char *dst;
14156 header_field_info *hf_field;
14157
14158 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14159
14160 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", 14160
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14160, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14160, "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", 14160, __func__, "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); } } }
;
14161
14162 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"
, 14162, ((hf_field))->abbrev))))
;
14163
14164 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);
;
14165
14166 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14167}
14168
14169proto_item *
14170proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14171 const unsigned bit_offset, const int no_of_chars)
14172{
14173 proto_item *pi;
14174 header_field_info *hfinfo;
14175 int byte_length;
14176 int byte_offset;
14177 char *string;
14178
14179 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14180
14181 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", 14181
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14181, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14181, "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", 14181, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14182
14183 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"
, 14183, ((hfinfo))->abbrev))))
;
14184
14185 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14186 byte_offset = bit_offset >> 3;
14187
14188 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14189
14190 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14191 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14191, "byte_length >= 0"
))))
;
14192 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14193
14194 return pi;
14195}
14196
14197proto_item *
14198proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14199 const unsigned bit_offset, const int no_of_chars)
14200{
14201 proto_item *pi;
14202 header_field_info *hfinfo;
14203 int byte_length;
14204 int byte_offset;
14205 char *string;
14206
14207 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14208
14209 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", 14209
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14209, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 14209, "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", 14209, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
14210
14211 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"
, 14211, ((hfinfo))->abbrev))))
;
14212
14213 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14214 byte_offset = bit_offset >> 3;
14215
14216 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14217
14218 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14219 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14219, "byte_length >= 0"
))))
;
14220 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14221
14222 return pi;
14223}
14224
14225const value_string proto_checksum_vals[] = {
14226 { PROTO_CHECKSUM_E_BAD, "Bad" },
14227 { PROTO_CHECKSUM_E_GOOD, "Good" },
14228 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14229 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14230 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14231
14232 { 0, NULL((void*)0) }
14233};
14234
14235#define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14236
14237proto_item *
14238proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14239 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14240 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14241{
14242 header_field_info *hfinfo;
14243 uint32_t checksum;
14244 uint32_t len;
14245 proto_item* ti = NULL((void*)0);
14246 proto_item* ti2;
14247 bool_Bool incorrect_checksum = true1;
14248
14249 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", 14249, __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", 14249
, "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", 14249, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14250
14251 switch (hfinfo->type) {
14252 case FT_UINT8:
14253 len = 1;
14254 break;
14255 case FT_UINT16:
14256 len = 2;
14257 break;
14258 case FT_UINT24:
14259 len = 3;
14260 break;
14261 case FT_UINT32:
14262 len = 4;
14263 break;
14264 default:
14265 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)
14266 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14267 }
14268
14269 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14270 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14271 proto_item_set_generated(ti);
14272 // Backward compatible with use of -1
14273 if (hf_checksum_status > 0) {
14274 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14275 proto_item_set_generated(ti2);
14276 }
14277 return ti;
14278 }
14279
14280 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14281 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14282 proto_item_set_generated(ti);
14283 } else {
14284 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14285 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14286 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14287 if (computed_checksum == 0) {
14288 proto_item_append_text(ti, " [correct]");
14289 // Backward compatible with use of -1
14290 if (hf_checksum_status > 0) {
14291 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14292 proto_item_set_generated(ti2);
14293 }
14294 incorrect_checksum = false0;
14295 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14296 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14297 /* XXX - This can't distinguish between "shouldbe"
14298 * 0x0000 and 0xFFFF unless we know whether there
14299 * were any nonzero bits (other than the checksum).
14300 * Protocols should not use this path if they might
14301 * have an all zero packet.
14302 * Some implementations put the wrong zero; maybe
14303 * we should have a special expert info for that?
14304 */
14305 }
14306 } else {
14307 if (checksum == computed_checksum) {
14308 proto_item_append_text(ti, " [correct]");
14309 // Backward compatible with use of -1
14310 if (hf_checksum_status > 0) {
14311 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14312 proto_item_set_generated(ti2);
14313 }
14314 incorrect_checksum = false0;
14315 }
14316 }
14317
14318 if (incorrect_checksum) {
14319 // Backward compatible with use of -1
14320 if (hf_checksum_status > 0) {
14321 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14322 proto_item_set_generated(ti2);
14323 }
14324 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14325 proto_item_append_text(ti, " [incorrect]");
14326 if (bad_checksum_expert != NULL((void*)0))
14327 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14328 } else {
14329 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14330 if (bad_checksum_expert != NULL((void*)0))
14331 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);
14332 }
14333 }
14334 } else {
14335 // Backward compatible with use of -1
14336 if (hf_checksum_status > 0) {
14337 proto_item_append_text(ti, " [unverified]");
14338 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14339 proto_item_set_generated(ti2);
14340 }
14341 }
14342 }
14343
14344 return ti;
14345}
14346
14347proto_item *
14348proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14349 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14350 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14351{
14352 header_field_info *hfinfo;
14353 uint8_t *checksum = NULL((void*)0);
14354 proto_item* ti = NULL((void*)0);
14355 proto_item* ti2;
14356 bool_Bool incorrect_checksum = true1;
14357
14358 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", 14358, __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", 14358
, "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", 14358, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14359
14360 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",
14360, ((hfinfo))->abbrev))))
;
14361
14362 /* Make sure a NULL computed_checksum isn't dereferenced.
14363 * If checksum_len is 0 it probably won't crash, but in the VERIFY
14364 * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14365 * cases the behavior is unexpected and still a programmer error;
14366 * proto_tree_add_bytes retrieves it from the tvb, thus neither
14367 * _NOT_PRESENT nor _GENERATED is correct.
14368 */
14369 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", 14369, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)"
))))
;
14370
14371 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14372 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14373 proto_item_set_generated(ti);
14374 // Backward compatible with use of -1
14375 if (hf_checksum_status > 0) {
14376 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14377 proto_item_set_generated(ti2);
14378 }
14379 return ti;
14380 }
14381
14382 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14383 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14384 proto_item_set_generated(ti);
14385 return ti;
14386 }
14387
14388 checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14389 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14390 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14391 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14392 bool_Bool non_zero_flag = false0;
14393 for (size_t index = 0; index < checksum_len; index++) {
14394 if (computed_checksum[index]) {
14395 non_zero_flag = true1;
14396 break;
14397 }
14398 }
14399 if (!non_zero_flag) {
14400 proto_item_append_text(ti, " [correct]");
14401 // Backward compatible with use of -1
14402 if (hf_checksum_status > 0) {
14403 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14404 proto_item_set_generated(ti2);
14405 }
14406 incorrect_checksum = false0;
14407 }
14408 } else {
14409 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14410 proto_item_append_text(ti, " [correct]");
14411 // Backward compatible with use of -1
14412 if (hf_checksum_status > 0) {
14413 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14414 proto_item_set_generated(ti2);
14415 }
14416 incorrect_checksum = false0;
14417 }
14418 }
14419
14420 if (incorrect_checksum) {
14421 // Backward compatible with use of -1
14422 if (hf_checksum_status > 0) {
14423 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14424 proto_item_set_generated(ti2);
14425 }
14426 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14427 proto_item_append_text(ti, " [incorrect]");
14428 if (bad_checksum_expert != NULL((void*)0))
14429 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14430 } else {
14431 char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14432 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14433 if (bad_checksum_expert != NULL((void*)0))
14434 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14435 }
14436 }
14437 } else {
14438 // Backward compatible with use of -1
14439 if (hf_checksum_status > 0) {
14440 proto_item_append_text(ti, " [unverified]");
14441 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14442 proto_item_set_generated(ti2);
14443 }
14444 }
14445
14446 return ti;
14447}
14448
14449unsigned char
14450proto_check_field_name(const char *field_name)
14451{
14452 return module_check_valid_name(field_name, false0);
14453}
14454
14455unsigned char
14456proto_check_field_name_lower(const char *field_name)
14457{
14458 return module_check_valid_name(field_name, true1);
14459}
14460
14461bool_Bool
14462tree_expanded(int tree_type)
14463{
14464 if (tree_type <= 0) {
14465 return false0;
14466 }
14467 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", 14467, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14468 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14469}
14470
14471void
14472tree_expanded_set(int tree_type, bool_Bool value)
14473{
14474 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", 14474, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14475
14476 if (value)
14477 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14478 else
14479 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14480}
14481
14482/*
14483 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14484 *
14485 * Local variables:
14486 * c-basic-offset: 8
14487 * tab-width: 8
14488 * indent-tabs-mode: t
14489 * End:
14490 *
14491 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14492 * :indentSize=8:tabSize=8:noTabs=false:
14493 */