Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13461, 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-18/lib/clang/18 -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/libxml2 -isystem /usr/include/lua5.4 -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-truncation -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -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 -dwarf-debug-flags /usr/lib/llvm-18/bin/clang -### --analyze -x c -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 -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/libxml2 -isystem /usr/include/lua5.4 -fvisibility=hidden -fexcess-precision=fast -fstrict-flex-arrays=3 -fstack-clash-protection -fcf-protection=full -D _GLIBCXX_ASSERTIONS -fstack-protector-strong -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fexceptions -Wno-format-truncation -Wno-format-nonliteral -fdiagnostics-color=always -Wno-pointer-sign -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -std=gnu11 -fPIC /builds/wireshark/wireshark/epan/proto.c -o /builds/wireshark/wireshark/sbout/2025-06-26-100304-3847-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-06-26-100304-3847-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30
31#include <ftypes/ftypes.h>
32
33#include "packet.h"
34#include "exceptions.h"
35#include "ptvcursor.h"
36#include "strutil.h"
37#include "addr_resolv.h"
38#include "address_types.h"
39#include "oids.h"
40#include "proto.h"
41#include "epan_dissect.h"
42#include "dfilter/dfilter.h"
43#include "tvbuff.h"
44#include "charsets.h"
45#include "column-info.h"
46#include "to_str.h"
47#include "osi-utils.h"
48#include "expert.h"
49#include "show_exception.h"
50#include "in_cksum.h"
51#include "register-int.h"
52
53#include <wsutil/crash_info.h>
54#include <wsutil/epochs.h>
55
56/* Ptvcursor limits */
57#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
58#define SUBTREE_MAX_LEVELS256 256
59
60typedef struct __subtree_lvl {
61 int cursor_offset;
62 proto_item *it;
63 proto_tree *tree;
64} subtree_lvl;
65
66struct ptvcursor {
67 wmem_allocator_t *scope;
68 subtree_lvl *pushed_tree;
69 uint8_t pushed_tree_index;
70 uint8_t pushed_tree_max;
71 proto_tree *tree;
72 tvbuff_t *tvb;
73 int offset;
74};
75
76#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
77
78/** See inlined comments.
79 @param tree the tree to append this item to
80 @param free_block a code block to call to free resources if this returns
81 @return NULL if 'tree' is null */
82#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
83 if (!tree) { \
84 free_block; \
85 return NULL((void*)0); \
86 }
87
88/** See inlined comments.
89 @param tree the tree to append this item to
90 @return NULL if 'tree' is null */
91#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
92 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
93
94/** See inlined comments.
95 @param length the length of this item
96 @param cleanup_block a code block to call to free resources if this returns
97 @return NULL if 'length' is lower -1 or equal 0 */
98#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
99 if (length < -1 || length == 0 ) { \
100 cleanup_block; \
101 return NULL((void*)0); \
102 }
103
104/** See inlined comments.
105 @param length the length of this item
106 @return NULL if 'length' is lower -1 or equal 0 */
107#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
108 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
109
110/** See inlined comments.
111 @param tree the tree to append this item to
112 @param hfindex field index
113 @param hfinfo header_field
114 @param free_block a code block to call to free resources if this returns
115 @return the header field matching 'hfinfo' */
116#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", 116
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 116, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 116, "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", 116, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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
); } } }
\
117 /* If the tree is not visible and this item is not referenced \
118 we don't have to do much work at all but we should still \
119 return a node so that referenced field items below this node \
120 (think proto_item_add_subtree()) will still have somewhere \
121 to attach to or else filtering will not work (they would be \
122 ignored since tree would be NULL). \
123 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
124 because that means we can change its length or repr, and we \
125 don't want to do so with calls intended for this faked new \
126 item, so this item needs a new (hidden) child node. \
127 We fake FT_PROTOCOL unless some clients have requested us \
128 not to do so. \
129 */ \
130 PTREE_DATA(tree)((tree)->tree_data)->count++; \
131 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", 131, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 131, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 131, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
132 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
133 free_block; \
134 if (wireshark_abort_on_too_many_items) \
135 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", 136
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
136 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 136
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
137 /* Let the exception handler add items to the tree */ \
138 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
139 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)))
140 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)))
141 "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)))
142 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)))
; \
143 } \
144 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
145 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
146 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
147 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
148 && (hfinfo->type != FT_PROTOCOL || \
149 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
150 free_block; \
151 /* return fake node with no field info */\
152 return proto_tree_add_fake_node(tree, hfinfo); \
153 } \
154 } \
155 }
156
157/** See inlined comments.
158 @param tree the tree to append this item to
159 @param hfindex field index
160 @param hfinfo header_field
161 @return the header field matching 'hfinfo' */
162#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", 162
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 162, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 162, "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", 162, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
\
163 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", 163
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 163, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 163, "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", 163, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
164
165
166/** See inlined comments.
167 @param pi the created protocol item we're about to return */
168#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 168, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
169 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 169, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
170 if (!PITEM_FINFO(pi)((pi)->finfo)) \
171 return pi; \
172 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
173 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
174 /* If the tree (GUI) or item isn't visible it's pointless for \
175 * us to generate the protocol item's string representation */ \
176 return pi; \
177 }
178/* Same as above but returning void */
179#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
180 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
181 return; \
182 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
183 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
184 /* If the tree (GUI) or item isn't visible it's pointless for \
185 * us to generate the protocol item's string representation */ \
186 return; \
187 }
188/* Similar to above, but allows a NULL tree */
189#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; }
\
190 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
191 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
192 /* If the tree (GUI) or item isn't visible it's pointless for \
193 * us to generate the protocol item's string representation */ \
194 return pi; \
195 }
196
197#ifdef ENABLE_CHECK_FILTER
198#define CHECK_HF_VALUE(type, spec, start_values) \
199{ \
200 const type *current; \
201 int n, m; \
202 current = start_values; \
203 for (n=0; current; n++, current++) { \
204 /* Drop out if we reached the end. */ \
205 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
206 break; \
207 } \
208 /* Check value against all previous */ \
209 for (m=0; m < n; m++) { \
210 /* There are lots of duplicates with the same string, \
211 so only report if different... */ \
212 if ((start_values[m].value == current->value) && \
213 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
214 ws_warning("Field '%s' (%s) has a conflicting entry in its" \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 217, __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); } } while (0)
215 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 217, __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); } } while (0)
216 hfinfo->name, hfinfo->abbrev, \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 217, __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); } } while (0)
217 current->value, m, start_values[m].strptr, n, current->strptr)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 217, __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); } } while (0)
; \
218 } \
219 } \
220 } \
221}
222#endif
223
224/* The longest NUMBER-like field label we have is for BASE_OUI, which
225 * can have up to 64 bytes for the manufacturer name if resolved plus
226 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
227 */
228#define NUMBER_LABEL_LENGTH80 80
229
230static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
231static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
232static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
233static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
234static int hfinfo_bitoffset(const header_field_info *hfinfo);
235static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
236static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
237
238#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
239 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
240
241static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
242static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
243#define LABEL_MARK_TRUNCATED_START(label_str, value_pos)label_mark_truncated(label_str, 0, value_pos) label_mark_truncated(label_str, 0, value_pos)
244
245static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
246static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
247static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
248static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
249static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252
253static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
254static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
255static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
256static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
257
258static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
259static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
260static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
261static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
264static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
265static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
266static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
267static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
268
269static void proto_cleanup_base(void);
270
271static proto_item *
272proto_tree_add_node(proto_tree *tree, field_info *fi);
273
274static proto_item *
275proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
276
277static void
278get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
279 int *item_length, const unsigned encoding);
280
281static int
282get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
283 int length, unsigned item_length, const int encoding);
284
285static field_info *
286new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
287 const int start, const int item_length);
288
289static proto_item *
290proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
291 int start, int *length);
292
293static void
294proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
295static void
296proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
297
298static void
299proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
300static void
301proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
302static void
303proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
304static void
305proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
306static void
307proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
308static void
309proto_tree_set_string(field_info *fi, const char* value);
310static void
311proto_tree_set_ax25(field_info *fi, const uint8_t* value);
312static void
313proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
314static void
315proto_tree_set_vines(field_info *fi, const uint8_t* value);
316static void
317proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
318static void
319proto_tree_set_ether(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_ipxnet(field_info *fi, uint32_t value);
324static void
325proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
326static void
327proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
328static void
329proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
330static void
331proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
332static void
333proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
334static void
335proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
336static void
337proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
338static void
339proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
340static void
341proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
342static void
343proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
344static void
345proto_tree_set_boolean(field_info *fi, uint64_t value);
346static void
347proto_tree_set_float(field_info *fi, float value);
348static void
349proto_tree_set_double(field_info *fi, double value);
350static void
351proto_tree_set_uint(field_info *fi, uint32_t value);
352static void
353proto_tree_set_int(field_info *fi, int32_t value);
354static void
355proto_tree_set_uint64(field_info *fi, uint64_t value);
356static void
357proto_tree_set_int64(field_info *fi, int64_t value);
358static void
359proto_tree_set_eui64(field_info *fi, const uint64_t value);
360static void
361proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
362
363/* Handle type length mismatch (now filterable) expert info */
364static int proto_type_length_mismatch;
365static expert_field ei_type_length_mismatch_error;
366static expert_field ei_type_length_mismatch_warn;
367static void register_type_length_mismatch(void);
368
369/* Handle byte array string decoding errors with expert info */
370static int proto_byte_array_string_decoding_error;
371static expert_field ei_byte_array_string_decoding_failed_error;
372static void register_byte_array_string_decodinws_error(void);
373
374/* Handle date and time string decoding errors with expert info */
375static int proto_date_time_string_decoding_error;
376static expert_field ei_date_time_string_decoding_failed_error;
377static void register_date_time_string_decodinws_error(void);
378
379/* Handle string errors expert info */
380static int proto_string_errors;
381static expert_field ei_string_trailing_characters;
382static void register_string_errors(void);
383
384static int proto_register_field_init(header_field_info *hfinfo, const int parent);
385
386/* special-case header field used within proto.c */
387static header_field_info hfi_text_only =
388 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
389int hf_text_only;
390
391/* Structure for information about a protocol */
392struct _protocol {
393 const char *name; /* long description */
394 const char *short_name; /* short description */
395 const char *filter_name; /* name of this protocol in filters */
396 GPtrArray *fields; /* fields for this protocol */
397 int proto_id; /* field ID for this protocol */
398 bool_Bool is_enabled; /* true if protocol is enabled */
399 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
400 bool_Bool can_toggle; /* true if is_enabled can be changed */
401 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
402 For dissectors that need a protocol name so they
403 can be added to a dissector table, but use the
404 parent_proto_id for things like enable/disable */
405 GList *heur_list; /* Heuristic dissectors associated with this protocol */
406};
407
408/* List of all protocols */
409static GList *protocols;
410
411/* Structure stored for deregistered g_slice */
412struct g_slice_data {
413 size_t block_size;
414 void *mem_block;
415};
416
417/* Deregistered fields */
418static GPtrArray *deregistered_fields;
419static GPtrArray *deregistered_data;
420static GPtrArray *deregistered_slice;
421
422/* indexed by prefix, contains initializers */
423static GHashTable* prefixes;
424
425/* Contains information about a field when a dissector calls
426 * proto_tree_add_item. */
427#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)))
428#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
429
430/* Contains the space for proto_nodes. */
431#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
432 node->first_child = NULL((void*)0); \
433 node->last_child = NULL((void*)0); \
434 node->next = NULL((void*)0);
435
436#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
437 wmem_free(pool, node)
438
439/* String space for protocol and field items for the GUI */
440#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;
\
441 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
442 il->value_pos = 0; \
443 il->value_len = 0;
444#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
445 wmem_free(pool, il);
446
447#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", 447, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 447, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 447, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
448 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
449 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 449
, __func__, "Unregistered hf! index=%d", hfindex)
; \
450 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", 450, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
451 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", 451, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
452 hfinfo = gpa_hfinfo.hfi[hfindex];
453
454/* List which stores protocols and fields that have been registered */
455typedef struct _gpa_hfinfo_t {
456 uint32_t len;
457 uint32_t allocated_len;
458 header_field_info **hfi;
459} gpa_hfinfo_t;
460
461static gpa_hfinfo_t gpa_hfinfo;
462
463/* Hash table of abbreviations and IDs */
464static GHashTable *gpa_name_map;
465static header_field_info *same_name_hfinfo;
466
467/* Hash table protocol aliases. const char * -> const char * */
468static GHashTable *gpa_protocol_aliases;
469
470/*
471 * We're called repeatedly with the same field name when sorting a column.
472 * Cache our last gpa_name_map hit for faster lookups.
473 */
474static char *last_field_name;
475static header_field_info *last_hfinfo;
476
477static void save_same_name_hfinfo(void *data)
478{
479 same_name_hfinfo = (header_field_info*)data;
480}
481
482/* Points to the first element of an array of bits, indexed by
483 a subtree item type; that array element is true if subtrees of
484 an item of that type are to be expanded. */
485static uint32_t *tree_is_expanded;
486
487/* Number of elements in that array. The entry with index 0 is not used. */
488int num_tree_types = 1;
489
490/* Name hashtables for fast detection of duplicate names */
491static GHashTable* proto_names;
492static GHashTable* proto_short_names;
493static GHashTable* proto_filter_names;
494
495static const char *reserved_filter_names[] = {
496 /* Display filter keywords. */
497 "eq",
498 "ne",
499 "all_eq",
500 "any_eq",
501 "all_ne",
502 "any_ne",
503 "gt",
504 "ge",
505 "lt",
506 "le",
507 "bitand",
508 "bitwise_and",
509 "contains",
510 "matches",
511 "not",
512 "and",
513 "or",
514 "xor",
515 "in",
516 "any",
517 "all",
518 "true",
519 "false",
520 "nan",
521 "inf",
522 "infinity",
523 NULL((void*)0)
524};
525
526static GHashTable *proto_reserved_filter_names;
527
528static int
529proto_compare_name(const void *p1_arg, const void *p2_arg)
530{
531 const protocol_t *p1 = (const protocol_t *)p1_arg;
532 const protocol_t *p2 = (const protocol_t *)p2_arg;
533
534 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
535}
536
537static GSList *dissector_plugins;
538
539#ifdef HAVE_PLUGINS1
540void
541proto_register_plugin(const proto_plugin *plug)
542{
543 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
544}
545#else /* HAVE_PLUGINS */
546void
547proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
548{
549 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 549, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
550}
551#endif /* HAVE_PLUGINS */
552
553static void
554call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
555{
556 proto_plugin *plug = (proto_plugin *)data;
557
558 if (plug->register_protoinfo) {
559 plug->register_protoinfo();
560 }
561}
562
563static void
564call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
565{
566 proto_plugin *plug = (proto_plugin *)data;
567
568 if (plug->register_handoff) {
569 plug->register_handoff();
570 }
571}
572
573/* initialize data structures and register protocols and fields */
574void
575proto_init(GSList *register_all_plugin_protocols_list,
576 GSList *register_all_plugin_handoffs_list,
577 register_cb cb,
578 void *client_data)
579{
580 proto_cleanup_base();
581
582 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
583 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
584 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
585
586 proto_reserved_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
587 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
588 /* GHashTable has no key destructor so the cast is safe. */
589 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
590 }
591
592 gpa_hfinfo.len = 0;
593 gpa_hfinfo.allocated_len = 0;
594 gpa_hfinfo.hfi = NULL((void*)0);
595 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL((void*)0), save_same_name_hfinfo);
596 gpa_protocol_aliases = g_hash_table_new(g_str_hash, g_str_equal);
597 deregistered_fields = g_ptr_array_new();
598 deregistered_data = g_ptr_array_new();
599 deregistered_slice = g_ptr_array_new();
600
601 /* Initialize the ftype subsystem */
602 ftypes_initialize();
603
604 /* Initialize the address type subsystem */
605 address_types_initialize();
606
607 /* Register one special-case FT_TEXT_ONLY field for use when
608 converting wireshark to new-style proto_tree. These fields
609 are merely strings on the GUI tree; they are not filterable */
610 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
611
612 /* Register the pseudo-protocols used for exceptions. */
613 register_show_exception();
614 register_type_length_mismatch();
615 register_byte_array_string_decodinws_error();
616 register_date_time_string_decodinws_error();
617 register_string_errors();
618 ftypes_register_pseudofields();
619 col_register_protocol();
620
621 /* Have each built-in dissector register its protocols, fields,
622 dissector tables, and dissectors to be called through a
623 handle, and do whatever one-time initialization it needs to
624 do. */
625 register_all_protocols(cb, client_data);
626
627 /* Now call the registration routines for all epan plugins. */
628 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
629 ((void (*)(register_cb, void *))l->data)(cb, client_data);
630 }
631
632 /* Now call the registration routines for all dissector plugins. */
633 if (cb)
634 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
635 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
636
637 /* Now call the "handoff registration" routines of all built-in
638 dissectors; those routines register the dissector in other
639 dissectors' handoff tables, and fetch any dissector handles
640 they need. */
641 register_all_protocol_handoffs(cb, client_data);
642
643 /* Now do the same with epan plugins. */
644 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
645 ((void (*)(register_cb, void *))l->data)(cb, client_data);
646 }
647
648 /* Now do the same with dissector plugins. */
649 if (cb)
650 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
651 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
652
653 /* sort the protocols by protocol name */
654 protocols = g_list_sort(protocols, proto_compare_name);
655
656 /* sort the dissector handles in dissector tables (for -G reports
657 * and -d error messages. The GUI sorts the handles itself.) */
658 packet_all_tables_sort_handles();
659
660 /* We've assigned all the subtree type values; allocate the array
661 for them, and zero it out. */
662 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
)))
;
663}
664
665static void
666proto_cleanup_base(void)
667{
668 protocol_t *protocol;
669 header_field_info *hfinfo;
670
671 /* Free the abbrev/ID hash table */
672 if (gpa_name_map) {
673 g_hash_table_destroy(gpa_name_map);
674 gpa_name_map = NULL((void*)0);
675 }
676 if (gpa_protocol_aliases) {
677 g_hash_table_destroy(gpa_protocol_aliases);
678 gpa_protocol_aliases = NULL((void*)0);
679 }
680 g_free(last_field_name);
681 last_field_name = NULL((void*)0);
682
683 while (protocols) {
684 protocol = (protocol_t *)protocols->data;
685 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", 685
, __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", 685, "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", 685, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
686 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", 686, "protocol->proto_id == hfinfo->id"
))))
;
687
688 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)
;
689 if (protocol->parent_proto_id != -1) {
690 // pino protocol
691 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 691, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
692 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"
, 692, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
693 } else {
694 if (protocol->fields) {
695 g_ptr_array_free(protocol->fields, true1);
696 }
697 g_list_free(protocol->heur_list);
698 }
699 protocols = g_list_remove(protocols, protocol);
700 g_free(protocol);
701 }
702
703 if (proto_names) {
704 g_hash_table_destroy(proto_names);
705 proto_names = NULL((void*)0);
706 }
707
708 if (proto_short_names) {
709 g_hash_table_destroy(proto_short_names);
710 proto_short_names = NULL((void*)0);
711 }
712
713 if (proto_filter_names) {
714 g_hash_table_destroy(proto_filter_names);
715 proto_filter_names = NULL((void*)0);
716 }
717
718 if (proto_reserved_filter_names) {
719 g_hash_table_destroy(proto_reserved_filter_names);
720 proto_reserved_filter_names = NULL((void*)0);
721 }
722
723 if (gpa_hfinfo.allocated_len) {
724 gpa_hfinfo.len = 0;
725 gpa_hfinfo.allocated_len = 0;
726 g_free(gpa_hfinfo.hfi);
727 gpa_hfinfo.hfi = NULL((void*)0);
728 }
729
730 if (deregistered_fields) {
731 g_ptr_array_free(deregistered_fields, true1);
732 deregistered_fields = NULL((void*)0);
733 }
734
735 if (deregistered_data) {
736 g_ptr_array_free(deregistered_data, true1);
737 deregistered_data = NULL((void*)0);
738 }
739
740 if (deregistered_slice) {
741 g_ptr_array_free(deregistered_slice, true1);
742 deregistered_slice = NULL((void*)0);
743 }
744
745 g_free(tree_is_expanded);
746 tree_is_expanded = NULL((void*)0);
747
748 if (prefixes)
749 g_hash_table_destroy(prefixes);
750}
751
752void
753proto_cleanup(void)
754{
755 proto_free_deregistered_fields();
756 proto_cleanup_base();
757
758 g_slist_free(dissector_plugins);
759 dissector_plugins = NULL((void*)0);
760}
761
762static bool_Bool
763// NOLINTNEXTLINE(misc-no-recursion)
764proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
765 void *data)
766{
767 proto_node *pnode = tree;
768 proto_node *child;
769 proto_node *current;
770
771 if (func(pnode, data))
772 return true1;
773
774 child = pnode->first_child;
775 while (child != NULL((void*)0)) {
776 /*
777 * The routine we call might modify the child, e.g. by
778 * freeing it, so we get the child's successor before
779 * calling that routine.
780 */
781 current = child;
782 child = current->next;
783 // We recurse here, but we're limited by prefs.gui_max_tree_depth
784 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
785 return true1;
786 }
787
788 return false0;
789}
790
791void
792proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
793 void *data)
794{
795 proto_node *node = tree;
796 proto_node *current;
797
798 if (!node)
799 return;
800
801 node = node->first_child;
802 while (node != NULL((void*)0)) {
803 current = node;
804 node = current->next;
805 func((proto_tree *)current, data);
806 }
807}
808
809static void
810free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
811{
812 GPtrArray *ptrs = (GPtrArray *)value;
813 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
814 header_field_info *hfinfo;
815
816 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", 816, __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", 816, "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", 816, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
817 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
818 /* when a field is referenced by a filter this also
819 affects the refcount for the parent protocol so we need
820 to adjust the refcount for the parent as well
821 */
822 if (hfinfo->parent != -1) {
823 header_field_info *parent_hfinfo;
824 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", 824
, __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", 824, "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", 824, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
825 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
826 }
827 hfinfo->ref_type = HF_REF_TYPE_NONE;
828 }
829
830 g_ptr_array_free(ptrs, true1);
831}
832
833static void
834proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
835{
836 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
837
838 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
839
840 if (finfo) {
841 fvalue_free(finfo->value);
842 finfo->value = NULL((void*)0);
843 }
844}
845
846void
847proto_tree_reset(proto_tree *tree)
848{
849 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
850
851 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
852
853 /* free tree data */
854 if (tree_data->interesting_hfids) {
855 /* Free all the GPtrArray's in the interesting_hfids hash. */
856 g_hash_table_foreach(tree_data->interesting_hfids,
857 free_GPtrArray_value, NULL((void*)0));
858
859 /* And then remove all values. */
860 g_hash_table_remove_all(tree_data->interesting_hfids);
861 }
862
863 /* Reset track of the number of children */
864 tree_data->count = 0;
865
866 /* Reset our loop checks */
867 tree_data->max_start = 0;
868 tree_data->start_idle_count = 0;
869
870 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
871}
872
873/* frees the resources that the dissection a proto_tree uses */
874void
875proto_tree_free(proto_tree *tree)
876{
877 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
878
879 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
880
881 /* free tree data */
882 if (tree_data->interesting_hfids) {
883 /* Free all the GPtrArray's in the interesting_hfids hash. */
884 g_hash_table_foreach(tree_data->interesting_hfids,
885 free_GPtrArray_value, NULL((void*)0));
886
887 /* And then destroy the hash. */
888 g_hash_table_destroy(tree_data->interesting_hfids);
889 }
890
891 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)
;
892
893 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
894}
895
896/* Is the parsing being done for a visible proto_tree or an invisible one?
897 * By setting this correctly, the proto_tree creation is sped up by not
898 * having to call vsnprintf and copy strings around.
899 */
900bool_Bool
901proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
902{
903 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
904
905 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
906
907 return old_visible;
908}
909
910void
911proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
912{
913 if (tree)
914 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
915}
916
917/* Assume dissector set only its protocol fields.
918 This function is called by dissectors and allows the speeding up of filtering
919 in wireshark; if this function returns false it is safe to reset tree to NULL
920 and thus skip calling most of the expensive proto_tree_add_...()
921 functions.
922 If the tree is visible we implicitly assume the field is referenced.
923*/
924bool_Bool
925proto_field_is_referenced(proto_tree *tree, int proto_id)
926{
927 register header_field_info *hfinfo;
928
929
930 if (!tree)
931 return false0;
932
933 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
934 return true1;
935
936 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", 936, __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", 936, "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", 936, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
937 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
938 return true1;
939
940 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
941 return true1;
942
943 return false0;
944}
945
946
947/* Finds a record in the hfinfo array by id. */
948header_field_info *
949proto_registrar_get_nth(unsigned hfindex)
950{
951 register header_field_info *hfinfo;
952
953 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", 953, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 953, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 953, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
954 return hfinfo;
955}
956
957
958/* Prefix initialization
959 * this allows for a dissector to register a display filter name prefix
960 * so that it can delay the initialization of the hf array as long as
961 * possible.
962 */
963
964/* compute a hash for the part before the dot of a display filter */
965static unsigned
966prefix_hash (const void *key) {
967 /* end the string at the dot and compute its hash */
968 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
969 char* c = copy;
970 unsigned tmp;
971
972 for (; *c; c++) {
973 if (*c == '.') {
974 *c = 0;
975 break;
976 }
977 }
978
979 tmp = g_str_hash(copy);
980 g_free(copy);
981 return tmp;
982}
983
984/* are both strings equal up to the end or the dot? */
985static gboolean
986prefix_equal (const void *ap, const void *bp) {
987 const char* a = (const char *)ap;
988 const char* b = (const char *)bp;
989
990 do {
991 char ac = *a++;
992 char bc = *b++;
993
994 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
995
996 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
997 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
998
999 if (ac != bc) return FALSE(0);
1000 } while (1);
1001
1002 return FALSE(0);
1003}
1004
1005/* Register a new prefix for "delayed" initialization of field arrays */
1006void
1007proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1008 if (! prefixes ) {
1009 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1010 }
1011
1012 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1013}
1014
1015/* helper to call all prefix initializers */
1016static gboolean
1017initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1018 ((prefix_initializer_t)v)((const char *)k);
1019 return TRUE(!(0));
1020}
1021
1022/** Initialize every remaining uninitialized prefix. */
1023void
1024proto_initialize_all_prefixes(void) {
1025 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1026}
1027
1028/* Finds a record in the hfinfo array by name.
1029 * If it fails to find it in the already registered fields,
1030 * it tries to find and call an initializer in the prefixes
1031 * table and if so it looks again.
1032 */
1033
1034header_field_info *
1035proto_registrar_get_byname(const char *field_name)
1036{
1037 header_field_info *hfinfo;
1038 prefix_initializer_t pi;
1039
1040 if (!field_name)
1041 return NULL((void*)0);
1042
1043 if (g_strcmp0(field_name, last_field_name) == 0) {
1044 return last_hfinfo;
1045 }
1046
1047 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1048
1049 if (hfinfo) {
1050 g_free(last_field_name);
1051 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1052 last_hfinfo = hfinfo;
1053 return hfinfo;
1054 }
1055
1056 if (!prefixes)
1057 return NULL((void*)0);
1058
1059 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1060 pi(field_name);
1061 g_hash_table_remove(prefixes, field_name);
1062 } else {
1063 return NULL((void*)0);
1064 }
1065
1066 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1067
1068 if (hfinfo) {
1069 g_free(last_field_name);
1070 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1071 last_hfinfo = hfinfo;
1072 }
1073 return hfinfo;
1074}
1075
1076header_field_info*
1077proto_registrar_get_byalias(const char *alias_name)
1078{
1079 if (!alias_name) {
1080 return NULL((void*)0);
1081 }
1082
1083 /* Find our aliased protocol. */
1084 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1085 char *dot = strchr(an_copy, '.');
1086 if (dot) {
1087 *dot = '\0';
1088 }
1089 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1090 if (!proto_pfx) {
1091 g_free(an_copy);
1092 return NULL((void*)0);
1093 }
1094
1095 /* Construct our aliased field and look it up. */
1096 GString *filter_name = g_string_new(proto_pfx);
1097 if (dot) {
1098 g_string_append_printf(filter_name, ".%s", dot+1);
1099 }
1100 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1101 g_free(an_copy);
1102 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)))))
;
1103
1104 return hfinfo;
1105}
1106
1107int
1108proto_registrar_get_id_byname(const char *field_name)
1109{
1110 header_field_info *hfinfo;
1111
1112 hfinfo = proto_registrar_get_byname(field_name);
1113
1114 if (!hfinfo)
1115 return -1;
1116
1117 return hfinfo->id;
1118}
1119
1120static int
1121label_strcat_flags(const header_field_info *hfinfo)
1122{
1123 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1124 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1125
1126 return 0;
1127}
1128
1129static char *
1130format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1131 const uint8_t *bytes, unsigned length, size_t max_str_len)
1132{
1133 char *str = NULL((void*)0);
1134 const uint8_t *p;
1135 bool_Bool is_printable;
1136
1137 if (bytes) {
1138 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1139 /*
1140 * If all bytes are valid and printable UTF-8, show the
1141 * bytes as a string - in quotes to indicate that it's
1142 * a string.
1143 */
1144 if (isprint_utf8_string(bytes, length)) {
1145 str = wmem_strdup_printf(scope, "\"%.*s\"",
1146 (int)length, bytes);
1147 return str;
1148 }
1149 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1150 /*
1151 * Check whether all bytes are printable.
1152 */
1153 is_printable = true1;
1154 for (p = bytes; p < bytes+length; p++) {
1155 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1156 /* Not printable. */
1157 is_printable = false0;
1158 break;
1159 }
1160 }
1161
1162 /*
1163 * If all bytes are printable ASCII, show the bytes
1164 * as a string - in quotes to indicate that it's
1165 * a string.
1166 */
1167 if (is_printable) {
1168 str = wmem_strdup_printf(scope, "\"%.*s\"",
1169 (int)length, bytes);
1170 return str;
1171 }
1172 }
1173
1174 /*
1175 * Either it's not printable ASCII, or we don't care whether
1176 * it's printable ASCII; show it as hex bytes.
1177 */
1178 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1179 case SEP_DOT:
1180 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1181 break;
1182 case SEP_DASH:
1183 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1184 break;
1185 case SEP_COLON:
1186 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1187 break;
1188 case SEP_SPACE:
1189 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1190 break;
1191 case BASE_NONE:
1192 default:
1193 if (prefs.display_byte_fields_with_spaces) {
1194 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1195 } else {
1196 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1197 }
1198 break;
1199 }
1200 }
1201 else {
1202 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1203 str = wmem_strdup(scope, "<none>");
1204 } else {
1205 str = wmem_strdup(scope, "<MISSING>");
1206 }
1207 }
1208 return str;
1209}
1210
1211static char *
1212format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1213 const uint8_t *bytes, unsigned length)
1214{
1215 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1216}
1217
1218static void
1219ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1220{
1221 subtree_lvl *pushed_tree;
1222
1223 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"
, 1223, "ptvc->pushed_tree_max <= 256-8"))))
;
1224 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1225
1226 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1227 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1227, "pushed_tree != ((void*)0)"
))))
;
1228 ptvc->pushed_tree = pushed_tree;
1229}
1230
1231static void
1232ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1233{
1234 ptvc->pushed_tree = NULL((void*)0);
1235 ptvc->pushed_tree_max = 0;
1236 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", 1236, "ptvc->pushed_tree_index == 0"
))))
;
1237 ptvc->pushed_tree_index = 0;
1238}
1239
1240/* Allocates an initializes a ptvcursor_t with 3 variables:
1241 * proto_tree, tvbuff, and offset. */
1242ptvcursor_t *
1243ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1244{
1245 ptvcursor_t *ptvc;
1246
1247 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1248 ptvc->scope = scope;
1249 ptvc->tree = tree;
1250 ptvc->tvb = tvb;
1251 ptvc->offset = offset;
1252 ptvc->pushed_tree = NULL((void*)0);
1253 ptvc->pushed_tree_max = 0;
1254 ptvc->pushed_tree_index = 0;
1255 return ptvc;
1256}
1257
1258
1259/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1260void
1261ptvcursor_free(ptvcursor_t *ptvc)
1262{
1263 ptvcursor_free_subtree_levels(ptvc);
1264 /*g_free(ptvc);*/
1265}
1266
1267/* Returns tvbuff. */
1268tvbuff_t *
1269ptvcursor_tvbuff(ptvcursor_t *ptvc)
1270{
1271 return ptvc->tvb;
1272}
1273
1274/* Returns current offset. */
1275int
1276ptvcursor_current_offset(ptvcursor_t *ptvc)
1277{
1278 return ptvc->offset;
1279}
1280
1281proto_tree *
1282ptvcursor_tree(ptvcursor_t *ptvc)
1283{
1284 if (!ptvc)
1285 return NULL((void*)0);
1286
1287 return ptvc->tree;
1288}
1289
1290void
1291ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1292{
1293 ptvc->tree = tree;
1294}
1295
1296/* creates a subtree, sets it as the working tree and pushes the old working tree */
1297proto_tree *
1298ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1299{
1300 subtree_lvl *subtree;
1301 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1302 ptvcursor_new_subtree_levels(ptvc);
1303
1304 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1305 subtree->tree = ptvc->tree;
1306 subtree->it= NULL((void*)0);
1307 ptvc->pushed_tree_index++;
1308 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1309}
1310
1311/* pops a subtree */
1312void
1313ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1314{
1315 subtree_lvl *subtree;
1316
1317 if (ptvc->pushed_tree_index <= 0)
1318 return;
1319
1320 ptvc->pushed_tree_index--;
1321 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1322 if (subtree->it != NULL((void*)0))
1323 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1324
1325 ptvc->tree = subtree->tree;
1326}
1327
1328/* saves the current tvb offset and the item in the current subtree level */
1329static void
1330ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1331{
1332 subtree_lvl *subtree;
1333
1334 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", 1334, "ptvc->pushed_tree_index > 0"
))))
;
1335
1336 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1337 subtree->it = it;
1338 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1339}
1340
1341/* Creates a subtree and adds it to the cursor as the working tree but does not
1342 * save the old working tree */
1343proto_tree *
1344ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1345{
1346 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1347 return ptvc->tree;
1348}
1349
1350static proto_tree *
1351ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1352{
1353 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1354 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1355 ptvcursor_subtree_set_item(ptvc, it);
1356 return ptvcursor_tree(ptvc);
1357}
1358
1359/* Add an item to the tree and create a subtree
1360 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1361 * In this case, when the subtree will be closed, the parent item length will
1362 * be equal to the advancement of the cursor since the creation of the subtree.
1363 */
1364proto_tree *
1365ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1366 const unsigned encoding, int ett_subtree)
1367{
1368 proto_item *it;
1369
1370 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1371 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1372}
1373
1374static proto_item *
1375proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1376
1377/* Add a text node to the tree and create a subtree
1378 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1379 * In this case, when the subtree will be closed, the item length will be equal
1380 * to the advancement of the cursor since the creation of the subtree.
1381 */
1382proto_tree *
1383ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1384 int ett_subtree, const char *format, ...)
1385{
1386 proto_item *pi;
1387 va_list ap;
1388 header_field_info *hfinfo;
1389 proto_tree *tree;
1390
1391 tree = ptvcursor_tree(ptvc);
1392
1393 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1394
1395 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", 1395
, __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", 1395, "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", 1395, "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", 1395, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1396
1397 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1398 ptvcursor_current_offset(ptvc), length);
1399
1400 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1400, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1401
1402 va_start(ap, format)__builtin_va_start(ap, format);
1403 proto_tree_set_representation(pi, format, ap);
1404 va_end(ap)__builtin_va_end(ap);
1405
1406 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1407}
1408
1409/* Add a text-only node, leaving it to our caller to fill the text in */
1410static proto_item *
1411proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1412{
1413 proto_item *pi;
1414
1415 if (tree == NULL((void*)0))
1416 return NULL((void*)0);
1417
1418 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1419
1420 return pi;
1421}
1422
1423/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1424proto_item *
1425proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1426 const char *format, ...)
1427{
1428 proto_item *pi;
1429 va_list ap;
1430 header_field_info *hfinfo;
1431
1432 if (length == -1) {
1433 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1434 } else {
1435 tvb_ensure_bytes_exist(tvb, start, length);
1436 }
1437
1438 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1439
1440 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", 1440
, __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", 1440, "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", 1440, "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", 1440, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1441
1442 pi = proto_tree_add_text_node(tree, tvb, start, length);
1443
1444 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1444, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1445
1446 va_start(ap, format)__builtin_va_start(ap, format);
1447 proto_tree_set_representation(pi, format, ap);
1448 va_end(ap)__builtin_va_end(ap);
1449
1450 return pi;
1451}
1452
1453/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1454proto_item *
1455proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1456 int length, const char *format, va_list ap)
1457{
1458 proto_item *pi;
1459 header_field_info *hfinfo;
1460
1461 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1462 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1463 * the length to be what's in the tvbuff if length is -1, and the
1464 * minimum of length and what's in the tvbuff if not.
1465 */
1466
1467 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1468
1469 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", 1469
, __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", 1469, "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", 1469, "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", 1469, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1470
1471 pi = proto_tree_add_text_node(tree, tvb, start, length);
1472
1473 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1473, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1474
1475 proto_tree_set_representation(pi, format, ap);
1476
1477 return pi;
1478}
1479
1480/* Add a text-only node that creates a subtree underneath.
1481 */
1482proto_tree *
1483proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1484{
1485 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1486}
1487
1488/* Add a text-only node that creates a subtree underneath.
1489 */
1490proto_tree *
1491proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1492{
1493 proto_tree *pt;
1494 proto_item *pi;
1495 va_list ap;
1496
1497 va_start(ap, format)__builtin_va_start(ap, format);
1498 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1499 va_end(ap)__builtin_va_end(ap);
1500
1501 if (tree_item != NULL((void*)0))
1502 *tree_item = pi;
1503
1504 pt = proto_item_add_subtree(pi, idx);
1505
1506 return pt;
1507}
1508
1509/* Add a text-only node for debugging purposes. The caller doesn't need
1510 * to worry about tvbuff, start, or length. Debug message gets sent to
1511 * STDOUT, too */
1512proto_item *
1513proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1514{
1515 proto_item *pi;
1516 va_list ap;
1517
1518 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1519
1520 if (pi) {
1521 va_start(ap, format)__builtin_va_start(ap, format);
1522 proto_tree_set_representation(pi, format, ap);
1523 va_end(ap)__builtin_va_end(ap);
1524 }
1525 va_start(ap, format)__builtin_va_start(ap, format);
1526 vprintf(format, ap);
1527 va_end(ap)__builtin_va_end(ap);
1528 printf("\n");
1529
1530 return pi;
1531}
1532
1533proto_item *
1534proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1535{
1536 proto_item *pi;
1537 header_field_info *hfinfo;
1538
1539 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1540
1541 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", 1541
, __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", 1541, "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", 1541, "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", 1541, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1542
1543 pi = proto_tree_add_text_node(tree, tvb, start, length);
1544
1545 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1545, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1546
1547 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1548
1549 return pi;
1550}
1551
1552proto_item *
1553proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1554{
1555 proto_item *pi;
1556 header_field_info *hfinfo;
1557 char *str;
1558
1559 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1560
1561 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", 1561
, __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", 1561, "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", 1561, "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", 1561, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1562
1563 pi = proto_tree_add_text_node(tree, tvb, start, length);
1564
1565 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1565, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1566
1567 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1568 proto_item_set_text(pi, "%s", str);
1569 wmem_free(NULL((void*)0), str);
1570
1571 return pi;
1572}
1573
1574void proto_report_dissector_bug(const char *format, ...)
1575{
1576 va_list args;
1577
1578 if (wireshark_abort_on_dissector_bug) {
1579 /*
1580 * Try to have the error message show up in the crash
1581 * information.
1582 */
1583 va_start(args, format)__builtin_va_start(args, format);
1584 ws_vadd_crash_info(format, args);
1585 va_end(args)__builtin_va_end(args);
1586
1587 /*
1588 * Print the error message.
1589 */
1590 va_start(args, format)__builtin_va_start(args, format);
1591 vfprintf(stderrstderr, format, args);
1592 va_end(args)__builtin_va_end(args);
1593 putc('\n', stderrstderr);
1594
1595 /*
1596 * And crash.
1597 */
1598 abort();
1599 } else {
1600 va_start(args, format)__builtin_va_start(args, format);
1601 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1602 va_end(args)__builtin_va_end(args);
1603 }
1604}
1605
1606/* We could probably get away with changing is_error to a minimum length value. */
1607static void
1608report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1609{
1610 if (is_error) {
1611 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1612 } else {
1613 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1614 }
1615
1616 if (is_error) {
1617 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1618 }
1619}
1620
1621static uint32_t
1622get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1623{
1624 uint32_t value;
1625 bool_Bool length_error;
1626
1627 switch (length) {
1628
1629 case 1:
1630 value = tvb_get_uint8(tvb, offset);
1631 if (encoding & ENC_ZIGBEE0x40000000) {
1632 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1633 value = 0;
1634 }
1635 }
1636 break;
1637
1638 case 2:
1639 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1640 : tvb_get_ntohs(tvb, offset);
1641 if (encoding & ENC_ZIGBEE0x40000000) {
1642 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1643 value = 0;
1644 }
1645 }
1646 break;
1647
1648 case 3:
1649 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1650 : tvb_get_ntoh24(tvb, offset);
1651 break;
1652
1653 case 4:
1654 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1655 : tvb_get_ntohl(tvb, offset);
1656 break;
1657
1658 default:
1659 if (length < 1) {
1660 length_error = true1;
1661 value = 0;
1662 } else {
1663 length_error = false0;
1664 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1665 : tvb_get_ntohl(tvb, offset);
1666 }
1667 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1668 break;
1669 }
1670 return value;
1671}
1672
1673static inline uint64_t
1674get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1675{
1676 uint64_t value;
1677
1678 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1679
1680 if (length < 1 || length > 8) {
1681 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1682 }
1683
1684 return value;
1685}
1686
1687static int32_t
1688get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1689{
1690 int32_t value;
1691 bool_Bool length_error;
1692
1693 switch (length) {
1694
1695 case 1:
1696 value = tvb_get_int8(tvb, offset);
1697 break;
1698
1699 case 2:
1700 value = encoding ? tvb_get_letohis(tvb, offset)
1701 : tvb_get_ntohis(tvb, offset);
1702 break;
1703
1704 case 3:
1705 value = encoding ? tvb_get_letohi24(tvb, offset)
1706 : tvb_get_ntohi24(tvb, offset);
1707 break;
1708
1709 case 4:
1710 value = encoding ? tvb_get_letohil(tvb, offset)
1711 : tvb_get_ntohil(tvb, offset);
1712 break;
1713
1714 default:
1715 if (length < 1) {
1716 length_error = true1;
1717 value = 0;
1718 } else {
1719 length_error = false0;
1720 value = encoding ? tvb_get_letohil(tvb, offset)
1721 : tvb_get_ntohil(tvb, offset);
1722 }
1723 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1724 break;
1725 }
1726 return value;
1727}
1728
1729/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1730 * be cast-able as a int64_t. This is weird, but what the code has always done.
1731 */
1732static inline uint64_t
1733get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1734{
1735 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1736
1737 switch (length) {
1738 case 7:
1739 value = ws_sign_ext64(value, 56);
1740 break;
1741 case 6:
1742 value = ws_sign_ext64(value, 48);
1743 break;
1744 case 5:
1745 value = ws_sign_ext64(value, 40);
1746 break;
1747 case 4:
1748 value = ws_sign_ext64(value, 32);
1749 break;
1750 case 3:
1751 value = ws_sign_ext64(value, 24);
1752 break;
1753 case 2:
1754 value = ws_sign_ext64(value, 16);
1755 break;
1756 case 1:
1757 value = ws_sign_ext64(value, 8);
1758 break;
1759 }
1760
1761 return value;
1762}
1763
1764/* For FT_STRING */
1765static inline const uint8_t *
1766get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1767 int length, int *ret_length, const unsigned encoding)
1768{
1769 if (length == -1) {
1770 length = tvb_ensure_captured_length_remaining(tvb, start);
1771 }
1772 *ret_length = length;
1773 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1774}
1775
1776/* For FT_STRINGZ */
1777static inline const uint8_t *
1778get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1779 int start, int length, int *ret_length, const unsigned encoding)
1780{
1781 const uint8_t *value;
1782
1783 if (length < -1) {
1784 report_type_length_mismatch(tree, "a string", length, true1);
1785 }
1786 if (length == -1) {
1787 /* This can throw an exception */
1788 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1789 } else {
1790 /* In this case, length signifies the length of the string.
1791 *
1792 * This could either be a null-padded string, which doesn't
1793 * necessarily have a '\0' at the end, or a null-terminated
1794 * string, with a trailing '\0'. (Yes, there are cases
1795 * where you have a string that's both counted and null-
1796 * terminated.)
1797 *
1798 * In the first case, we must allocate a buffer of length
1799 * "length+1", to make room for a trailing '\0'.
1800 *
1801 * In the second case, we don't assume that there is a
1802 * trailing '\0' there, as the packet might be malformed.
1803 * (XXX - should we throw an exception if there's no
1804 * trailing '\0'?) Therefore, we allocate a buffer of
1805 * length "length+1", and put in a trailing '\0', just to
1806 * be safe.
1807 *
1808 * (XXX - this would change if we made string values counted
1809 * rather than null-terminated.)
1810 */
1811 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1812 }
1813 *ret_length = length;
1814 return value;
1815}
1816
1817/* For FT_UINT_STRING */
1818static inline const uint8_t *
1819get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1820 tvbuff_t *tvb, int start, int length, int *ret_length,
1821 const unsigned encoding)
1822{
1823 uint32_t n;
1824 const uint8_t *value;
1825
1826 /* I believe it's ok if this is called with a NULL tree */
1827 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1828 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1829 length += n;
1830 *ret_length = length;
1831 return value;
1832}
1833
1834/* For FT_STRINGZPAD */
1835static inline const uint8_t *
1836get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1837 int length, int *ret_length, const unsigned encoding)
1838{
1839 /*
1840 * XXX - currently, string values are null-
1841 * terminated, so a "zero-padded" string
1842 * isn't special. If we represent string
1843 * values as something that includes a counted
1844 * array of bytes, we'll need to strip the
1845 * trailing NULs.
1846 */
1847 if (length == -1) {
1848 length = tvb_ensure_captured_length_remaining(tvb, start);
1849 }
1850 *ret_length = length;
1851 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1852}
1853
1854/* For FT_STRINGZTRUNC */
1855static inline const uint8_t *
1856get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1857 int length, int *ret_length, const unsigned encoding)
1858{
1859 /*
1860 * XXX - currently, string values are null-
1861 * terminated, so a "zero-truncated" string
1862 * isn't special. If we represent string
1863 * values as something that includes a counted
1864 * array of bytes, we'll need to strip everything
1865 * starting with the terminating NUL.
1866 */
1867 if (length == -1) {
1868 length = tvb_ensure_captured_length_remaining(tvb, start);
1869 }
1870 *ret_length = length;
1871 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1872}
1873
1874/*
1875 * Deltas between the epochs for various non-UN*X time stamp formats and
1876 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1877 * stamp format.
1878 */
1879
1880/*
1881 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1882 * XXX - if it's OK if this is unsigned, can we just use
1883 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1884 */
1885#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1886
1887/*
1888 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1889 */
1890#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1891
1892/* this can be called when there is no tree, so tree may be null */
1893static void
1894get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1895 const int length, const unsigned encoding, nstime_t *time_stamp,
1896 const bool_Bool is_relative)
1897{
1898 uint32_t tmpsecs;
1899 uint64_t tmp64secs;
1900 uint64_t todusecs;
1901
1902 switch (encoding) {
1903
1904 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1905 /*
1906 * If the length is 16, 8-byte seconds, followed
1907 * by 8-byte fractional time in nanoseconds,
1908 * both big-endian.
1909 *
1910 * If the length is 12, 8-byte seconds, followed
1911 * by 4-byte fractional time in nanoseconds,
1912 * both big-endian.
1913 *
1914 * If the length is 8, 4-byte seconds, followed
1915 * by 4-byte fractional time in nanoseconds,
1916 * both big-endian.
1917 *
1918 * For absolute times, the seconds are seconds
1919 * since the UN*X epoch.
1920 */
1921 if (length == 16) {
1922 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1923 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1924 } else if (length == 12) {
1925 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1926 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1927 } else if (length == 8) {
1928 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1929 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1930 } else if (length == 4) {
1931 /*
1932 * Backwards compatibility.
1933 * ENC_TIME_SECS_NSECS is 0; using
1934 * ENC_BIG_ENDIAN by itself with a 4-byte
1935 * time-in-seconds value was done in the
1936 * past.
1937 */
1938 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1939 time_stamp->nsecs = 0;
1940 } else {
1941 time_stamp->secs = 0;
1942 time_stamp->nsecs = 0;
1943 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1944 }
1945 break;
1946
1947 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
1948 /*
1949 * If the length is 16, 8-byte seconds, followed
1950 * by 8-byte fractional time in nanoseconds,
1951 * both little-endian.
1952 *
1953 * If the length is 12, 8-byte seconds, followed
1954 * by 4-byte fractional time in nanoseconds,
1955 * both little-endian.
1956 *
1957 * If the length is 8, 4-byte seconds, followed
1958 * by 4-byte fractional time in nanoseconds,
1959 * both little-endian.
1960 *
1961 * For absolute times, the seconds are seconds
1962 * since the UN*X epoch.
1963 */
1964 if (length == 16) {
1965 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1966 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
1967 } else if (length == 12) {
1968 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1969 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1970 } else if (length == 8) {
1971 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1972 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1973 } else if (length == 4) {
1974 /*
1975 * Backwards compatibility.
1976 * ENC_TIME_SECS_NSECS is 0; using
1977 * ENC_LITTLE_ENDIAN by itself with a 4-byte
1978 * time-in-seconds value was done in the
1979 * past.
1980 */
1981 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1982 time_stamp->nsecs = 0;
1983 } else {
1984 time_stamp->secs = 0;
1985 time_stamp->nsecs = 0;
1986 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1987 }
1988 break;
1989
1990 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
1991 /*
1992 * NTP time stamp, big-endian.
1993 * Only supported for absolute times.
1994 */
1995 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1995, "!is_relative"
))))
;
1996
1997 /* We need a temporary variable here so the unsigned math
1998 * works correctly (for years > 2036 according to RFC 2030
1999 * chapter 3).
2000 *
2001 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2002 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2003 * If bit 0 is not set, the time is in the range 2036-2104 and
2004 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2005 */
2006 tmpsecs = tvb_get_ntohl(tvb, start);
2007 if ((tmpsecs & 0x80000000) != 0)
2008 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2009 else
2010 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2011
2012 if (length == 8) {
2013 tmp64secs = tvb_get_ntoh64(tvb, start);
2014 if (tmp64secs == 0) {
2015 //This is "NULL" time
2016 time_stamp->secs = 0;
2017 time_stamp->nsecs = 0;
2018 } else {
2019 /*
2020 * Convert 1/2^32s of a second to
2021 * nanoseconds.
2022 */
2023 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2024 }
2025 } else if (length == 4) {
2026 /*
2027 * Backwards compatibility.
2028 */
2029 if (tmpsecs == 0) {
2030 //This is "NULL" time
2031 time_stamp->secs = 0;
2032 }
2033 time_stamp->nsecs = 0;
2034 } else {
2035 time_stamp->secs = 0;
2036 time_stamp->nsecs = 0;
2037 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2038 }
2039 break;
2040
2041 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2042 /*
2043 * NTP time stamp, little-endian.
2044 * Only supported for absolute times.
2045 *
2046 * NTP doesn't use this, because it's an Internet format
2047 * and hence big-endian. Any implementation must decide
2048 * whether the NTP timestamp is a 64-bit unsigned fixed
2049 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2050 * with a 32-bit unsigned seconds field followed by a
2051 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2052 * the previous two).
2053 *
2054 * XXX: We do the latter, but no dissector uses this format.
2055 * OTOH, ERF timestamps do the former, so perhaps we
2056 * should switch the interpretation so that packet-erf.c
2057 * could use this directly?
2058 */
2059 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2059, "!is_relative"
))))
;
2060
2061 /* We need a temporary variable here so the unsigned math
2062 * works correctly (for years > 2036 according to RFC 2030
2063 * chapter 3).
2064 *
2065 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2066 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2067 * If bit 0 is not set, the time is in the range 2036-2104 and
2068 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2069 */
2070 tmpsecs = tvb_get_letohl(tvb, start);
2071 if ((tmpsecs & 0x80000000) != 0)
2072 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2073 else
2074 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2075
2076 if (length == 8) {
2077 tmp64secs = tvb_get_letoh64(tvb, start);
2078 if (tmp64secs == 0) {
2079 //This is "NULL" time
2080 time_stamp->secs = 0;
2081 time_stamp->nsecs = 0;
2082 } else {
2083 /*
2084 * Convert 1/2^32s of a second to
2085 * nanoseconds.
2086 */
2087 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2088 }
2089 } else if (length == 4) {
2090 /*
2091 * Backwards compatibility.
2092 */
2093 if (tmpsecs == 0) {
2094 //This is "NULL" time
2095 time_stamp->secs = 0;
2096 }
2097 time_stamp->nsecs = 0;
2098 } else {
2099 time_stamp->secs = 0;
2100 time_stamp->nsecs = 0;
2101 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2102 }
2103 break;
2104
2105 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2106 /*
2107 * S/3x0 and z/Architecture TOD clock time stamp,
2108 * big-endian. The epoch is January 1, 1900,
2109 * 00:00:00 (proleptic?) UTC.
2110 *
2111 * Only supported for absolute times.
2112 */
2113 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2113, "!is_relative"
))))
;
2114 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2114, "length == 8"
))))
;
2115
2116 if (length == 8) {
2117 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2118 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2119 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2120 } else {
2121 time_stamp->secs = 0;
2122 time_stamp->nsecs = 0;
2123 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2124 }
2125 break;
2126
2127 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2128 /*
2129 * S/3x0 and z/Architecture TOD clock time stamp,
2130 * little-endian. The epoch is January 1, 1900,
2131 * 00:00:00 (proleptic?) UTC.
2132 *
2133 * Only supported for absolute times.
2134 */
2135 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2135, "!is_relative"
))))
;
2136
2137 if (length == 8) {
2138 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2139 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2140 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2141 } else {
2142 time_stamp->secs = 0;
2143 time_stamp->nsecs = 0;
2144 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2145 }
2146 break;
2147
2148 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2149 /*
2150 * Time stamp using the same seconds/fraction format
2151 * as NTP, but with the origin of the time stamp being
2152 * the UNIX epoch rather than the NTP epoch; big-
2153 * endian.
2154 *
2155 * Only supported for absolute times.
2156 */
2157 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2157, "!is_relative"
))))
;
2158
2159 if (length == 8) {
2160 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2161 /*
2162 * Convert 1/2^32s of a second to nanoseconds.
2163 */
2164 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2165 } else {
2166 time_stamp->secs = 0;
2167 time_stamp->nsecs = 0;
2168 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2169 }
2170 break;
2171
2172 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2173 /*
2174 * Time stamp using the same seconds/fraction format
2175 * as NTP, but with the origin of the time stamp being
2176 * the UNIX epoch rather than the NTP epoch; little-
2177 * endian.
2178 *
2179 * Only supported for absolute times.
2180 *
2181 * The RTPS specification explicitly supports Little
2182 * Endian encoding. In one place, it states that its
2183 * Time_t representation "is the one defined by ...
2184 * RFC 1305", but in another explicitly defines it as
2185 * a struct consisting of an 32 bit unsigned seconds
2186 * field and a 32 bit unsigned fraction field, not a 64
2187 * bit fixed point, so we do that here.
2188 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
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
2192 if (length == 8) {
2193 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2194 /*
2195 * Convert 1/2^32s of a second to nanoseconds.
2196 */
2197 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2198 } else {
2199 time_stamp->secs = 0;
2200 time_stamp->nsecs = 0;
2201 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2202 }
2203 break;
2204
2205 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2206 /*
2207 * MIP6 time stamp, big-endian.
2208 * A 64-bit unsigned integer field containing a timestamp. The
2209 * value indicates the number of seconds since January 1, 1970,
2210 * 00:00 UTC, by using a fixed point format. In this format, the
2211 * integer number of seconds is contained in the first 48 bits of
2212 * the field, and the remaining 16 bits indicate the number of
2213 * 1/65536 fractions of a second.
2214
2215 * Only supported for absolute times.
2216 */
2217 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2217, "!is_relative"
))))
;
2218
2219 if (length == 8) {
2220 /* We need a temporary variable here so the casting and fractions
2221 * of a second work correctly.
2222 */
2223 tmp64secs = tvb_get_ntoh48(tvb, start);
2224 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2225 tmpsecs <<= 16;
2226
2227 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2228 //This is "NULL" time
2229 time_stamp->secs = 0;
2230 time_stamp->nsecs = 0;
2231 } else {
2232 time_stamp->secs = (time_t)tmp64secs;
2233 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2234 }
2235 } else {
2236 time_stamp->secs = 0;
2237 time_stamp->nsecs = 0;
2238 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2239 }
2240 break;
2241
2242 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2243 /*
2244 * If the length is 16, 8-byte seconds, followed
2245 * by 8-byte fractional time in microseconds,
2246 * both big-endian.
2247 *
2248 * If the length is 12, 8-byte seconds, followed
2249 * by 4-byte fractional time in microseconds,
2250 * both big-endian.
2251 *
2252 * If the length is 8, 4-byte seconds, followed
2253 * by 4-byte fractional time in microseconds,
2254 * both big-endian.
2255 *
2256 * For absolute times, the seconds are seconds
2257 * since the UN*X epoch.
2258 */
2259 if (length == 16) {
2260 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2261 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2262 } else if (length == 12) {
2263 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2264 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2265 } else if (length == 8) {
2266 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2267 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2268 } else {
2269 time_stamp->secs = 0;
2270 time_stamp->nsecs = 0;
2271 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2272 }
2273 break;
2274
2275 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2276 /*
2277 * If the length is 16, 8-byte seconds, followed
2278 * by 8-byte fractional time in microseconds,
2279 * both little-endian.
2280 *
2281 * If the length is 12, 8-byte seconds, followed
2282 * by 4-byte fractional time in microseconds,
2283 * both little-endian.
2284 *
2285 * If the length is 8, 4-byte seconds, followed
2286 * by 4-byte fractional time in microseconds,
2287 * both little-endian.
2288 *
2289 * For absolute times, the seconds are seconds
2290 * since the UN*X epoch.
2291 */
2292 if (length == 16) {
2293 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2294 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2295 } else if (length == 12) {
2296 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2297 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2298 } else if (length == 8) {
2299 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2300 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2301 } else {
2302 time_stamp->secs = 0;
2303 time_stamp->nsecs = 0;
2304 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2305 }
2306 break;
2307
2308 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2309 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2310 /*
2311 * Seconds, 1 to 8 bytes.
2312 * For absolute times, it's seconds since the
2313 * UN*X epoch.
2314 */
2315 if (length >= 1 && length <= 8) {
2316 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2317 time_stamp->nsecs = 0;
2318 } else {
2319 time_stamp->secs = 0;
2320 time_stamp->nsecs = 0;
2321 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2322 }
2323 break;
2324
2325 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2326 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2327 /*
2328 * Milliseconds, 1 to 8 bytes.
2329 * For absolute times, it's milliseconds since the
2330 * UN*X epoch.
2331 */
2332 if (length >= 1 && length <= 8) {
2333 uint64_t msecs;
2334
2335 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2336 time_stamp->secs = (time_t)(msecs / 1000);
2337 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2338 } else {
2339 time_stamp->secs = 0;
2340 time_stamp->nsecs = 0;
2341 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2342 }
2343 break;
2344
2345 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2346 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2347 /*
2348 * Microseconds, 1 to 8 bytes.
2349 * For absolute times, it's microseconds since the
2350 * UN*X epoch.
2351 */
2352 if (length >= 1 && length <= 8) {
2353 uint64_t usecs;
2354
2355 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2356 time_stamp->secs = (time_t)(usecs / 1000000);
2357 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2358 } else {
2359 time_stamp->secs = 0;
2360 time_stamp->nsecs = 0;
2361 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2362 }
2363 break;
2364
2365 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2366 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2367 /*
2368 * nanoseconds, 1 to 8 bytes.
2369 * For absolute times, it's nanoseconds since the
2370 * UN*X epoch.
2371 */
2372
2373 if (length >= 1 && length <= 8) {
2374 uint64_t nsecs;
2375
2376 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2377 time_stamp->secs = (time_t)(nsecs / 1000000000);
2378 time_stamp->nsecs = (int)(nsecs % 1000000000);
2379 } else {
2380 time_stamp->secs = 0;
2381 time_stamp->nsecs = 0;
2382 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2383 }
2384 break;
2385
2386 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2387 /*
2388 * 1/64ths of a second since the UN*X epoch,
2389 * big-endian.
2390 *
2391 * Only supported for absolute times.
2392 */
2393 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2393, "!is_relative"
))))
;
2394
2395 if (length == 8) {
2396 /*
2397 * The upper 48 bits are seconds since the
2398 * UN*X epoch.
2399 */
2400 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2401 /*
2402 * The lower 16 bits are 1/2^16s of a second;
2403 * convert them to nanoseconds.
2404 *
2405 * XXX - this may give the impression of higher
2406 * precision than you actually get.
2407 */
2408 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2409 } else {
2410 time_stamp->secs = 0;
2411 time_stamp->nsecs = 0;
2412 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2413 }
2414 break;
2415
2416 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2417 /*
2418 * 1/64ths of a second since the UN*X epoch,
2419 * little-endian.
2420 *
2421 * Only supported for absolute times.
2422 */
2423 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2423, "!is_relative"
))))
;
2424
2425 if (length == 8) {
2426 /*
2427 * XXX - this is assuming that, if anybody
2428 * were ever to use this format - RFC 3971
2429 * doesn't, because that's an Internet
2430 * protocol, and those use network byte
2431 * order, i.e. big-endian - they'd treat it
2432 * as a 64-bit count of 1/2^16s of a second,
2433 * putting the upper 48 bits at the end.
2434 *
2435 * The lower 48 bits are seconds since the
2436 * UN*X epoch.
2437 */
2438 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2439 /*
2440 * The upper 16 bits are 1/2^16s of a second;
2441 * convert them to nanoseconds.
2442 *
2443 * XXX - this may give the impression of higher
2444 * precision than you actually get.
2445 */
2446 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2447 } else {
2448 time_stamp->secs = 0;
2449 time_stamp->nsecs = 0;
2450 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2451 }
2452 break;
2453
2454 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2455 /*
2456 * NTP time stamp, with 1-second resolution (i.e.,
2457 * seconds since the NTP epoch), big-endian.
2458 * Only supported for absolute times.
2459 */
2460 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2460, "!is_relative"
))))
;
2461
2462 if (length == 4) {
2463 /*
2464 * We need a temporary variable here so the unsigned math
2465 * works correctly (for years > 2036 according to RFC 2030
2466 * chapter 3).
2467 *
2468 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2469 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2470 * If bit 0 is not set, the time is in the range 2036-2104 and
2471 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2472 */
2473 tmpsecs = tvb_get_ntohl(tvb, start);
2474 if ((tmpsecs & 0x80000000) != 0)
2475 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2476 else
2477 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2478 time_stamp->nsecs = 0;
2479 } else {
2480 time_stamp->secs = 0;
2481 time_stamp->nsecs = 0;
2482 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2483 }
2484 break;
2485
2486 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2487 /*
2488 * NTP time stamp, with 1-second resolution (i.e.,
2489 * seconds since the NTP epoch), little-endian.
2490 * Only supported for absolute times.
2491 */
2492 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2492, "!is_relative"
))))
;
2493
2494 /*
2495 * We need a temporary variable here so the unsigned math
2496 * works correctly (for years > 2036 according to RFC 2030
2497 * chapter 3).
2498 *
2499 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2500 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2501 * If bit 0 is not set, the time is in the range 2036-2104 and
2502 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2503 */
2504 if (length == 4) {
2505 tmpsecs = tvb_get_letohl(tvb, start);
2506 if ((tmpsecs & 0x80000000) != 0)
2507 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2508 else
2509 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2510 time_stamp->nsecs = 0;
2511 } else {
2512 time_stamp->secs = 0;
2513 time_stamp->nsecs = 0;
2514 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2515 }
2516 break;
2517
2518 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2519 /*
2520 * Milliseconds, 6 to 8 bytes.
2521 * For absolute times, it's milliseconds since the
2522 * NTP epoch.
2523 *
2524 * ETSI TS 129.274 8.119 defines this as:
2525 * "a 48 bit unsigned integer in network order format
2526 * ...encoded as the number of milliseconds since
2527 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2528 * rounded value of 1000 x the value of the 64-bit
2529 * timestamp (Seconds + (Fraction / (1<<32))) defined
2530 * in clause 6 of IETF RFC 5905."
2531 *
2532 * Taken literally, the part after "i.e." would
2533 * mean that the value rolls over before reaching
2534 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2535 * when the 64 bit timestamp rolls over, and we have
2536 * to pick an NTP Era equivalence class to support
2537 * (such as 1968-01-20 to 2104-02-06).
2538 *
2539 * OTOH, the extra room might be used to store Era
2540 * information instead, in which case times until
2541 * 10819-08-03 can be represented with 6 bytes without
2542 * ambiguity. We handle both implementations, and assume
2543 * that times before 1968-01-20 are not represented.
2544 *
2545 * Only 6 bytes or more makes sense as an absolute
2546 * time. 5 bytes or fewer could express a span of
2547 * less than 35 years, either 1900-1934 or 2036-2070.
2548 */
2549 if (length >= 6 && length <= 8) {
2550 uint64_t msecs;
2551
2552 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2553 tmp64secs = (msecs / 1000);
2554 /*
2555 * Assume that times in the first half of NTP
2556 * Era 0 really represent times in the NTP
2557 * Era 1.
2558 */
2559 if (tmp64secs >= 0x80000000)
2560 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2561 else
2562 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2563 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2564 }
2565 else {
2566 time_stamp->secs = 0;
2567 time_stamp->nsecs = 0;
2568 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2569 }
2570 break;
2571
2572 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2573 /*
2574 * MP4 file time stamps, big-endian.
2575 * Only supported for absolute times.
2576 */
2577 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2577, "!is_relative"
))))
;
2578
2579 if (length == 8) {
2580 tmp64secs = tvb_get_ntoh64(tvb, start);
2581 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2582 time_stamp->nsecs = 0;
2583 } else if (length == 4) {
2584 tmpsecs = tvb_get_ntohl(tvb, start);
2585 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2586 time_stamp->nsecs = 0;
2587 } else {
2588 time_stamp->secs = 0;
2589 time_stamp->nsecs = 0;
2590 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2591 }
2592 break;
2593
2594 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2595 /*
2596 * Zigbee ZCL time stamps, big-endian.
2597 * Only supported for absolute times.
2598 */
2599 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2599, "!is_relative"
))))
;
2600
2601 if (length == 8) {
2602 tmp64secs = tvb_get_ntoh64(tvb, start);
2603 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);
2604 time_stamp->nsecs = 0;
2605 } else if (length == 4) {
2606 tmpsecs = tvb_get_ntohl(tvb, start);
2607 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2608 time_stamp->nsecs = 0;
2609 } else {
2610 time_stamp->secs = 0;
2611 time_stamp->nsecs = 0;
2612 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2613 }
2614 break;
2615
2616 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2617 /*
2618 * Zigbee ZCL time stamps, little-endian.
2619 * Only supported for absolute times.
2620 */
2621 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2621, "!is_relative"
))))
;
2622
2623 if (length == 8) {
2624 tmp64secs = tvb_get_letoh64(tvb, start);
2625 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);
2626 time_stamp->nsecs = 0;
2627 } else if (length == 4) {
2628 tmpsecs = tvb_get_letohl(tvb, start);
2629 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2630 time_stamp->nsecs = 0;
2631 } else {
2632 time_stamp->secs = 0;
2633 time_stamp->nsecs = 0;
2634 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2635 }
2636 break;
2637
2638 default:
2639 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2639))
;
2640 break;
2641 }
2642}
2643
2644static void
2645tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2646{
2647 const header_field_info *hfinfo = fi->hfinfo;
2648
2649 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2650 GPtrArray *ptrs = NULL((void*)0);
2651
2652 if (tree_data->interesting_hfids == NULL((void*)0)) {
2653 /* Initialize the hash because we now know that it is needed */
2654 tree_data->interesting_hfids =
2655 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2656 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2657 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2658 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2659 }
2660
2661 if (!ptrs) {
2662 /* First element triggers the creation of pointer array */
2663 ptrs = g_ptr_array_new();
2664 g_hash_table_insert(tree_data->interesting_hfids,
2665 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2666 }
2667
2668 g_ptr_array_add(ptrs, fi);
2669 }
2670}
2671
2672
2673/*
2674 * Validates that field length bytes are available starting from
2675 * start (pos/neg). Throws an exception if they aren't.
2676 */
2677static void
2678test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2679 int start, int length, const unsigned encoding)
2680{
2681 int size = length;
2682
2683 if (!tvb)
2684 return;
2685
2686 if ((hfinfo->type == FT_STRINGZ) ||
2687 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2688 (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
))
))) {
2689 /* If we're fetching until the end of the TVB, only validate
2690 * that the offset is within range.
2691 */
2692 if (length == -1)
2693 size = 0;
2694 }
2695
2696 tvb_ensure_bytes_exist(tvb, start, size);
2697}
2698
2699static void
2700detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2701{
2702 bool_Bool found_stray_character = false0;
2703
2704 if (!string)
2705 return;
2706
2707 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2708 case ENC_ASCII0x00000000:
2709 case ENC_UTF_80x00000002:
2710 for (int i = (int)strlen(string); i < length; i++) {
2711 if (string[i] != '\0') {
2712 found_stray_character = true1;
2713 break;
2714 }
2715 }
2716 break;
2717
2718 default:
2719 break;
2720 }
2721
2722 if (found_stray_character) {
2723 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2724 }
2725}
2726
2727static void
2728free_fvalue_cb(void *data)
2729{
2730 fvalue_t *fv = (fvalue_t*)data;
2731 fvalue_free(fv);
2732}
2733
2734/* Add an item to a proto_tree, using the text label registered to that item;
2735 the item is extracted from the tvbuff handed to it. */
2736static proto_item *
2737proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2738 tvbuff_t *tvb, int start, int length,
2739 unsigned encoding)
2740{
2741 proto_item *pi;
2742 uint32_t value, n;
2743 uint64_t value64;
2744 ws_in4_addr ipv4_value;
2745 float floatval;
2746 double doubleval;
2747 const char *stringval = NULL((void*)0);
2748 nstime_t time_stamp;
2749 bool_Bool length_error;
2750
2751 /* Ensure that the newly created fvalue_t is freed if we throw an
2752 * exception before adding it to the tree. (gcc creates clobbering
2753 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2754 * XXX: Move the new_field_info() call inside here?
2755 */
2756 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))
;
2757
2758 switch (new_fi->hfinfo->type) {
2759 case FT_NONE:
2760 /* no value to set for FT_NONE */
2761 break;
2762
2763 case FT_PROTOCOL:
2764 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2765 break;
2766
2767 case FT_BYTES:
2768 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2769 break;
2770
2771 case FT_UINT_BYTES:
2772 n = get_uint_value(tree, tvb, start, length, encoding);
2773 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2774
2775 /* Instead of calling proto_item_set_len(), since we don't yet
2776 * have a proto_item, we set the field_info's length ourselves. */
2777 new_fi->length = n + length;
2778 break;
2779
2780 case FT_BOOLEAN:
2781 /*
2782 * Map all non-zero values to little-endian for
2783 * backwards compatibility.
2784 */
2785 if (encoding)
2786 encoding = ENC_LITTLE_ENDIAN0x80000000;
2787 proto_tree_set_boolean(new_fi,
2788 get_uint64_value(tree, tvb, start, length, encoding));
2789 break;
2790
2791 case FT_CHAR:
2792 /* XXX - make these just FT_UINT? */
2793 case FT_UINT8:
2794 case FT_UINT16:
2795 case FT_UINT24:
2796 case FT_UINT32:
2797 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2798 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2799 value = (uint32_t)value64;
2800 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2801 new_fi->flags |= FI_VARINT0x00040000;
2802 }
2803 }
2804 else {
2805 /*
2806 * Map all non-zero values to little-endian for
2807 * backwards compatibility.
2808 */
2809 if (encoding)
2810 encoding = ENC_LITTLE_ENDIAN0x80000000;
2811
2812 value = get_uint_value(tree, tvb, start, length, encoding);
2813 }
2814 proto_tree_set_uint(new_fi, value);
2815 break;
2816
2817 case FT_UINT40:
2818 case FT_UINT48:
2819 case FT_UINT56:
2820 case FT_UINT64:
2821 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2822 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2823 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2824 new_fi->flags |= FI_VARINT0x00040000;
2825 }
2826 }
2827 else {
2828 /*
2829 * Map all other non-zero values to little-endian for
2830 * backwards compatibility.
2831 */
2832 if (encoding)
2833 encoding = ENC_LITTLE_ENDIAN0x80000000;
2834
2835 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2836 }
2837 proto_tree_set_uint64(new_fi, value64);
2838 break;
2839
2840 /* XXX - make these just FT_INT? */
2841 case FT_INT8:
2842 case FT_INT16:
2843 case FT_INT24:
2844 case FT_INT32:
2845 /*
2846 * Map all non-zero values to little-endian for
2847 * backwards compatibility.
2848 */
2849 if (encoding)
2850 encoding = ENC_LITTLE_ENDIAN0x80000000;
2851 proto_tree_set_int(new_fi,
2852 get_int_value(tree, tvb, start, length, encoding));
2853 break;
2854
2855 case FT_INT40:
2856 case FT_INT48:
2857 case FT_INT56:
2858 case FT_INT64:
2859 /*
2860 * Map all non-zero values to little-endian for
2861 * backwards compatibility.
2862 */
2863 if (encoding)
2864 encoding = ENC_LITTLE_ENDIAN0x80000000;
2865 proto_tree_set_int64(new_fi,
2866 get_int64_value(tree, tvb, start, length, encoding));
2867 break;
2868
2869 case FT_IPv4:
2870 /*
2871 * Map all non-zero values to little-endian for
2872 * backwards compatibility.
2873 */
2874 if (encoding)
2875 encoding = ENC_LITTLE_ENDIAN0x80000000;
2876 if (length != FT_IPv4_LEN4) {
2877 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2878 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2879 }
2880 ipv4_value = tvb_get_ipv4(tvb, start);
2881 /*
2882 * NOTE: to support code written when
2883 * proto_tree_add_item() took a bool as its
2884 * last argument, with false meaning "big-endian"
2885 * and true meaning "little-endian", we treat any
2886 * non-zero value of "encoding" as meaning
2887 * "little-endian".
2888 */
2889 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);
2890 break;
2891
2892 case FT_IPXNET:
2893 if (length != FT_IPXNET_LEN4) {
2894 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2895 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2896 }
2897 proto_tree_set_ipxnet(new_fi,
2898 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2899 break;
2900
2901 case FT_IPv6:
2902 if (length != FT_IPv6_LEN16) {
2903 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2904 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2905 }
2906 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2907 break;
2908
2909 case FT_FCWWN:
2910 if (length != FT_FCWWN_LEN8) {
2911 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2912 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2913 }
2914 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2915 break;
2916
2917 case FT_AX25:
2918 if (length != 7) {
2919 length_error = length < 7 ? true1 : false0;
2920 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2921 }
2922 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2923 break;
2924
2925 case FT_VINES:
2926 if (length != VINES_ADDR_LEN6) {
2927 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2928 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2929 }
2930 proto_tree_set_vines_tvb(new_fi, tvb, start);
2931 break;
2932
2933 case FT_ETHER:
2934 if (length != FT_ETHER_LEN6) {
2935 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2936 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2937 }
2938 proto_tree_set_ether_tvb(new_fi, tvb, start);
2939 break;
2940
2941 case FT_EUI64:
2942 /*
2943 * Map all non-zero values to little-endian for
2944 * backwards compatibility.
2945 */
2946 if (encoding)
2947 encoding = ENC_LITTLE_ENDIAN0x80000000;
2948 if (length != FT_EUI64_LEN8) {
2949 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
2950 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2951 }
2952 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2953 break;
2954 case FT_GUID:
2955 /*
2956 * Map all non-zero values to little-endian for
2957 * backwards compatibility.
2958 */
2959 if (encoding)
2960 encoding = ENC_LITTLE_ENDIAN0x80000000;
2961 if (length != FT_GUID_LEN16) {
2962 length_error = length < FT_GUID_LEN16 ? true1 : false0;
2963 report_type_length_mismatch(tree, "a GUID", length, length_error);
2964 }
2965 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2966 break;
2967
2968 case FT_OID:
2969 case FT_REL_OID:
2970 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2971 break;
2972
2973 case FT_SYSTEM_ID:
2974 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2975 break;
2976
2977 case FT_FLOAT:
2978 /*
2979 * NOTE: to support code written when
2980 * proto_tree_add_item() took a bool as its
2981 * last argument, with false meaning "big-endian"
2982 * and true meaning "little-endian", we treat any
2983 * non-zero value of "encoding" as meaning
2984 * "little-endian".
2985 *
2986 * At some point in the future, we might
2987 * support non-IEEE-binary floating-point
2988 * formats in the encoding as well
2989 * (IEEE decimal, System/3x0, VAX).
2990 */
2991 if (encoding)
2992 encoding = ENC_LITTLE_ENDIAN0x80000000;
2993 if (length != 4) {
2994 length_error = length < 4 ? true1 : false0;
2995 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2996 }
2997 if (encoding)
2998 floatval = tvb_get_letohieee_float(tvb, start);
2999 else
3000 floatval = tvb_get_ntohieee_float(tvb, start);
3001 proto_tree_set_float(new_fi, floatval);
3002 break;
3003
3004 case FT_DOUBLE:
3005 /*
3006 * NOTE: to support code written when
3007 * proto_tree_add_item() took a bool as its
3008 * last argument, with false meaning "big-endian"
3009 * and true meaning "little-endian", we treat any
3010 * non-zero value of "encoding" as meaning
3011 * "little-endian".
3012 *
3013 * At some point in the future, we might
3014 * support non-IEEE-binary floating-point
3015 * formats in the encoding as well
3016 * (IEEE decimal, System/3x0, VAX).
3017 */
3018 if (encoding == true1)
3019 encoding = ENC_LITTLE_ENDIAN0x80000000;
3020 if (length != 8) {
3021 length_error = length < 8 ? true1 : false0;
3022 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3023 }
3024 if (encoding)
3025 doubleval = tvb_get_letohieee_double(tvb, start);
3026 else
3027 doubleval = tvb_get_ntohieee_double(tvb, start);
3028 proto_tree_set_double(new_fi, doubleval);
3029 break;
3030
3031 case FT_STRING:
3032 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3033 tvb, start, length, &length, encoding);
3034 proto_tree_set_string(new_fi, stringval);
3035
3036 /* Instead of calling proto_item_set_len(), since we
3037 * don't yet have a proto_item, we set the
3038 * field_info's length ourselves.
3039 *
3040 * XXX - our caller can't use that length to
3041 * advance an offset unless they arrange that
3042 * there always be a protocol tree into which
3043 * we're putting this item.
3044 */
3045 new_fi->length = length;
3046 break;
3047
3048 case FT_STRINGZ:
3049 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3050 tree, tvb, start, length, &length, encoding);
3051 proto_tree_set_string(new_fi, stringval);
3052
3053 /* Instead of calling proto_item_set_len(),
3054 * since we don't yet have a proto_item, we
3055 * set the field_info's length ourselves.
3056 *
3057 * XXX - our caller can't use that length to
3058 * advance an offset unless they arrange that
3059 * there always be a protocol tree into which
3060 * we're putting this item.
3061 */
3062 new_fi->length = length;
3063 break;
3064
3065 case FT_UINT_STRING:
3066 /*
3067 * NOTE: to support code written when
3068 * proto_tree_add_item() took a bool as its
3069 * last argument, with false meaning "big-endian"
3070 * and true meaning "little-endian", if the
3071 * encoding value is true, treat that as
3072 * ASCII with a little-endian length.
3073 *
3074 * This won't work for code that passes
3075 * arbitrary non-zero values; that code
3076 * will need to be fixed.
3077 */
3078 if (encoding == true1)
3079 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3080 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3081 tree, tvb, start, length, &length, encoding);
3082 proto_tree_set_string(new_fi, stringval);
3083
3084 /* Instead of calling proto_item_set_len(), since we
3085 * don't yet have a proto_item, we set the
3086 * field_info's length ourselves.
3087 *
3088 * XXX - our caller can't use that length to
3089 * advance an offset unless they arrange that
3090 * there always be a protocol tree into which
3091 * we're putting this item.
3092 */
3093 new_fi->length = length;
3094 break;
3095
3096 case FT_STRINGZPAD:
3097 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3098 tvb, start, length, &length, encoding);
3099 proto_tree_set_string(new_fi, stringval);
3100
3101 /* Instead of calling proto_item_set_len(), since we
3102 * don't yet have a proto_item, we set the
3103 * field_info's length ourselves.
3104 *
3105 * XXX - our caller can't use that length to
3106 * advance an offset unless they arrange that
3107 * there always be a protocol tree into which
3108 * we're putting this item.
3109 */
3110 new_fi->length = length;
3111 break;
3112
3113 case FT_STRINGZTRUNC:
3114 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3115 tvb, start, length, &length, encoding);
3116 proto_tree_set_string(new_fi, stringval);
3117
3118 /* Instead of calling proto_item_set_len(), since we
3119 * don't yet have a proto_item, we set the
3120 * field_info's length ourselves.
3121 *
3122 * XXX - our caller can't use that length to
3123 * advance an offset unless they arrange that
3124 * there always be a protocol tree into which
3125 * we're putting this item.
3126 */
3127 new_fi->length = length;
3128 break;
3129
3130 case FT_ABSOLUTE_TIME:
3131 /*
3132 * Absolute times can be in any of a number of
3133 * formats, and they can be big-endian or
3134 * little-endian.
3135 *
3136 * Historically FT_TIMEs were only timespecs;
3137 * the only question was whether they were stored
3138 * in big- or little-endian format.
3139 *
3140 * For backwards compatibility, we interpret an
3141 * encoding of 1 as meaning "little-endian timespec",
3142 * so that passing true is interpreted as that.
3143 */
3144 if (encoding == true1)
3145 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3146
3147 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3148
3149 proto_tree_set_time(new_fi, &time_stamp);
3150 break;
3151
3152 case FT_RELATIVE_TIME:
3153 /*
3154 * Relative times can be in any of a number of
3155 * formats, and they can be big-endian or
3156 * little-endian.
3157 *
3158 * Historically FT_TIMEs were only timespecs;
3159 * the only question was whether they were stored
3160 * in big- or little-endian format.
3161 *
3162 * For backwards compatibility, we interpret an
3163 * encoding of 1 as meaning "little-endian timespec",
3164 * so that passing true is interpreted as that.
3165 */
3166 if (encoding == true1)
3167 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3168
3169 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3170
3171 proto_tree_set_time(new_fi, &time_stamp);
3172 break;
3173 case FT_IEEE_11073_SFLOAT:
3174 if (encoding)
3175 encoding = ENC_LITTLE_ENDIAN0x80000000;
3176 if (length != 2) {
3177 length_error = length < 2 ? true1 : false0;
3178 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3179 }
3180
3181 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3182
3183 break;
3184 case FT_IEEE_11073_FLOAT:
3185 if (encoding)
3186 encoding = ENC_LITTLE_ENDIAN0x80000000;
3187 if (length != 4) {
3188 length_error = length < 4 ? true1 : false0;
3189 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3190 }
3191 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3192
3193 break;
3194 default:
3195 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))
3196 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))
3197 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))
3198 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))
;
3199 break;
3200 }
3201 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)
;
3202
3203 /* Don't add new node to proto_tree until now so that any exceptions
3204 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3205 /* XXX. wouldn't be better to add this item to tree, with some special
3206 * flag (FI_EXCEPTION?) to know which item caused exception? For
3207 * strings and bytes, we would have to set new_fi->value to something
3208 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3209 * could handle NULL values. */
3210 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3211 pi = proto_tree_add_node(tree, new_fi);
3212
3213 switch (new_fi->hfinfo->type) {
3214
3215 case FT_STRING:
3216 /* XXX: trailing stray character detection should be done
3217 * _before_ conversion to UTF-8, because conversion can change
3218 * the length, or else get_string_length should return a value
3219 * for the "length in bytes of the string after conversion
3220 * including internal nulls." (Noting that we do, for other
3221 * reasons, still need the "length in bytes in the field",
3222 * especially for FT_STRINGZ.)
3223 *
3224 * This is true even for ASCII and UTF-8, because
3225 * substituting REPLACEMENT CHARACTERS for illegal characters
3226 * can also do so (and for UTF-8 possibly even make the
3227 * string _shorter_).
3228 */
3229 detect_trailing_stray_characters(encoding, stringval, length, pi);
3230 break;
3231
3232 default:
3233 break;
3234 }
3235
3236 return pi;
3237}
3238
3239proto_item *
3240proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3241 const int start, int length,
3242 const unsigned encoding, int32_t *retval)
3243{
3244 header_field_info *hfinfo;
3245 field_info *new_fi;
3246 int32_t value;
3247
3248 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", 3248, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3248,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3248, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3249
3250 switch (hfinfo->type) {
3251 case FT_INT8:
3252 case FT_INT16:
3253 case FT_INT24:
3254 case FT_INT32:
3255 break;
3256 case FT_INT64:
3257 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)
3258 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3259 default:
3260 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)
3261 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3262 }
3263
3264 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3265 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3266 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3267 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3268 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3269 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3270 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3271
3272 if (encoding & ENC_STRING0x03000000) {
3273 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3274 }
3275 /* I believe it's ok if this is called with a NULL tree */
3276 value = get_int_value(tree, tvb, start, length, encoding);
3277
3278 if (retval) {
3279 int no_of_bits;
3280 *retval = value;
3281 if (hfinfo->bitmask) {
3282 /* Mask out irrelevant portions */
3283 *retval &= (uint32_t)(hfinfo->bitmask);
3284 /* Shift bits */
3285 *retval >>= hfinfo_bitshift(hfinfo);
3286 }
3287 no_of_bits = ws_count_ones(hfinfo->bitmask);
3288 *retval = ws_sign_ext32(*retval, no_of_bits);
3289 }
3290
3291 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3292
3293 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", 3293
, __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", 3293, "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", 3293, "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", 3293, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3294
3295 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3296
3297 proto_tree_set_int(new_fi, value);
3298
3299 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3300
3301 return proto_tree_add_node(tree, new_fi);
3302}
3303
3304proto_item *
3305proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3306 const int start, int length,
3307 const unsigned encoding, uint32_t *retval)
3308{
3309 header_field_info *hfinfo;
3310 field_info *new_fi;
3311 uint32_t value;
3312
3313 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", 3313, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3313,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3313, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3314
3315 switch (hfinfo->type) {
3316 case FT_CHAR:
3317 case FT_UINT8:
3318 case FT_UINT16:
3319 case FT_UINT24:
3320 case FT_UINT32:
3321 break;
3322 default:
3323 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)
3324 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)
;
3325 }
3326
3327 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3328 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3329 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3330 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3331 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3332 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3333 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3334
3335 if (encoding & ENC_STRING0x03000000) {
3336 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3337 }
3338 /* I believe it's ok if this is called with a NULL tree */
3339 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3340 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3341 uint64_t temp64;
3342 tvb_get_varint(tvb, start, length, &temp64, encoding);
3343 value = (uint32_t)temp64;
3344 } else {
3345 value = get_uint_value(tree, tvb, start, length, encoding);
3346 }
3347
3348 if (retval) {
3349 *retval = value;
3350 if (hfinfo->bitmask) {
3351 /* Mask out irrelevant portions */
3352 *retval &= (uint32_t)(hfinfo->bitmask);
3353 /* Shift bits */
3354 *retval >>= hfinfo_bitshift(hfinfo);
3355 }
3356 }
3357
3358 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3359
3360 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", 3360
, __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", 3360, "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", 3360, "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", 3360, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3361
3362 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3363
3364 proto_tree_set_uint(new_fi, value);
3365
3366 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3367 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3368 new_fi->flags |= FI_VARINT0x00040000;
3369 }
3370 return proto_tree_add_node(tree, new_fi);
3371}
3372
3373/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3374 * and returns proto_item* and uint value retreived*/
3375proto_item *
3376ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3377 const unsigned encoding, uint32_t *retval)
3378{
3379 field_info *new_fi;
3380 header_field_info *hfinfo;
3381 int item_length;
3382 int offset;
3383 uint32_t value;
3384
3385 offset = ptvc->offset;
3386 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", 3386, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3386,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3386, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3387
3388 switch (hfinfo->type) {
3389 case FT_CHAR:
3390 case FT_UINT8:
3391 case FT_UINT16:
3392 case FT_UINT24:
3393 case FT_UINT32:
3394 break;
3395 default:
3396 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)
3397 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)
;
3398 }
3399
3400 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3401 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3402
3403 /* I believe it's ok if this is called with a NULL tree */
3404 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3405 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3406
3407 if (retval) {
3408 *retval = value;
3409 if (hfinfo->bitmask) {
3410 /* Mask out irrelevant portions */
3411 *retval &= (uint32_t)(hfinfo->bitmask);
3412 /* Shift bits */
3413 *retval >>= hfinfo_bitshift(hfinfo);
3414 }
3415 }
3416
3417 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3418 item_length, encoding);
3419
3420 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3421
3422 /* Coast clear. Try and fake it */
3423 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", 3423
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3423, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3423, "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", 3423, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((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); } } }
;
3424
3425 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3426
3427 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3428 offset, length, encoding);
3429}
3430
3431/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3432 * and returns proto_item* and int value retreived*/
3433proto_item *
3434ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3435 const unsigned encoding, int32_t *retval)
3436{
3437 field_info *new_fi;
3438 header_field_info *hfinfo;
3439 int item_length;
3440 int offset;
3441 uint32_t value;
3442
3443 offset = ptvc->offset;
3444 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", 3444, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3444,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3444, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3445
3446 switch (hfinfo->type) {
3447 case FT_INT8:
3448 case FT_INT16:
3449 case FT_INT24:
3450 case FT_INT32:
3451 break;
3452 default:
3453 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)
3454 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3455 }
3456
3457 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3458 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3459
3460 /* I believe it's ok if this is called with a NULL tree */
3461 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3462 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3463
3464 if (retval) {
3465 int no_of_bits;
3466 *retval = value;
3467 if (hfinfo->bitmask) {
3468 /* Mask out irrelevant portions */
3469 *retval &= (uint32_t)(hfinfo->bitmask);
3470 /* Shift bits */
3471 *retval >>= hfinfo_bitshift(hfinfo);
3472 }
3473 no_of_bits = ws_count_ones(hfinfo->bitmask);
3474 *retval = ws_sign_ext32(*retval, no_of_bits);
3475 }
3476
3477 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3478 item_length, encoding);
3479
3480 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3481
3482 /* Coast clear. Try and fake it */
3483 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", 3483
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3483, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3483, "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", 3483, __func__, "Adding %s would put more than %d 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); } } }
;
3484
3485 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3486
3487 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3488 offset, length, encoding);
3489}
3490
3491/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3492 * and returns proto_item* and string value retreived */
3493proto_item*
3494ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3495{
3496 header_field_info *hfinfo;
3497 field_info *new_fi;
3498 const uint8_t *value;
3499 int item_length;
3500 int offset;
3501
3502 offset = ptvc->offset;
3503
3504 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", 3504
, __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", 3504, "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", 3504, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3505
3506 switch (hfinfo->type) {
3507 case FT_STRING:
3508 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3509 break;
3510 case FT_STRINGZ:
3511 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3512 break;
3513 case FT_UINT_STRING:
3514 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3515 break;
3516 case FT_STRINGZPAD:
3517 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3518 break;
3519 case FT_STRINGZTRUNC:
3520 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3521 break;
3522 default:
3523 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)
3524 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)
;
3525 }
3526
3527 if (retval)
3528 *retval = value;
3529
3530 ptvc->offset += item_length;
3531
3532 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3533
3534 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", 3534, __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", 3534,
"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", 3534, "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", 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 boolean value retreived */
3544proto_item*
3545ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3546{
3547 header_field_info *hfinfo;
3548 field_info *new_fi;
3549 int item_length;
3550 int offset;
3551 uint64_t value, bitval;
3552
3553 offset = ptvc->offset;
3554 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", 3554, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3554,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3554, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3555
3556 if (hfinfo->type != FT_BOOLEAN) {
3557 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)
3558 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3559 }
3560
3561 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3562 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3563 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3564 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3565 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3566 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3567 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3568
3569 if (encoding & ENC_STRING0x03000000) {
3570 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3571 }
3572
3573 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3574 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3575
3576 /* I believe it's ok if this is called with a NULL tree */
3577 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3578
3579 if (retval) {
3580 bitval = value;
3581 if (hfinfo->bitmask) {
3582 /* Mask out irrelevant portions */
3583 bitval &= hfinfo->bitmask;
3584 }
3585 *retval = (bitval != 0);
3586 }
3587
3588 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3589 item_length, encoding);
3590
3591 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3592
3593 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", 3593, __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", 3593,
"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", 3593, "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", 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
3601proto_item *
3602proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3603 const int start, int length, const unsigned encoding, uint64_t *retval)
3604{
3605 header_field_info *hfinfo;
3606 field_info *new_fi;
3607 uint64_t value;
3608
3609 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", 3609, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3609,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3609, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3610
3611 switch (hfinfo->type) {
3612 case FT_UINT40:
3613 case FT_UINT48:
3614 case FT_UINT56:
3615 case FT_UINT64:
3616 break;
3617 default:
3618 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)
3619 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3620 }
3621
3622 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3623 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3624 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3625 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3626 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3627 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3628 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3629
3630 if (encoding & ENC_STRING0x03000000) {
3631 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3632 }
3633 /* I believe it's ok if this is called with a NULL tree */
3634 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3635 tvb_get_varint(tvb, start, length, &value, encoding);
3636 } else {
3637 value = get_uint64_value(tree, tvb, start, length, encoding);
3638 }
3639
3640 if (retval) {
3641 *retval = value;
3642 if (hfinfo->bitmask) {
3643 /* Mask out irrelevant portions */
3644 *retval &= hfinfo->bitmask;
3645 /* Shift bits */
3646 *retval >>= hfinfo_bitshift(hfinfo);
3647 }
3648 }
3649
3650 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3651
3652 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", 3652
, __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", 3652, "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", 3652, "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", 3652, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3653
3654 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3655
3656 proto_tree_set_uint64(new_fi, value);
3657
3658 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3659 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3660 new_fi->flags |= FI_VARINT0x00040000;
3661 }
3662
3663 return proto_tree_add_node(tree, new_fi);
3664}
3665
3666proto_item *
3667proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3668 const int start, int length, const unsigned encoding, int64_t *retval)
3669{
3670 header_field_info *hfinfo;
3671 field_info *new_fi;
3672 int64_t value;
3673
3674 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", 3674, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3674,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3674, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3675
3676 switch (hfinfo->type) {
3677 case FT_INT40:
3678 case FT_INT48:
3679 case FT_INT56:
3680 case FT_INT64:
3681 break;
3682 default:
3683 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)
3684 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3685 }
3686
3687 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3688 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3689 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3690 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3691 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3692 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3693 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3694
3695 if (encoding & ENC_STRING0x03000000) {
3696 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3697 }
3698 /* I believe it's ok if this is called with a NULL tree */
3699 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3700 tvb_get_varint(tvb, start, length, &value, encoding);
3701 }
3702 else {
3703 value = get_int64_value(tree, tvb, start, length, encoding);
3704 }
3705
3706 if (retval) {
3707 *retval = value;
3708 }
3709
3710 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3711
3712 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3712
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3712, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3712, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3712, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3713
3714 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3715
3716 proto_tree_set_int64(new_fi, value);
3717
3718 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3719 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3720 new_fi->flags |= FI_VARINT0x00040000;
3721 }
3722
3723 return proto_tree_add_node(tree, new_fi);
3724}
3725
3726proto_item *
3727proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3728 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3729{
3730 header_field_info *hfinfo;
3731 field_info *new_fi;
3732 uint64_t value;
3733
3734 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3734, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3734,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3734, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3735
3736 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
))
)) {
3737 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)
3738 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3739 }
3740
3741 /* length validation for native number encoding caught by get_uint64_value() */
3742 /* length has to be -1 or > 0 regardless of encoding */
3743 if (length == 0)
3744 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)
3745 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3746
3747 if (encoding & ENC_STRING0x03000000) {
3748 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3749 }
3750
3751 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3752
3753 if (retval) {
3754 *retval = value;
3755 if (hfinfo->bitmask) {
3756 /* Mask out irrelevant portions */
3757 *retval &= hfinfo->bitmask;
3758 /* Shift bits */
3759 *retval >>= hfinfo_bitshift(hfinfo);
3760 }
3761 }
3762
3763 if (lenretval) {
3764 *lenretval = length;
3765 }
3766
3767 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3768
3769 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", 3769
, __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", 3769, "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", 3769, "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", 3769, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3770
3771 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3772
3773 proto_tree_set_uint64(new_fi, value);
3774
3775 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3776 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3777 new_fi->flags |= FI_VARINT0x00040000;
3778 }
3779
3780 return proto_tree_add_node(tree, new_fi);
3781
3782}
3783
3784proto_item *
3785proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3786 const int start, int length,
3787 const unsigned encoding, bool_Bool *retval)
3788{
3789 header_field_info *hfinfo;
3790 field_info *new_fi;
3791 uint64_t value, bitval;
3792
3793 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", 3793, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3793,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3793, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3794
3795 if (hfinfo->type != FT_BOOLEAN) {
3796 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)
3797 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3798 }
3799
3800 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3801 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3802 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3803 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3804 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3805 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3806 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3807
3808 if (encoding & ENC_STRING0x03000000) {
3809 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3810 }
3811 /* I believe it's ok if this is called with a NULL tree */
3812 value = get_uint64_value(tree, tvb, start, length, encoding);
3813
3814 if (retval) {
3815 bitval = value;
3816 if (hfinfo->bitmask) {
3817 /* Mask out irrelevant portions */
3818 bitval &= hfinfo->bitmask;
3819 }
3820 *retval = (bitval != 0);
3821 }
3822
3823 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3824
3825 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", 3825
, __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", 3825, "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", 3825, "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", 3825, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3826
3827 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3828
3829 proto_tree_set_boolean(new_fi, value);
3830
3831 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3832
3833 return proto_tree_add_node(tree, new_fi);
3834}
3835
3836proto_item *
3837proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3838 const int start, int length,
3839 const unsigned encoding, float *retval)
3840{
3841 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3842 field_info *new_fi;
3843 float value;
3844
3845 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", 3845,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3846
3847 if (hfinfo->type != FT_FLOAT) {
3848 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)
;
3849 }
3850
3851 if (length != 4) {
3852 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3853 }
3854
3855 /* treat any nonzero encoding as little endian for backwards compatibility */
3856 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3857 if (retval) {
3858 *retval = value;
3859 }
3860
3861 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3862
3863 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", 3863
, __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", 3863, "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", 3863, "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", 3863, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3864
3865 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3866 if (encoding) {
3867 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3868 }
3869
3870 proto_tree_set_float(new_fi, value);
3871
3872 return proto_tree_add_node(tree, new_fi);
3873}
3874
3875proto_item *
3876proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3877 const int start, int length,
3878 const unsigned encoding, double *retval)
3879{
3880 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3881 field_info *new_fi;
3882 double value;
3883
3884 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", 3884,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3885
3886 if (hfinfo->type != FT_DOUBLE) {
3887 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)
;
3888 }
3889
3890 if (length != 8) {
3891 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3892 }
3893
3894 /* treat any nonzero encoding as little endian for backwards compatibility */
3895 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3896 if (retval) {
3897 *retval = value;
3898 }
3899
3900 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3901
3902 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", 3902
, __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", 3902, "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", 3902, "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", 3902, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3903
3904 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3905 if (encoding) {
3906 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3907 }
3908
3909 proto_tree_set_double(new_fi, value);
3910
3911 return proto_tree_add_node(tree, new_fi);
3912}
3913
3914proto_item *
3915proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3916 const int start, int length,
3917 const unsigned encoding, ws_in4_addr *retval)
3918{
3919 header_field_info *hfinfo;
3920 field_info *new_fi;
3921 ws_in4_addr value;
3922
3923 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", 3923, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3923,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3923, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3924
3925 switch (hfinfo->type) {
3926 case FT_IPv4:
3927 break;
3928 default:
3929 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)
3930 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3931 }
3932
3933 if (length != FT_IPv4_LEN4)
3934 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)
3935 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3936
3937 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3938 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3939 }
3940
3941 /*
3942 * NOTE: to support code written when proto_tree_add_item() took
3943 * a bool as its last argument, with false meaning "big-endian"
3944 * and true meaning "little-endian", we treat any non-zero value
3945 * of "encoding" as meaning "little-endian".
3946 */
3947 value = tvb_get_ipv4(tvb, start);
3948 if (encoding)
3949 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))))
;
3950
3951 if (retval) {
3952 *retval = value;
3953 }
3954
3955 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3956
3957 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", 3957
, __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", 3957, "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", 3957, "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", 3957, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3958
3959 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3960
3961 proto_tree_set_ipv4(new_fi, value);
3962
3963 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3964 return proto_tree_add_node(tree, new_fi);
3965}
3966
3967proto_item *
3968proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3969 const int start, int length,
3970 const unsigned encoding, ws_in6_addr *addr)
3971{
3972 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3973 field_info *new_fi;
3974
3975 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", 3975,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3976
3977 switch (hfinfo->type) {
3978 case FT_IPv6:
3979 break;
3980 default:
3981 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)
3982 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
3983 }
3984
3985 if (length != FT_IPv6_LEN16)
3986 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)
3987 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
3988
3989 if (encoding) {
3990 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"
)
;
3991 }
3992
3993 tvb_get_ipv6(tvb, start, addr);
3994
3995 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3996
3997 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", 3997
, __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", 3997, "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", 3997, "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", 3997, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3998
3999 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4000
4001 proto_tree_set_ipv6(new_fi, addr);
4002
4003 return proto_tree_add_node(tree, new_fi);
4004}
4005
4006proto_item *
4007proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4008 const int start, int length, const unsigned encoding, uint8_t *retval) {
4009
4010 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4011 field_info *new_fi;
4012
4013 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", 4013,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4014
4015 switch (hfinfo->type) {
4016 case FT_ETHER:
4017 break;
4018 default:
4019 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)
4020 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4021 }
4022
4023 if (length != FT_ETHER_LEN6)
4024 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)
4025 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4026
4027 if (encoding) {
4028 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"
)
;
4029 }
4030
4031 tvb_memcpy(tvb, retval, start, length);
4032
4033 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4034
4035 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", 4035
, __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", 4035, "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", 4035, "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", 4035, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4036
4037 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4038
4039 proto_tree_set_ether(new_fi, retval);
4040
4041 return proto_tree_add_node(tree, new_fi);
4042}
4043
4044
4045proto_item *
4046proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4047 tvbuff_t *tvb,
4048 const int start, int length,
4049 const unsigned encoding,
4050 wmem_allocator_t *scope,
4051 const uint8_t **retval,
4052 int *lenretval)
4053{
4054 proto_item *pi;
4055 header_field_info *hfinfo;
4056 field_info *new_fi;
4057 const uint8_t *value;
4058
4059 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", 4059, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4059,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4059, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4060
4061 switch (hfinfo->type) {
4062 case FT_STRING:
4063 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4064 break;
4065 case FT_STRINGZ:
4066 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4067 break;
4068 case FT_UINT_STRING:
4069 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4070 break;
4071 case FT_STRINGZPAD:
4072 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4073 break;
4074 case FT_STRINGZTRUNC:
4075 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4076 break;
4077 default:
4078 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)
4079 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)
;
4080 }
4081
4082 if (retval)
4083 *retval = value;
4084
4085 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4086
4087 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", 4087
, __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", 4087, "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", 4087, "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", 4087, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4088
4089 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4090
4091 proto_tree_set_string(new_fi, value);
4092
4093 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4094
4095 pi = proto_tree_add_node(tree, new_fi);
4096
4097 switch (hfinfo->type) {
4098
4099 case FT_STRINGZ:
4100 case FT_STRINGZPAD:
4101 case FT_STRINGZTRUNC:
4102 case FT_UINT_STRING:
4103 break;
4104
4105 case FT_STRING:
4106 detect_trailing_stray_characters(encoding, value, length, pi);
4107 break;
4108
4109 default:
4110 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4110
, __func__, "assertion \"not reached\" failed")
;
4111 }
4112
4113 return pi;
4114}
4115
4116proto_item *
4117proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4118 const int start, int length,
4119 const unsigned encoding, wmem_allocator_t *scope,
4120 const uint8_t **retval)
4121{
4122 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4123 tvb, start, length, encoding, scope, retval, &length);
4124}
4125
4126proto_item *
4127proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4128 tvbuff_t *tvb,
4129 const int start, int length,
4130 const unsigned encoding,
4131 wmem_allocator_t *scope,
4132 char **retval,
4133 int *lenretval)
4134{
4135 proto_item *pi;
4136 header_field_info *hfinfo;
4137 field_info *new_fi;
4138 const uint8_t *value;
4139 uint32_t n = 0;
4140
4141 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", 4141, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4141,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4141, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4142
4143 switch (hfinfo->type) {
4144 case FT_STRING:
4145 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4146 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4147 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4148 break;
4149 case FT_STRINGZ:
4150 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4151 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4152 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4153 break;
4154 case FT_UINT_STRING:
4155 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4156 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4157 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4158 break;
4159 case FT_STRINGZPAD:
4160 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4161 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4162 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4163 break;
4164 case FT_STRINGZTRUNC:
4165 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4166 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4167 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4168 break;
4169 case FT_BYTES:
4170 tvb_ensure_bytes_exist(tvb, start, length);
4171 value = tvb_get_ptr(tvb, start, length);
4172 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4173 *lenretval = length;
4174 break;
4175 case FT_UINT_BYTES:
4176 n = get_uint_value(tree, tvb, start, length, encoding);
4177 tvb_ensure_bytes_exist(tvb, start + length, n);
4178 value = tvb_get_ptr(tvb, start + length, n);
4179 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4180 *lenretval = length + n;
4181 break;
4182 default:
4183 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)
4184 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)
;
4185 }
4186
4187 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4188
4189 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", 4189
, __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", 4189, "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", 4189, "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", 4189, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4190
4191 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4192
4193 switch (hfinfo->type) {
4194
4195 case FT_STRING:
4196 case FT_STRINGZ:
4197 case FT_UINT_STRING:
4198 case FT_STRINGZPAD:
4199 case FT_STRINGZTRUNC:
4200 proto_tree_set_string(new_fi, value);
4201 break;
4202
4203 case FT_BYTES:
4204 proto_tree_set_bytes(new_fi, value, length);
4205 break;
4206
4207 case FT_UINT_BYTES:
4208 proto_tree_set_bytes(new_fi, value, n);
4209 break;
4210
4211 default:
4212 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4212
, __func__, "assertion \"not reached\" failed")
;
4213 }
4214
4215 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4216
4217 pi = proto_tree_add_node(tree, new_fi);
4218
4219 switch (hfinfo->type) {
4220
4221 case FT_STRINGZ:
4222 case FT_STRINGZPAD:
4223 case FT_STRINGZTRUNC:
4224 case FT_UINT_STRING:
4225 break;
4226
4227 case FT_STRING:
4228 detect_trailing_stray_characters(encoding, value, length, pi);
4229 break;
4230
4231 case FT_BYTES:
4232 case FT_UINT_BYTES:
4233 break;
4234
4235 default:
4236 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4236
, __func__, "assertion \"not reached\" failed")
;
4237 }
4238
4239 return pi;
4240}
4241
4242proto_item *
4243proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4244 tvbuff_t *tvb,
4245 const int start, int length,
4246 const unsigned encoding,
4247 wmem_allocator_t *scope,
4248 char **retval)
4249{
4250 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4251 tvb, start, length, encoding, scope, retval, &length);
4252}
4253
4254proto_item *
4255proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4256 tvbuff_t *tvb,
4257 const int start, int length, const unsigned encoding,
4258 wmem_allocator_t *scope, char **retval)
4259{
4260 header_field_info *hfinfo;
4261 field_info *new_fi;
4262 nstime_t time_stamp;
4263 int flags;
4264
4265 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", 4265, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4265,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4265, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4266
4267 switch (hfinfo->type) {
4268 case FT_ABSOLUTE_TIME:
4269 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4270 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4271 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4272 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4273 }
4274 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4275 break;
4276 case FT_RELATIVE_TIME:
4277 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4278 *retval = rel_time_to_secs_str(scope, &time_stamp);
4279 break;
4280 default:
4281 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)
4282 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4283 }
4284
4285 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4286
4287 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", 4287
, __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", 4287, "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", 4287, "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", 4287, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4288
4289 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4290
4291 switch (hfinfo->type) {
4292
4293 case FT_ABSOLUTE_TIME:
4294 case FT_RELATIVE_TIME:
4295 proto_tree_set_time(new_fi, &time_stamp);
4296 break;
4297 default:
4298 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4298
, __func__, "assertion \"not reached\" failed")
;
4299 }
4300
4301 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4302
4303 return proto_tree_add_node(tree, new_fi);
4304}
4305
4306/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4307 and returns proto_item* */
4308proto_item *
4309ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4310 const unsigned encoding)
4311{
4312 field_info *new_fi;
4313 header_field_info *hfinfo;
4314 int item_length;
4315 int offset;
4316
4317 offset = ptvc->offset;
4318 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", 4318, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4318,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4318, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4319 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4320 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4321
4322 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
4323 item_length, encoding);
4324
4325 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4326
4327 /* Coast clear. Try and fake it */
4328 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", 4328
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4328, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4328, "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", 4328, __func__, "Adding %s would put more than %d 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); } } }
;
4329
4330 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4331
4332 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4333 offset, length, encoding);
4334}
4335
4336/* Add an item to a proto_tree, using the text label registered to that item;
4337 the item is extracted from the tvbuff handed to it. */
4338proto_item *
4339proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4340 const int start, int length, const unsigned encoding)
4341{
4342 field_info *new_fi;
4343 int item_length;
4344
4345 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", 4345,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4346
4347 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4348 test_length(hfinfo, tvb, start, item_length, encoding);
4349
4350 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4351
4352 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", 4352
, __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", 4352, "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", 4352, "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", 4352, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4353
4354 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4355
4356 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4357}
4358
4359proto_item *
4360proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4361 const int start, int length, const unsigned encoding)
4362{
4363 register header_field_info *hfinfo;
4364
4365 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", 4365, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4365,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4365, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4366 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4367}
4368
4369/* Add an item to a proto_tree, using the text label registered to that item;
4370 the item is extracted from the tvbuff handed to it.
4371
4372 Return the length of the item through the pointer. */
4373proto_item *
4374proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4375 tvbuff_t *tvb, const int start,
4376 int length, const unsigned encoding,
4377 int *lenretval)
4378{
4379 field_info *new_fi;
4380 int item_length;
4381 proto_item *item;
4382
4383 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", 4383,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4384
4385 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4386 test_length(hfinfo, tvb, start, item_length, encoding);
4387
4388 if (!tree) {
4389 /*
4390 * We need to get the correct item length here.
4391 * That's normally done by proto_tree_new_item(),
4392 * but we won't be calling it.
4393 */
4394 *lenretval = get_full_length(hfinfo, tvb, start, length,
4395 item_length, encoding);
4396 return NULL((void*)0);
4397 }
4398
4399 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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4400 /*((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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4401 * 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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4402 * 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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4403 */((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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4404 *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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4405 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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4406 })((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", 4406
, __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", 4406, "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", 4406, "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", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4407
4408 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4409
4410 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4411 *lenretval = new_fi->length;
4412 return item;
4413}
4414
4415proto_item *
4416proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4417 const int start, int length,
4418 const unsigned encoding, int *lenretval)
4419{
4420 register header_field_info *hfinfo;
4421
4422 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", 4422, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4422,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4422, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4423 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4424}
4425
4426/* which FT_ types can use proto_tree_add_bytes_item() */
4427static inline bool_Bool
4428validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4429{
4430 return (type == FT_BYTES ||
4431 type == FT_UINT_BYTES ||
4432 type == FT_OID ||
4433 type == FT_REL_OID ||
4434 type == FT_SYSTEM_ID );
4435}
4436
4437/* Note: this does no validation that the byte array of an FT_OID or
4438 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4439 so I think it's ok to continue not validating it?
4440 */
4441proto_item *
4442proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4443 const int start, int length, const unsigned encoding,
4444 GByteArray *retval, int *endoff, int *err)
4445{
4446 field_info *new_fi;
4447 GByteArray *bytes = retval;
4448 GByteArray *created_bytes = NULL((void*)0);
4449 bool_Bool failed = false0;
4450 uint32_t n = 0;
4451 header_field_info *hfinfo;
4452 bool_Bool generate = (bytes || tree) ? true1 : false0;
4453
4454 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", 4454, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4454,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4454, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4455
4456 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", 4456,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4457
4458 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", 4459, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4459 "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", 4459, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4460
4461 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4462
4463 if (encoding & ENC_STR_NUM0x01000000) {
4464 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"
)
;
4465 }
4466
4467 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4468 if (hfinfo->type == FT_UINT_BYTES) {
4469 /* can't decode FT_UINT_BYTES from strings */
4470 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")
4471 "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")
;
4472 }
4473
4474 unsigned hex_encoding = encoding;
4475 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4476 /* If none of the separator values are used,
4477 * assume no separator (the common case). */
4478 hex_encoding |= ENC_SEP_NONE0x00010000;
4479#if 0
4480 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")
4481 "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")
;
4482#endif
4483 }
4484
4485 if (!bytes) {
4486 /* caller doesn't care about return value, but we need it to
4487 call tvb_get_string_bytes() and set the tree later */
4488 bytes = created_bytes = g_byte_array_new();
4489 }
4490
4491 /*
4492 * bytes might be NULL after this, but can't add expert
4493 * error until later; if it's NULL, just note that
4494 * it failed.
4495 */
4496 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4497 if (bytes == NULL((void*)0))
4498 failed = true1;
4499 }
4500 else if (generate) {
4501 tvb_ensure_bytes_exist(tvb, start, length);
4502
4503 if (hfinfo->type == FT_UINT_BYTES) {
4504 n = length; /* n is now the "header" length */
4505 length = get_uint_value(tree, tvb, start, n, encoding);
4506 /* length is now the value's length; only store the value in the array */
4507 tvb_ensure_bytes_exist(tvb, start + n, length);
4508 if (!bytes) {
4509 /* caller doesn't care about return value, but
4510 * we may need it to set the tree later */
4511 bytes = created_bytes = g_byte_array_new();
4512 }
4513 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4514 }
4515 else if (length > 0) {
4516 if (!bytes) {
4517 /* caller doesn't care about return value, but
4518 * we may need it to set the tree later */
4519 bytes = created_bytes = g_byte_array_new();
4520 }
4521 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4522 }
4523
4524 if (endoff)
4525 *endoff = start + n + length;
4526 }
4527
4528 if (err)
4529 *err = failed ? EINVAL22 : 0;
4530
4531 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); }
4532 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4533 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); }
4534 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); }
4535 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); }
4536 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4537 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4538
4539 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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4540 {((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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4541 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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4542 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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4543 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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4544 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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4545 } )((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", 4545
, __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", 4545, "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", 4545, "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", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4546
4547 /* n will be zero except when it's a FT_UINT_BYTES */
4548 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4549
4550 if (encoding & ENC_STRING0x03000000) {
4551 if (failed)
4552 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4553
4554 if (bytes)
4555 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4556 else
4557 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4558
4559 if (created_bytes)
4560 g_byte_array_free(created_bytes, true1);
4561 }
4562 else {
4563 /* n will be zero except when it's a FT_UINT_BYTES */
4564 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4565
4566 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4567 * use the byte array created above in this case.
4568 */
4569 if (created_bytes)
4570 g_byte_array_free(created_bytes, true1);
4571
4572 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4573 (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)
;
4574 }
4575
4576 return proto_tree_add_node(tree, new_fi);
4577}
4578
4579
4580proto_item *
4581proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4582 const int start, int length, const unsigned encoding,
4583 nstime_t *retval, int *endoff, int *err)
4584{
4585 field_info *new_fi;
4586 nstime_t time_stamp;
4587 int saved_err = 0;
4588 header_field_info *hfinfo;
4589
4590 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", 4590, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4590,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4590, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4591
4592 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", 4592,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4593
4594 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4595 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4596 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4597 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4598 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4599 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4600 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4601
4602 nstime_set_zero(&time_stamp);
4603
4604 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4605 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", 4605, ((hfinfo))->abbrev))))
;
4606 /* The only string format that could be a relative time is
4607 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4608 * relative to "now" currently.
4609 */
4610 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4611 saved_err = EINVAL22;
4612 }
4613 else {
4614 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", 4614, ((hfinfo))->abbrev))))
;
4615 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4616
4617 tvb_ensure_bytes_exist(tvb, start, length);
4618 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4619 if (endoff) *endoff = start + length;
4620 }
4621
4622 if (err) *err = saved_err;
4623
4624 if (retval) {
4625 retval->secs = time_stamp.secs;
4626 retval->nsecs = time_stamp.nsecs;
4627 }
4628
4629 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4630
4631 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", 4631
, __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", 4631, "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", 4631, "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", 4631, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4632
4633 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4634
4635 proto_tree_set_time(new_fi, &time_stamp);
4636
4637 if (encoding & ENC_STRING0x03000000) {
4638 if (saved_err)
4639 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4640 }
4641 else {
4642 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4643 (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)
;
4644 }
4645
4646 return proto_tree_add_node(tree, new_fi);
4647}
4648
4649/* Add a FT_NONE to a proto_tree */
4650proto_item *
4651proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4652 const int start, int length, const char *format,
4653 ...)
4654{
4655 proto_item *pi;
4656 va_list ap;
4657 header_field_info *hfinfo;
4658
4659 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4660
4661 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", 4661
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4661, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4661, "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", 4661, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4662
4663 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", 4663
, ((hfinfo))->abbrev))))
;
4664
4665 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4666
4667 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4667, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4668
4669 va_start(ap, format)__builtin_va_start(ap, format);
4670 proto_tree_set_representation(pi, format, ap);
4671 va_end(ap)__builtin_va_end(ap);
4672
4673 /* no value to set for FT_NONE */
4674 return pi;
4675}
4676
4677/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4678 * offset, and returns proto_item* */
4679proto_item *
4680ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4681 const unsigned encoding)
4682{
4683 proto_item *item;
4684
4685 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4686 length, encoding);
4687
4688 return item;
4689}
4690
4691/* Advance the ptvcursor's offset within its tvbuff without
4692 * adding anything to the proto_tree. */
4693void
4694ptvcursor_advance(ptvcursor_t* ptvc, int length)
4695{
4696 ptvc->offset += length;
4697}
4698
4699
4700static void
4701proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4702{
4703 fvalue_set_protocol(fi->value, tvb, field_data, length);
4704}
4705
4706/* Add a FT_PROTOCOL to a proto_tree */
4707proto_item *
4708proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4709 int start, int length, const char *format, ...)
4710{
4711 proto_item *pi;
4712 tvbuff_t *protocol_tvb;
4713 va_list ap;
4714 header_field_info *hfinfo;
4715 char* protocol_rep;
4716
4717 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4718
4719 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", 4719
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4719, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4719, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4719, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4720
4721 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"
, 4721, ((hfinfo))->abbrev))))
;
4722
4723 /*
4724 * This can throw an exception, so do it before we allocate anything.
4725 */
4726 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4727
4728 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4729
4730 va_start(ap, format)__builtin_va_start(ap, format);
4731 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4732 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4733 g_free(protocol_rep);
4734 va_end(ap)__builtin_va_end(ap);
4735
4736 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4736, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4737
4738 va_start(ap, format)__builtin_va_start(ap, format);
4739 proto_tree_set_representation(pi, format, ap);
4740 va_end(ap)__builtin_va_end(ap);
4741
4742 return pi;
4743}
4744
4745/* Add a FT_BYTES to a proto_tree */
4746proto_item *
4747proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4748 int length, const uint8_t *start_ptr)
4749{
4750 proto_item *pi;
4751 header_field_info *hfinfo;
4752 int item_length;
4753
4754 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", 4754, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4754,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4754, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4755 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4756 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4757
4758 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4759
4760 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", 4760
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4760, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4760, "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", 4760, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4761
4762 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",
4762, ((hfinfo))->abbrev))))
;
4763
4764 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4765 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4766
4767 return pi;
4768}
4769
4770/* Add a FT_BYTES to a proto_tree */
4771proto_item *
4772proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4773 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4774{
4775 proto_item *pi;
4776 header_field_info *hfinfo;
4777 int item_length;
4778
4779 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", 4779, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4779,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4779, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4780 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4781 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4782
4783 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4784
4785 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", 4785
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4785, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4785, "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", 4785, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4786
4787 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",
4787, ((hfinfo))->abbrev))))
;
4788
4789 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4790 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4791
4792 return pi;
4793}
4794
4795proto_item *
4796proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4797 int start, int length,
4798 const uint8_t *start_ptr,
4799 const char *format, ...)
4800{
4801 proto_item *pi;
4802 va_list ap;
4803
4804 if (start_ptr == NULL((void*)0))
4805 start_ptr = tvb_get_ptr(tvb, start, length);
4806
4807 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4808
4809 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; }
;
4810
4811 va_start(ap, format)__builtin_va_start(ap, format);
4812 proto_tree_set_representation_value(pi, format, ap);
4813 va_end(ap)__builtin_va_end(ap);
4814
4815 return pi;
4816}
4817
4818proto_item *
4819proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4820 int start, int length, const uint8_t *start_ptr,
4821 const char *format, ...)
4822{
4823 proto_item *pi;
4824 va_list ap;
4825
4826 if (start_ptr == NULL((void*)0))
4827 start_ptr = tvb_get_ptr(tvb, start, length);
4828
4829 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4830
4831 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; }
;
4832
4833 va_start(ap, format)__builtin_va_start(ap, format);
4834 proto_tree_set_representation(pi, format, ap);
4835 va_end(ap)__builtin_va_end(ap);
4836
4837 return pi;
4838}
4839
4840static void
4841proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4842{
4843 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4843, "length >= 0"
))))
;
4844 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", 4844, "start_ptr != ((void*)0) || length == 0"
))))
;
4845
4846 fvalue_set_bytes_data(fi->value, start_ptr, length);
4847}
4848
4849
4850static void
4851proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4852{
4853 tvb_ensure_bytes_exist(tvb, offset, length);
4854 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4855}
4856
4857static void
4858proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4859{
4860 GByteArray *bytes;
4861
4862 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4862, "value != ((void*)0)"
))))
;
4863
4864 bytes = byte_array_dup(value);
4865
4866 fvalue_set_byte_array(fi->value, bytes);
4867}
4868
4869/* Add a FT_*TIME to a proto_tree */
4870proto_item *
4871proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4872 int length, const nstime_t *value_ptr)
4873{
4874 proto_item *pi;
4875 header_field_info *hfinfo;
4876
4877 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4878
4879 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", 4879
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4879, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4879, "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", 4879, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4880
4881 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", 4881, ((hfinfo))->abbrev))))
;
4882
4883 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4884 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4885
4886 return pi;
4887}
4888
4889proto_item *
4890proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4891 int start, int length, nstime_t *value_ptr,
4892 const char *format, ...)
4893{
4894 proto_item *pi;
4895 va_list ap;
4896
4897 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4898 if (pi != tree) {
4899 va_start(ap, format)__builtin_va_start(ap, format);
4900 proto_tree_set_representation_value(pi, format, ap);
4901 va_end(ap)__builtin_va_end(ap);
4902 }
4903
4904 return pi;
4905}
4906
4907proto_item *
4908proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4909 int start, int length, nstime_t *value_ptr,
4910 const char *format, ...)
4911{
4912 proto_item *pi;
4913 va_list ap;
4914
4915 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4916 if (pi != tree) {
4917 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4917, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4918
4919 va_start(ap, format)__builtin_va_start(ap, format);
4920 proto_tree_set_representation(pi, format, ap);
4921 va_end(ap)__builtin_va_end(ap);
4922 }
4923
4924 return pi;
4925}
4926
4927/* Set the FT_*TIME value */
4928static void
4929proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4930{
4931 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4931, "value_ptr != ((void*)0)"
))))
;
4932
4933 fvalue_set_time(fi->value, value_ptr);
4934}
4935
4936/* Add a FT_IPXNET to a proto_tree */
4937proto_item *
4938proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4939 int length, uint32_t value)
4940{
4941 proto_item *pi;
4942 header_field_info *hfinfo;
4943
4944 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4945
4946 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", 4946
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4946, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4946, "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", 4946, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4947
4948 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"
, 4948, ((hfinfo))->abbrev))))
;
4949
4950 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4951 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
4952
4953 return pi;
4954}
4955
4956proto_item *
4957proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4958 int start, int length, uint32_t value,
4959 const char *format, ...)
4960{
4961 proto_item *pi;
4962 va_list ap;
4963
4964 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4965 if (pi != tree) {
4966 va_start(ap, format)__builtin_va_start(ap, format);
4967 proto_tree_set_representation_value(pi, format, ap);
4968 va_end(ap)__builtin_va_end(ap);
4969 }
4970
4971 return pi;
4972}
4973
4974proto_item *
4975proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4976 int start, int length, uint32_t value,
4977 const char *format, ...)
4978{
4979 proto_item *pi;
4980 va_list ap;
4981
4982 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4983 if (pi != tree) {
4984 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4984, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4985
4986 va_start(ap, format)__builtin_va_start(ap, format);
4987 proto_tree_set_representation(pi, format, ap);
4988 va_end(ap)__builtin_va_end(ap);
4989 }
4990
4991 return pi;
4992}
4993
4994/* Set the FT_IPXNET value */
4995static void
4996proto_tree_set_ipxnet(field_info *fi, uint32_t value)
4997{
4998 fvalue_set_uinteger(fi->value, value);
4999}
5000
5001/* Add a FT_IPv4 to a proto_tree */
5002proto_item *
5003proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5004 int length, ws_in4_addr value)
5005{
5006 proto_item *pi;
5007 header_field_info *hfinfo;
5008
5009 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5010
5011 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", 5011
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5011, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5011, "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", 5011, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5012
5013 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", 5013
, ((hfinfo))->abbrev))))
;
5014
5015 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5016 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5017
5018 return pi;
5019}
5020
5021proto_item *
5022proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5023 int start, int length, ws_in4_addr value,
5024 const char *format, ...)
5025{
5026 proto_item *pi;
5027 va_list ap;
5028
5029 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5030 if (pi != tree) {
5031 va_start(ap, format)__builtin_va_start(ap, format);
5032 proto_tree_set_representation_value(pi, format, ap);
5033 va_end(ap)__builtin_va_end(ap);
5034 }
5035
5036 return pi;
5037}
5038
5039proto_item *
5040proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5041 int start, int length, ws_in4_addr value,
5042 const char *format, ...)
5043{
5044 proto_item *pi;
5045 va_list ap;
5046
5047 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5048 if (pi != tree) {
5049 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5049, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5050
5051 va_start(ap, format)__builtin_va_start(ap, format);
5052 proto_tree_set_representation(pi, format, ap);
5053 va_end(ap)__builtin_va_end(ap);
5054 }
5055
5056 return pi;
5057}
5058
5059/* Set the FT_IPv4 value */
5060static void
5061proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5062{
5063 ipv4_addr_and_mask ipv4;
5064 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5065 fvalue_set_ipv4(fi->value, &ipv4);
5066}
5067
5068/* Add a FT_IPv6 to a proto_tree */
5069proto_item *
5070proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5071 int length, const ws_in6_addr *value)
5072{
5073 proto_item *pi;
5074 header_field_info *hfinfo;
5075
5076 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5077
5078 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", 5078
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5078, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5078, "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", 5078, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5079
5080 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", 5080
, ((hfinfo))->abbrev))))
;
5081
5082 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5083 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5084
5085 return pi;
5086}
5087
5088proto_item *
5089proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5090 int start, int length,
5091 const ws_in6_addr *value_ptr,
5092 const char *format, ...)
5093{
5094 proto_item *pi;
5095 va_list ap;
5096
5097 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5098 if (pi != tree) {
5099 va_start(ap, format)__builtin_va_start(ap, format);
5100 proto_tree_set_representation_value(pi, format, ap);
5101 va_end(ap)__builtin_va_end(ap);
5102 }
5103
5104 return pi;
5105}
5106
5107proto_item *
5108proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5109 int start, int length,
5110 const ws_in6_addr *value_ptr,
5111 const char *format, ...)
5112{
5113 proto_item *pi;
5114 va_list ap;
5115
5116 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5117 if (pi != tree) {
5118 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5118, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5119
5120 va_start(ap, format)__builtin_va_start(ap, format);
5121 proto_tree_set_representation(pi, format, ap);
5122 va_end(ap)__builtin_va_end(ap);
5123 }
5124
5125 return pi;
5126}
5127
5128/* Set the FT_IPv6 value */
5129static void
5130proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5131{
5132 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5132, "value != ((void*)0)"
))))
;
5133 ipv6_addr_and_prefix ipv6;
5134 ipv6.addr = *value;
5135 ipv6.prefix = 128;
5136 fvalue_set_ipv6(fi->value, &ipv6);
5137}
5138
5139static void
5140proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5141{
5142 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5143}
5144
5145/* Set the FT_FCWWN value */
5146static void
5147proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5148{
5149 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5149, "value_ptr != ((void*)0)"
))))
;
5150 fvalue_set_fcwwn(fi->value, value_ptr);
5151}
5152
5153static void
5154proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5155{
5156 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5157}
5158
5159/* Add a FT_GUID to a proto_tree */
5160proto_item *
5161proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5162 int length, const e_guid_t *value_ptr)
5163{
5164 proto_item *pi;
5165 header_field_info *hfinfo;
5166
5167 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5168
5169 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", 5169
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5169, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5169, "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", 5169, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5170
5171 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", 5171
, ((hfinfo))->abbrev))))
;
5172
5173 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5174 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5175
5176 return pi;
5177}
5178
5179proto_item *
5180proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5181 int start, int length,
5182 const e_guid_t *value_ptr,
5183 const char *format, ...)
5184{
5185 proto_item *pi;
5186 va_list ap;
5187
5188 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5189 if (pi != tree) {
5190 va_start(ap, format)__builtin_va_start(ap, format);
5191 proto_tree_set_representation_value(pi, format, ap);
5192 va_end(ap)__builtin_va_end(ap);
5193 }
5194
5195 return pi;
5196}
5197
5198proto_item *
5199proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5200 int start, int length, const e_guid_t *value_ptr,
5201 const char *format, ...)
5202{
5203 proto_item *pi;
5204 va_list ap;
5205
5206 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5207 if (pi != tree) {
5208 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5208, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5209
5210 va_start(ap, format)__builtin_va_start(ap, format);
5211 proto_tree_set_representation(pi, format, ap);
5212 va_end(ap)__builtin_va_end(ap);
5213 }
5214
5215 return pi;
5216}
5217
5218/* Set the FT_GUID value */
5219static void
5220proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5221{
5222 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5222, "value_ptr != ((void*)0)"
))))
;
5223 fvalue_set_guid(fi->value, value_ptr);
5224}
5225
5226static void
5227proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5228 const unsigned encoding)
5229{
5230 e_guid_t guid;
5231
5232 tvb_get_guid(tvb, start, &guid, encoding);
5233 proto_tree_set_guid(fi, &guid);
5234}
5235
5236/* Add a FT_OID to a proto_tree */
5237proto_item *
5238proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5239 int length, const uint8_t* value_ptr)
5240{
5241 proto_item *pi;
5242 header_field_info *hfinfo;
5243
5244 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5245
5246 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", 5246
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5246, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5246, "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", 5246, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5247
5248 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", 5248
, ((hfinfo))->abbrev))))
;
5249
5250 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5251 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5252
5253 return pi;
5254}
5255
5256proto_item *
5257proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5258 int start, int length,
5259 const uint8_t* value_ptr,
5260 const char *format, ...)
5261{
5262 proto_item *pi;
5263 va_list ap;
5264
5265 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5266 if (pi != tree) {
5267 va_start(ap, format)__builtin_va_start(ap, format);
5268 proto_tree_set_representation_value(pi, format, ap);
5269 va_end(ap)__builtin_va_end(ap);
5270 }
5271
5272 return pi;
5273}
5274
5275proto_item *
5276proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5277 int start, int length, const uint8_t* value_ptr,
5278 const char *format, ...)
5279{
5280 proto_item *pi;
5281 va_list ap;
5282
5283 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5284 if (pi != tree) {
5285 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5285, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5286
5287 va_start(ap, format)__builtin_va_start(ap, format);
5288 proto_tree_set_representation(pi, format, ap);
5289 va_end(ap)__builtin_va_end(ap);
5290 }
5291
5292 return pi;
5293}
5294
5295/* Set the FT_OID value */
5296static void
5297proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5298{
5299 GByteArray *bytes;
5300
5301 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", 5301, "value_ptr != ((void*)0) || length == 0"
))))
;
5302
5303 bytes = g_byte_array_new();
5304 if (length > 0) {
5305 g_byte_array_append(bytes, value_ptr, length);
5306 }
5307 fvalue_set_byte_array(fi->value, bytes);
5308}
5309
5310static void
5311proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5312{
5313 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5314}
5315
5316/* Set the FT_SYSTEM_ID value */
5317static void
5318proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5319{
5320 GByteArray *bytes;
5321
5322 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", 5322, "value_ptr != ((void*)0) || length == 0"
))))
;
5323
5324 bytes = g_byte_array_new();
5325 if (length > 0) {
5326 g_byte_array_append(bytes, value_ptr, length);
5327 }
5328 fvalue_set_byte_array(fi->value, bytes);
5329}
5330
5331static void
5332proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5333{
5334 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5335}
5336
5337/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5338 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5339 * is destroyed. */
5340proto_item *
5341proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5342 int length, const char* value)
5343{
5344 proto_item *pi;
5345 header_field_info *hfinfo;
5346 int item_length;
5347
5348 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", 5348, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5348,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5348, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5349 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5350 /*
5351 * Special case - if the length is 0, skip the test, so that
5352 * we can have an empty string right after the end of the
5353 * packet. (This handles URL-encoded forms where the last field
5354 * has no value so the form ends right after the =.)
5355 */
5356 if (item_length != 0)
5357 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
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_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", 5363, ((hfinfo))->abbrev))))
;
5364
5365 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5366 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5366, "length >= 0"
))))
;
5367
5368 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", 5368, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5369 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5370
5371 return pi;
5372}
5373
5374proto_item *
5375proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5376 int start, int length, const char* value,
5377 const char *format,
5378 ...)
5379{
5380 proto_item *pi;
5381 va_list ap;
5382
5383 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5384 if (pi != tree) {
5385 va_start(ap, format)__builtin_va_start(ap, format);
5386 proto_tree_set_representation_value(pi, format, ap);
5387 va_end(ap)__builtin_va_end(ap);
5388 }
5389
5390 return pi;
5391}
5392
5393proto_item *
5394proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5395 int start, int length, const char* value,
5396 const char *format, ...)
5397{
5398 proto_item *pi;
5399 va_list ap;
5400
5401 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5402 if (pi != tree) {
5403 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5403, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5404
5405 va_start(ap, format)__builtin_va_start(ap, format);
5406 proto_tree_set_representation(pi, format, ap);
5407 va_end(ap)__builtin_va_end(ap);
5408 }
5409
5410 return pi;
5411}
5412
5413/* Set the FT_STRING value */
5414static void
5415proto_tree_set_string(field_info *fi, const char* value)
5416{
5417 if (value) {
5418 fvalue_set_string(fi->value, value);
5419 } else {
5420 /*
5421 * XXX - why is a null value for a string field
5422 * considered valid?
5423 */
5424 fvalue_set_string(fi->value, "[ Null ]");
5425 }
5426}
5427
5428/* Set the FT_AX25 value */
5429static void
5430proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5431{
5432 fvalue_set_ax25(fi->value, value);
5433}
5434
5435static void
5436proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5437{
5438 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5439}
5440
5441/* Set the FT_VINES value */
5442static void
5443proto_tree_set_vines(field_info *fi, const uint8_t* value)
5444{
5445 fvalue_set_vines(fi->value, value);
5446}
5447
5448static void
5449proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5450{
5451 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5452}
5453
5454/* Add a FT_ETHER to a proto_tree */
5455proto_item *
5456proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5457 int length, const uint8_t* value)
5458{
5459 proto_item *pi;
5460 header_field_info *hfinfo;
5461
5462 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5463
5464 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", 5464
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5464, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5464, "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", 5464, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5465
5466 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",
5466, ((hfinfo))->abbrev))))
;
5467
5468 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5469 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5470
5471 return pi;
5472}
5473
5474proto_item *
5475proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5476 int start, int length, const uint8_t* value,
5477 const char *format, ...)
5478{
5479 proto_item *pi;
5480 va_list ap;
5481
5482 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5483 if (pi != tree) {
5484 va_start(ap, format)__builtin_va_start(ap, format);
5485 proto_tree_set_representation_value(pi, format, ap);
5486 va_end(ap)__builtin_va_end(ap);
5487 }
5488
5489 return pi;
5490}
5491
5492proto_item *
5493proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5494 int start, int length, const uint8_t* value,
5495 const char *format, ...)
5496{
5497 proto_item *pi;
5498 va_list ap;
5499
5500 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5501 if (pi != tree) {
5502 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5502, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5503
5504 va_start(ap, format)__builtin_va_start(ap, format);
5505 proto_tree_set_representation(pi, format, ap);
5506 va_end(ap)__builtin_va_end(ap);
5507 }
5508
5509 return pi;
5510}
5511
5512/* Set the FT_ETHER value */
5513static void
5514proto_tree_set_ether(field_info *fi, const uint8_t* value)
5515{
5516 fvalue_set_ether(fi->value, value);
5517}
5518
5519static void
5520proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5521{
5522 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5523}
5524
5525/* Add a FT_BOOLEAN to a proto_tree */
5526proto_item *
5527proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5528 int length, uint64_t value)
5529{
5530 proto_item *pi;
5531 header_field_info *hfinfo;
5532
5533 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5534
5535 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", 5535
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5535, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5535, "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", 5535, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5536
5537 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"
, 5537, ((hfinfo))->abbrev))))
;
5538
5539 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5540 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5541
5542 return pi;
5543}
5544
5545proto_item *
5546proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5547 tvbuff_t *tvb, int start, int length,
5548 uint64_t value, const char *format, ...)
5549{
5550 proto_item *pi;
5551 va_list ap;
5552
5553 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5554 if (pi != tree) {
5555 va_start(ap, format)__builtin_va_start(ap, format);
5556 proto_tree_set_representation_value(pi, format, ap);
5557 va_end(ap)__builtin_va_end(ap);
5558 }
5559
5560 return pi;
5561}
5562
5563proto_item *
5564proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5565 int start, int length, uint64_t value,
5566 const char *format, ...)
5567{
5568 proto_item *pi;
5569 va_list ap;
5570
5571 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5572 if (pi != tree) {
5573 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5573, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5574
5575 va_start(ap, format)__builtin_va_start(ap, format);
5576 proto_tree_set_representation(pi, format, ap);
5577 va_end(ap)__builtin_va_end(ap);
5578 }
5579
5580 return pi;
5581}
5582
5583/* Set the FT_BOOLEAN value */
5584static void
5585proto_tree_set_boolean(field_info *fi, uint64_t value)
5586{
5587 proto_tree_set_uint64(fi, value);
5588}
5589
5590/* Generate, into "buf", a string showing the bits of a bitfield.
5591 Return a pointer to the character after that string. */
5592static char *
5593other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5594{
5595 int i = 0;
5596 uint64_t bit;
5597 char *p;
5598
5599 p = buf;
5600
5601 /* This is a devel error. It is safer to stop here. */
5602 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5602, "width >= 1"
))))
;
5603
5604 bit = UINT64_C(1)1UL << (width - 1);
5605 for (;;) {
5606 if (mask & bit) {
5607 /* This bit is part of the field. Show its value. */
5608 if (val & bit)
5609 *p++ = '1';
5610 else
5611 *p++ = '0';
5612 } else {
5613 /* This bit is not part of the field. */
5614 *p++ = '.';
5615 }
5616 bit >>= 1;
5617 i++;
5618 if (i >= width)
5619 break;
5620 if (i % 4 == 0)
5621 *p++ = ' ';
5622 }
5623 *p = '\0';
5624 return p;
5625}
5626
5627static char *
5628decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5629{
5630 char *p;
5631
5632 p = other_decode_bitfield_value(buf, val, mask, width);
5633 p = g_stpcpy(p, " = ");
5634
5635 return p;
5636}
5637
5638static char *
5639other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5640{
5641 int i = 0;
5642 uint64_t bit;
5643 char *p;
5644
5645 p = buf;
5646
5647 /* This is a devel error. It is safer to stop here. */
5648 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5648, "width >= 1"
))))
;
5649
5650 bit = UINT64_C(1)1UL << (width - 1);
5651 for (;;) {
5652 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5653 (mask & bit)) {
5654 /* This bit is part of the field. Show its value. */
5655 if (val & bit)
5656 *p++ = '1';
5657 else
5658 *p++ = '0';
5659 } else {
5660 /* This bit is not part of the field. */
5661 *p++ = '.';
5662 }
5663 bit >>= 1;
5664 i++;
5665 if (i >= width)
5666 break;
5667 if (i % 4 == 0)
5668 *p++ = ' ';
5669 }
5670
5671 *p = '\0';
5672 return p;
5673}
5674
5675static char *
5676decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5677{
5678 char *p;
5679
5680 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5681 p = g_stpcpy(p, " = ");
5682
5683 return p;
5684}
5685
5686/* Add a FT_FLOAT to a proto_tree */
5687proto_item *
5688proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5689 int length, float value)
5690{
5691 proto_item *pi;
5692 header_field_info *hfinfo;
5693
5694 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5695
5696 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", 5696
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5696, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5696, "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", 5696, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5697
5698 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",
5698, ((hfinfo))->abbrev))))
;
5699
5700 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5701 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5702
5703 return pi;
5704}
5705
5706proto_item *
5707proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5708 int start, int length, float value,
5709 const char *format, ...)
5710{
5711 proto_item *pi;
5712 va_list ap;
5713
5714 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5715 if (pi != tree) {
5716 va_start(ap, format)__builtin_va_start(ap, format);
5717 proto_tree_set_representation_value(pi, format, ap);
5718 va_end(ap)__builtin_va_end(ap);
5719 }
5720
5721 return pi;
5722}
5723
5724proto_item *
5725proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5726 int start, int length, float value,
5727 const char *format, ...)
5728{
5729 proto_item *pi;
5730 va_list ap;
5731
5732 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5733 if (pi != tree) {
5734 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5734, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5735
5736 va_start(ap, format)__builtin_va_start(ap, format);
5737 proto_tree_set_representation(pi, format, ap);
5738 va_end(ap)__builtin_va_end(ap);
5739 }
5740
5741 return pi;
5742}
5743
5744/* Set the FT_FLOAT value */
5745static void
5746proto_tree_set_float(field_info *fi, float value)
5747{
5748 fvalue_set_floating(fi->value, value);
5749}
5750
5751/* Add a FT_DOUBLE to a proto_tree */
5752proto_item *
5753proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5754 int length, double value)
5755{
5756 proto_item *pi;
5757 header_field_info *hfinfo;
5758
5759 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5760
5761 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5761
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5761, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5761, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5761, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5762
5763 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_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"
, 5763, ((hfinfo))->abbrev))))
;
5764
5765 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5766 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5767
5768 return pi;
5769}
5770
5771proto_item *
5772proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5773 int start, int length, double value,
5774 const char *format, ...)
5775{
5776 proto_item *pi;
5777 va_list ap;
5778
5779 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5780 if (pi != tree) {
5781 va_start(ap, format)__builtin_va_start(ap, format);
5782 proto_tree_set_representation_value(pi, format, ap);
5783 va_end(ap)__builtin_va_end(ap);
5784 }
5785
5786 return pi;
5787}
5788
5789proto_item *
5790proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5791 int start, int length, double value,
5792 const char *format, ...)
5793{
5794 proto_item *pi;
5795 va_list ap;
5796
5797 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5798 if (pi != tree) {
5799 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5799, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5800
5801 va_start(ap, format)__builtin_va_start(ap, format);
5802 proto_tree_set_representation(pi, format, ap);
5803 va_end(ap)__builtin_va_end(ap);
5804 }
5805
5806 return pi;
5807}
5808
5809/* Set the FT_DOUBLE value */
5810static void
5811proto_tree_set_double(field_info *fi, double value)
5812{
5813 fvalue_set_floating(fi->value, value);
5814}
5815
5816/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5817proto_item *
5818proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5819 int length, uint32_t value)
5820{
5821 proto_item *pi = NULL((void*)0);
5822 header_field_info *hfinfo;
5823
5824 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5825
5826 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", 5826
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5826, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5826, "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", 5826, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5827
5828 switch (hfinfo->type) {
5829 case FT_CHAR:
5830 case FT_UINT8:
5831 case FT_UINT16:
5832 case FT_UINT24:
5833 case FT_UINT32:
5834 case FT_FRAMENUM:
5835 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5836 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5837 break;
5838
5839 default:
5840 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)
5841 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)
;
5842 }
5843
5844 return pi;
5845}
5846
5847proto_item *
5848proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5849 int start, int length, uint32_t value,
5850 const char *format, ...)
5851{
5852 proto_item *pi;
5853 va_list ap;
5854
5855 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5856 if (pi != tree) {
5857 va_start(ap, format)__builtin_va_start(ap, format);
5858 proto_tree_set_representation_value(pi, format, ap);
5859 va_end(ap)__builtin_va_end(ap);
5860 }
5861
5862 return pi;
5863}
5864
5865proto_item *
5866proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5867 int start, int length, uint32_t value,
5868 const char *format, ...)
5869{
5870 proto_item *pi;
5871 va_list ap;
5872
5873 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5874 if (pi != tree) {
5875 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5875, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5876
5877 va_start(ap, format)__builtin_va_start(ap, format);
5878 proto_tree_set_representation(pi, format, ap);
5879 va_end(ap)__builtin_va_end(ap);
5880 }
5881
5882 return pi;
5883}
5884
5885/* Set the FT_UINT{8,16,24,32} value */
5886static void
5887proto_tree_set_uint(field_info *fi, uint32_t value)
5888{
5889 const header_field_info *hfinfo;
5890 uint32_t integer;
5891
5892 hfinfo = fi->hfinfo;
5893 integer = value;
5894
5895 if (hfinfo->bitmask) {
5896 /* Mask out irrelevant portions */
5897 integer &= (uint32_t)(hfinfo->bitmask);
5898
5899 /* Shift bits */
5900 integer >>= hfinfo_bitshift(hfinfo);
5901
5902 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5903 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)
;
5904 }
5905
5906 fvalue_set_uinteger(fi->value, integer);
5907}
5908
5909/* Add FT_UINT{40,48,56,64} to a proto_tree */
5910proto_item *
5911proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5912 int length, uint64_t value)
5913{
5914 proto_item *pi = NULL((void*)0);
5915 header_field_info *hfinfo;
5916
5917 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5918
5919 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", 5919
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5919, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5919, "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", 5919, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5920
5921 switch (hfinfo->type) {
5922 case FT_UINT40:
5923 case FT_UINT48:
5924 case FT_UINT56:
5925 case FT_UINT64:
5926 case FT_FRAMENUM:
5927 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5928 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5929 break;
5930
5931 default:
5932 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)
5933 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)
;
5934 }
5935
5936 return pi;
5937}
5938
5939proto_item *
5940proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5941 int start, int length, uint64_t value,
5942 const char *format, ...)
5943{
5944 proto_item *pi;
5945 va_list ap;
5946
5947 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5948 if (pi != tree) {
5949 va_start(ap, format)__builtin_va_start(ap, format);
5950 proto_tree_set_representation_value(pi, format, ap);
5951 va_end(ap)__builtin_va_end(ap);
5952 }
5953
5954 return pi;
5955}
5956
5957proto_item *
5958proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5959 int start, int length, uint64_t value,
5960 const char *format, ...)
5961{
5962 proto_item *pi;
5963 va_list ap;
5964
5965 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5966 if (pi != tree) {
5967 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5967, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5968
5969 va_start(ap, format)__builtin_va_start(ap, format);
5970 proto_tree_set_representation(pi, format, ap);
5971 va_end(ap)__builtin_va_end(ap);
5972 }
5973
5974 return pi;
5975}
5976
5977/* Set the FT_UINT{40,48,56,64} value */
5978static void
5979proto_tree_set_uint64(field_info *fi, uint64_t value)
5980{
5981 const header_field_info *hfinfo;
5982 uint64_t integer;
5983
5984 hfinfo = fi->hfinfo;
5985 integer = value;
5986
5987 if (hfinfo->bitmask) {
5988 /* Mask out irrelevant portions */
5989 integer &= hfinfo->bitmask;
5990
5991 /* Shift bits */
5992 integer >>= hfinfo_bitshift(hfinfo);
5993
5994 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5995 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)
;
5996 }
5997
5998 fvalue_set_uinteger64(fi->value, integer);
5999}
6000
6001/* Add FT_INT{8,16,24,32} to a proto_tree */
6002proto_item *
6003proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6004 int length, int32_t value)
6005{
6006 proto_item *pi = NULL((void*)0);
6007 header_field_info *hfinfo;
6008
6009 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6010
6011 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", 6011
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6011, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6011, "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", 6011, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6012
6013 switch (hfinfo->type) {
6014 case FT_INT8:
6015 case FT_INT16:
6016 case FT_INT24:
6017 case FT_INT32:
6018 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6019 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6020 break;
6021
6022 default:
6023 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)
6024 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6025 }
6026
6027 return pi;
6028}
6029
6030proto_item *
6031proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6032 int start, int length, int32_t value,
6033 const char *format, ...)
6034{
6035 proto_item *pi;
6036 va_list ap;
6037
6038 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6039 if (pi != tree) {
6040 va_start(ap, format)__builtin_va_start(ap, format);
6041 proto_tree_set_representation_value(pi, format, ap);
6042 va_end(ap)__builtin_va_end(ap);
6043 }
6044
6045 return pi;
6046}
6047
6048proto_item *
6049proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6050 int start, int length, int32_t value,
6051 const char *format, ...)
6052{
6053 proto_item *pi;
6054 va_list ap;
6055
6056 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6057 if (pi != tree) {
6058 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6058, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6059
6060 va_start(ap, format)__builtin_va_start(ap, format);
6061 proto_tree_set_representation(pi, format, ap);
6062 va_end(ap)__builtin_va_end(ap);
6063 }
6064
6065 return pi;
6066}
6067
6068/* Set the FT_INT{8,16,24,32} value */
6069static void
6070proto_tree_set_int(field_info *fi, int32_t value)
6071{
6072 const header_field_info *hfinfo;
6073 uint32_t integer;
6074 int no_of_bits;
6075
6076 hfinfo = fi->hfinfo;
6077 integer = (uint32_t) value;
6078
6079 if (hfinfo->bitmask) {
6080 /* Mask out irrelevant portions */
6081 integer &= (uint32_t)(hfinfo->bitmask);
6082
6083 /* Shift bits */
6084 integer >>= hfinfo_bitshift(hfinfo);
6085
6086 no_of_bits = ws_count_ones(hfinfo->bitmask);
6087 integer = ws_sign_ext32(integer, no_of_bits);
6088
6089 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6090 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)
;
6091 }
6092
6093 fvalue_set_sinteger(fi->value, integer);
6094}
6095
6096/* Add FT_INT{40,48,56,64} to a proto_tree */
6097proto_item *
6098proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6099 int length, int64_t value)
6100{
6101 proto_item *pi = NULL((void*)0);
6102 header_field_info *hfinfo;
6103
6104 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6105
6106 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", 6106
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6106, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6106, "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", 6106, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6107
6108 switch (hfinfo->type) {
6109 case FT_INT40:
6110 case FT_INT48:
6111 case FT_INT56:
6112 case FT_INT64:
6113 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6114 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6115 break;
6116
6117 default:
6118 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)
6119 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6120 }
6121
6122 return pi;
6123}
6124
6125proto_item *
6126proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6127 int start, int length, int64_t value,
6128 const char *format, ...)
6129{
6130 proto_item *pi;
6131 va_list ap;
6132
6133 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6134 if (pi != tree) {
6135 va_start(ap, format)__builtin_va_start(ap, format);
6136 proto_tree_set_representation_value(pi, format, ap);
6137 va_end(ap)__builtin_va_end(ap);
6138 }
6139
6140 return pi;
6141}
6142
6143/* Set the FT_INT{40,48,56,64} value */
6144static void
6145proto_tree_set_int64(field_info *fi, int64_t value)
6146{
6147 const header_field_info *hfinfo;
6148 uint64_t integer;
6149 int no_of_bits;
6150
6151 hfinfo = fi->hfinfo;
6152 integer = value;
6153
6154 if (hfinfo->bitmask) {
6155 /* Mask out irrelevant portions */
6156 integer &= hfinfo->bitmask;
6157
6158 /* Shift bits */
6159 integer >>= hfinfo_bitshift(hfinfo);
6160
6161 no_of_bits = ws_count_ones(hfinfo->bitmask);
6162 integer = ws_sign_ext64(integer, no_of_bits);
6163
6164 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6165 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)
;
6166 }
6167
6168 fvalue_set_sinteger64(fi->value, integer);
6169}
6170
6171proto_item *
6172proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6173 int start, int length, int64_t value,
6174 const char *format, ...)
6175{
6176 proto_item *pi;
6177 va_list ap;
6178
6179 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6180 if (pi != tree) {
6181 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6181, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6182
6183 va_start(ap, format)__builtin_va_start(ap, format);
6184 proto_tree_set_representation(pi, format, ap);
6185 va_end(ap)__builtin_va_end(ap);
6186 }
6187
6188 return pi;
6189}
6190
6191/* Add a FT_EUI64 to a proto_tree */
6192proto_item *
6193proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6194 int length, const uint64_t value)
6195{
6196 proto_item *pi;
6197 header_field_info *hfinfo;
6198
6199 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6200
6201 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", 6201
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6201, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6201, "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", 6201, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6202
6203 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",
6203, ((hfinfo))->abbrev))))
;
6204
6205 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6206 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6207
6208 return pi;
6209}
6210
6211proto_item *
6212proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6213 int start, int length, const uint64_t value,
6214 const char *format, ...)
6215{
6216 proto_item *pi;
6217 va_list ap;
6218
6219 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6220 if (pi != tree) {
6221 va_start(ap, format)__builtin_va_start(ap, format);
6222 proto_tree_set_representation_value(pi, format, ap);
6223 va_end(ap)__builtin_va_end(ap);
6224 }
6225
6226 return pi;
6227}
6228
6229proto_item *
6230proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6231 int start, int length, const uint64_t value,
6232 const char *format, ...)
6233{
6234 proto_item *pi;
6235 va_list ap;
6236
6237 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6238 if (pi != tree) {
6239 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6239, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6240
6241 va_start(ap, format)__builtin_va_start(ap, format);
6242 proto_tree_set_representation(pi, format, ap);
6243 va_end(ap)__builtin_va_end(ap);
6244 }
6245
6246 return pi;
6247}
6248
6249/* Set the FT_EUI64 value */
6250static void
6251proto_tree_set_eui64(field_info *fi, const uint64_t value)
6252{
6253 uint8_t v[FT_EUI64_LEN8];
6254 phton64(v, value);
6255 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6256}
6257
6258static void
6259proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6260{
6261 if (encoding)
6262 {
6263 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6264 } else {
6265 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6266 }
6267}
6268
6269proto_item *
6270proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6271 const mac_hf_list_t *list_generic,
6272 int idx, tvbuff_t *tvb,
6273 proto_tree *tree, int offset)
6274{
6275 const uint8_t addr[6];
6276 const char *addr_name = NULL((void*)0);
6277 const char *oui_name = NULL((void*)0);
6278 proto_item *addr_item = NULL((void*)0);
6279 proto_tree *addr_tree = NULL((void*)0);
6280 proto_item *ret_val = NULL((void*)0);
6281
6282 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6283 return NULL((void*)0);
6284 }
6285
6286 /* Resolve what we can of the address */
6287 tvb_memcpy(tvb, (void *)addr, offset, 6);
6288 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6289 addr_name = get_ether_name(addr);
6290 }
6291 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6292 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6293 }
6294
6295 /* Add the item for the specific address type */
6296 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6297 if (idx >= 0) {
6298 addr_tree = proto_item_add_subtree(ret_val, idx);
6299 }
6300 else {
6301 addr_tree = tree;
6302 }
6303
6304 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6305 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6306 tvb, offset, 6, addr_name);
6307 proto_item_set_generated(addr_item);
6308 proto_item_set_hidden(addr_item);
6309 }
6310
6311 if (list_specific->hf_oui != NULL((void*)0)) {
6312 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6313 proto_item_set_generated(addr_item);
6314 proto_item_set_hidden(addr_item);
6315
6316 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6317 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6318 proto_item_set_generated(addr_item);
6319 proto_item_set_hidden(addr_item);
6320 }
6321 }
6322
6323 if (list_specific->hf_lg != NULL((void*)0)) {
6324 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6325 }
6326 if (list_specific->hf_ig != NULL((void*)0)) {
6327 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6328 }
6329
6330 /* Were we given a list for generic address fields? If not, stop here */
6331 if (list_generic == NULL((void*)0)) {
6332 return ret_val;
6333 }
6334
6335 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6336 proto_item_set_hidden(addr_item);
6337
6338 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6339 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6340 tvb, offset, 6, addr_name);
6341 proto_item_set_generated(addr_item);
6342 proto_item_set_hidden(addr_item);
6343 }
6344
6345 if (list_generic->hf_oui != NULL((void*)0)) {
6346 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6347 proto_item_set_generated(addr_item);
6348 proto_item_set_hidden(addr_item);
6349
6350 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6351 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6352 proto_item_set_generated(addr_item);
6353 proto_item_set_hidden(addr_item);
6354 }
6355 }
6356
6357 if (list_generic->hf_lg != NULL((void*)0)) {
6358 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6359 proto_item_set_hidden(addr_item);
6360 }
6361 if (list_generic->hf_ig != NULL((void*)0)) {
6362 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6363 proto_item_set_hidden(addr_item);
6364 }
6365 return ret_val;
6366}
6367
6368static proto_item *
6369proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6370{
6371 proto_node *pnode, *tnode, *sibling;
6372 field_info *tfi;
6373 unsigned depth = 1;
6374
6375 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6375, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6376
6377 /*
6378 * Restrict our depth. proto_tree_traverse_pre_order and
6379 * proto_tree_traverse_post_order (and possibly others) are recursive
6380 * so we need to be mindful of our stack size.
6381 */
6382 if (tree->first_child == NULL((void*)0)) {
6383 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6384 depth++;
6385 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6386 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__)), 6389)))
6387 "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__)), 6389)))
6388 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__)), 6389)))
6389 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__)), 6389)))
;
6390 }
6391 }
6392 }
6393
6394 /*
6395 * Make sure "tree" is ready to have subtrees under it, by
6396 * checking whether it's been given an ett_ value.
6397 *
6398 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6399 * node of the protocol tree. That node is not displayed,
6400 * so it doesn't need an ett_ value to remember whether it
6401 * was expanded.
6402 */
6403 tnode = tree;
6404 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6405 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6406 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"
, 6407)
6407 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"
, 6407)
;
6408 /* XXX - is it safe to continue here? */
6409 }
6410
6411 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6412 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6413 pnode->parent = tnode;
6414 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6415 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6416 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6417
6418 if (tnode->last_child != NULL((void*)0)) {
6419 sibling = tnode->last_child;
6420 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6420, "sibling->next == ((void*)0)"
))))
;
6421 sibling->next = pnode;
6422 } else
6423 tnode->first_child = pnode;
6424 tnode->last_child = pnode;
6425
6426 /* We should not be adding a fake node for an interesting field */
6427 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", 6427, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6428
6429 /* XXX - Should the proto_item have a header_field_info member, at least
6430 * for faked items, to know what hfi was faked? (Some dissectors look at
6431 * the tree items directly.)
6432 */
6433 return (proto_item *)pnode;
6434}
6435
6436/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6437static proto_item *
6438proto_tree_add_node(proto_tree *tree, field_info *fi)
6439{
6440 proto_node *pnode, *tnode, *sibling;
6441 field_info *tfi;
6442 unsigned depth = 1;
6443
6444 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6444, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6445
6446 /*
6447 * Restrict our depth. proto_tree_traverse_pre_order and
6448 * proto_tree_traverse_post_order (and possibly others) are recursive
6449 * so we need to be mindful of our stack size.
6450 */
6451 if (tree->first_child == NULL((void*)0)) {
6452 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6453 depth++;
6454 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6455 fvalue_free(fi->value);
6456 fi->value = NULL((void*)0);
6457 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__)), 6460)))
6458 "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__)), 6460)))
6459 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__)), 6460)))
6460 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__)), 6460)))
;
6461 }
6462 }
6463 }
6464
6465 /*
6466 * Make sure "tree" is ready to have subtrees under it, by
6467 * checking whether it's been given an ett_ value.
6468 *
6469 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6470 * node of the protocol tree. That node is not displayed,
6471 * so it doesn't need an ett_ value to remember whether it
6472 * was expanded.
6473 */
6474 tnode = tree;
6475 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6476 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6477 /* Since we are not adding fi to a node, its fvalue won't get
6478 * freed by proto_tree_free_node(), so free it now.
6479 */
6480 fvalue_free(fi->value);
6481 fi->value = NULL((void*)0);
6482 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", 6483)
6483 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", 6483)
;
6484 /* XXX - is it safe to continue here? */
6485 }
6486
6487 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6488 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6489 pnode->parent = tnode;
6490 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6491 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6492 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6493
6494 if (tnode->last_child != NULL((void*)0)) {
6495 sibling = tnode->last_child;
6496 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6496, "sibling->next == ((void*)0)"
))))
;
6497 sibling->next = pnode;
6498 } else
6499 tnode->first_child = pnode;
6500 tnode->last_child = pnode;
6501
6502 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6503
6504 return (proto_item *)pnode;
6505}
6506
6507
6508/* Generic way to allocate field_info and add to proto_tree.
6509 * Sets *pfi to address of newly-allocated field_info struct */
6510static proto_item *
6511proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6512 int *length)
6513{
6514 proto_item *pi;
6515 field_info *fi;
6516 int item_length;
6517
6518 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6519 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6520 pi = proto_tree_add_node(tree, fi);
6521
6522 return pi;
6523}
6524
6525
6526static void
6527get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6528 int *item_length, const unsigned encoding)
6529{
6530 int length_remaining;
6531
6532 /*
6533 * We only allow a null tvbuff if the item has a zero length,
6534 * i.e. if there's no data backing it.
6535 */
6536 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", 6536, "tvb != ((void*)0) || *length == 0"
))))
;
6537
6538 /*
6539 * XXX - in some protocols, there are 32-bit unsigned length
6540 * fields, so lengths in protocol tree and tvbuff routines
6541 * should really be unsigned. We should have, for those
6542 * field types for which "to the end of the tvbuff" makes sense,
6543 * additional routines that take no length argument and
6544 * add fields that run to the end of the tvbuff.
6545 */
6546 if (*length == -1) {
6547 /*
6548 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6549 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6550 * of -1 means "set the length to what remains in the
6551 * tvbuff".
6552 *
6553 * The assumption is either that
6554 *
6555 * 1) the length of the item can only be determined
6556 * by dissection (typically true of items with
6557 * subitems, which are probably FT_NONE or
6558 * FT_PROTOCOL)
6559 *
6560 * or
6561 *
6562 * 2) if the tvbuff is "short" (either due to a short
6563 * snapshot length or due to lack of reassembly of
6564 * fragments/segments/whatever), we want to display
6565 * what's available in the field (probably FT_BYTES
6566 * or FT_STRING) and then throw an exception later
6567 *
6568 * or
6569 *
6570 * 3) the field is defined to be "what's left in the
6571 * packet"
6572 *
6573 * so we set the length to what remains in the tvbuff so
6574 * that, if we throw an exception while dissecting, it
6575 * has what is probably the right value.
6576 *
6577 * For FT_STRINGZ, it means "the string is null-terminated,
6578 * not null-padded; set the length to the actual length
6579 * of the string", and if the tvbuff if short, we just
6580 * throw an exception.
6581 *
6582 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6583 * it means "find the end of the string",
6584 * and if the tvbuff if short, we just throw an exception.
6585 *
6586 * It's not valid for any other type of field. For those
6587 * fields, we treat -1 the same way we treat other
6588 * negative values - we assume the length is a Really
6589 * Big Positive Number, and throw a ReportedBoundsError
6590 * exception, under the assumption that the Really Big
6591 * Length would run past the end of the packet.
6592 */
6593 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
))
)) {
6594 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6595 /*
6596 * Leave the length as -1, so our caller knows
6597 * it was -1.
6598 */
6599 *item_length = *length;
6600 return;
6601 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6602 switch (tvb_get_uint8(tvb, start) >> 6)
6603 {
6604 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6605 *item_length = 1;
6606 break;
6607 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6608 *item_length = 2;
6609 break;
6610 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6611 *item_length = 4;
6612 break;
6613 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6614 *item_length = 8;
6615 break;
6616 }
6617 }
6618 }
6619
6620 switch (hfinfo->type) {
6621
6622 case FT_PROTOCOL:
6623 case FT_NONE:
6624 case FT_BYTES:
6625 case FT_STRING:
6626 case FT_STRINGZPAD:
6627 case FT_STRINGZTRUNC:
6628 /*
6629 * We allow FT_PROTOCOLs to be zero-length -
6630 * for example, an ONC RPC NULL procedure has
6631 * neither arguments nor reply, so the
6632 * payload for that protocol is empty.
6633 *
6634 * We also allow the others to be zero-length -
6635 * because that's the way the code has been for a
6636 * long, long time.
6637 *
6638 * However, we want to ensure that the start
6639 * offset is not *past* the byte past the end
6640 * of the tvbuff: we throw an exception in that
6641 * case.
6642 */
6643 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6644 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6644, "*length >= 0"
))))
;
6645 break;
6646
6647 case FT_STRINGZ:
6648 /*
6649 * Leave the length as -1, so our caller knows
6650 * it was -1.
6651 */
6652 break;
6653
6654 default:
6655 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6656 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6656))
;
6657 }
6658 *item_length = *length;
6659 } else {
6660 *item_length = *length;
6661 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6662 /*
6663 * These types are for interior nodes of the
6664 * tree, and don't have data associated with
6665 * them; if the length is negative (XXX - see
6666 * above) or goes past the end of the tvbuff,
6667 * cut it short at the end of the tvbuff.
6668 * That way, if this field is selected in
6669 * Wireshark, we don't highlight stuff past
6670 * the end of the data.
6671 */
6672 /* XXX - what to do, if we don't have a tvb? */
6673 if (tvb) {
6674 length_remaining = tvb_captured_length_remaining(tvb, start);
6675 if (*item_length < 0 ||
6676 (*item_length > 0 &&
6677 (length_remaining < *item_length)))
6678 *item_length = length_remaining;
6679 }
6680 }
6681 if (*item_length < 0) {
6682 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6683 }
6684 }
6685}
6686
6687static int
6688get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6689 int length, unsigned item_length, const int encoding)
6690{
6691 uint32_t n;
6692
6693 /*
6694 * We need to get the correct item length here.
6695 * That's normally done by proto_tree_new_item(),
6696 * but we won't be calling it.
6697 */
6698 switch (hfinfo->type) {
6699
6700 case FT_NONE:
6701 case FT_PROTOCOL:
6702 case FT_BYTES:
6703 /*
6704 * The length is the specified length.
6705 */
6706 break;
6707
6708 case FT_UINT_BYTES:
6709 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6710 item_length += n;
6711 if ((int)item_length < length) {
6712 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6713 }
6714 break;
6715
6716 /* XXX - make these just FT_UINT? */
6717 case FT_UINT8:
6718 case FT_UINT16:
6719 case FT_UINT24:
6720 case FT_UINT32:
6721 case FT_UINT40:
6722 case FT_UINT48:
6723 case FT_UINT56:
6724 case FT_UINT64:
6725 /* XXX - make these just FT_INT? */
6726 case FT_INT8:
6727 case FT_INT16:
6728 case FT_INT24:
6729 case FT_INT32:
6730 case FT_INT40:
6731 case FT_INT48:
6732 case FT_INT56:
6733 case FT_INT64:
6734 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6735 if (length < -1) {
6736 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6737 }
6738 if (length == -1) {
6739 uint64_t dummy;
6740 /* This can throw an exception */
6741 /* XXX - do this without fetching the varint? */
6742 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6743 if (length == 0) {
6744 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6745 }
6746 }
6747 item_length = length;
6748 break;
6749 }
6750
6751 /*
6752 * The length is the specified length.
6753 */
6754 break;
6755
6756 case FT_BOOLEAN:
6757 case FT_CHAR:
6758 case FT_IPv4:
6759 case FT_IPXNET:
6760 case FT_IPv6:
6761 case FT_FCWWN:
6762 case FT_AX25:
6763 case FT_VINES:
6764 case FT_ETHER:
6765 case FT_EUI64:
6766 case FT_GUID:
6767 case FT_OID:
6768 case FT_REL_OID:
6769 case FT_SYSTEM_ID:
6770 case FT_FLOAT:
6771 case FT_DOUBLE:
6772 case FT_STRING:
6773 /*
6774 * The length is the specified length.
6775 */
6776 break;
6777
6778 case FT_STRINGZ:
6779 if (length < -1) {
6780 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6781 }
6782 if (length == -1) {
6783 /* This can throw an exception */
6784 /* XXX - do this without fetching the string? */
6785 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6786 }
6787 item_length = length;
6788 break;
6789
6790 case FT_UINT_STRING:
6791 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6792 item_length += n;
6793 if ((int)item_length < length) {
6794 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6795 }
6796 break;
6797
6798 case FT_STRINGZPAD:
6799 case FT_STRINGZTRUNC:
6800 case FT_ABSOLUTE_TIME:
6801 case FT_RELATIVE_TIME:
6802 case FT_IEEE_11073_SFLOAT:
6803 case FT_IEEE_11073_FLOAT:
6804 /*
6805 * The length is the specified length.
6806 */
6807 break;
6808
6809 default:
6810 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
))
6811 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
))
6812 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
))
6813 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
))
;
6814 break;
6815 }
6816 return item_length;
6817}
6818
6819// This was arbitrarily chosen, but if you're adding 50K items to the tree
6820// without advancing the offset you should probably take a long, hard look
6821// at what you're doing.
6822// We *could* make this a configurable option, but I (Gerald) would like to
6823// avoid adding yet another nerd knob.
6824# define PROTO_TREE_MAX_IDLE50000 50000
6825static field_info *
6826new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6827 const int start, const int item_length)
6828{
6829 field_info *fi;
6830
6831 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6832
6833 fi->hfinfo = hfinfo;
6834 fi->start = start;
6835 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6836 // If our start offset hasn't advanced after adding many items it probably
6837 // means we're in a large or infinite loop.
6838 if (fi->start > 0) {
6839 if (fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6840 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6841 DISSECTOR_ASSERT_HINT(PTREE_DATA(tree)->start_idle_count < PROTO_TREE_MAX_IDLE, fi->hfinfo->abbrev)((void) ((((tree)->tree_data)->start_idle_count < 50000
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6841, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6842 } else {
6843 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6844 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6845 }
6846 }
6847 fi->length = item_length;
6848 fi->tree_type = -1;
6849 fi->flags = 0;
6850 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6851 /* If the tree is not visible, set the item hidden, unless we
6852 * need the representation or length and can't fake them.
6853 */
6854 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6855 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6856 }
6857 }
6858 fi->value = fvalue_new(fi->hfinfo->type);
6859 fi->rep = NULL((void*)0);
6860
6861 /* add the data source tvbuff */
6862 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6863
6864 fi->appendix_start = 0;
6865 fi->appendix_length = 0;
6866
6867 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6868 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6869
6870 return fi;
6871}
6872
6873static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6874{
6875 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6876 return 0;
6877 }
6878
6879 /* Search for field name */
6880 char *ptr = strstr(representation, hfinfo->name);
6881 if (!ptr) {
6882 return 0;
6883 }
6884
6885 /* Check if field name ends with the ": " delimiter */
6886 ptr += strlen(hfinfo->name);
6887 if (strncmp(ptr, ": ", 2) == 0) {
6888 ptr += 2;
6889 }
6890
6891 /* Return offset to after field name */
6892 return ptr - representation;
6893}
6894
6895/* If the protocol tree is to be visible, set the representation of a
6896 proto_tree entry with the name of the field for the item and with
6897 the value formatted with the supplied printf-style format and
6898 argument list. */
6899static void
6900proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6901{
6902 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6902, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6903
6904 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6905 * items string representation */
6906 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6907 size_t name_pos, ret = 0;
6908 char *str;
6909 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6910 const header_field_info *hf;
6911
6912 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6912, "fi"))))
;
6913
6914 hf = fi->hfinfo;
6915
6916 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;
;
6917 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))
)) {
6918 uint64_t val;
6919 char *p;
6920
6921 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)
)
6922 val = fvalue_get_uinteger(fi->value);
6923 else
6924 val = fvalue_get_uinteger64(fi->value);
6925
6926 val <<= hfinfo_bitshift(hf);
6927
6928 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6929 ret = (p - fi->rep->representation);
6930 }
6931
6932 /* put in the hf name */
6933 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
6934
6935 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
6936 /* If possible, Put in the value of the string */
6937 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6938 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"
, 6938, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6939 fi->rep->value_pos = ret;
6940 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
6941 if (ret >= ITEM_LABEL_LENGTH240) {
6942 /* Uh oh, we don't have enough room. Tell the user
6943 * that the field is truncated.
6944 */
6945 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6946 }
6947 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6948 }
6949}
6950
6951/* If the protocol tree is to be visible, set the representation of a
6952 proto_tree entry with the representation formatted with the supplied
6953 printf-style format and argument list. */
6954static void
6955proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6956{
6957 size_t ret; /*tmp return value */
6958 char *str;
6959 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6960
6961 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6961, "fi"))))
;
6962
6963 if (!proto_item_is_hidden(pi)) {
6964 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;
;
6965
6966 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6967 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"
, 6967, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6968 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
6969 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
6970 if (ret >= ITEM_LABEL_LENGTH240) {
6971 /* Uh oh, we don't have enough room. Tell the user
6972 * that the field is truncated.
6973 */
6974 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
6975 }
6976 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6977 }
6978}
6979
6980static int
6981proto_strlcpy(char *dest, const char *src, size_t dest_size)
6982{
6983 if (dest_size == 0) return 0;
6984
6985 size_t res = g_strlcpy(dest, src, dest_size);
6986
6987 /* At most dest_size - 1 characters will be copied
6988 * (unless dest_size is 0). */
6989 if (res >= dest_size)
6990 res = dest_size - 1;
6991 return (int) res;
6992}
6993
6994static header_field_info *
6995hfinfo_same_name_get_prev(const header_field_info *hfinfo)
6996{
6997 header_field_info *dup_hfinfo;
6998
6999 if (hfinfo->same_name_prev_id == -1)
7000 return NULL((void*)0);
7001 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", 7001
, __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", 7001, "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", 7001,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7002 return dup_hfinfo;
7003}
7004
7005static void
7006hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7007{
7008 g_free(last_field_name);
7009 last_field_name = NULL((void*)0);
7010
7011 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7012 /* No hfinfo with the same name */
7013 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
7014 return;
7015 }
7016
7017 if (hfinfo->same_name_next) {
7018 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7019 }
7020
7021 if (hfinfo->same_name_prev_id != -1) {
7022 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7023 same_name_prev->same_name_next = hfinfo->same_name_next;
7024 if (!hfinfo->same_name_next) {
7025 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7026 g_hash_table_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7027 }
7028 }
7029}
7030
7031int
7032proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7033{
7034 const header_field_info *hfinfo = finfo->hfinfo;
7035 int label_len = 0;
7036 char *tmp_str;
7037 const char *str;
7038 const uint8_t *bytes;
7039 uint32_t number;
7040 uint64_t number64;
7041 const char *hf_str_val;
7042 char number_buf[NUMBER_LABEL_LENGTH80];
7043 const char *number_out;
7044 address addr;
7045 const ipv4_addr_and_mask *ipv4;
7046 const ipv6_addr_and_prefix *ipv6;
7047
7048 switch (hfinfo->type) {
7049
7050 case FT_NONE:
7051 case FT_PROTOCOL:
7052 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7053
7054 case FT_UINT_BYTES:
7055 case FT_BYTES:
7056 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7057 hfinfo,
7058 fvalue_get_bytes_data(finfo->value),
7059 (unsigned)fvalue_length2(finfo->value),
7060 label_str_size);
7061 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7062 wmem_free(NULL((void*)0), tmp_str);
7063 break;
7064
7065 case FT_ABSOLUTE_TIME:
7066 {
7067 const nstime_t *value = fvalue_get_time(finfo->value);
7068 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7069 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7070 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7071 }
7072 if (hfinfo->strings) {
7073 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7074 if (time_string != NULL((void*)0)) {
7075 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7076 break;
7077 }
7078 }
7079 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7080 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7081 wmem_free(NULL((void*)0), tmp_str);
7082 break;
7083 }
7084
7085 case FT_RELATIVE_TIME:
7086 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7087 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7088 wmem_free(NULL((void*)0), tmp_str);
7089 break;
7090
7091 case FT_BOOLEAN:
7092 number64 = fvalue_get_uinteger64(finfo->value);
7093 label_len = proto_strlcpy(display_label_str,
7094 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7095 break;
7096
7097 case FT_CHAR:
7098 number = fvalue_get_uinteger(finfo->value);
7099
7100 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7101 char tmp[ITEM_LABEL_LENGTH240];
7102 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7103
7104 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7104, "fmtfunc"))))
;
7105 fmtfunc(tmp, number);
7106
7107 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7108
7109 } else if (hfinfo->strings) {
7110 number_out = hf_try_val_to_str(number, hfinfo);
7111
7112 if (!number_out) {
7113 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7114 }
7115
7116 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7117
7118 } else {
7119 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7120
7121 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7122 }
7123
7124 break;
7125
7126 /* XXX - make these just FT_NUMBER? */
7127 case FT_INT8:
7128 case FT_INT16:
7129 case FT_INT24:
7130 case FT_INT32:
7131 case FT_UINT8:
7132 case FT_UINT16:
7133 case FT_UINT24:
7134 case FT_UINT32:
7135 case FT_FRAMENUM:
7136 hf_str_val = NULL((void*)0);
7137 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
))
?
7138 (uint32_t) fvalue_get_sinteger(finfo->value) :
7139 fvalue_get_uinteger(finfo->value);
7140
7141 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7142 char tmp[ITEM_LABEL_LENGTH240];
7143 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7144
7145 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7145, "fmtfunc"))))
;
7146 fmtfunc(tmp, number);
7147
7148 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7149
7150 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7151 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7152 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7153 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7154 hf_str_val = hf_try_val_to_str(number, hfinfo);
7155 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7156 } else {
7157 number_out = hf_try_val_to_str(number, hfinfo);
7158
7159 if (!number_out) {
7160 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7161 }
7162
7163 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7164 }
7165 } else {
7166 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7167
7168 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7169 }
7170
7171 break;
7172
7173 case FT_INT40:
7174 case FT_INT48:
7175 case FT_INT56:
7176 case FT_INT64:
7177 case FT_UINT40:
7178 case FT_UINT48:
7179 case FT_UINT56:
7180 case FT_UINT64:
7181 hf_str_val = NULL((void*)0);
7182 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
))
?
7183 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7184 fvalue_get_uinteger64(finfo->value);
7185
7186 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7187 char tmp[ITEM_LABEL_LENGTH240];
7188 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7189
7190 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7190, "fmtfunc64"
))))
;
7191 fmtfunc64(tmp, number64);
7192
7193 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7194 } else if (hfinfo->strings) {
7195 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7196 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7197 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7198 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7199 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7200 } else {
7201 number_out = hf_try_val64_to_str(number64, hfinfo);
7202
7203 if (!number_out)
7204 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7205
7206 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7207 }
7208 } else {
7209 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7210
7211 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7212 }
7213
7214 break;
7215
7216 case FT_EUI64:
7217 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7218 tmp_str = address_to_display(NULL((void*)0), &addr);
7219 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7220 wmem_free(NULL((void*)0), tmp_str);
7221 break;
7222
7223 case FT_IPv4:
7224 ipv4 = fvalue_get_ipv4(finfo->value);
7225 //XXX: Should we ignore the mask?
7226 set_address_ipv4(&addr, ipv4);
7227 tmp_str = address_to_display(NULL((void*)0), &addr);
7228 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7229 wmem_free(NULL((void*)0), tmp_str);
7230 free_address(&addr);
7231 break;
7232
7233 case FT_IPv6:
7234 ipv6 = fvalue_get_ipv6(finfo->value);
7235 set_address_ipv6(&addr, ipv6);
7236 tmp_str = address_to_display(NULL((void*)0), &addr);
7237 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7238 wmem_free(NULL((void*)0), tmp_str);
7239 free_address(&addr);
7240 break;
7241
7242 case FT_FCWWN:
7243 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7244 tmp_str = address_to_display(NULL((void*)0), &addr);
7245 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7246 wmem_free(NULL((void*)0), tmp_str);
7247 break;
7248
7249 case FT_ETHER:
7250 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7251 tmp_str = address_to_display(NULL((void*)0), &addr);
7252 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7253 wmem_free(NULL((void*)0), tmp_str);
7254 break;
7255
7256 case FT_GUID:
7257 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7258 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7259 wmem_free(NULL((void*)0), tmp_str);
7260 break;
7261
7262 case FT_REL_OID:
7263 bytes = fvalue_get_bytes_data(finfo->value);
7264 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7265 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7266 wmem_free(NULL((void*)0), tmp_str);
7267 break;
7268
7269 case FT_OID:
7270 bytes = fvalue_get_bytes_data(finfo->value);
7271 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7272 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7273 wmem_free(NULL((void*)0), tmp_str);
7274 break;
7275
7276 case FT_SYSTEM_ID:
7277 bytes = fvalue_get_bytes_data(finfo->value);
7278 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7279 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7280 wmem_free(NULL((void*)0), tmp_str);
7281 break;
7282
7283 case FT_FLOAT:
7284 case FT_DOUBLE:
7285 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7286 break;
7287
7288 case FT_IEEE_11073_SFLOAT:
7289 case FT_IEEE_11073_FLOAT:
7290 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7291 break;
7292
7293 case FT_STRING:
7294 case FT_STRINGZ:
7295 case FT_UINT_STRING:
7296 case FT_STRINGZPAD:
7297 case FT_STRINGZTRUNC:
7298 str = fvalue_get_string(finfo->value);
7299 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7300 if (label_len >= label_str_size) {
7301 /* Truncation occurred. Get the real length
7302 * copied (not including '\0') */
7303 label_len = label_str_size ? label_str_size - 1 : 0;
7304 }
7305 break;
7306
7307 default:
7308 /* First try ftype string representation */
7309 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7310 if (!tmp_str) {
7311 /* Default to show as bytes */
7312 bytes = fvalue_get_bytes_data(finfo->value);
7313 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7314 }
7315 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7316 wmem_free(NULL((void*)0), tmp_str);
7317 break;
7318 }
7319 return label_len;
7320}
7321
7322const char *
7323proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7324 char *result, char *expr, const int size)
7325{
7326 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7327 GPtrArray *finfos;
7328 field_info *finfo = NULL((void*)0);
7329 header_field_info* hfinfo;
7330 const char *abbrev = NULL((void*)0);
7331
7332 char *str;
7333 col_custom_t *field_idx;
7334 int field_id;
7335 int ii = 0;
7336
7337 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7337, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7338 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7339 field_id = field_idx->field_id;
7340 if (field_id == 0) {
7341 GPtrArray *fvals = NULL((void*)0);
7342 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7343 if (fvals != NULL((void*)0)) {
7344
7345 // XXX - Handling occurrences is unusual when more
7346 // than one field is involved, e.g. there's four
7347 // results for tcp.port + tcp.port. We may really
7348 // want to apply it to the operands, not the output.
7349 // Note that occurrences are not quite the same as
7350 // the layer operator (should the grammar support
7351 // both?)
7352 /* Calculate single index or set outer boundaries */
7353 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7354 if (occurrence < 0) {
7355 i = occurrence + len;
7356 last = i;
7357 } else if (occurrence > 0) {
7358 i = occurrence - 1;
7359 last = i;
7360 } else {
7361 i = 0;
7362 last = len - 1;
7363 }
7364 if (i < 0 || i >= len) {
7365 g_ptr_array_unref(fvals);
7366 continue;
7367 }
7368 for (; i <= last; i++) {
7369 /* XXX - We could have a "resolved" result
7370 * for types where the value depends only
7371 * on the type, e.g. FT_IPv4, and not on
7372 * hfinfo->strings. Supporting the latter
7373 * requires knowing which hfinfo matched
7374 * if there are multiple with the same
7375 * abbreviation. In any case, we need to
7376 * know the expected return type of the
7377 * field expression.
7378 */
7379 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7380 if (offset_r && (offset_r < (size - 1)))
7381 result[offset_r++] = ',';
7382 if (offset_e && (offset_e < (size - 1)))
7383 expr[offset_e++] = ',';
7384 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7385 // col_{add,append,set}_* calls ws_label_strcpy
7386 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7387
7388 g_free(str);
7389 }
7390 g_ptr_array_unref(fvals);
7391 } else if (passed) {
7392 // XXX - Occurrence doesn't make sense for a test
7393 // output, it should be applied to the operands.
7394 if (offset_r && (offset_r < (size - 1)))
7395 result[offset_r++] = ',';
7396 if (offset_e && (offset_e < (size - 1)))
7397 expr[offset_e++] = ',';
7398 /* Prevent multiple check marks */
7399 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7400 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7401 } else {
7402 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7403 }
7404 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7405 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7406 } else {
7407 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7408 }
7409 }
7410 continue;
7411 }
7412 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", 7412
, __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", 7412,
"(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", 7412,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7413
7414 /* do we need to rewind ? */
7415 if (!hfinfo)
7416 return "";
7417
7418 if (occurrence < 0) {
7419 /* Search other direction */
7420 while (hfinfo->same_name_prev_id != -1) {
7421 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", 7421
, __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", 7421, "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", 7421,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7422 }
7423 }
7424
7425 prev_len = 0; /* Reset handled occurrences */
7426
7427 while (hfinfo) {
7428 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7429
7430 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7431 if (occurrence < 0) {
7432 hfinfo = hfinfo->same_name_next;
7433 } else {
7434 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7435 }
7436 continue;
7437 }
7438
7439 /* Are there enough occurrences of the field? */
7440 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7441 if (occurrence < 0) {
7442 hfinfo = hfinfo->same_name_next;
7443 } else {
7444 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7445 }
7446 prev_len += len;
7447 continue;
7448 }
7449
7450 /* Calculate single index or set outer boundaries */
7451 if (occurrence < 0) {
7452 i = occurrence + len + prev_len;
7453 last = i;
7454 } else if (occurrence > 0) {
7455 i = occurrence - 1 - prev_len;
7456 last = i;
7457 } else {
7458 i = 0;
7459 last = len - 1;
7460 }
7461
7462 prev_len += len; /* Count handled occurrences */
7463
7464 while (i <= last) {
7465 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7466
7467 if (offset_r && (offset_r < (size - 1)))
7468 result[offset_r++] = ',';
7469
7470 if (display_details) {
7471 char representation[ITEM_LABEL_LENGTH240];
7472 size_t offset = 0;
7473
7474 if (finfo->rep && finfo->rep->value_len) {
7475 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7476 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7477 } else {
7478 proto_item_fill_label(finfo, representation, &offset);
7479 }
7480 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7481 } else {
7482 switch (hfinfo->type) {
7483
7484 case FT_NONE:
7485 case FT_PROTOCOL:
7486 /* Prevent multiple check marks */
7487 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7488 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7489 } else {
7490 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7491 }
7492 break;
7493
7494 default:
7495 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7496 break;
7497 }
7498 }
7499
7500 if (offset_e && (offset_e < (size - 1)))
7501 expr[offset_e++] = ',';
7502
7503 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
))
)) {
7504 const char *hf_str_val;
7505 /* Integer types with BASE_NONE never get the numeric value. */
7506 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7507 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7508 } 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
)
) {
7509 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7510 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7511 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7512 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7513 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7514 }
7515 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7516 offset_e = (int)strlen(expr);
7517 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7518 /* Prevent multiple check marks */
7519 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7520 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7521 } else {
7522 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7523 }
7524 } else {
7525 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7526 // col_{add,append,set}_* calls ws_label_strcpy
7527 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7528 wmem_free(NULL((void*)0), str);
7529 }
7530 i++;
7531 }
7532
7533 /* XXX: Why is only the first abbreviation returned for a multifield
7534 * custom column? */
7535 if (!abbrev) {
7536 /* Store abbrev for return value */
7537 abbrev = hfinfo->abbrev;
7538 }
7539
7540 if (occurrence == 0) {
7541 /* Fetch next hfinfo with same name (abbrev) */
7542 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7543 } else {
7544 hfinfo = NULL((void*)0);
7545 }
7546 }
7547 }
7548
7549 if (offset_r >= (size - 1)) {
7550 mark_truncated(result, 0, size, NULL((void*)0));
7551 }
7552 if (offset_e >= (size - 1)) {
7553 mark_truncated(expr, 0, size, NULL((void*)0));
7554 }
7555 return abbrev ? abbrev : "";
7556}
7557
7558char *
7559proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7560{
7561 int len, prev_len, last, i;
7562 GPtrArray *finfos;
7563 field_info *finfo = NULL((void*)0);
7564 header_field_info* hfinfo;
7565
7566 char *filter = NULL((void*)0);
7567 GPtrArray *filter_array;
7568
7569 col_custom_t *col_custom;
7570 int field_id;
7571
7572 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7572, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7573 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7574 for (GSList *iter = field_ids; iter; iter = iter->next) {
7575 col_custom = (col_custom_t*)iter->data;
7576 field_id = col_custom->field_id;
7577 if (field_id == 0) {
7578 GPtrArray *fvals = NULL((void*)0);
7579 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7580 if (fvals != NULL((void*)0)) {
7581 // XXX - Handling occurrences is unusual when more
7582 // than one field is involved, e.g. there's four
7583 // results for tcp.port + tcp.port. We really
7584 // want to apply it to the operands, not the output.
7585 /* Calculate single index or set outer boundaries */
7586 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7587 if (occurrence < 0) {
7588 i = occurrence + len;
7589 last = i;
7590 } else if (occurrence > 0) {
7591 i = occurrence - 1;
7592 last = i;
7593 } else {
7594 i = 0;
7595 last = len - 1;
7596 }
7597 if (i < 0 || i >= len) {
7598 g_ptr_array_unref(fvals);
7599 continue;
7600 }
7601 for (; i <= last; i++) {
7602 /* XXX - Should multiple values for one
7603 * field use set membership to reduce
7604 * verbosity, here and below? */
7605 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7606 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7607 wmem_free(NULL((void*)0), str);
7608 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7609 g_ptr_array_add(filter_array, filter);
7610 }
7611 }
7612 g_ptr_array_unref(fvals);
7613 } else if (passed) {
7614 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7615 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7616 g_ptr_array_add(filter_array, filter);
7617 }
7618 } else {
7619 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7620 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7621 g_ptr_array_add(filter_array, filter);
7622 }
7623 }
7624 continue;
7625 }
7626
7627 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", 7627
, __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", 7627,
"(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", 7627,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7628
7629 /* do we need to rewind ? */
7630 if (!hfinfo)
7631 return NULL((void*)0);
7632
7633 if (occurrence < 0) {
7634 /* Search other direction */
7635 while (hfinfo->same_name_prev_id != -1) {
7636 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", 7636
, __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", 7636, "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", 7636,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7637 }
7638 }
7639
7640 prev_len = 0; /* Reset handled occurrences */
7641
7642 while (hfinfo) {
7643 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7644
7645 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7646 if (occurrence < 0) {
7647 hfinfo = hfinfo->same_name_next;
7648 } else {
7649 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7650 }
7651 continue;
7652 }
7653
7654 /* Are there enough occurrences of the field? */
7655 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7656 if (occurrence < 0) {
7657 hfinfo = hfinfo->same_name_next;
7658 } else {
7659 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7660 }
7661 prev_len += len;
7662 continue;
7663 }
7664
7665 /* Calculate single index or set outer boundaries */
7666 if (occurrence < 0) {
7667 i = occurrence + len + prev_len;
7668 last = i;
7669 } else if (occurrence > 0) {
7670 i = occurrence - 1 - prev_len;
7671 last = i;
7672 } else {
7673 i = 0;
7674 last = len - 1;
7675 }
7676
7677 prev_len += len; /* Count handled occurrences */
7678
7679 while (i <= last) {
7680 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7681
7682 filter = proto_construct_match_selected_string(finfo, edt);
7683 if (filter) {
7684 /* Only add the same expression once (especially for FT_PROTOCOL).
7685 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7686 */
7687 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7688 g_ptr_array_add(filter_array, filter);
7689 }
7690 }
7691 i++;
7692 }
7693
7694 if (occurrence == 0) {
7695 /* Fetch next hfinfo with same name (abbrev) */
7696 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7697 } else {
7698 hfinfo = NULL((void*)0);
7699 }
7700 }
7701 }
7702
7703 g_ptr_array_add(filter_array, NULL((void*)0));
7704
7705 /* XXX: Should this be || or && ? */
7706 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7707
7708 g_ptr_array_free(filter_array, true1);
7709
7710 return output;
7711}
7712
7713/* Set text of proto_item after having already been created. */
7714void
7715proto_item_set_text(proto_item *pi, const char *format, ...)
7716{
7717 field_info *fi = NULL((void*)0);
7718 va_list ap;
7719
7720 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7721
7722 fi = PITEM_FINFO(pi)((pi)->finfo);
7723 if (fi == NULL((void*)0))
7724 return;
7725
7726 if (fi->rep) {
7727 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7728 fi->rep = NULL((void*)0);
7729 }
7730
7731 va_start(ap, format)__builtin_va_start(ap, format);
7732 proto_tree_set_representation(pi, format, ap);
7733 va_end(ap)__builtin_va_end(ap);
7734}
7735
7736/* Append to text of proto_item after having already been created. */
7737void
7738proto_item_append_text(proto_item *pi, const char *format, ...)
7739{
7740 field_info *fi = NULL((void*)0);
7741 size_t curlen;
7742 char *str;
7743 va_list ap;
7744
7745 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7746
7747 fi = PITEM_FINFO(pi)((pi)->finfo);
7748 if (fi == NULL((void*)0)) {
7749 return;
7750 }
7751
7752 if (!proto_item_is_hidden(pi)) {
7753 /*
7754 * If we don't already have a representation,
7755 * generate the default representation.
7756 */
7757 if (fi->rep == NULL((void*)0)) {
7758 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;
;
7759 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7760 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7761 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7762 (strncmp(format, ": ", 2) == 0)) {
7763 fi->rep->value_pos += 2;
7764 }
7765 }
7766 if (fi->rep) {
7767 curlen = strlen(fi->rep->representation);
7768 /* curlen doesn't include the \0 byte.
7769 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7770 * the representation has already been truncated (of an up
7771 * to 4 byte UTF-8 character) or is just at the maximum length
7772 * unless we search for " [truncated]" (which may not be
7773 * at the start.)
7774 * It's safer to do nothing.
7775 */
7776 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7777 va_start(ap, format)__builtin_va_start(ap, format);
7778 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7779 va_end(ap)__builtin_va_end(ap);
7780 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"
, 7780, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7781 /* Keep fi->rep->value_pos */
7782 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7783 if (curlen >= ITEM_LABEL_LENGTH240) {
7784 /* Uh oh, we don't have enough room. Tell the user
7785 * that the field is truncated.
7786 */
7787 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7788 }
7789 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7790 }
7791 }
7792 }
7793}
7794
7795/* Prepend to text of proto_item after having already been created. */
7796void
7797proto_item_prepend_text(proto_item *pi, const char *format, ...)
7798{
7799 field_info *fi = NULL((void*)0);
7800 size_t pos;
7801 char representation[ITEM_LABEL_LENGTH240];
7802 char *str;
7803 va_list ap;
7804
7805 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7806
7807 fi = PITEM_FINFO(pi)((pi)->finfo);
7808 if (fi == NULL((void*)0)) {
7809 return;
7810 }
7811
7812 if (!proto_item_is_hidden(pi)) {
7813 /*
7814 * If we don't already have a representation,
7815 * generate the default representation.
7816 */
7817 if (fi->rep == NULL((void*)0)) {
7818 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;
;
7819 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7820 } else
7821 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7822
7823 va_start(ap, format)__builtin_va_start(ap, format);
7824 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7825 va_end(ap)__builtin_va_end(ap);
7826 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"
, 7826, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7827 fi->rep->value_pos += strlen(str);
7828 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7829 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7830 /* XXX: As above, if the old representation is close to the label
7831 * length, it might already be marked as truncated. */
7832 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7833 /* Uh oh, we don't have enough room. Tell the user
7834 * that the field is truncated.
7835 */
7836 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7837 }
7838 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7839 }
7840}
7841
7842static void
7843finfo_set_len(field_info *fi, const int length)
7844{
7845 int length_remaining;
7846
7847 DISSECTOR_ASSERT_HINT(length >= 0, fi->hfinfo->abbrev)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7847,
"length >= 0", fi->hfinfo->abbrev))))
;
7848 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7849 if (length > length_remaining)
7850 fi->length = length_remaining;
7851 else
7852 fi->length = length;
7853
7854 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7855 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7856 fvalue_set_protocol_length(fi->value, fi->length);
7857 }
7858
7859 /*
7860 * You cannot just make the "len" field of a GByteArray
7861 * larger, if there's no data to back that length;
7862 * you can only make it smaller.
7863 */
7864 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7865 GBytes *bytes = fvalue_get_bytes(fi->value);
7866 size_t size;
7867 const void *data = g_bytes_get_data(bytes, &size);
7868 if ((size_t)fi->length <= size) {
7869 fvalue_set_bytes_data(fi->value, data, fi->length);
7870 }
7871 g_bytes_unref(bytes);
7872 }
7873}
7874
7875void
7876proto_item_set_len(proto_item *pi, const int length)
7877{
7878 field_info *fi;
7879
7880 if (pi == NULL((void*)0))
7881 return;
7882
7883 fi = PITEM_FINFO(pi)((pi)->finfo);
7884 if (fi == NULL((void*)0))
7885 return;
7886
7887 finfo_set_len(fi, length);
7888}
7889
7890/*
7891 * Sets the length of the item based on its start and on the specified
7892 * offset, which is the offset past the end of the item; as the start
7893 * in the item is relative to the beginning of the data source tvbuff,
7894 * we need to pass in a tvbuff - the end offset is relative to the beginning
7895 * of that tvbuff.
7896 */
7897void
7898proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7899{
7900 field_info *fi;
7901 int length;
7902
7903 if (pi == NULL((void*)0))
7904 return;
7905
7906 fi = PITEM_FINFO(pi)((pi)->finfo);
7907 if (fi == NULL((void*)0))
7908 return;
7909
7910 end += tvb_raw_offset(tvb);
7911 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7911, "end >= fi->start"
))))
;
7912 length = end - fi->start;
7913
7914 finfo_set_len(fi, length);
7915}
7916
7917int
7918proto_item_get_len(const proto_item *pi)
7919{
7920 field_info *fi;
7921
7922 if (!pi)
7923 return -1;
7924 fi = PITEM_FINFO(pi)((pi)->finfo);
7925 return fi ? fi->length : -1;
7926}
7927
7928void
7929proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7930 if (!ti) {
7931 return;
7932 }
7933 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)
;
7934 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)
;
7935}
7936
7937char *
7938proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7939{
7940 field_info *fi;
7941
7942 if (!pi)
7943 return wmem_strdup(scope, "");
7944 fi = PITEM_FINFO(pi)((pi)->finfo);
7945 if (!fi)
7946 return wmem_strdup(scope, "");
7947 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7947, "fi->hfinfo != ((void*)0)"
))))
;
7948 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7949}
7950
7951proto_tree *
7952proto_tree_create_root(packet_info *pinfo)
7953{
7954 proto_node *pnode;
7955
7956 /* Initialize the proto_node */
7957 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
7958 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
7959 pnode->parent = NULL((void*)0);
7960 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
7961 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
7962
7963 /* Make sure we can access pinfo everywhere */
7964 pnode->tree_data->pinfo = pinfo;
7965
7966 /* Don't initialize the tree_data_t. Wait until we know we need it */
7967 pnode->tree_data->interesting_hfids = NULL((void*)0);
7968
7969 /* Set the default to false so it's easier to
7970 * find errors; if we expect to see the protocol tree
7971 * but for some reason the default 'visible' is not
7972 * changed, then we'll find out very quickly. */
7973 pnode->tree_data->visible = false0;
7974
7975 /* Make sure that we fake protocols (if possible) */
7976 pnode->tree_data->fake_protocols = true1;
7977
7978 /* Keep track of the number of children */
7979 pnode->tree_data->count = 0;
7980
7981 /* Initialize our loop checks */
7982 pnode->tree_data->max_start = 0;
7983 pnode->tree_data->start_idle_count = 0;
7984
7985 return (proto_tree *)pnode;
7986}
7987
7988
7989/* "prime" a proto_tree with a single hfid that a dfilter
7990 * is interested in. */
7991void
7992proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
7993{
7994 header_field_info *hfinfo;
7995
7996 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", 7996, __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", 7996, "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", 7996, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
7997 /* this field is referenced by a filter so increase the refcount.
7998 also increase the refcount for the parent, i.e the protocol.
7999 Don't increase the refcount if we're already printing the
8000 type, as that is a superset of direct reference.
8001 */
8002 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8003 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8004 }
8005 /* only increase the refcount if there is a parent.
8006 if this is a protocol and not a field then parent will be -1
8007 and there is no parent to add any refcounting for.
8008 */
8009 if (hfinfo->parent != -1) {
8010 header_field_info *parent_hfinfo;
8011 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", 8011
, __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", 8011,
"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", 8011,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8012
8013 /* Mark parent as indirectly referenced unless it is already directly
8014 * referenced, i.e. the user has specified the parent in a filter.
8015 */
8016 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8017 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8018 }
8019}
8020
8021/* "prime" a proto_tree with a single hfid that a dfilter
8022 * is interested in. */
8023void
8024proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8025{
8026 header_field_info *hfinfo;
8027
8028 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", 8028, __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", 8028, "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", 8028, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8029 /* this field is referenced by an (output) filter so increase the refcount.
8030 also increase the refcount for the parent, i.e the protocol.
8031 */
8032 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8033 /* only increase the refcount if there is a parent.
8034 if this is a protocol and not a field then parent will be -1
8035 and there is no parent to add any refcounting for.
8036 */
8037 if (hfinfo->parent != -1) {
8038 header_field_info *parent_hfinfo;
8039 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", 8039
, __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", 8039,
"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", 8039,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8040
8041 /* Mark parent as indirectly referenced unless it is already directly
8042 * referenced, i.e. the user has specified the parent in a filter.
8043 */
8044 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8045 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8046 }
8047}
8048
8049proto_tree *
8050proto_item_add_subtree(proto_item *pi, const int idx) {
8051 field_info *fi;
8052
8053 if (!pi)
8054 return NULL((void*)0);
8055
8056 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", 8056, "idx >= 0 && idx < num_tree_types"
))))
;
8057
8058 fi = PITEM_FINFO(pi)((pi)->finfo);
8059 if (!fi)
8060 return (proto_tree *)pi;
8061
8062 fi->tree_type = idx;
8063
8064 return (proto_tree *)pi;
8065}
8066
8067proto_tree *
8068proto_item_get_subtree(proto_item *pi) {
8069 field_info *fi;
8070
8071 if (!pi)
8072 return NULL((void*)0);
8073 fi = PITEM_FINFO(pi)((pi)->finfo);
8074 if ( (fi) && (fi->tree_type == -1) )
8075 return NULL((void*)0);
8076 return (proto_tree *)pi;
8077}
8078
8079proto_item *
8080proto_item_get_parent(const proto_item *ti) {
8081 if (!ti)
8082 return NULL((void*)0);
8083 return ti->parent;
8084}
8085
8086proto_item *
8087proto_item_get_parent_nth(proto_item *ti, int gen) {
8088 if (!ti)
8089 return NULL((void*)0);
8090 while (gen--) {
8091 ti = ti->parent;
8092 if (!ti)
8093 return NULL((void*)0);
8094 }
8095 return ti;
8096}
8097
8098
8099proto_item *
8100proto_tree_get_parent(proto_tree *tree) {
8101 if (!tree)
8102 return NULL((void*)0);
8103 return (proto_item *)tree;
8104}
8105
8106proto_tree *
8107proto_tree_get_parent_tree(proto_tree *tree) {
8108 if (!tree)
8109 return NULL((void*)0);
8110
8111 /* we're the root tree, there's no parent
8112 return ourselves so the caller has at least a tree to attach to */
8113 if (!tree->parent)
8114 return tree;
8115
8116 return (proto_tree *)tree->parent;
8117}
8118
8119proto_tree *
8120proto_tree_get_root(proto_tree *tree) {
8121 if (!tree)
8122 return NULL((void*)0);
8123 while (tree->parent) {
8124 tree = tree->parent;
8125 }
8126 return tree;
8127}
8128
8129void
8130proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8131 proto_item *item_to_move)
8132{
8133 /* This function doesn't generate any values. It only reorganizes the prococol tree
8134 * so we can bail out immediately if it isn't visible. */
8135 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8136 return;
8137
8138 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", 8138, "item_to_move->parent == tree"
))))
;
8139 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", 8139, "fixed_item->parent == tree"
))))
;
8140
8141 /*** cut item_to_move out ***/
8142
8143 /* is item_to_move the first? */
8144 if (tree->first_child == item_to_move) {
8145 /* simply change first child to next */
8146 tree->first_child = item_to_move->next;
8147
8148 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", 8148, "tree->last_child != item_to_move"
))))
;
8149 } else {
8150 proto_item *curr_item;
8151 /* find previous and change it's next */
8152 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8153 if (curr_item->next == item_to_move) {
8154 break;
8155 }
8156 }
8157
8158 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8158, "curr_item"
))))
;
8159
8160 curr_item->next = item_to_move->next;
8161
8162 /* fix last_child if required */
8163 if (tree->last_child == item_to_move) {
8164 tree->last_child = curr_item;
8165 }
8166 }
8167
8168 /*** insert to_move after fixed ***/
8169 item_to_move->next = fixed_item->next;
8170 fixed_item->next = item_to_move;
8171 if (tree->last_child == fixed_item) {
8172 tree->last_child = item_to_move;
8173 }
8174}
8175
8176void
8177proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8178 const int length)
8179{
8180 field_info *fi;
8181
8182 if (tree == NULL((void*)0))
8183 return;
8184
8185 fi = PTREE_FINFO(tree)((tree)->finfo);
8186 if (fi == NULL((void*)0))
8187 return;
8188
8189 start += tvb_raw_offset(tvb);
8190 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8190, "start >= 0"
))))
;
8191 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8191, "length >= 0"
))))
;
8192
8193 fi->appendix_start = start;
8194 fi->appendix_length = length;
8195}
8196
8197static void
8198check_protocol_filter_name_or_fail(const char *filter_name)
8199{
8200 /* Require at least two characters. */
8201 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8202 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)
;
8203 }
8204
8205 if (proto_check_field_name(filter_name) != '\0') {
8206 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)
8207 " 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)
8208 " 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)
;
8209 }
8210
8211 /* Check that it doesn't match some very common numeric forms. */
8212 if (filter_name[0] == '0' &&
8213 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8214 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8215 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])
8216 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])
;
8217 }
8218
8219 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8220
8221 /* Check that it contains at least one letter. */
8222 bool_Bool have_letter = false0;
8223 for (const char *s = filter_name; *s != '\0'; s++) {
8224 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8225 have_letter = true1;
8226 break;
8227 }
8228 }
8229 if (!have_letter) {
8230 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)
8231 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8232 }
8233
8234 /* Check for reserved keywords. */
8235 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8236 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)
8237 " 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)
;
8238 }
8239}
8240
8241int
8242proto_register_protocol(const char *name, const char *short_name,
8243 const char *filter_name)
8244{
8245 protocol_t *protocol;
8246 header_field_info *hfinfo;
8247
8248 /*
8249 * Make sure there's not already a protocol with any of those
8250 * names. Crash if there is, as that's an error in the code
8251 * or an inappropriate plugin.
8252 * This situation has to be fixed to not register more than one
8253 * protocol with the same name.
8254 */
8255
8256 if (g_hash_table_lookup(proto_names, name)) {
8257 /* ws_error will terminate the program */
8258 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)
8259 " 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)
;
8260 }
8261
8262 if (g_hash_table_lookup(proto_short_names, short_name)) {
8263 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)
8264 " 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)
;
8265 }
8266
8267 check_protocol_filter_name_or_fail(filter_name);
8268
8269 if (g_hash_table_lookup(proto_filter_names, filter_name)) {
8270 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)
8271 " 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)
;
8272 }
8273
8274 /*
8275 * Add this protocol to the list of known protocols;
8276 * the list is sorted by protocol short name.
8277 */
8278 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8279 protocol->name = name;
8280 protocol->short_name = short_name;
8281 protocol->filter_name = filter_name;
8282 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8283 protocol->is_enabled = true1; /* protocol is enabled by default */
8284 protocol->enabled_by_default = true1; /* see previous comment */
8285 protocol->can_toggle = true1;
8286 protocol->parent_proto_id = -1;
8287 protocol->heur_list = NULL((void*)0);
8288
8289 /* List will be sorted later by name, when all protocols completed registering */
8290 protocols = g_list_prepend(protocols, protocol);
8291 g_hash_table_insert(proto_names, (void *)name, protocol);
8292 g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol);
8293 g_hash_table_insert(proto_short_names, (void *)short_name, protocol);
8294
8295 /* Here we allocate a new header_field_info struct */
8296 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8297 hfinfo->name = name;
8298 hfinfo->abbrev = filter_name;
8299 hfinfo->type = FT_PROTOCOL;
8300 hfinfo->display = BASE_NONE;
8301 hfinfo->strings = protocol;
8302 hfinfo->bitmask = 0;
8303 hfinfo->ref_type = HF_REF_TYPE_NONE;
8304 hfinfo->blurb = NULL((void*)0);
8305 hfinfo->parent = -1; /* This field differentiates protos and fields */
8306
8307 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8308 return protocol->proto_id;
8309}
8310
8311int
8312proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8313{
8314 protocol_t *protocol;
8315 header_field_info *hfinfo;
8316
8317 /*
8318 * Helper protocols don't need the strict rules as a "regular" protocol
8319 * Just register it in a list and make a hf_ field from it
8320 */
8321 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8322 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)
;
8323 }
8324
8325 if (parent_proto <= 0) {
8326 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)
8327 " 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)
;
8328 }
8329
8330 check_protocol_filter_name_or_fail(filter_name);
8331
8332 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8333 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8334 protocol->name = name;
8335 protocol->short_name = short_name;
8336 protocol->filter_name = filter_name;
8337 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8338
8339 /* Enabling and toggling is really determined by parent protocol,
8340 but provide default values here */
8341 protocol->is_enabled = true1;
8342 protocol->enabled_by_default = true1;
8343 protocol->can_toggle = true1;
8344
8345 protocol->parent_proto_id = parent_proto;
8346 protocol->heur_list = NULL((void*)0);
8347
8348 /* List will be sorted later by name, when all protocols completed registering */
8349 protocols = g_list_prepend(protocols, protocol);
8350
8351 /* Here we allocate a new header_field_info struct */
8352 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8353 hfinfo->name = name;
8354 hfinfo->abbrev = filter_name;
8355 hfinfo->type = field_type;
8356 hfinfo->display = BASE_NONE;
8357 if (field_type == FT_BYTES) {
8358 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8359 }
8360 hfinfo->strings = protocol;
8361 hfinfo->bitmask = 0;
8362 hfinfo->ref_type = HF_REF_TYPE_NONE;
8363 hfinfo->blurb = NULL((void*)0);
8364 hfinfo->parent = -1; /* This field differentiates protos and fields */
8365
8366 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8367 return protocol->proto_id;
8368}
8369
8370bool_Bool
8371proto_deregister_protocol(const char *short_name)
8372{
8373 protocol_t *protocol;
8374 header_field_info *hfinfo;
8375 int proto_id;
8376 unsigned i;
8377
8378 proto_id = proto_get_id_by_short_name(short_name);
8379 protocol = find_protocol_by_id(proto_id);
8380 if (protocol == NULL((void*)0))
8381 return false0;
8382
8383 g_hash_table_remove(proto_names, protocol->name);
8384 g_hash_table_remove(proto_short_names, (void *)short_name);
8385 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8386
8387 if (protocol->fields) {
8388 for (i = 0; i < protocol->fields->len; i++) {
8389 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8390 hfinfo_remove_from_gpa_name_map(hfinfo);
8391 expert_deregister_expertinfo(hfinfo->abbrev);
8392 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8393 }
8394 g_ptr_array_free(protocol->fields, true1);
8395 protocol->fields = NULL((void*)0);
8396 }
8397
8398 g_list_free(protocol->heur_list);
8399
8400 /* Remove this protocol from the list of known protocols */
8401 protocols = g_list_remove(protocols, protocol);
8402
8403 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8404 g_hash_table_steal(gpa_name_map, protocol->filter_name);
8405
8406 g_free(last_field_name);
8407 last_field_name = NULL((void*)0);
8408
8409 return true1;
8410}
8411
8412void
8413proto_register_alias(const int proto_id, const char *alias_name)
8414{
8415 protocol_t *protocol;
8416
8417 protocol = find_protocol_by_id(proto_id);
8418 if (alias_name && protocol) {
8419 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8420 }
8421}
8422
8423/*
8424 * Routines to use to iterate over the protocols.
8425 * The argument passed to the iterator routines is an opaque cookie to
8426 * their callers; it's the GList pointer for the current element in
8427 * the list.
8428 * The ID of the protocol is returned, or -1 if there is no protocol.
8429 */
8430int
8431proto_get_first_protocol(void **cookie)
8432{
8433 protocol_t *protocol;
8434
8435 if (protocols == NULL((void*)0))
8436 return -1;
8437 *cookie = protocols;
8438 protocol = (protocol_t *)protocols->data;
8439 return protocol->proto_id;
8440}
8441
8442int
8443proto_get_data_protocol(void *cookie)
8444{
8445 GList *list_item = (GList *)cookie;
8446
8447 protocol_t *protocol = (protocol_t *)list_item->data;
8448 return protocol->proto_id;
8449}
8450
8451int
8452proto_get_next_protocol(void **cookie)
8453{
8454 GList *list_item = (GList *)*cookie;
8455 protocol_t *protocol;
8456
8457 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8458 if (list_item == NULL((void*)0))
8459 return -1;
8460 *cookie = list_item;
8461 protocol = (protocol_t *)list_item->data;
8462 return protocol->proto_id;
8463}
8464
8465header_field_info *
8466proto_get_first_protocol_field(const int proto_id, void **cookie)
8467{
8468 protocol_t *protocol = find_protocol_by_id(proto_id);
8469
8470 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8471 return NULL((void*)0);
8472
8473 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8474 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8475}
8476
8477header_field_info *
8478proto_get_next_protocol_field(const int proto_id, void **cookie)
8479{
8480 protocol_t *protocol = find_protocol_by_id(proto_id);
8481 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8482
8483 i++;
8484
8485 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8486 return NULL((void*)0);
8487
8488 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8489 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8490}
8491
8492protocol_t *
8493find_protocol_by_id(const int proto_id)
8494{
8495 header_field_info *hfinfo;
8496
8497 if (proto_id <= 0)
8498 return NULL((void*)0);
8499
8500 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", 8500, __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", 8500,
"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", 8500, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8501 if (hfinfo->type != FT_PROTOCOL) {
8502 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", 8502, "hfinfo->display & 0x00004000"
))))
;
8503 }
8504 return (protocol_t *)hfinfo->strings;
8505}
8506
8507int
8508proto_get_id(const protocol_t *protocol)
8509{
8510 return protocol->proto_id;
8511}
8512
8513bool_Bool
8514proto_name_already_registered(const char *name)
8515{
8516 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8516, "name", "No name present"))))
;
8517
8518 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8519 return true1;
8520 return false0;
8521}
8522
8523int
8524proto_get_id_by_filter_name(const char *filter_name)
8525{
8526 const protocol_t *protocol = NULL((void*)0);
8527
8528 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", 8528,
"filter_name", "No filter name present"))))
;
8529
8530 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8531
8532 if (protocol == NULL((void*)0))
8533 return -1;
8534 return protocol->proto_id;
8535}
8536
8537int
8538proto_get_id_by_short_name(const char *short_name)
8539{
8540 const protocol_t *protocol = NULL((void*)0);
8541
8542 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", 8542,
"short_name", "No short name present"))))
;
8543
8544 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8545
8546 if (protocol == NULL((void*)0))
8547 return -1;
8548 return protocol->proto_id;
8549}
8550
8551const char *
8552proto_get_protocol_name(const int proto_id)
8553{
8554 protocol_t *protocol;
8555
8556 protocol = find_protocol_by_id(proto_id);
8557
8558 if (protocol == NULL((void*)0))
8559 return NULL((void*)0);
8560 return protocol->name;
8561}
8562
8563const char *
8564proto_get_protocol_short_name(const protocol_t *protocol)
8565{
8566 if (protocol == NULL((void*)0))
8567 return "(none)";
8568 return protocol->short_name;
8569}
8570
8571const char *
8572proto_get_protocol_long_name(const protocol_t *protocol)
8573{
8574 if (protocol == NULL((void*)0))
8575 return "(none)";
8576 return protocol->name;
8577}
8578
8579const char *
8580proto_get_protocol_filter_name(const int proto_id)
8581{
8582 protocol_t *protocol;
8583
8584 protocol = find_protocol_by_id(proto_id);
8585 if (protocol == NULL((void*)0))
8586 return "(none)";
8587 return protocol->filter_name;
8588}
8589
8590void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8591{
8592 heur_dtbl_entry_t* heuristic_dissector;
8593
8594 if (protocol == NULL((void*)0))
8595 return;
8596
8597 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8598 if (heuristic_dissector != NULL((void*)0))
8599 {
8600 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8601 }
8602}
8603
8604void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8605{
8606 if (protocol == NULL((void*)0))
8607 return;
8608
8609 g_list_foreach(protocol->heur_list, func, user_data);
8610}
8611
8612void
8613proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8614 bool_Bool *is_tcp, bool_Bool *is_udp,
8615 bool_Bool *is_sctp, bool_Bool *is_tls,
8616 bool_Bool *is_rtp,
8617 bool_Bool *is_lte_rlc)
8618{
8619 wmem_list_frame_t *protos = wmem_list_head(layers);
8620 int proto_id;
8621 const char *proto_name;
8622
8623 /* Walk the list of a available protocols in the packet and
8624 attempt to find "major" ones. */
8625 /* It might make more sense to assemble and return a bitfield. */
8626 while (protos != NULL((void*)0))
8627 {
8628 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8629 proto_name = proto_get_protocol_filter_name(proto_id);
8630
8631 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8632 (!strcmp(proto_name, "ipv6")))) {
8633 *is_ip = true1;
8634 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8635 *is_tcp = true1;
8636 } else if (is_udp && !strcmp(proto_name, "udp")) {
8637 *is_udp = true1;
8638 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8639 *is_sctp = true1;
8640 } else if (is_tls && !strcmp(proto_name, "tls")) {
8641 *is_tls = true1;
8642 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8643 *is_rtp = true1;
8644 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8645 *is_lte_rlc = true1;
8646 }
8647
8648 protos = wmem_list_frame_next(protos);
8649 }
8650}
8651
8652bool_Bool
8653proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8654{
8655 wmem_list_frame_t *protos = wmem_list_head(layers);
8656 int proto_id;
8657 const char *name;
8658
8659 /* Walk the list of a available protocols in the packet and
8660 attempt to find the specified protocol. */
8661 while (protos != NULL((void*)0))
8662 {
8663 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8664 name = proto_get_protocol_filter_name(proto_id);
8665
8666 if (!strcmp(name, proto_name))
8667 {
8668 return true1;
8669 }
8670
8671 protos = wmem_list_frame_next(protos);
8672 }
8673
8674 return false0;
8675}
8676
8677char *
8678proto_list_layers(const packet_info *pinfo)
8679{
8680 wmem_strbuf_t *buf;
8681 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8682
8683 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8684
8685 /* Walk the list of layers in the packet and
8686 return a string of all entries. */
8687 while (layers != NULL((void*)0))
8688 {
8689 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8690
8691 layers = wmem_list_frame_next(layers);
8692 if (layers != NULL((void*)0)) {
8693 wmem_strbuf_append_c(buf, ':');
8694 }
8695 }
8696
8697 return wmem_strbuf_finalize(buf);
8698}
8699
8700uint8_t
8701proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8702{
8703 int *proto_layer_num_ptr;
8704
8705 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8706 if (proto_layer_num_ptr == NULL((void*)0)) {
8707 return 0;
8708 }
8709
8710 return (uint8_t)*proto_layer_num_ptr;
8711}
8712
8713bool_Bool
8714proto_is_pino(const protocol_t *protocol)
8715{
8716 return (protocol->parent_proto_id != -1);
8717}
8718
8719bool_Bool
8720// NOLINTNEXTLINE(misc-no-recursion)
8721proto_is_protocol_enabled(const protocol_t *protocol)
8722{
8723 if (protocol == NULL((void*)0))
8724 return false0;
8725
8726 //parent protocol determines enable/disable for helper dissectors
8727 if (proto_is_pino(protocol))
8728 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8729
8730 return protocol->is_enabled;
8731}
8732
8733bool_Bool
8734// NOLINTNEXTLINE(misc-no-recursion)
8735proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8736{
8737 //parent protocol determines enable/disable for helper dissectors
8738 if (proto_is_pino(protocol))
8739 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8740
8741 return protocol->enabled_by_default;
8742}
8743
8744bool_Bool
8745// NOLINTNEXTLINE(misc-no-recursion)
8746proto_can_toggle_protocol(const int proto_id)
8747{
8748 protocol_t *protocol;
8749
8750 protocol = find_protocol_by_id(proto_id);
8751 //parent protocol determines toggling for helper dissectors
8752 if (proto_is_pino(protocol))
8753 return proto_can_toggle_protocol(protocol->parent_proto_id);
8754
8755 return protocol->can_toggle;
8756}
8757
8758void
8759proto_disable_by_default(const int proto_id)
8760{
8761 protocol_t *protocol;
8762
8763 protocol = find_protocol_by_id(proto_id);
8764 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8764, "protocol->can_toggle"
))))
;
8765 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", 8765, "proto_is_pino(protocol) == 0"
))))
;
8766 protocol->is_enabled = false0;
8767 protocol->enabled_by_default = false0;
8768}
8769
8770void
8771proto_set_decoding(const int proto_id, const bool_Bool enabled)
8772{
8773 protocol_t *protocol;
8774
8775 protocol = find_protocol_by_id(proto_id);
8776 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8776, "protocol->can_toggle"
))))
;
8777 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", 8777, "proto_is_pino(protocol) == 0"
))))
;
8778 protocol->is_enabled = enabled;
8779}
8780
8781void
8782proto_disable_all(void)
8783{
8784 /* This doesn't explicitly disable heuristic protocols,
8785 * but the heuristic doesn't get called if the parent
8786 * protocol isn't enabled.
8787 */
8788 protocol_t *protocol;
8789 GList *list_item = protocols;
8790
8791 if (protocols == NULL((void*)0))
8792 return;
8793
8794 while (list_item) {
8795 protocol = (protocol_t *)list_item->data;
8796 if (protocol->can_toggle) {
8797 protocol->is_enabled = false0;
8798 }
8799 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8800 }
8801}
8802
8803static void
8804heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8805{
8806 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8807
8808 heur->enabled = heur->enabled_by_default;
8809}
8810
8811void
8812proto_reenable_all(void)
8813{
8814 protocol_t *protocol;
8815 GList *list_item = protocols;
8816
8817 if (protocols == NULL((void*)0))
8818 return;
8819
8820 while (list_item) {
8821 protocol = (protocol_t *)list_item->data;
8822 if (protocol->can_toggle)
8823 protocol->is_enabled = protocol->enabled_by_default;
8824 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8825 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8826 }
8827}
8828
8829void
8830proto_set_cant_toggle(const int proto_id)
8831{
8832 protocol_t *protocol;
8833
8834 protocol = find_protocol_by_id(proto_id);
8835 protocol->can_toggle = false0;
8836}
8837
8838static int
8839proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8840{
8841 if (proto != NULL((void*)0)) {
8842 g_ptr_array_add(proto->fields, hfi);
8843 }
8844
8845 return proto_register_field_init(hfi, parent);
8846}
8847
8848/* for use with static arrays only, since we don't allocate our own copies
8849of the header_field_info struct contained within the hf_register_info struct */
8850void
8851proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8852{
8853 hf_register_info *ptr = hf;
8854 protocol_t *proto;
8855 int i;
8856
8857 proto = find_protocol_by_id(parent);
8858
8859 if (proto->fields == NULL((void*)0)) {
8860 proto->fields = g_ptr_array_sized_new(num_records);
8861 }
8862
8863 for (i = 0; i < num_records; i++, ptr++) {
8864 /*
8865 * Make sure we haven't registered this yet.
8866 * Most fields have variables associated with them
8867 * that are initialized to -1; some have array elements,
8868 * or possibly uninitialized variables, so we also allow
8869 * 0 (which is unlikely to be the field ID we get back
8870 * from "proto_register_field_init()").
8871 */
8872 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8873 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8874 "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)
8875 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8876 return;
8877 }
8878
8879 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8880 }
8881}
8882
8883/* deregister already registered fields */
8884void
8885proto_deregister_field (const int parent, int hf_id)
8886{
8887 header_field_info *hfi;
8888 protocol_t *proto;
8889 unsigned i;
8890
8891 g_free(last_field_name);
8892 last_field_name = NULL((void*)0);
8893
8894 if (hf_id == -1 || hf_id == 0)
8895 return;
8896
8897 proto = find_protocol_by_id (parent);
8898 if (!proto || proto->fields == NULL((void*)0)) {
8899 return;
8900 }
8901
8902 for (i = 0; i < proto->fields->len; i++) {
8903 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8904 if (hfi->id == hf_id) {
8905 /* Found the hf_id in this protocol */
8906 g_hash_table_steal(gpa_name_map, hfi->abbrev);
8907 g_ptr_array_remove_index_fast(proto->fields, i);
8908 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8909 return;
8910 }
8911 }
8912}
8913
8914/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8915void
8916proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8917{
8918 header_field_info *hfinfo;
8919 protocol_t *proto;
8920
8921 g_free(last_field_name);
8922 last_field_name = NULL((void*)0);
8923
8924 proto = find_protocol_by_id(parent);
8925 if (proto && proto->fields && proto->fields->len > 0) {
8926 guint i = proto->fields->len;
8927 do {
8928 i--;
8929
8930 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8931 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) )
) {
8932 hfinfo_remove_from_gpa_name_map(hfinfo);
8933 expert_deregister_expertinfo(hfinfo->abbrev);
8934 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8935 g_ptr_array_remove_index_fast(proto->fields, i);
8936 }
8937 } while (i > 0);
8938 }
8939}
8940
8941void
8942proto_add_deregistered_data (void *data)
8943{
8944 g_ptr_array_add(deregistered_data, data);
8945}
8946
8947void
8948proto_add_deregistered_slice (size_t block_size, void *mem_block)
8949{
8950 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
)))
;
8951
8952 slice_data->block_size = block_size;
8953 slice_data->mem_block = mem_block;
8954
8955 g_ptr_array_add(deregistered_slice, slice_data);
8956}
8957
8958void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8959{
8960 if (field_strings == NULL((void*)0)) {
8961 return;
8962 }
8963
8964 switch (field_type) {
8965 case FT_FRAMENUM:
8966 /* This is just an integer represented as a pointer */
8967 break;
8968 case FT_PROTOCOL: {
8969 protocol_t *protocol = (protocol_t *)field_strings;
8970 g_free((char *)protocol->short_name);
8971 break;
8972 }
8973 case FT_BOOLEAN: {
8974 true_false_string *tf = (true_false_string *)field_strings;
8975 g_free((char *)tf->true_string);
8976 g_free((char *)tf->false_string);
8977 break;
8978 }
8979 case FT_UINT40:
8980 case FT_INT40:
8981 case FT_UINT48:
8982 case FT_INT48:
8983 case FT_UINT56:
8984 case FT_INT56:
8985 case FT_UINT64:
8986 case FT_INT64: {
8987 if (field_display & BASE_UNIT_STRING0x00001000) {
8988 unit_name_string *unit = (unit_name_string *)field_strings;
8989 g_free((char *)unit->singular);
8990 g_free((char *)unit->plural);
8991 } else if (field_display & BASE_RANGE_STRING0x00000100) {
8992 range_string *rs = (range_string *)field_strings;
8993 while (rs->strptr) {
8994 g_free((char *)rs->strptr);
8995 rs++;
8996 }
8997 } else if (field_display & BASE_EXT_STRING0x00000200) {
8998 val64_string_ext *vse = (val64_string_ext *)field_strings;
8999 val64_string *vs = (val64_string *)vse->_vs_p;
9000 while (vs->strptr) {
9001 g_free((char *)vs->strptr);
9002 vs++;
9003 }
9004 val64_string_ext_free(vse);
9005 field_strings = NULL((void*)0);
9006 } else if (field_display == BASE_CUSTOM) {
9007 /* this will be a pointer to a function, don't free that */
9008 field_strings = NULL((void*)0);
9009 } else {
9010 val64_string *vs64 = (val64_string *)field_strings;
9011 while (vs64->strptr) {
9012 g_free((char *)vs64->strptr);
9013 vs64++;
9014 }
9015 }
9016 break;
9017 }
9018 case FT_CHAR:
9019 case FT_UINT8:
9020 case FT_INT8:
9021 case FT_UINT16:
9022 case FT_INT16:
9023 case FT_UINT24:
9024 case FT_INT24:
9025 case FT_UINT32:
9026 case FT_INT32:
9027 case FT_FLOAT:
9028 case FT_DOUBLE: {
9029 if (field_display & BASE_UNIT_STRING0x00001000) {
9030 unit_name_string *unit = (unit_name_string *)field_strings;
9031 g_free((char *)unit->singular);
9032 g_free((char *)unit->plural);
9033 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9034 range_string *rs = (range_string *)field_strings;
9035 while (rs->strptr) {
9036 g_free((char *)rs->strptr);
9037 rs++;
9038 }
9039 } else if (field_display & BASE_EXT_STRING0x00000200) {
9040 value_string_ext *vse = (value_string_ext *)field_strings;
9041 value_string *vs = (value_string *)vse->_vs_p;
9042 while (vs->strptr) {
9043 g_free((char *)vs->strptr);
9044 vs++;
9045 }
9046 value_string_ext_free(vse);
9047 field_strings = NULL((void*)0);
9048 } else if (field_display == BASE_CUSTOM) {
9049 /* this will be a pointer to a function, don't free that */
9050 field_strings = NULL((void*)0);
9051 } else {
9052 value_string *vs = (value_string *)field_strings;
9053 while (vs->strptr) {
9054 g_free((char *)vs->strptr);
9055 vs++;
9056 }
9057 }
9058 break;
9059 default:
9060 break;
9061 }
9062 }
9063
9064 if (field_type != FT_FRAMENUM) {
9065 g_free((void *)field_strings);
9066 }
9067}
9068
9069static void
9070free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9071{
9072 header_field_info *hfi = (header_field_info *) data;
9073 int hf_id = hfi->id;
9074
9075 g_free((char *)hfi->name);
9076 g_free((char *)hfi->abbrev);
9077 g_free((char *)hfi->blurb);
9078
9079 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9080
9081 if (hfi->parent == -1)
9082 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)
;
9083
9084 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9085}
9086
9087static void
9088free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9089{
9090 g_free (data);
9091}
9092
9093static void
9094free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9095{
9096 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9097
9098 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9099 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)
;
9100}
9101
9102/* free deregistered fields and data */
9103void
9104proto_free_deregistered_fields (void)
9105{
9106 expert_free_deregistered_expertinfos();
9107
9108 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9109 g_ptr_array_free(deregistered_fields, true1);
9110 deregistered_fields = g_ptr_array_new();
9111
9112 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9113 g_ptr_array_free(deregistered_data, true1);
9114 deregistered_data = g_ptr_array_new();
9115
9116 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9117 g_ptr_array_free(deregistered_slice, true1);
9118 deregistered_slice = g_ptr_array_new();
9119}
9120
9121static const value_string hf_display[] = {
9122 { BASE_NONE, "BASE_NONE" },
9123 { BASE_DEC, "BASE_DEC" },
9124 { BASE_HEX, "BASE_HEX" },
9125 { BASE_OCT, "BASE_OCT" },
9126 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9127 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9128 { BASE_CUSTOM, "BASE_CUSTOM" },
9129 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9130 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9131 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9132 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9133 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9134 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9135 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9136 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9137 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9138 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9139 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9140 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9141 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9142 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9143 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9144 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9145 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9146 { BASE_PT_UDP, "BASE_PT_UDP" },
9147 { BASE_PT_TCP, "BASE_PT_TCP" },
9148 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9149 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9150 { BASE_OUI, "BASE_OUI" },
9151 { 0, NULL((void*)0) } };
9152
9153const char* proto_field_display_to_string(int field_display)
9154{
9155 return val_to_str_const(field_display, hf_display, "Unknown");
9156}
9157
9158static inline port_type
9159display_to_port_type(field_display_e e)
9160{
9161 switch (e) {
9162 case BASE_PT_UDP:
9163 return PT_UDP;
9164 case BASE_PT_TCP:
9165 return PT_TCP;
9166 case BASE_PT_DCCP:
9167 return PT_DCCP;
9168 case BASE_PT_SCTP:
9169 return PT_SCTP;
9170 default:
9171 break;
9172 }
9173 return PT_NONE;
9174}
9175
9176/* temporary function containing assert part for easier profiling */
9177static void
9178tmp_fld_check_assert(header_field_info *hfinfo)
9179{
9180 char* tmp_str;
9181
9182 /* The field must have a name (with length > 0) */
9183 if (!hfinfo->name || !hfinfo->name[0]) {
9184 if (hfinfo->abbrev)
9185 /* Try to identify the field */
9186 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)
9187 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9188 else
9189 /* Hum, no luck */
9190 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)"
)
;
9191 }
9192
9193 /* fields with an empty string for an abbreviation aren't filterable */
9194 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9195 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)
;
9196
9197 /* These types of fields are allowed to have value_strings,
9198 * true_false_strings or a protocol_t struct
9199 */
9200 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9201 switch (hfinfo->type) {
9202
9203 /*
9204 * These types are allowed to support display value_strings,
9205 * value64_strings, the extended versions of the previous
9206 * two, range strings, or unit strings.
9207 */
9208 case FT_CHAR:
9209 case FT_UINT8:
9210 case FT_UINT16:
9211 case FT_UINT24:
9212 case FT_UINT32:
9213 case FT_UINT40:
9214 case FT_UINT48:
9215 case FT_UINT56:
9216 case FT_UINT64:
9217 case FT_INT8:
9218 case FT_INT16:
9219 case FT_INT24:
9220 case FT_INT32:
9221 case FT_INT40:
9222 case FT_INT48:
9223 case FT_INT56:
9224 case FT_INT64:
9225 case FT_BOOLEAN:
9226 case FT_PROTOCOL:
9227 break;
9228
9229 /*
9230 * This is allowed to have a value of type
9231 * enum ft_framenum_type to indicate what relationship
9232 * the frame in question has to the frame in which
9233 * the field is put.
9234 */
9235 case FT_FRAMENUM:
9236 break;
9237
9238 /*
9239 * These types are allowed to support only unit strings.
9240 */
9241 case FT_FLOAT:
9242 case FT_DOUBLE:
9243 case FT_IEEE_11073_SFLOAT:
9244 case FT_IEEE_11073_FLOAT:
9245 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9246 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))
9247 " (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))
9248 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))
;
9249 }
9250 break;
9251
9252 /*
9253 * These types are allowed to support display
9254 * time_value_strings.
9255 */
9256 case FT_ABSOLUTE_TIME:
9257 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9258 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9259 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9260 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9261 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))
9262 " (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))
9263 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))
;
9264 }
9265 break;
9266
9267 /*
9268 * This type is only allowed to support a string if it's
9269 * a protocol (for pinos).
9270 */
9271 case FT_BYTES:
9272 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9273 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))
9274 " (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))
9275 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))
;
9276 }
9277 break;
9278
9279 default:
9280 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))
9281 " (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))
9282 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))
;
9283 }
9284 }
9285
9286 /* TODO: This check may slow down startup, and output quite a few warnings.
9287 It would be good to be able to enable this (and possibly other checks?)
9288 in non-release builds. */
9289#ifdef ENABLE_CHECK_FILTER
9290 /* Check for duplicate value_string values.
9291 There are lots that have the same value *and* string, so for now only
9292 report those that have same value but different string. */
9293 if ((hfinfo->strings != NULL((void*)0)) &&
9294 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9295 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9296 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9297 (
9298 (hfinfo->type == FT_CHAR) ||
9299 (hfinfo->type == FT_UINT8) ||
9300 (hfinfo->type == FT_UINT16) ||
9301 (hfinfo->type == FT_UINT24) ||
9302 (hfinfo->type == FT_UINT32) ||
9303 (hfinfo->type == FT_INT8) ||
9304 (hfinfo->type == FT_INT16) ||
9305 (hfinfo->type == FT_INT24) ||
9306 (hfinfo->type == FT_INT32) )) {
9307
9308 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9309 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9310 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9311 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9312 } else {
9313 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9314 CHECK_HF_VALUE(value_string, "u", start_values);
9315 }
9316 } else {
9317 const value_string *start_values = (const value_string*)hfinfo->strings;
9318 CHECK_HF_VALUE(value_string, "u", start_values);
9319 }
9320 }
9321
9322 if (hfinfo->type == FT_BOOLEAN) {
9323 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9324 if (tfs) {
9325 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9326 ws_warning("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9328, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9327 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9328, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9328 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9328, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9329 }
9330 }
9331 }
9332
9333 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9334 const range_string *rs = (const range_string*)(hfinfo->strings);
9335 if (rs) {
9336 const range_string *this_it = rs;
9337
9338 do {
9339 if (this_it->value_max < this_it->value_min) {
9340 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"
, 9344, __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)
9341 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9344, __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)
9342 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9344, __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)
9343 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9344, __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)
9344 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9344, __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)
;
9345 ++this_it;
9346 continue;
9347 }
9348
9349 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9350 /* Not OK if this one is completely hidden by an earlier one! */
9351 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9352 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"
, 9358, __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)
9353 "(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"
, 9358, __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)
9354 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9358, __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)
9355 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9358, __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)
9356 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9358, __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)
9357 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9358, __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)
9358 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9358, __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)
;
9359 }
9360 }
9361 ++this_it;
9362 } while (this_it->strptr);
9363 }
9364 }
9365#endif
9366
9367 switch (hfinfo->type) {
9368
9369 case FT_CHAR:
9370 /* Require the char type to have BASE_HEX, BASE_OCT,
9371 * BASE_CUSTOM, or BASE_NONE as its base.
9372 *
9373 * If the display value is BASE_NONE and there is a
9374 * strings conversion then the dissector writer is
9375 * telling us that the field's numerical value is
9376 * meaningless; we'll avoid showing the value to the
9377 * user.
9378 */
9379 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9380 case BASE_HEX:
9381 case BASE_OCT:
9382 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9383 break;
9384 case BASE_NONE:
9385 if (hfinfo->strings == NULL((void*)0))
9386 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
))
9387 " 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
))
9388 " 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
))
9389 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
))
9390 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
))
;
9391 break;
9392 default:
9393 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9394 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)
9395 " 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)
9396 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)
9397 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)
;
9398 //wmem_free(NULL, tmp_str);
9399 }
9400 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9401 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
))
9402 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
))
9403 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
))
;
9404 }
9405 break;
9406 case FT_INT8:
9407 case FT_INT16:
9408 case FT_INT24:
9409 case FT_INT32:
9410 case FT_INT40:
9411 case FT_INT48:
9412 case FT_INT56:
9413 case FT_INT64:
9414 /* Hexadecimal and octal are, in printf() and everywhere
9415 * else, unsigned so don't allow dissectors to register a
9416 * signed field to be displayed unsigned. (Else how would
9417 * we display negative values?)
9418 */
9419 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9420 case BASE_HEX:
9421 case BASE_OCT:
9422 case BASE_DEC_HEX:
9423 case BASE_HEX_DEC:
9424 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9425 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)
9426 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)
9427 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)
;
9428 //wmem_free(NULL, tmp_str);
9429 }
9430 /* FALL THROUGH */
9431 case FT_UINT8:
9432 case FT_UINT16:
9433 case FT_UINT24:
9434 case FT_UINT32:
9435 case FT_UINT40:
9436 case FT_UINT48:
9437 case FT_UINT56:
9438 case FT_UINT64:
9439 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
))
) {
9440 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9441 if (hfinfo->type != FT_UINT16) {
9442 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))
9443 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))
9444 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))
;
9445 }
9446 if (hfinfo->strings != NULL((void*)0)) {
9447 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)
9448 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)
9449 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)
;
9450 }
9451 if (hfinfo->bitmask != 0) {
9452 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)
9453 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)
9454 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)
;
9455 }
9456 wmem_free(NULL((void*)0), tmp_str);
9457 break;
9458 }
9459
9460 if (hfinfo->display == BASE_OUI) {
9461 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9462 if (hfinfo->type != FT_UINT24) {
9463 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))
9464 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))
9465 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))
;
9466 }
9467 if (hfinfo->strings != NULL((void*)0)) {
9468 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)
9469 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)
9470 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)
;
9471 }
9472 if (hfinfo->bitmask != 0) {
9473 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)
9474 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)
9475 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)
;
9476 }
9477 wmem_free(NULL((void*)0), tmp_str);
9478 break;
9479 }
9480
9481 /* Require integral types (other than frame number,
9482 * which is always displayed in decimal) to have a
9483 * number base.
9484 *
9485 * If the display value is BASE_NONE and there is a
9486 * strings conversion then the dissector writer is
9487 * telling us that the field's numerical value is
9488 * meaningless; we'll avoid showing the value to the
9489 * user.
9490 */
9491 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9492 case BASE_DEC:
9493 case BASE_HEX:
9494 case BASE_OCT:
9495 case BASE_DEC_HEX:
9496 case BASE_HEX_DEC:
9497 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9498 break;
9499 case BASE_NONE:
9500 if (hfinfo->strings == NULL((void*)0)) {
9501 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
))
9502 " 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
))
9503 " 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
))
9504 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
))
9505 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
))
;
9506 }
9507 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9508 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
))
9509 " 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
))
9510 " 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
))
9511 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
))
9512 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
))
;
9513 }
9514 break;
9515
9516 default:
9517 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9518 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)
9519 " 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)
9520 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)
9521 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)
;
9522 //wmem_free(NULL, tmp_str);
9523 }
9524 break;
9525 case FT_BYTES:
9526 case FT_UINT_BYTES:
9527 /* Require bytes to have a "display type" that could
9528 * add a character between displayed bytes.
9529 */
9530 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9531 case BASE_NONE:
9532 case SEP_DOT:
9533 case SEP_DASH:
9534 case SEP_COLON:
9535 case SEP_SPACE:
9536 break;
9537 default:
9538 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9539 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)
9540 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)
;
9541 //wmem_free(NULL, tmp_str);
9542 }
9543 if (hfinfo->bitmask != 0)
9544 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
))
9545 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
))
9546 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
))
;
9547 //allowed to support string if its a protocol (for pinos)
9548 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9549 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
))
9550 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
))
9551 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
))
;
9552 break;
9553
9554 case FT_PROTOCOL:
9555 case FT_FRAMENUM:
9556 if (hfinfo->display != BASE_NONE) {
9557 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9558 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)
9559 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)
9560 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)
;
9561 //wmem_free(NULL, tmp_str);
9562 }
9563 if (hfinfo->bitmask != 0)
9564 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
))
9565 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
))
9566 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
))
;
9567 break;
9568
9569 case FT_BOOLEAN:
9570 break;
9571
9572 case FT_ABSOLUTE_TIME:
9573 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9574 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9575 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)
9576 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)
;
9577 //wmem_free(NULL, tmp_str);
9578 }
9579 if (hfinfo->bitmask != 0)
9580 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
))
9581 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
))
9582 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
))
;
9583 break;
9584
9585 case FT_STRING:
9586 case FT_STRINGZ:
9587 case FT_UINT_STRING:
9588 case FT_STRINGZPAD:
9589 case FT_STRINGZTRUNC:
9590 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9591 case BASE_NONE:
9592 case BASE_STR_WSP:
9593 break;
9594
9595 default:
9596 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9597 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)
9598 " 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)
9599 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)
9600 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)
;
9601 //wmem_free(NULL, tmp_str);
9602 }
9603
9604 if (hfinfo->bitmask != 0)
9605 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
))
9606 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
))
9607 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
))
;
9608 if (hfinfo->strings != NULL((void*)0))
9609 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
))
9610 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
))
9611 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
))
;
9612 break;
9613
9614 case FT_IPv4:
9615 switch (hfinfo->display) {
9616 case BASE_NONE:
9617 case BASE_NETMASK:
9618 break;
9619
9620 default:
9621 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9622 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)
9623 " 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)
9624 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)
9625 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)
;
9626 //wmem_free(NULL, tmp_str);
9627 break;
9628 }
9629 break;
9630 case FT_FLOAT:
9631 case FT_DOUBLE:
9632 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9633 case BASE_NONE:
9634 case BASE_DEC:
9635 case BASE_HEX:
9636 case BASE_EXP:
9637 case BASE_CUSTOM:
9638 break;
9639 default:
9640 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9641 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)
9642 " 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)
9643 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)
9644 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)
;
9645 //wmem_free(NULL, tmp_str);
9646 }
9647 if (hfinfo->bitmask != 0)
9648 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
))
9649 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
))
9650 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
))
;
9651 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9652 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
))
9653 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
))
9654 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
))
;
9655 break;
9656 case FT_IEEE_11073_SFLOAT:
9657 case FT_IEEE_11073_FLOAT:
9658 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9659 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9660 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)
9661 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)
9662 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)
9663 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)
;
9664 //wmem_free(NULL, tmp_str);
9665 }
9666 if (hfinfo->bitmask != 0)
9667 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
))
9668 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
))
9669 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
))
;
9670 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9671 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
))
9672 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
))
9673 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
))
;
9674 break;
9675 default:
9676 if (hfinfo->display != BASE_NONE) {
9677 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9678 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)
9679 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)
9680 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)
9681 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)
;
9682 //wmem_free(NULL, tmp_str);
9683 }
9684 if (hfinfo->bitmask != 0)
9685 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
))
9686 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
))
9687 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
))
;
9688 if (hfinfo->strings != NULL((void*)0))
9689 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
))
9690 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
))
9691 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
))
;
9692 break;
9693 }
9694}
9695
9696static void
9697register_type_length_mismatch(void)
9698{
9699 static ei_register_info ei[] = {
9700 { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
9701 { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", PI_MALFORMED0x07000000, PI_WARN0x00600000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}},
9702 };
9703
9704 expert_module_t* expert_type_length_mismatch;
9705
9706 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9707
9708 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9709 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9710
9711 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9712 disabling them makes no sense. */
9713 proto_set_cant_toggle(proto_type_length_mismatch);
9714}
9715
9716static void
9717register_byte_array_string_decodinws_error(void)
9718{
9719 static ei_register_info ei[] = {
9720 { &ei_byte_array_string_decoding_failed_error,
9721 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9722 "Failed to decode byte array from string", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
9723 }
9724 },
9725 };
9726
9727 expert_module_t* expert_byte_array_string_decoding_error;
9728
9729 proto_byte_array_string_decoding_error =
9730 proto_register_protocol("Byte Array-String Decoding Error",
9731 "Byte Array-string decoding error",
9732 "_ws.byte_array_string.decoding_error");
9733
9734 expert_byte_array_string_decoding_error =
9735 expert_register_protocol(proto_byte_array_string_decoding_error);
9736 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9737
9738 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9739 disabling them makes no sense. */
9740 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9741}
9742
9743static void
9744register_date_time_string_decodinws_error(void)
9745{
9746 static ei_register_info ei[] = {
9747 { &ei_date_time_string_decoding_failed_error,
9748 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9749 "Failed to decode date and time from string", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
9750 }
9751 },
9752 };
9753
9754 expert_module_t* expert_date_time_string_decoding_error;
9755
9756 proto_date_time_string_decoding_error =
9757 proto_register_protocol("Date and Time-String Decoding Error",
9758 "Date and Time-string decoding error",
9759 "_ws.date_time_string.decoding_error");
9760
9761 expert_date_time_string_decoding_error =
9762 expert_register_protocol(proto_date_time_string_decoding_error);
9763 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9764
9765 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9766 disabling them makes no sense. */
9767 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9768}
9769
9770static void
9771register_string_errors(void)
9772{
9773 static ei_register_info ei[] = {
9774 { &ei_string_trailing_characters,
9775 { "_ws.string.trailing_stray_characters", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Trailing stray characters", EXPFILL0, ((void*)0), 0, {0, {((void*)0), ((void*)0), FT_NONE, BASE_NONE
, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE, -1, ((void
*)0)}}
}
9776 },
9777 };
9778
9779 expert_module_t* expert_string_errors;
9780
9781 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9782
9783 expert_string_errors = expert_register_protocol(proto_string_errors);
9784 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9785
9786 /* "String Errors" isn't really a protocol, it's an error indication;
9787 disabling them makes no sense. */
9788 proto_set_cant_toggle(proto_string_errors);
9789}
9790
9791#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
9792static int
9793proto_register_field_init(header_field_info *hfinfo, const int parent)
9794{
9795
9796 tmp_fld_check_assert(hfinfo);
9797
9798 hfinfo->parent = parent;
9799 hfinfo->same_name_next = NULL((void*)0);
9800 hfinfo->same_name_prev_id = -1;
9801
9802 /* if we always add and never delete, then id == len - 1 is correct */
9803 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9804 if (!gpa_hfinfo.hfi) {
9805 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9806 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9807 /* The entry with index 0 is not used. */
9808 gpa_hfinfo.hfi[0] = NULL((void*)0);
9809 gpa_hfinfo.len = 1;
9810 } else {
9811 gpa_hfinfo.allocated_len += 1000;
9812 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9813 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9814 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9815 }
9816 }
9817 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9818 gpa_hfinfo.len++;
9819 hfinfo->id = gpa_hfinfo.len - 1;
9820
9821 /* if we have real names, enter this field in the name tree */
9822 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
9823
9824 header_field_info *same_name_next_hfinfo;
9825 unsigned char c;
9826
9827 /* Check that the filter name (abbreviation) is legal;
9828 * it must contain only alphanumerics, '-', "_", and ".". */
9829 c = proto_check_field_name(hfinfo->abbrev);
9830 if (c) {
9831 if (c == '.') {
9832 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)
;
9833 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9834 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)
;
9835 } else {
9836 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)
;
9837 }
9838 }
9839
9840 /* We allow multiple hfinfo's to be registered under the same
9841 * abbreviation. This was done for X.25, as, depending
9842 * on whether it's modulo-8 or modulo-128 operation,
9843 * some bitfield fields may be in different bits of
9844 * a byte, and we want to be able to refer to that field
9845 * with one name regardless of whether the packets
9846 * are modulo-8 or modulo-128 packets. */
9847
9848 same_name_hfinfo = NULL((void*)0);
9849
9850 g_hash_table_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9851 /* GLIB 2.x - if it is already present
9852 * the previous hfinfo with the same name is saved
9853 * to same_name_hfinfo by value destroy callback */
9854 if (same_name_hfinfo) {
9855 /* There's already a field with this name.
9856 * Put the current field *before* that field
9857 * in the list of fields with this name, Thus,
9858 * we end up with an effectively
9859 * doubly-linked-list of same-named hfinfo's,
9860 * with the head of the list (stored in the
9861 * hash) being the last seen hfinfo.
9862 */
9863 same_name_next_hfinfo =
9864 same_name_hfinfo->same_name_next;
9865
9866 hfinfo->same_name_next = same_name_next_hfinfo;
9867 if (same_name_next_hfinfo)
9868 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9869
9870 same_name_hfinfo->same_name_next = hfinfo;
9871 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9872#ifdef ENABLE_CHECK_FILTER
9873 while (same_name_hfinfo) {
9874 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9875 ws_warning("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type))do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9875, __func__, "'%s' exists multiple times with incompatible types: %s and %s"
, hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(
same_name_hfinfo->type)); } } while (0)
;
9876 same_name_hfinfo = same_name_hfinfo->same_name_next;
9877 }
9878#endif
9879 }
9880 }
9881
9882 return hfinfo->id;
9883}
9884
9885void
9886proto_register_subtree_array(int * const *indices, const int num_indices)
9887{
9888 int i;
9889 int *const *ptr = indices;
9890
9891 /*
9892 * If we've already allocated the array of tree types, expand
9893 * it; this lets plugins such as mate add tree types after
9894 * the initial startup. (If we haven't already allocated it,
9895 * we don't allocate it; on the first pass, we just assign
9896 * ett values and keep track of how many we've assigned, and
9897 * when we're finished registering all dissectors we allocate
9898 * the array, so that we do only one allocation rather than
9899 * wasting CPU time and memory by growing the array for each
9900 * dissector that registers ett values.)
9901 */
9902 if (tree_is_expanded != NULL((void*)0)) {
9903 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9904
9905 /* set new items to 0 */
9906 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9907 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9908 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9909 }
9910
9911 /*
9912 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9913 * returning the indices through the pointers in the array whose
9914 * first element is pointed to by "indices", and update
9915 * "num_tree_types" appropriately.
9916 */
9917 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9918 if (**ptr != -1 && **ptr != 0) {
9919 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.")
9920 " 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.")
9921 " 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.")
9922 " 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.")
;
9923 }
9924 **ptr = num_tree_types;
9925 }
9926}
9927
9928static void
9929mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
9930{
9931 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "]";
9932 const size_t trunc_len = sizeof(trunc_str)-1;
9933 char *last_char;
9934
9935 /* ..... field_name: dataaaaaaaaaaaaa
9936 * |
9937 * ^^^^^ name_pos
9938 *
9939 * ..... field_name […]: dataaaaaaaaaaaaa
9940 *
9941 * name_pos==0 means that we have only data or only a field_name
9942 */
9943
9944 if (name_pos < size - trunc_len) {
9945 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
9946 memcpy(label_str + name_pos, trunc_str, trunc_len);
9947
9948 /* in general, label_str is UTF-8
9949 we can truncate it only at the beginning of a new character
9950 we go backwards from the byte right after our buffer and
9951 find the next starting byte of a UTF-8 character, this is
9952 where we cut
9953 there's no need to use g_utf8_find_prev_char(), the search
9954 will always succeed since we copied trunc_str into the
9955 buffer */
9956 /* g_utf8_prev_char does not deference the memory address
9957 * passed in (until after decrementing it, so it is perfectly
9958 * legal to pass in a pointer one past the last element.
9959 */
9960 last_char = g_utf8_prev_char(label_str + size);
9961 *last_char = '\0';
9962
9963 if (value_pos && *value_pos > 0) {
9964 if (name_pos == 0) {
9965 *value_pos += trunc_len;
9966 } else {
9967 /* Move one back to include trunc_str in the value. */
9968 *value_pos -= 1;
9969 }
9970 }
9971 } else if (name_pos < size)
9972 (void) g_strlcpy(label_str + name_pos, trunc_str, size - name_pos);
9973}
9974
9975static void
9976label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
9977{
9978 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
9979}
9980
9981static size_t
9982label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
9983{
9984 size_t name_pos;
9985
9986 /* "%s: %s", hfinfo->name, text */
9987 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
9988 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
9989 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
9990 if (value_pos) {
9991 *value_pos = pos;
9992 }
9993 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
9994 }
9995
9996 if (pos >= ITEM_LABEL_LENGTH240) {
9997 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9998 label_mark_truncated(label_str, name_pos, value_pos);
9999 }
10000
10001 return pos;
10002}
10003
10004static size_t
10005label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10006{
10007 size_t name_pos;
10008
10009 /* "%s: %s (%s)", hfinfo->name, text, descr */
10010 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10011 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10012 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10013 if (value_pos) {
10014 *value_pos = pos;
10015 }
10016 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10017 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10018 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10019 } else {
10020 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10021 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10022 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10023 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10024 }
10025 }
10026
10027 if (pos >= ITEM_LABEL_LENGTH240) {
10028 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10029 label_mark_truncated(label_str, name_pos, value_pos);
10030 }
10031
10032 return pos;
10033}
10034
10035void
10036proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10037{
10038 const header_field_info *hfinfo;
10039 const char *str;
10040 const uint8_t *bytes;
10041 uint32_t integer;
10042 const ipv4_addr_and_mask *ipv4;
10043 const ipv6_addr_and_prefix *ipv6;
10044 const e_guid_t *guid;
10045 char *name;
10046 address addr;
10047 char *addr_str;
10048 char *tmp;
10049
10050 if (!label_str) {
10051 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10051, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10052 return;
10053 }
10054
10055 label_str[0]= '\0';
10056
10057 if (!fi) {
10058 return;
10059 }
10060
10061 hfinfo = fi->hfinfo;
10062
10063 switch (hfinfo->type) {
10064 case FT_NONE:
10065 case FT_PROTOCOL:
10066 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10067 if (value_pos) {
10068 *value_pos = strlen(hfinfo->name);
10069 }
10070 break;
10071
10072 case FT_BOOLEAN:
10073 fill_label_boolean(fi, label_str, value_pos);
10074 break;
10075
10076 case FT_BYTES:
10077 case FT_UINT_BYTES:
10078 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10079 fvalue_get_bytes_data(fi->value),
10080 (unsigned)fvalue_length2(fi->value));
10081 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10082 wmem_free(NULL((void*)0), tmp);
10083 break;
10084
10085 case FT_CHAR:
10086 if (hfinfo->bitmask) {
10087 fill_label_bitfield_char(fi, label_str, value_pos);
10088 } else {
10089 fill_label_char(fi, label_str, value_pos);
10090 }
10091 break;
10092
10093 /* Four types of integers to take care of:
10094 * Bitfield, with val_string
10095 * Bitfield, w/o val_string
10096 * Non-bitfield, with val_string
10097 * Non-bitfield, w/o val_string
10098 */
10099 case FT_UINT8:
10100 case FT_UINT16:
10101 case FT_UINT24:
10102 case FT_UINT32:
10103 if (hfinfo->bitmask) {
10104 fill_label_bitfield(fi, label_str, value_pos, false0);
10105 } else {
10106 fill_label_number(fi, label_str, value_pos, false0);
10107 }
10108 break;
10109
10110 case FT_FRAMENUM:
10111 fill_label_number(fi, label_str, value_pos, false0);
10112 break;
10113
10114 case FT_UINT40:
10115 case FT_UINT48:
10116 case FT_UINT56:
10117 case FT_UINT64:
10118 if (hfinfo->bitmask) {
10119 fill_label_bitfield64(fi, label_str, value_pos, false0);
10120 } else {
10121 fill_label_number64(fi, label_str, value_pos, false0);
10122 }
10123 break;
10124
10125 case FT_INT8:
10126 case FT_INT16:
10127 case FT_INT24:
10128 case FT_INT32:
10129 if (hfinfo->bitmask) {
10130 fill_label_bitfield(fi, label_str, value_pos, true1);
10131 } else {
10132 fill_label_number(fi, label_str, value_pos, true1);
10133 }
10134 break;
10135
10136 case FT_INT40:
10137 case FT_INT48:
10138 case FT_INT56:
10139 case FT_INT64:
10140 if (hfinfo->bitmask) {
10141 fill_label_bitfield64(fi, label_str, value_pos, true1);
10142 } else {
10143 fill_label_number64(fi, label_str, value_pos, true1);
10144 }
10145 break;
10146
10147 case FT_FLOAT:
10148 case FT_DOUBLE:
10149 fill_label_float(fi, label_str, value_pos);
10150 break;
10151
10152 case FT_ABSOLUTE_TIME:
10153 {
10154 const nstime_t *value = fvalue_get_time(fi->value);
10155 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10156 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10157 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10158 }
10159 if (hfinfo->strings) {
10160 /*
10161 * Table of time valus to be displayed
10162 * specially.
10163 */
10164 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10165 if (time_string != NULL((void*)0)) {
10166 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10167 break;
10168 }
10169 }
10170 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10171 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10172 wmem_free(NULL((void*)0), tmp);
10173 break;
10174 }
10175 case FT_RELATIVE_TIME:
10176 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10177 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10178 wmem_free(NULL((void*)0), tmp);
10179 break;
10180
10181 case FT_IPXNET:
10182 integer = fvalue_get_uinteger(fi->value);
10183 tmp = get_ipxnet_name(NULL((void*)0), integer);
10184 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10185 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10186 wmem_free(NULL((void*)0), tmp);
10187 wmem_free(NULL((void*)0), addr_str);
10188 break;
10189
10190 case FT_VINES:
10191 addr.type = AT_VINES;
10192 addr.len = VINES_ADDR_LEN6;
10193 addr.data = fvalue_get_bytes_data(fi->value);
10194
10195 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10196 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10197 wmem_free(NULL((void*)0), addr_str);
10198 break;
10199
10200 case FT_ETHER:
10201 bytes = fvalue_get_bytes_data(fi->value);
10202
10203 addr.type = AT_ETHER;
10204 addr.len = 6;
10205 addr.data = bytes;
10206
10207 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10208 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10209 wmem_free(NULL((void*)0), addr_str);
10210 break;
10211
10212 case FT_IPv4:
10213 ipv4 = fvalue_get_ipv4(fi->value);
10214 set_address_ipv4(&addr, ipv4);
10215
10216 if (hfinfo->display == BASE_NETMASK) {
10217 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10218 } else {
10219 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10220 }
10221 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10222 wmem_free(NULL((void*)0), addr_str);
10223 free_address(&addr);
10224 break;
10225
10226 case FT_IPv6:
10227 ipv6 = fvalue_get_ipv6(fi->value);
10228 set_address_ipv6(&addr, ipv6);
10229
10230 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10231 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10232 wmem_free(NULL((void*)0), addr_str);
10233 free_address(&addr);
10234 break;
10235
10236 case FT_FCWWN:
10237 bytes = fvalue_get_bytes_data(fi->value);
10238 addr.type = AT_FCWWN;
10239 addr.len = FCWWN_ADDR_LEN8;
10240 addr.data = bytes;
10241
10242 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10243 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10244 wmem_free(NULL((void*)0), addr_str);
10245 break;
10246
10247 case FT_GUID:
10248 guid = fvalue_get_guid(fi->value);
10249 tmp = guid_to_str(NULL((void*)0), guid);
10250 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10251 wmem_free(NULL((void*)0), tmp);
10252 break;
10253
10254 case FT_OID:
10255 bytes = fvalue_get_bytes_data(fi->value);
10256 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10257 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10258 if (name) {
10259 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10260 wmem_free(NULL((void*)0), name);
10261 } else {
10262 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10263 }
10264 wmem_free(NULL((void*)0), tmp);
10265 break;
10266
10267 case FT_REL_OID:
10268 bytes = fvalue_get_bytes_data(fi->value);
10269 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10270 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10271 if (name) {
10272 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10273 wmem_free(NULL((void*)0), name);
10274 } else {
10275 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10276 }
10277 wmem_free(NULL((void*)0), tmp);
10278 break;
10279
10280 case FT_SYSTEM_ID:
10281 bytes = fvalue_get_bytes_data(fi->value);
10282 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10283 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10284 wmem_free(NULL((void*)0), tmp);
10285 break;
10286
10287 case FT_EUI64:
10288 bytes = fvalue_get_bytes_data(fi->value);
10289 addr.type = AT_EUI64;
10290 addr.len = EUI64_ADDR_LEN8;
10291 addr.data = bytes;
10292
10293 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10294 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10295 wmem_free(NULL((void*)0), addr_str);
10296 break;
10297 case FT_STRING:
10298 case FT_STRINGZ:
10299 case FT_UINT_STRING:
10300 case FT_STRINGZPAD:
10301 case FT_STRINGZTRUNC:
10302 case FT_AX25:
10303 str = fvalue_get_string(fi->value);
10304 label_fill(label_str, 0, hfinfo, str, value_pos);
10305 break;
10306
10307 case FT_IEEE_11073_SFLOAT:
10308 case FT_IEEE_11073_FLOAT:
10309 fill_label_ieee_11073_float(fi, label_str, value_pos);
10310 break;
10311
10312 default:
10313 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
))
10314 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
))
10315 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
))
10316 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
))
;
10317 break;
10318 }
10319}
10320
10321static void
10322fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10323{
10324 char *p;
10325 int bitfield_byte_length = 0, bitwidth;
10326 uint64_t unshifted_value;
10327 uint64_t value;
10328
10329 const header_field_info *hfinfo = fi->hfinfo;
10330
10331 value = fvalue_get_uinteger64(fi->value);
10332 if (hfinfo->bitmask) {
10333 /* Figure out the bit width */
10334 bitwidth = hfinfo_container_bitwidth(hfinfo);
10335
10336 /* Un-shift bits */
10337 unshifted_value = value;
10338 unshifted_value <<= hfinfo_bitshift(hfinfo);
10339
10340 /* Create the bitfield first */
10341 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10342 bitfield_byte_length = (int) (p - label_str);
10343 }
10344
10345 /* Fill in the textual info */
10346 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10347}
10348
10349static const char *
10350hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10351{
10352 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10353 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10354
10355 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10356 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10357 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10358 else
10359 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10360 }
10361
10362 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10363 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10364
10365 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10366 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10367
10368 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10369}
10370
10371static const char *
10372hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10373{
10374 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10375 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10376 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10377 else
10378 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10379 }
10380
10381 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10382 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10383
10384 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10385 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10386
10387 /* If this is reached somebody registered a 64-bit field with a 32-bit
10388 * value-string, which isn't right. */
10389 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)
10390 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10391
10392 /* This is necessary to squelch MSVC errors; is there
10393 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10394 never returns? */
10395 return NULL((void*)0);
10396}
10397
10398static const char *
10399hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10400{
10401 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10402 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10403
10404 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)
;
10405
10406 /* This is necessary to squelch MSVC errors; is there
10407 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10408 never returns? */
10409 return NULL((void*)0);
10410}
10411
10412static const char *
10413hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10414{
10415 const char *str = hf_try_val_to_str(value, hfinfo);
10416
10417 return (str) ? str : unknown_str;
10418}
10419
10420static const char *
10421hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10422{
10423 const char *str = hf_try_val64_to_str(value, hfinfo);
10424
10425 return (str) ? str : unknown_str;
10426}
10427
10428/* Fills data for bitfield chars with val_strings */
10429static void
10430fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10431{
10432 char *p;
10433 int bitfield_byte_length, bitwidth;
10434 uint32_t unshifted_value;
10435 uint32_t value;
10436
10437 char buf[32];
10438 const char *out;
10439
10440 const header_field_info *hfinfo = fi->hfinfo;
10441
10442 /* Figure out the bit width */
10443 bitwidth = hfinfo_container_bitwidth(hfinfo);
10444
10445 /* Un-shift bits */
10446 value = fvalue_get_uinteger(fi->value);
10447
10448 unshifted_value = value;
10449 if (hfinfo->bitmask) {
10450 unshifted_value <<= hfinfo_bitshift(hfinfo);
10451 }
10452
10453 /* Create the bitfield first */
10454 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10455 bitfield_byte_length = (int) (p - label_str);
10456
10457 /* Fill in the textual info using stored (shifted) value */
10458 if (hfinfo->display == BASE_CUSTOM) {
10459 char tmp[ITEM_LABEL_LENGTH240];
10460 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10461
10462 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10462, "fmtfunc"))))
;
10463 fmtfunc(tmp, value);
10464 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10465 }
10466 else if (hfinfo->strings) {
10467 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10468
10469 out = hfinfo_char_vals_format(hfinfo, buf, value);
10470 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10471 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10472 else
10473 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10474 }
10475 else {
10476 out = hfinfo_char_value_format(hfinfo, buf, value);
10477
10478 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10479 }
10480}
10481
10482/* Fills data for bitfield ints with val_strings */
10483static void
10484fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10485{
10486 char *p;
10487 int bitfield_byte_length, bitwidth;
10488 uint32_t value, unshifted_value;
10489 char buf[NUMBER_LABEL_LENGTH80];
10490 const char *out;
10491
10492 const header_field_info *hfinfo = fi->hfinfo;
10493
10494 /* Figure out the bit width */
10495 if (fi->flags & FI_VARINT0x00040000)
10496 bitwidth = fi->length*8;
10497 else
10498 bitwidth = hfinfo_container_bitwidth(hfinfo);
10499
10500 /* Un-shift bits */
10501 if (is_signed)
10502 value = fvalue_get_sinteger(fi->value);
10503 else
10504 value = fvalue_get_uinteger(fi->value);
10505
10506 unshifted_value = value;
10507 if (hfinfo->bitmask) {
10508 unshifted_value <<= hfinfo_bitshift(hfinfo);
10509 }
10510
10511 /* Create the bitfield first */
10512 if (fi->flags & FI_VARINT0x00040000)
10513 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10514 else
10515 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10516 bitfield_byte_length = (int) (p - label_str);
10517
10518 /* Fill in the textual info using stored (shifted) value */
10519 if (hfinfo->display == BASE_CUSTOM) {
10520 char tmp[ITEM_LABEL_LENGTH240];
10521 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10522
10523 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10523, "fmtfunc"))))
;
10524 fmtfunc(tmp, value);
10525 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10526 }
10527 else if (hfinfo->strings) {
10528 const char *val_str = hf_try_val_to_str(value, hfinfo);
10529
10530 out = hfinfo_number_vals_format(hfinfo, buf, value);
10531 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10532 /*
10533 * Unique values only display value_string string
10534 * if there is a match. Otherwise it's just a number
10535 */
10536 if (val_str) {
10537 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10538 } else {
10539 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10540 }
10541 } else {
10542 if (val_str == NULL((void*)0))
10543 val_str = "Unknown";
10544
10545 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10546 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10547 else
10548 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10549 }
10550 }
10551 else {
10552 out = hfinfo_number_value_format(hfinfo, buf, value);
10553
10554 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10555 }
10556}
10557
10558static void
10559fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10560{
10561 char *p;
10562 int bitfield_byte_length, bitwidth;
10563 uint64_t value, unshifted_value;
10564 char buf[NUMBER_LABEL_LENGTH80];
10565 const char *out;
10566
10567 const header_field_info *hfinfo = fi->hfinfo;
10568
10569 /* Figure out the bit width */
10570 if (fi->flags & FI_VARINT0x00040000)
10571 bitwidth = fi->length*8;
10572 else
10573 bitwidth = hfinfo_container_bitwidth(hfinfo);
10574
10575 /* Un-shift bits */
10576 if (is_signed)
10577 value = fvalue_get_sinteger64(fi->value);
10578 else
10579 value = fvalue_get_uinteger64(fi->value);
10580
10581 unshifted_value = value;
10582 if (hfinfo->bitmask) {
10583 unshifted_value <<= hfinfo_bitshift(hfinfo);
10584 }
10585
10586 /* Create the bitfield first */
10587 if (fi->flags & FI_VARINT0x00040000)
10588 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10589 else
10590 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10591 bitfield_byte_length = (int) (p - label_str);
10592
10593 /* Fill in the textual info using stored (shifted) value */
10594 if (hfinfo->display == BASE_CUSTOM) {
10595 char tmp[ITEM_LABEL_LENGTH240];
10596 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10597
10598 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10598, "fmtfunc64"
))))
;
10599 fmtfunc64(tmp, value);
10600 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10601 }
10602 else if (hfinfo->strings) {
10603 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10604
10605 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10606 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10607 /*
10608 * Unique values only display value_string string
10609 * if there is a match. Otherwise it's just a number
10610 */
10611 if (val_str) {
10612 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10613 } else {
10614 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10615 }
10616 } else {
10617 if (val_str == NULL((void*)0))
10618 val_str = "Unknown";
10619
10620 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10621 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10622 else
10623 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10624 }
10625 }
10626 else {
10627 out = hfinfo_number_value_format64(hfinfo, buf, value);
10628
10629 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10630 }
10631}
10632
10633static void
10634fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10635{
10636 const header_field_info *hfinfo = fi->hfinfo;
10637 uint32_t value;
10638
10639 char buf[32];
10640 const char *out;
10641
10642 value = fvalue_get_uinteger(fi->value);
10643
10644 /* Fill in the textual info */
10645 if (hfinfo->display == BASE_CUSTOM) {
10646 char tmp[ITEM_LABEL_LENGTH240];
10647 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10648
10649 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10649, "fmtfunc"))))
;
10650 fmtfunc(tmp, value);
10651 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10652 }
10653 else if (hfinfo->strings) {
10654 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10655
10656 out = hfinfo_char_vals_format(hfinfo, buf, value);
10657 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10658 }
10659 else {
10660 out = hfinfo_char_value_format(hfinfo, buf, value);
10661
10662 label_fill(label_str, 0, hfinfo, out, value_pos);
10663 }
10664}
10665
10666static void
10667fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10668{
10669 const header_field_info *hfinfo = fi->hfinfo;
10670 uint32_t value;
10671
10672 char buf[NUMBER_LABEL_LENGTH80];
10673 const char *out;
10674
10675 if (is_signed)
10676 value = fvalue_get_sinteger(fi->value);
10677 else
10678 value = fvalue_get_uinteger(fi->value);
10679
10680 /* Fill in the textual info */
10681 if (hfinfo->display == BASE_CUSTOM) {
10682 char tmp[ITEM_LABEL_LENGTH240];
10683 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10684
10685 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10685, "fmtfunc"))))
;
10686 fmtfunc(tmp, value);
10687 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10688 }
10689 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10690 /*
10691 * It makes no sense to have a value-string table for a
10692 * frame-number field - they're just integers giving
10693 * the ordinal frame number.
10694 */
10695 const char *val_str = hf_try_val_to_str(value, hfinfo);
10696
10697 out = hfinfo_number_vals_format(hfinfo, buf, value);
10698 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10699 /*
10700 * Unique values only display value_string string
10701 * if there is a match. Otherwise it's just a number
10702 */
10703 if (val_str) {
10704 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10705 } else {
10706 label_fill(label_str, 0, hfinfo, out, value_pos);
10707 }
10708 } else {
10709 if (val_str == NULL((void*)0))
10710 val_str = "Unknown";
10711
10712 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10713 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10714 else
10715 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10716 }
10717 }
10718 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
))
) {
10719 char tmp[ITEM_LABEL_LENGTH240];
10720
10721 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10722 display_to_port_type((field_display_e)hfinfo->display), value);
10723 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10724 }
10725 else {
10726 out = hfinfo_number_value_format(hfinfo, buf, value);
10727
10728 label_fill(label_str, 0, hfinfo, out, value_pos);
10729 }
10730}
10731
10732static void
10733fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10734{
10735 const header_field_info *hfinfo = fi->hfinfo;
10736 uint64_t value;
10737
10738 char buf[NUMBER_LABEL_LENGTH80];
10739 const char *out;
10740
10741 if (is_signed)
10742 value = fvalue_get_sinteger64(fi->value);
10743 else
10744 value = fvalue_get_uinteger64(fi->value);
10745
10746 /* Fill in the textual info */
10747 if (hfinfo->display == BASE_CUSTOM) {
10748 char tmp[ITEM_LABEL_LENGTH240];
10749 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10750
10751 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10751, "fmtfunc64"
))))
;
10752 fmtfunc64(tmp, value);
10753 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10754 }
10755 else if (hfinfo->strings) {
10756 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10757
10758 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10759 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10760 /*
10761 * Unique values only display value_string string
10762 * if there is a match. Otherwise it's just a number
10763 */
10764 if (val_str) {
10765 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10766 } else {
10767 label_fill(label_str, 0, hfinfo, out, value_pos);
10768 }
10769 } else {
10770 if (val_str == NULL((void*)0))
10771 val_str = "Unknown";
10772
10773 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10774 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10775 else
10776 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10777 }
10778 }
10779 else {
10780 out = hfinfo_number_value_format64(hfinfo, buf, value);
10781
10782 label_fill(label_str, 0, hfinfo, out, value_pos);
10783 }
10784}
10785
10786static size_t
10787fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10788{
10789 int display;
10790 int n;
10791 double value;
10792
10793 if (label_str_size < 12) {
10794 /* Not enough room to write an entire floating point value. */
10795 return 0;
10796 }
10797
10798 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10799 value = fvalue_get_floating(fi->value);
10800
10801 if (display == BASE_CUSTOM) {
10802 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10803 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10803, "fmtfunc"))))
;
10804 fmtfunc(label_str, value);
10805 return strlen(label_str);
10806 }
10807
10808 switch (display) {
10809 case BASE_NONE:
10810 if (fi->hfinfo->type == FT_FLOAT) {
10811 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10812 } else {
10813 n = (int)strlen(dtoa_g_fmt(label_str, value));
10814 }
10815 break;
10816 case BASE_DEC:
10817 n = snprintf(label_str, label_str_size, "%f", value);
10818 break;
10819 case BASE_HEX:
10820 n = snprintf(label_str, label_str_size, "%a", value);
10821 break;
10822 case BASE_EXP:
10823 n = snprintf(label_str, label_str_size, "%e", value);
10824 break;
10825 default:
10826 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10826
, __func__, "assertion \"not reached\" failed")
;
10827 }
10828 if (n < 0) {
10829 return 0; /* error */
10830 }
10831 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10832 const char *hf_str_val;
10833 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10834 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10835 }
10836 if (n > label_str_size) {
10837 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10837, __func__, "label length too small"); } } while (0)
;
10838 return strlen(label_str);
10839 }
10840
10841 return n;
10842}
10843
10844void
10845fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10846{
10847 char tmp[ITEM_LABEL_LENGTH240];
10848
10849 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10850 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10851}
10852
10853static size_t
10854fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10855{
10856 int display;
10857 size_t pos = 0;
10858 double value;
10859 char* tmp_str;
10860
10861 if (label_str_size < 12) {
10862 /* Not enough room to write an entire floating point value. */
10863 return 0;
10864 }
10865
10866 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10867 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10868 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10869 wmem_free(NULL((void*)0), tmp_str);
10870
10871 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10872 const char *hf_str_val;
10873 fvalue_to_double(fi->value, &value);
10874 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10875 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10876 }
10877 if ((int)pos > label_str_size) {
10878 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10878, __func__, "label length too small"); } } while (0)
;
10879 return strlen(label_str);
10880 }
10881
10882 return pos;
10883}
10884
10885void
10886fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10887{
10888 char tmp[ITEM_LABEL_LENGTH240];
10889
10890 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10891 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10892}
10893
10894int
10895hfinfo_bitshift(const header_field_info *hfinfo)
10896{
10897 return ws_ctz(hfinfo->bitmask);
10898}
10899
10900
10901static int
10902hfinfo_bitoffset(const header_field_info *hfinfo)
10903{
10904 if (!hfinfo->bitmask) {
10905 return 0;
10906 }
10907
10908 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10909 * as the first bit */
10910 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10911}
10912
10913static int
10914hfinfo_mask_bitwidth(const header_field_info *hfinfo)
10915{
10916 if (!hfinfo->bitmask) {
10917 return 0;
10918 }
10919
10920 /* ilog2 = first set bit, ctz = last set bit */
10921 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
10922}
10923
10924static int
10925hfinfo_type_bitwidth(enum ftenum type)
10926{
10927 int bitwidth = 0;
10928
10929 switch (type) {
10930 case FT_CHAR:
10931 case FT_UINT8:
10932 case FT_INT8:
10933 bitwidth = 8;
10934 break;
10935 case FT_UINT16:
10936 case FT_INT16:
10937 bitwidth = 16;
10938 break;
10939 case FT_UINT24:
10940 case FT_INT24:
10941 bitwidth = 24;
10942 break;
10943 case FT_UINT32:
10944 case FT_INT32:
10945 bitwidth = 32;
10946 break;
10947 case FT_UINT40:
10948 case FT_INT40:
10949 bitwidth = 40;
10950 break;
10951 case FT_UINT48:
10952 case FT_INT48:
10953 bitwidth = 48;
10954 break;
10955 case FT_UINT56:
10956 case FT_INT56:
10957 bitwidth = 56;
10958 break;
10959 case FT_UINT64:
10960 case FT_INT64:
10961 bitwidth = 64;
10962 break;
10963 default:
10964 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 10964))
;
10965 ;
10966 }
10967 return bitwidth;
10968}
10969
10970
10971static int
10972hfinfo_container_bitwidth(const header_field_info *hfinfo)
10973{
10974 if (!hfinfo->bitmask) {
10975 return 0;
10976 }
10977
10978 if (hfinfo->type == FT_BOOLEAN) {
10979 return hfinfo->display; /* hacky? :) */
10980 }
10981
10982 return hfinfo_type_bitwidth(hfinfo->type);
10983}
10984
10985static int
10986hfinfo_hex_digits(const header_field_info *hfinfo)
10987{
10988 int bitwidth;
10989
10990 /* If we have a bitmask, hfinfo->type is the width of the container, so not
10991 * appropriate to determine the number of hex digits for the field.
10992 * So instead, we compute it from the bitmask.
10993 */
10994 if (hfinfo->bitmask != 0) {
10995 bitwidth = hfinfo_mask_bitwidth(hfinfo);
10996 } else {
10997 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
10998 }
10999
11000 /* Divide by 4, rounding up, to get number of hex digits. */
11001 return (bitwidth + 3) / 4;
11002}
11003
11004const char *
11005hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11006{
11007 char *ptr = &buf[6];
11008 static const char hex_digits[16] =
11009 { '0', '1', '2', '3', '4', '5', '6', '7',
11010 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11011
11012 *ptr = '\0';
11013 *(--ptr) = '\'';
11014 /* Properly format value */
11015 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11016 /*
11017 * Printable, so just show the character, and, if it needs
11018 * to be escaped, escape it.
11019 */
11020 *(--ptr) = value;
11021 if (value == '\\' || value == '\'')
11022 *(--ptr) = '\\';
11023 } else {
11024 /*
11025 * Non-printable; show it as an escape sequence.
11026 */
11027 switch (value) {
11028
11029 case '\0':
11030 /*
11031 * Show a NUL with only one digit.
11032 */
11033 *(--ptr) = '0';
11034 break;
11035
11036 case '\a':
11037 case '\b':
11038 case '\f':
11039 case '\n':
11040 case '\r':
11041 case '\t':
11042 case '\v':
11043 *(--ptr) = value - '\a' + 'a';
11044 break;
11045
11046 default:
11047 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11048
11049 case BASE_OCT:
11050 *(--ptr) = (value & 0x7) + '0';
11051 value >>= 3;
11052 *(--ptr) = (value & 0x7) + '0';
11053 value >>= 3;
11054 *(--ptr) = (value & 0x7) + '0';
11055 break;
11056
11057 case BASE_HEX:
11058 *(--ptr) = hex_digits[value & 0x0F];
11059 value >>= 4;
11060 *(--ptr) = hex_digits[value & 0x0F];
11061 *(--ptr) = 'x';
11062 break;
11063
11064 default:
11065 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11066 }
11067 }
11068 *(--ptr) = '\\';
11069 }
11070 *(--ptr) = '\'';
11071 return ptr;
11072}
11073
11074static const char *
11075hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11076{
11077 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11078 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
))
;
11079
11080 *ptr = '\0';
11081 /* Properly format value */
11082 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11083 case BASE_DEC:
11084 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11085
11086 case BASE_DEC_HEX:
11087 *(--ptr) = ')';
11088 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11089 *(--ptr) = '(';
11090 *(--ptr) = ' ';
11091 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11092 return ptr;
11093
11094 case BASE_OCT:
11095 return oct_to_str_back(ptr, value);
11096
11097 case BASE_HEX:
11098 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11099
11100 case BASE_HEX_DEC:
11101 *(--ptr) = ')';
11102 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11103 *(--ptr) = '(';
11104 *(--ptr) = ' ';
11105 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11106 return ptr;
11107
11108 case BASE_PT_UDP:
11109 case BASE_PT_TCP:
11110 case BASE_PT_DCCP:
11111 case BASE_PT_SCTP:
11112 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11113 display_to_port_type((field_display_e)display), value);
11114 return buf;
11115 case BASE_OUI:
11116 {
11117 uint8_t p_oui[3];
11118 const char *manuf_name;
11119
11120 p_oui[0] = value >> 16 & 0xFF;
11121 p_oui[1] = value >> 8 & 0xFF;
11122 p_oui[2] = value & 0xFF;
11123
11124 /* Attempt an OUI lookup. */
11125 manuf_name = uint_get_manuf_name_if_known(value);
11126 if (manuf_name == NULL((void*)0)) {
11127 /* Could not find an OUI. */
11128 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11129 }
11130 else {
11131 /* Found an address string. */
11132 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11133 }
11134 return buf;
11135 }
11136
11137 default:
11138 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11139 }
11140 return ptr;
11141}
11142
11143static const char *
11144hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11145{
11146 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11147 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
))
;
11148
11149 *ptr = '\0';
11150 /* Properly format value */
11151 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11152 case BASE_DEC:
11153 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11154
11155 case BASE_DEC_HEX:
11156 *(--ptr) = ')';
11157 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11158 *(--ptr) = '(';
11159 *(--ptr) = ' ';
11160 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11161 return ptr;
11162
11163 case BASE_OCT:
11164 return oct64_to_str_back(ptr, value);
11165
11166 case BASE_HEX:
11167 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11168
11169 case BASE_HEX_DEC:
11170 *(--ptr) = ')';
11171 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11172 *(--ptr) = '(';
11173 *(--ptr) = ' ';
11174 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11175 return ptr;
11176
11177 default:
11178 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11179 }
11180
11181 return ptr;
11182}
11183
11184static const char *
11185hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11186{
11187 int display = hfinfo->display;
11188
11189 if (hfinfo->type == FT_FRAMENUM) {
11190 /*
11191 * Frame numbers are always displayed in decimal.
11192 */
11193 display = BASE_DEC;
11194 }
11195
11196 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11197}
11198
11199static const char *
11200hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11201{
11202 int display = hfinfo->display;
11203
11204 if (hfinfo->type == FT_FRAMENUM) {
11205 /*
11206 * Frame numbers are always displayed in decimal.
11207 */
11208 display = BASE_DEC;
11209 }
11210
11211 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11212}
11213
11214static const char *
11215hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11216{
11217 /* Get the underlying BASE_ value */
11218 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11219
11220 return hfinfo_char_value_format_display(display, buf, value);
11221}
11222
11223static const char *
11224hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11225{
11226 /* Get the underlying BASE_ value */
11227 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11228
11229 if (hfinfo->type == FT_FRAMENUM) {
11230 /*
11231 * Frame numbers are always displayed in decimal.
11232 */
11233 display = BASE_DEC;
11234 }
11235
11236 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11237 display = BASE_DEC;
11238 } else if (display == BASE_OUI) {
11239 display = BASE_HEX;
11240 }
11241
11242 switch (display) {
11243 case BASE_NONE:
11244 /* case BASE_DEC: */
11245 case BASE_DEC_HEX:
11246 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11247 case BASE_CUSTOM:
11248 display = BASE_DEC;
11249 break;
11250
11251 /* case BASE_HEX: */
11252 case BASE_HEX_DEC:
11253 display = BASE_HEX;
11254 break;
11255 }
11256
11257 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11258}
11259
11260static const char *
11261hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11262{
11263 /* Get the underlying BASE_ value */
11264 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11265
11266 if (hfinfo->type == FT_FRAMENUM) {
11267 /*
11268 * Frame numbers are always displayed in decimal.
11269 */
11270 display = BASE_DEC;
11271 }
11272
11273 switch (display) {
11274 case BASE_NONE:
11275 /* case BASE_DEC: */
11276 case BASE_DEC_HEX:
11277 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11278 case BASE_CUSTOM:
11279 display = BASE_DEC;
11280 break;
11281
11282 /* case BASE_HEX: */
11283 case BASE_HEX_DEC:
11284 display = BASE_HEX;
11285 break;
11286 }
11287
11288 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11289}
11290
11291static const char *
11292hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11293{
11294 /* Get the underlying BASE_ value */
11295 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11296
11297 return hfinfo_char_value_format_display(display, buf, value);
11298}
11299
11300static const char *
11301hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11302{
11303 /* Get the underlying BASE_ value */
11304 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11305
11306 if (display == BASE_NONE)
11307 return NULL((void*)0);
11308
11309 if (display == BASE_DEC_HEX)
11310 display = BASE_DEC;
11311 if (display == BASE_HEX_DEC)
11312 display = BASE_HEX;
11313
11314 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11315}
11316
11317static const char *
11318hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11319{
11320 /* Get the underlying BASE_ value */
11321 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11322
11323 if (display == BASE_NONE)
11324 return NULL((void*)0);
11325
11326 if (display == BASE_DEC_HEX)
11327 display = BASE_DEC;
11328 if (display == BASE_HEX_DEC)
11329 display = BASE_HEX;
11330
11331 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11332}
11333
11334const char *
11335proto_registrar_get_name(const int n)
11336{
11337 header_field_info *hfinfo;
11338
11339 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", 11339
, __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", 11339
, "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", 11339, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11340 return hfinfo->name;
11341}
11342
11343const char *
11344proto_registrar_get_abbrev(const int n)
11345{
11346 header_field_info *hfinfo;
11347
11348 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", 11348
, __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", 11348
, "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", 11348, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11349 return hfinfo->abbrev;
11350}
11351
11352enum ftenum
11353proto_registrar_get_ftype(const int n)
11354{
11355 header_field_info *hfinfo;
11356
11357 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", 11357
, __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", 11357
, "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", 11357, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11358 return hfinfo->type;
11359}
11360
11361int
11362proto_registrar_get_parent(const int n)
11363{
11364 header_field_info *hfinfo;
11365
11366 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", 11366
, __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", 11366
, "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", 11366, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11367 return hfinfo->parent;
11368}
11369
11370bool_Bool
11371proto_registrar_is_protocol(const int n)
11372{
11373 header_field_info *hfinfo;
11374
11375 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", 11375
, __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", 11375
, "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", 11375, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11376 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11377}
11378
11379/* Returns length of field in packet (not necessarily the length
11380 * in our internal representation, as in the case of IPv4).
11381 * 0 means undeterminable at time of registration
11382 * -1 means the field is not registered. */
11383int
11384proto_registrar_get_length(const int n)
11385{
11386 header_field_info *hfinfo;
11387
11388 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", 11388
, __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", 11388
, "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", 11388, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11389 return ftype_wire_size(hfinfo->type);
11390}
11391
11392/* Looks for a protocol or a field in a proto_tree. Returns true if
11393 * it exists anywhere, or false if it exists nowhere. */
11394bool_Bool
11395proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11396{
11397 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11398
11399 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11400 return true1;
11401 }
11402 else {
11403 return false0;
11404 }
11405}
11406
11407/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11408 * This only works if the hfindex was "primed" before the dissection
11409 * took place, as we just pass back the already-created GPtrArray*.
11410 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11411 * handles that. */
11412GPtrArray *
11413proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11414{
11415 if (!tree)
11416 return NULL((void*)0);
11417
11418 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11419 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11420 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11421 else
11422 return NULL((void*)0);
11423}
11424
11425bool_Bool
11426proto_tracking_interesting_fields(const proto_tree *tree)
11427{
11428 GHashTable *interesting_hfids;
11429
11430 if (!tree)
11431 return false0;
11432
11433 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11434
11435 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11436}
11437
11438/* Helper struct for proto_find_info() and proto_all_finfos() */
11439typedef struct {
11440 GPtrArray *array;
11441 int id;
11442} ffdata_t;
11443
11444/* Helper function for proto_find_info() */
11445static bool_Bool
11446find_finfo(proto_node *node, void * data)
11447{
11448 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11449 if (fi && fi->hfinfo) {
11450 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11451 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11452 }
11453 }
11454
11455 /* Don't stop traversing. */
11456 return false0;
11457}
11458
11459/* Helper function for proto_find_first_info() */
11460static bool_Bool
11461find_first_finfo(proto_node *node, void *data)
11462{
11463 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11464 if (fi && fi->hfinfo) {
11465 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11466 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11467
11468 /* Stop traversing. */
11469 return true1;
11470 }
11471 }
11472
11473 /* Continue traversing. */
11474 return false0;
11475}
11476
11477/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11478* This works on any proto_tree, primed or unprimed, but actually searches
11479* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11480* The caller does need to free the returned GPtrArray with
11481* g_ptr_array_free(<array>, true).
11482*/
11483GPtrArray *
11484proto_find_finfo(proto_tree *tree, const int id)
11485{
11486 ffdata_t ffdata;
11487
11488 ffdata.array = g_ptr_array_new();
11489 ffdata.id = id;
11490
11491 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11492
11493 return ffdata.array;
11494}
11495
11496/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11497* This works on any proto_tree, primed or unprimed, but actually searches
11498* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11499* The caller does need to free the returned GPtrArray with
11500* g_ptr_array_free(<array>, true).
11501*/
11502GPtrArray *
11503proto_find_first_finfo(proto_tree *tree, const int id)
11504{
11505 ffdata_t ffdata;
11506
11507 ffdata.array = g_ptr_array_new();
11508 ffdata.id = id;
11509
11510 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11511
11512 return ffdata.array;
11513}
11514
11515/* Helper function for proto_all_finfos() */
11516static bool_Bool
11517every_finfo(proto_node *node, void * data)
11518{
11519 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11520 if (fi && fi->hfinfo) {
11521 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11522 }
11523
11524 /* Don't stop traversing. */
11525 return false0;
11526}
11527
11528/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11529 * The caller does need to free the returned GPtrArray with
11530 * g_ptr_array_free(<array>, true).
11531 */
11532GPtrArray *
11533proto_all_finfos(proto_tree *tree)
11534{
11535 ffdata_t ffdata;
11536
11537 /* Pre allocate enough space to hold all fields in most cases */
11538 ffdata.array = g_ptr_array_sized_new(512);
11539 ffdata.id = 0;
11540
11541 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11542
11543 return ffdata.array;
11544}
11545
11546
11547typedef struct {
11548 unsigned offset;
11549 field_info *finfo;
11550 tvbuff_t *tvb;
11551} offset_search_t;
11552
11553static bool_Bool
11554check_for_offset(proto_node *node, void * data)
11555{
11556 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11557 offset_search_t *offsearch = (offset_search_t *)data;
11558
11559 /* !fi == the top most container node which holds nothing */
11560 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11561 if (offsearch->offset >= (unsigned) fi->start &&
11562 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11563
11564 offsearch->finfo = fi;
11565 return false0; /* keep traversing */
11566 }
11567 }
11568 return false0; /* keep traversing */
11569}
11570
11571/* Search a proto_tree backwards (from leaves to root) looking for the field
11572 * whose start/length occupies 'offset' */
11573/* XXX - I couldn't find an easy way to search backwards, so I search
11574 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11575 * the one I want to return to the user. This algorithm is inefficient
11576 * and could be re-done, but I'd have to handle all the children and
11577 * siblings of each node myself. When I have more time I'll do that.
11578 * (yeah right) */
11579field_info *
11580proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11581{
11582 offset_search_t offsearch;
11583
11584 offsearch.offset = offset;
11585 offsearch.finfo = NULL((void*)0);
11586 offsearch.tvb = tvb;
11587
11588 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11589
11590 return offsearch.finfo;
11591}
11592
11593typedef struct {
11594 int length;
11595 char *buf;
11596} decoded_data_t;
11597
11598static bool_Bool
11599check_for_undecoded(proto_node *node, void * data)
11600{
11601 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11602 decoded_data_t* decoded = (decoded_data_t*)data;
11603 int i;
11604 unsigned byte;
11605 unsigned bit;
11606
11607 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11608 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11609 byte = i / 8;
11610 bit = i % 8;
11611 decoded->buf[byte] |= (1 << bit);
11612 }
11613 }
11614
11615 return false0;
11616}
11617
11618char*
11619proto_find_undecoded_data(proto_tree *tree, unsigned length)
11620{
11621 decoded_data_t decoded;
11622 decoded.length = length;
11623 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11624
11625 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11626 return decoded.buf;
11627}
11628
11629/* Dumps the protocols in the registration database to stdout. An independent
11630 * program can take this output and format it into nice tables or HTML or
11631 * whatever.
11632 *
11633 * There is one record per line. The fields are tab-delimited.
11634 *
11635 * Field 1 = protocol name
11636 * Field 2 = protocol short name
11637 * Field 3 = protocol filter name
11638 * Field 4 = protocol enabled
11639 * Field 5 = protocol enabled by default
11640 * Field 6 = protocol can toggle
11641 */
11642void
11643proto_registrar_dump_protocols(void)
11644{
11645 protocol_t *protocol;
11646 int i;
11647 void *cookie = NULL((void*)0);
11648
11649
11650 i = proto_get_first_protocol(&cookie);
11651 while (i != -1) {
11652 protocol = find_protocol_by_id(i);
11653 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11654 protocol->name,
11655 protocol->short_name,
11656 protocol->filter_name,
11657 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11658 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11659 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11660 i = proto_get_next_protocol(&cookie);
11661 }
11662}
11663
11664/* Dumps the value_strings, extended value string headers, range_strings
11665 * or true/false strings for fields that have them.
11666 * There is one record per line. Fields are tab-delimited.
11667 * There are four types of records: Value String, Extended Value String Header,
11668 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11669 * the type of record.
11670 *
11671 * Note that a record will be generated only if the value_string,... is referenced
11672 * in a registered hfinfo entry.
11673 *
11674 *
11675 * Value Strings
11676 * -------------
11677 * Field 1 = 'V'
11678 * Field 2 = Field abbreviation to which this value string corresponds
11679 * Field 3 = Integer value
11680 * Field 4 = String
11681 *
11682 * Extended Value String Headers
11683 * -----------------------------
11684 * Field 1 = 'E'
11685 * Field 2 = Field abbreviation to which this extended value string header corresponds
11686 * Field 3 = Extended Value String "Name"
11687 * Field 4 = Number of entries in the associated value_string array
11688 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11689 *
11690 * Range Strings
11691 * -------------
11692 * Field 1 = 'R'
11693 * Field 2 = Field abbreviation to which this range string corresponds
11694 * Field 3 = Integer value: lower bound
11695 * Field 4 = Integer value: upper bound
11696 * Field 5 = String
11697 *
11698 * True/False Strings
11699 * ------------------
11700 * Field 1 = 'T'
11701 * Field 2 = Field abbreviation to which this true/false string corresponds
11702 * Field 3 = True String
11703 * Field 4 = False String
11704 */
11705void
11706proto_registrar_dump_values(void)
11707{
11708 header_field_info *hfinfo;
11709 int i, len, vi;
11710 const value_string *vals;
11711 const val64_string *vals64;
11712 const range_string *range;
11713 const true_false_string *tfs;
11714 const unit_name_string *units;
11715
11716 len = gpa_hfinfo.len;
11717 for (i = 0; i < len ; i++) {
11718 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11719 continue; /* This is a deregistered protocol or field */
11720
11721 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", 11721
, __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", 11721
, "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", 11721, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11722
11723 if (hfinfo->id == hf_text_only) {
11724 continue;
11725 }
11726
11727 /* ignore protocols */
11728 if (proto_registrar_is_protocol(i)) {
11729 continue;
11730 }
11731 /* process header fields */
11732#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11733 /*
11734 * If this field isn't at the head of the list of
11735 * fields with this name, skip this field - all
11736 * fields with the same name are really just versions
11737 * of the same field stored in different bits, and
11738 * should have the same type/radix/value list, and
11739 * just differ in their bit masks. (If a field isn't
11740 * a bitfield, but can be, say, 1 or 2 bytes long,
11741 * it can just be made FT_UINT16, meaning the
11742 * *maximum* length is 2 bytes, and be used
11743 * for all lengths.)
11744 */
11745 if (hfinfo->same_name_prev_id != -1)
11746 continue;
11747#endif
11748 vals = NULL((void*)0);
11749 vals64 = NULL((void*)0);
11750 range = NULL((void*)0);
11751 tfs = NULL((void*)0);
11752 units = NULL((void*)0);
11753
11754 if (hfinfo->strings != NULL((void*)0)) {
11755 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11756 (hfinfo->type == FT_CHAR ||
11757 hfinfo->type == FT_UINT8 ||
11758 hfinfo->type == FT_UINT16 ||
11759 hfinfo->type == FT_UINT24 ||
11760 hfinfo->type == FT_UINT32 ||
11761 hfinfo->type == FT_UINT40 ||
11762 hfinfo->type == FT_UINT48 ||
11763 hfinfo->type == FT_UINT56 ||
11764 hfinfo->type == FT_UINT64 ||
11765 hfinfo->type == FT_INT8 ||
11766 hfinfo->type == FT_INT16 ||
11767 hfinfo->type == FT_INT24 ||
11768 hfinfo->type == FT_INT32 ||
11769 hfinfo->type == FT_INT40 ||
11770 hfinfo->type == FT_INT48 ||
11771 hfinfo->type == FT_INT56 ||
11772 hfinfo->type == FT_INT64 ||
11773 hfinfo->type == FT_FLOAT ||
11774 hfinfo->type == FT_DOUBLE)) {
11775
11776 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11777 range = (const range_string *)hfinfo->strings;
11778 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11779 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11780 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11781 } else {
11782 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11783 }
11784 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11785 vals64 = (const val64_string *)hfinfo->strings;
11786 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11787 units = (const unit_name_string *)hfinfo->strings;
11788 } else {
11789 vals = (const value_string *)hfinfo->strings;
11790 }
11791 }
11792 else if (hfinfo->type == FT_BOOLEAN) {
11793 tfs = (const struct true_false_string *)hfinfo->strings;
11794 }
11795 }
11796
11797 /* Print value strings? */
11798 if (vals) {
11799 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11800 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11801 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11802 if (!val64_string_ext_validate(vse_p)) {
11803 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11803, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11804 continue;
11805 }
11806 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11807 printf("E\t%s\t%u\t%s\t%s\n",
11808 hfinfo->abbrev,
11809 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11810 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11811 val64_string_ext_match_type_str(vse_p));
11812 } else {
11813 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11814 if (!value_string_ext_validate(vse_p)) {
11815 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11815, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11816 continue;
11817 }
11818 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11819 printf("E\t%s\t%u\t%s\t%s\n",
11820 hfinfo->abbrev,
11821 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11822 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11823 value_string_ext_match_type_str(vse_p));
11824 }
11825 }
11826 vi = 0;
11827 while (vals[vi].strptr) {
11828 /* Print in the proper base */
11829 if (hfinfo->type == FT_CHAR) {
11830 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11831 printf("V\t%s\t'%c'\t%s\n",
11832 hfinfo->abbrev,
11833 vals[vi].value,
11834 vals[vi].strptr);
11835 } else {
11836 if (hfinfo->display == BASE_HEX) {
11837 printf("V\t%s\t'\\x%02x'\t%s\n",
11838 hfinfo->abbrev,
11839 vals[vi].value,
11840 vals[vi].strptr);
11841 }
11842 else {
11843 printf("V\t%s\t'\\%03o'\t%s\n",
11844 hfinfo->abbrev,
11845 vals[vi].value,
11846 vals[vi].strptr);
11847 }
11848 }
11849 } else {
11850 if (hfinfo->display == BASE_HEX) {
11851 printf("V\t%s\t0x%x\t%s\n",
11852 hfinfo->abbrev,
11853 vals[vi].value,
11854 vals[vi].strptr);
11855 }
11856 else {
11857 printf("V\t%s\t%u\t%s\n",
11858 hfinfo->abbrev,
11859 vals[vi].value,
11860 vals[vi].strptr);
11861 }
11862 }
11863 vi++;
11864 }
11865 }
11866 else if (vals64) {
11867 vi = 0;
11868 while (vals64[vi].strptr) {
11869 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11870 hfinfo->abbrev,
11871 vals64[vi].value,
11872 vals64[vi].strptr);
11873 vi++;
11874 }
11875 }
11876
11877 /* print range strings? */
11878 else if (range) {
11879 vi = 0;
11880 while (range[vi].strptr) {
11881 /* Print in the proper base */
11882 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11883 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11884 hfinfo->abbrev,
11885 range[vi].value_min,
11886 range[vi].value_max,
11887 range[vi].strptr);
11888 }
11889 else {
11890 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11891 hfinfo->abbrev,
11892 range[vi].value_min,
11893 range[vi].value_max,
11894 range[vi].strptr);
11895 }
11896 vi++;
11897 }
11898 }
11899
11900 /* Print true/false strings? */
11901 else if (tfs) {
11902 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11903 tfs->true_string, tfs->false_string);
11904 }
11905 /* Print unit strings? */
11906 else if (units) {
11907 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11908 units->singular, units->plural ? units->plural : "(no plural)");
11909 }
11910 }
11911}
11912
11913/* Prints the number of registered fields.
11914 * Useful for determining an appropriate value for
11915 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
11916 *
11917 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
11918 * the number of fields, true otherwise.
11919 */
11920bool_Bool
11921proto_registrar_dump_fieldcount(void)
11922{
11923 uint32_t i;
11924 header_field_info *hfinfo;
11925 uint32_t deregistered_count = 0;
11926 uint32_t same_name_count = 0;
11927 uint32_t protocol_count = 0;
11928
11929 for (i = 0; i < gpa_hfinfo.len; i++) {
11930 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
11931 deregistered_count++;
11932 continue; /* This is a deregistered protocol or header field */
11933 }
11934
11935 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", 11935
, __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", 11935
, "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", 11935, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11936
11937 if (proto_registrar_is_protocol(i))
11938 protocol_count++;
11939
11940 if (hfinfo->same_name_prev_id != -1)
11941 same_name_count++;
11942 }
11943
11944 printf("There are %u header fields registered, of which:\n"
11945 "\t%u are deregistered\n"
11946 "\t%u are protocols\n"
11947 "\t%u have the same name as another field\n\n",
11948 gpa_hfinfo.len, deregistered_count, protocol_count,
11949 same_name_count);
11950
11951 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
11952 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
11953 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
11954 "\n");
11955
11956 printf("The header field table consumes %u KiB of memory.\n",
11957 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
11958 printf("The fields themselves consume %u KiB of memory.\n",
11959 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
11960
11961 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
11962}
11963
11964static void
11965elastic_add_base_mapping(json_dumper *dumper)
11966{
11967 json_dumper_set_member_name(dumper, "index_patterns");
11968 json_dumper_begin_array(dumper);
11969 // The index names from write_json_index() in print.c
11970 json_dumper_value_string(dumper, "packets-*");
11971 json_dumper_end_array(dumper);
11972
11973 json_dumper_set_member_name(dumper, "settings");
11974 json_dumper_begin_object(dumper);
11975 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
11976 json_dumper_value_anyf(dumper, "%d", 1000000);
11977 json_dumper_end_object(dumper);
11978}
11979
11980static char*
11981ws_type_to_elastic(unsigned type)
11982{
11983 switch(type) {
11984 case FT_INT8:
11985 return "byte";
11986 case FT_UINT8:
11987 case FT_INT16:
11988 return "short";
11989 case FT_UINT16:
11990 case FT_INT32:
11991 case FT_UINT24:
11992 case FT_INT24:
11993 return "integer";
11994 case FT_FRAMENUM:
11995 case FT_UINT32:
11996 case FT_UINT40:
11997 case FT_UINT48:
11998 case FT_UINT56:
11999 case FT_INT40:
12000 case FT_INT48:
12001 case FT_INT56:
12002 case FT_INT64:
12003 return "long";
12004 case FT_UINT64:
12005 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12006 case FT_FLOAT:
12007 return "float";
12008 case FT_DOUBLE:
12009 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12010 return "double";
12011 case FT_IPv6:
12012 case FT_IPv4:
12013 return "ip";
12014 case FT_ABSOLUTE_TIME:
12015 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12016 case FT_BOOLEAN:
12017 return "boolean";
12018 default:
12019 return NULL((void*)0);
12020 }
12021}
12022
12023static char*
12024dot_to_underscore(char* str)
12025{
12026 unsigned i;
12027 for (i = 0; i < strlen(str); i++) {
12028 if (str[i] == '.')
12029 str[i] = '_';
12030 }
12031 return str;
12032}
12033
12034/* Dumps a mapping file for ElasticSearch
12035 * This is the v1 (legacy) _template API.
12036 * At some point it may need to be updated with the composable templates
12037 * introduced in Elasticsearch 7.8 (_index_template)
12038 */
12039void
12040proto_registrar_dump_elastic(const char* filter)
12041{
12042 header_field_info *hfinfo;
12043 header_field_info *parent_hfinfo;
12044 unsigned i;
12045 bool_Bool open_object = true1;
12046 const char* prev_proto = NULL((void*)0);
12047 char* str;
12048 char** protos = NULL((void*)0);
12049 char* proto;
12050 bool_Bool found;
12051 unsigned j;
12052 char* type;
12053 char* prev_item = NULL((void*)0);
12054
12055 /* We have filtering protocols. Extract them. */
12056 if (filter) {
12057 protos = g_strsplit(filter, ",", -1);
12058 }
12059
12060 /*
12061 * To help tracking down the json tree, objects have been appended with a comment:
12062 * n.label -> where n is the indentation level and label the name of the object
12063 */
12064
12065 json_dumper dumper = {
12066 .output_file = stdoutstdout,
12067 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12068 };
12069 json_dumper_begin_object(&dumper); // 1.root
12070 elastic_add_base_mapping(&dumper);
12071
12072 json_dumper_set_member_name(&dumper, "mappings");
12073 json_dumper_begin_object(&dumper); // 2.mappings
12074
12075 json_dumper_set_member_name(&dumper, "properties");
12076 json_dumper_begin_object(&dumper); // 3.properties
12077 json_dumper_set_member_name(&dumper, "timestamp");
12078 json_dumper_begin_object(&dumper); // 4.timestamp
12079 json_dumper_set_member_name(&dumper, "type");
12080 json_dumper_value_string(&dumper, "date");
12081 json_dumper_end_object(&dumper); // 4.timestamp
12082
12083 json_dumper_set_member_name(&dumper, "layers");
12084 json_dumper_begin_object(&dumper); // 4.layers
12085 json_dumper_set_member_name(&dumper, "properties");
12086 json_dumper_begin_object(&dumper); // 5.properties
12087
12088 for (i = 0; i < gpa_hfinfo.len; i++) {
12089 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12090 continue; /* This is a deregistered protocol or header field */
12091
12092 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", 12092
, __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", 12092
, "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", 12092, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12093
12094 /*
12095 * Skip the pseudo-field for "proto_tree_add_text()" since
12096 * we don't want it in the list of filterable protocols.
12097 */
12098 if (hfinfo->id == hf_text_only)
12099 continue;
12100
12101 if (!proto_registrar_is_protocol(i)) {
12102 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", 12102
, __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", 12102
, "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", 12102
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12103
12104 /*
12105 * Skip the field if filter protocols have been set and this one's
12106 * parent is not listed.
12107 */
12108 if (protos) {
12109 found = false0;
12110 j = 0;
12111 proto = protos[0];
12112 while(proto) {
12113 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12114 found = true1;
12115 break;
12116 }
12117 j++;
12118 proto = protos[j];
12119 }
12120 if (!found)
12121 continue;
12122 }
12123
12124 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12125 json_dumper_end_object(&dumper); // 7.properties
12126 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12127 open_object = true1;
12128 }
12129
12130 prev_proto = parent_hfinfo->abbrev;
12131
12132 if (open_object) {
12133 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12134 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12135 json_dumper_set_member_name(&dumper, "properties");
12136 json_dumper_begin_object(&dumper); // 7.properties
12137 open_object = false0;
12138 }
12139 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12140 type = ws_type_to_elastic(hfinfo->type);
12141 /* when type is NULL, we have the default mapping: string */
12142 if (type) {
12143 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12144 dot_to_underscore(str);
12145 if (g_strcmp0(prev_item, str)) {
12146 json_dumper_set_member_name(&dumper, str);
12147 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12148 json_dumper_set_member_name(&dumper, "type");
12149 json_dumper_value_string(&dumper, type);
12150 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12151 }
12152 g_free(prev_item);
12153 prev_item = str;
12154 }
12155 }
12156 }
12157 g_free(prev_item);
12158
12159 if (prev_proto) {
12160 json_dumper_end_object(&dumper); // 7.properties
12161 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12162 }
12163
12164 json_dumper_end_object(&dumper); // 5.properties
12165 json_dumper_end_object(&dumper); // 4.layers
12166 json_dumper_end_object(&dumper); // 3.properties
12167 json_dumper_end_object(&dumper); // 2.mappings
12168 json_dumper_end_object(&dumper); // 1.root
12169 bool_Bool ret = json_dumper_finish(&dumper);
12170 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12170, "ret"))))
;
12171
12172 g_strfreev(protos);
12173}
12174
12175/* Dumps the contents of the registration database to stdout. An independent
12176 * program can take this output and format it into nice tables or HTML or
12177 * whatever.
12178 *
12179 * There is one record per line. Each record is either a protocol or a header
12180 * field, differentiated by the first field. The fields are tab-delimited.
12181 *
12182 * Protocols
12183 * ---------
12184 * Field 1 = 'P'
12185 * Field 2 = descriptive protocol name
12186 * Field 3 = protocol abbreviation
12187 *
12188 * Header Fields
12189 * -------------
12190 * Field 1 = 'F'
12191 * Field 2 = descriptive field name
12192 * Field 3 = field abbreviation
12193 * Field 4 = type ( textual representation of the ftenum type )
12194 * Field 5 = parent protocol abbreviation
12195 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12196 * Field 7 = bitmask: format: hex: 0x....
12197 * Field 8 = blurb describing field
12198 */
12199void
12200proto_registrar_dump_fields(void)
12201{
12202 header_field_info *hfinfo, *parent_hfinfo;
12203 int i, len;
12204 const char *enum_name;
12205 const char *base_name;
12206 const char *blurb;
12207 char width[5];
12208
12209 len = gpa_hfinfo.len;
12210 for (i = 0; i < len ; i++) {
12211 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12212 continue; /* This is a deregistered protocol or header field */
12213
12214 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", 12214
, __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", 12214
, "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", 12214, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12215
12216 /*
12217 * Skip the pseudo-field for "proto_tree_add_text()" since
12218 * we don't want it in the list of filterable fields.
12219 */
12220 if (hfinfo->id == hf_text_only)
12221 continue;
12222
12223 /* format for protocols */
12224 if (proto_registrar_is_protocol(i)) {
12225 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12226 }
12227 /* format for header fields */
12228 else {
12229 /*
12230 * If this field isn't at the head of the list of
12231 * fields with this name, skip this field - all
12232 * fields with the same name are really just versions
12233 * of the same field stored in different bits, and
12234 * should have the same type/radix/value list, and
12235 * just differ in their bit masks. (If a field isn't
12236 * a bitfield, but can be, say, 1 or 2 bytes long,
12237 * it can just be made FT_UINT16, meaning the
12238 * *maximum* length is 2 bytes, and be used
12239 * for all lengths.)
12240 */
12241 if (hfinfo->same_name_prev_id != -1)
12242 continue;
12243
12244 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", 12244
, __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", 12244
, "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", 12244
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12245
12246 enum_name = ftype_name(hfinfo->type);
12247 base_name = "";
12248
12249 if (hfinfo->type == FT_CHAR ||
12250 hfinfo->type == FT_UINT8 ||
12251 hfinfo->type == FT_UINT16 ||
12252 hfinfo->type == FT_UINT24 ||
12253 hfinfo->type == FT_UINT32 ||
12254 hfinfo->type == FT_UINT40 ||
12255 hfinfo->type == FT_UINT48 ||
12256 hfinfo->type == FT_UINT56 ||
12257 hfinfo->type == FT_UINT64 ||
12258 hfinfo->type == FT_INT8 ||
12259 hfinfo->type == FT_INT16 ||
12260 hfinfo->type == FT_INT24 ||
12261 hfinfo->type == FT_INT32 ||
12262 hfinfo->type == FT_INT40 ||
12263 hfinfo->type == FT_INT48 ||
12264 hfinfo->type == FT_INT56 ||
12265 hfinfo->type == FT_INT64) {
12266
12267 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12268 case BASE_NONE:
12269 case BASE_DEC:
12270 case BASE_HEX:
12271 case BASE_OCT:
12272 case BASE_DEC_HEX:
12273 case BASE_HEX_DEC:
12274 case BASE_CUSTOM:
12275 case BASE_PT_UDP:
12276 case BASE_PT_TCP:
12277 case BASE_PT_DCCP:
12278 case BASE_PT_SCTP:
12279 case BASE_OUI:
12280 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12281 break;
12282 default:
12283 base_name = "????";
12284 break;
12285 }
12286 } else if (hfinfo->type == FT_BOOLEAN) {
12287 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12288 snprintf(width, sizeof(width), "%d", hfinfo->display);
12289 base_name = width;
12290 }
12291
12292 blurb = hfinfo->blurb;
12293 if (blurb == NULL((void*)0))
12294 blurb = "";
12295 else if (strlen(blurb) == 0)
12296 blurb = "\"\"";
12297
12298 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12299 hfinfo->name, hfinfo->abbrev, enum_name,
12300 parent_hfinfo->abbrev, base_name,
12301 hfinfo->bitmask, blurb);
12302 }
12303 }
12304}
12305
12306/* Dumps all abbreviated field and protocol completions of the given string to
12307 * stdout. An independent program may use this for command-line tab completion
12308 * of fields.
12309 */
12310bool_Bool
12311proto_registrar_dump_field_completions(const char *prefix)
12312{
12313 header_field_info *hfinfo;
12314 int i, len;
12315 size_t prefix_len;
12316 bool_Bool matched = false0;
12317
12318 prefix_len = strlen(prefix);
12319 len = gpa_hfinfo.len;
12320 for (i = 0; i < len ; i++) {
12321 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12322 continue; /* This is a deregistered protocol or header field */
12323
12324 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", 12324
, __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", 12324
, "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", 12324, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12325
12326 /*
12327 * Skip the pseudo-field for "proto_tree_add_text()" since
12328 * we don't want it in the list of filterable fields.
12329 */
12330 if (hfinfo->id == hf_text_only)
12331 continue;
12332
12333 /* format for protocols */
12334 if (proto_registrar_is_protocol(i)) {
12335 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12336 matched = true1;
12337 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12338 }
12339 }
12340 /* format for header fields */
12341 else {
12342 /*
12343 * If this field isn't at the head of the list of
12344 * fields with this name, skip this field - all
12345 * fields with the same name are really just versions
12346 * of the same field stored in different bits, and
12347 * should have the same type/radix/value list, and
12348 * just differ in their bit masks. (If a field isn't
12349 * a bitfield, but can be, say, 1 or 2 bytes long,
12350 * it can just be made FT_UINT16, meaning the
12351 * *maximum* length is 2 bytes, and be used
12352 * for all lengths.)
12353 */
12354 if (hfinfo->same_name_prev_id != -1)
12355 continue;
12356
12357 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12358 matched = true1;
12359 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12360 }
12361 }
12362 }
12363 return matched;
12364}
12365
12366/* Dumps field types and descriptive names to stdout. An independent
12367 * program can take this output and format it into nice tables or HTML or
12368 * whatever.
12369 *
12370 * There is one record per line. The fields are tab-delimited.
12371 *
12372 * Field 1 = field type name, e.g. FT_UINT8
12373 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12374 */
12375void
12376proto_registrar_dump_ftypes(void)
12377{
12378 int fte;
12379
12380 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12381 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12382 }
12383}
12384
12385/* This function indicates whether it's possible to construct a
12386 * "match selected" display filter string for the specified field,
12387 * returns an indication of whether it's possible, and, if it's
12388 * possible and "filter" is non-null, constructs the filter and
12389 * sets "*filter" to point to it.
12390 * You do not need to [g_]free() this string since it will be automatically
12391 * freed once the next packet is dissected.
12392 */
12393static bool_Bool
12394construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12395 char **filter)
12396{
12397 const header_field_info *hfinfo;
12398 char *ptr;
12399 int buf_len;
12400 int i;
12401 int start, length, length_remaining;
12402 uint8_t c;
12403
12404 if (!finfo)
12405 return false0;
12406
12407 hfinfo = finfo->hfinfo;
12408 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12408, "hfinfo"))))
;
12409
12410 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12411 * then "the numeric value ... is not used when preparing
12412 * filters for the field in question." If it's any other
12413 * base, we'll generate the filter normally (which will
12414 * be numeric, even though the human-readable string does
12415 * work for filtering.)
12416 *
12417 * XXX - It might be nice to use fvalue_to_string_repr() in
12418 * "proto_item_fill_label()" as well, although, there, you'd
12419 * have to deal with the base *and* with resolved values for
12420 * addresses.
12421 *
12422 * Perhaps in addition to taking the repr type (DISPLAY
12423 * or DFILTER) and the display (base), fvalue_to_string_repr()
12424 * should have the the "strings" values in the header_field_info
12425 * structure for the field as a parameter, so it can have
12426 * if the field is Boolean or an enumerated integer type,
12427 * the tables used to generate human-readable values.
12428 */
12429 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12430 const char *str = NULL((void*)0);
12431
12432 switch (hfinfo->type) {
12433
12434 case FT_INT8:
12435 case FT_INT16:
12436 case FT_INT24:
12437 case FT_INT32:
12438 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12439 break;
12440
12441 case FT_CHAR:
12442 case FT_UINT8:
12443 case FT_UINT16:
12444 case FT_UINT24:
12445 case FT_UINT32:
12446 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12447 break;
12448
12449 default:
12450 break;
12451 }
12452
12453 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12454 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12455 return true1;
12456 }
12457 }
12458
12459 switch (hfinfo->type) {
12460
12461 case FT_PROTOCOL:
12462 if (filter != NULL((void*)0))
12463 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12464 break;
12465
12466 case FT_NONE:
12467 /*
12468 * If the length is 0, just match the name of the
12469 * field.
12470 *
12471 * (Also check for negative values, just in case,
12472 * as we'll cast it to an unsigned value later.)
12473 */
12474 length = finfo->length;
12475 if (length == 0) {
12476 if (filter != NULL((void*)0))
12477 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12478 break;
12479 }
12480 if (length < 0)
12481 return false0;
12482
12483 /*
12484 * This doesn't have a value, so we'd match
12485 * on the raw bytes at this address.
12486 *
12487 * Should we be allowed to access to the raw bytes?
12488 * If "edt" is NULL, the answer is "no".
12489 */
12490 if (edt == NULL((void*)0))
12491 return false0;
12492
12493 /*
12494 * Is this field part of the raw frame tvbuff?
12495 * If not, we can't use "frame[N:M]" to match
12496 * it.
12497 *
12498 * XXX - should this be frame-relative, or
12499 * protocol-relative?
12500 *
12501 * XXX - does this fallback for non-registered
12502 * fields even make sense?
12503 */
12504 if (finfo->ds_tvb != edt->tvb)
12505 return false0; /* you lose */
12506
12507 /*
12508 * Don't go past the end of that tvbuff.
12509 */
12510 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12511 if (length > length_remaining)
12512 length = length_remaining;
12513 if (length <= 0)
12514 return false0;
12515
12516 if (filter != NULL((void*)0)) {
12517 start = finfo->start;
12518 buf_len = 32 + length * 3;
12519 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12520 ptr = *filter;
12521
12522 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12523 "frame[%d:%d] == ", finfo->start, length);
12524 for (i=0; i<length; i++) {
12525 c = tvb_get_uint8(finfo->ds_tvb, start);
12526 start++;
12527 if (i == 0 ) {
12528 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12529 }
12530 else {
12531 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12532 }
12533 }
12534 }
12535 break;
12536
12537 /* By default, use the fvalue's "to_string_repr" method. */
12538 default:
12539 if (filter != NULL((void*)0)) {
12540 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12541 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12542 wmem_free(NULL((void*)0), str);
12543 }
12544 break;
12545 }
12546
12547 return true1;
12548}
12549
12550/*
12551 * Returns true if we can do a "match selected" on the field, false
12552 * otherwise.
12553 */
12554bool_Bool
12555proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12556{
12557 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12558}
12559
12560/* This function attempts to construct a "match selected" display filter
12561 * string for the specified field; if it can do so, it returns a pointer
12562 * to the string, otherwise it returns NULL.
12563 *
12564 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12565 */
12566char *
12567proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12568{
12569 char *filter = NULL((void*)0);
12570
12571 if (!construct_match_selected_string(finfo, edt, &filter))
12572 {
12573 wmem_free(NULL((void*)0), filter);
12574 return NULL((void*)0);
12575 }
12576 return filter;
12577}
12578
12579/* This function is common code for all proto_tree_add_bitmask... functions.
12580 */
12581
12582static bool_Bool
12583proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12584 const int len, const int ett, int * const *fields,
12585 const int flags, bool_Bool first,
12586 bool_Bool use_parent_tree,
12587 proto_tree* tree, uint64_t value)
12588{
12589 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12590 uint64_t bitmask = 0;
12591 uint64_t tmpval;
12592 header_field_info *hf;
12593 uint32_t integer32;
12594 int bit_offset;
12595 int no_of_bits;
12596
12597 if (!*fields)
12598 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"
)
;
12599
12600 if (len < 0 || len > 8)
12601 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12602 /**
12603 * packet-frame.c uses len=0 since the value is taken from the packet
12604 * metadata, not the packet bytes. In that case, assume that all bits
12605 * in the provided value are valid.
12606 */
12607 if (len > 0) {
12608 available_bits >>= (8 - (unsigned)len)*8;
12609 }
12610
12611 if (use_parent_tree == false0)
12612 tree = proto_item_add_subtree(item, ett);
12613
12614 while (*fields) {
12615 uint64_t present_bits;
12616 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", 12616, __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", 12616
, "**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", 12616, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12617 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", 12617
, "hf->bitmask != 0", hf->abbrev))))
;
12618
12619 bitmask |= hf->bitmask;
12620
12621 /* Skip fields that aren't fully present */
12622 present_bits = available_bits & hf->bitmask;
12623 if (present_bits != hf->bitmask) {
12624 fields++;
12625 continue;
12626 }
12627
12628 switch (hf->type) {
12629 case FT_CHAR:
12630 case FT_UINT8:
12631 case FT_UINT16:
12632 case FT_UINT24:
12633 case FT_UINT32:
12634 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12635 break;
12636
12637 case FT_INT8:
12638 case FT_INT16:
12639 case FT_INT24:
12640 case FT_INT32:
12641 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12642 break;
12643
12644 case FT_UINT40:
12645 case FT_UINT48:
12646 case FT_UINT56:
12647 case FT_UINT64:
12648 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12649 break;
12650
12651 case FT_INT40:
12652 case FT_INT48:
12653 case FT_INT56:
12654 case FT_INT64:
12655 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12656 break;
12657
12658 case FT_BOOLEAN:
12659 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12660 break;
12661
12662 default:
12663 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))
12664 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))
12665 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))
12666 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))
;
12667 break;
12668 }
12669 if (flags & BMT_NO_APPEND0x01) {
12670 fields++;
12671 continue;
12672 }
12673 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12674
12675 /* XXX: README.developer and the comments have always defined
12676 * BMT_NO_INT as "only boolean flags are added to the title /
12677 * don't add non-boolean (integral) fields", but the
12678 * implementation has always added BASE_CUSTOM and fields with
12679 * value_strings, though not fields with unit_strings.
12680 * Possibly this is because some dissectors use a FT_UINT8
12681 * with a value_string for fields that should be a FT_BOOLEAN.
12682 */
12683 switch (hf->type) {
12684 case FT_CHAR:
12685 if (hf->display == BASE_CUSTOM) {
12686 char lbl[ITEM_LABEL_LENGTH240];
12687 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12688
12689 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12689, "fmtfunc"))))
;
12690 fmtfunc(lbl, (uint32_t) tmpval);
12691 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12692 hf->name, lbl);
12693 first = false0;
12694 }
12695 else if (hf->strings) {
12696 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12697 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12698 first = false0;
12699 }
12700 else if (!(flags & BMT_NO_INT0x02)) {
12701 char buf[32];
12702 const char *out;
12703
12704 if (!first) {
12705 proto_item_append_text(item, ", ");
12706 }
12707
12708 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12709 proto_item_append_text(item, "%s: %s", hf->name, out);
12710 first = false0;
12711 }
12712
12713 break;
12714
12715 case FT_UINT8:
12716 case FT_UINT16:
12717 case FT_UINT24:
12718 case FT_UINT32:
12719 if (hf->display == BASE_CUSTOM) {
12720 char lbl[ITEM_LABEL_LENGTH240];
12721 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12722
12723 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12723, "fmtfunc"))))
;
12724 fmtfunc(lbl, (uint32_t) tmpval);
12725 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12726 hf->name, lbl);
12727 first = false0;
12728 }
12729 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12730 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12731 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12732 first = false0;
12733 }
12734 else if (!(flags & BMT_NO_INT0x02)) {
12735 char buf[NUMBER_LABEL_LENGTH80];
12736 const char *out = NULL((void*)0);
12737
12738 if (!first) {
12739 proto_item_append_text(item, ", ");
12740 }
12741
12742 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12743 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12744 }
12745 if (out == NULL((void*)0)) {
12746 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12747 }
12748 proto_item_append_text(item, "%s: %s", hf->name, out);
12749 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12750 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12751 }
12752 first = false0;
12753 }
12754
12755 break;
12756
12757 case FT_INT8:
12758 case FT_INT16:
12759 case FT_INT24:
12760 case FT_INT32:
12761 integer32 = (uint32_t) tmpval;
12762 if (hf->bitmask) {
12763 no_of_bits = ws_count_ones(hf->bitmask);
12764 integer32 = ws_sign_ext32(integer32, no_of_bits);
12765 }
12766 if (hf->display == BASE_CUSTOM) {
12767 char lbl[ITEM_LABEL_LENGTH240];
12768 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12769
12770 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12770, "fmtfunc"))))
;
12771 fmtfunc(lbl, (int32_t) integer32);
12772 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12773 hf->name, lbl);
12774 first = false0;
12775 }
12776 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12777 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12778 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12779 first = false0;
12780 }
12781 else if (!(flags & BMT_NO_INT0x02)) {
12782 char buf[NUMBER_LABEL_LENGTH80];
12783 const char *out = NULL((void*)0);
12784
12785 if (!first) {
12786 proto_item_append_text(item, ", ");
12787 }
12788
12789 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12790 out = hf_try_val_to_str((int32_t) integer32, hf);
12791 }
12792 if (out == NULL((void*)0)) {
12793 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12794 }
12795 proto_item_append_text(item, "%s: %s", hf->name, out);
12796 if (hf->display & BASE_UNIT_STRING0x00001000) {
12797 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12798 }
12799 first = false0;
12800 }
12801
12802 break;
12803
12804 case FT_UINT40:
12805 case FT_UINT48:
12806 case FT_UINT56:
12807 case FT_UINT64:
12808 if (hf->display == BASE_CUSTOM) {
12809 char lbl[ITEM_LABEL_LENGTH240];
12810 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12811
12812 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12812, "fmtfunc"))))
;
12813 fmtfunc(lbl, tmpval);
12814 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12815 hf->name, lbl);
12816 first = false0;
12817 }
12818 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12819 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12820 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12821 first = false0;
12822 }
12823 else if (!(flags & BMT_NO_INT0x02)) {
12824 char buf[NUMBER_LABEL_LENGTH80];
12825 const char *out = NULL((void*)0);
12826
12827 if (!first) {
12828 proto_item_append_text(item, ", ");
12829 }
12830
12831 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12832 out = hf_try_val64_to_str(tmpval, hf);
12833 }
12834 if (out == NULL((void*)0)) {
12835 out = hfinfo_number_value_format64(hf, buf, tmpval);
12836 }
12837 proto_item_append_text(item, "%s: %s", hf->name, out);
12838 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12839 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12840 }
12841 first = false0;
12842 }
12843
12844 break;
12845
12846 case FT_INT40:
12847 case FT_INT48:
12848 case FT_INT56:
12849 case FT_INT64:
12850 if (hf->bitmask) {
12851 no_of_bits = ws_count_ones(hf->bitmask);
12852 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12853 }
12854 if (hf->display == BASE_CUSTOM) {
12855 char lbl[ITEM_LABEL_LENGTH240];
12856 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12857
12858 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12858, "fmtfunc"))))
;
12859 fmtfunc(lbl, (int64_t) tmpval);
12860 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12861 hf->name, lbl);
12862 first = false0;
12863 }
12864 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12865 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12866 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12867 first = false0;
12868 }
12869 else if (!(flags & BMT_NO_INT0x02)) {
12870 char buf[NUMBER_LABEL_LENGTH80];
12871 const char *out = NULL((void*)0);
12872
12873 if (!first) {
12874 proto_item_append_text(item, ", ");
12875 }
12876
12877 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12878 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12879 }
12880 if (out == NULL((void*)0)) {
12881 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12882 }
12883 proto_item_append_text(item, "%s: %s", hf->name, out);
12884 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12885 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12886 }
12887 first = false0;
12888 }
12889
12890 break;
12891
12892 case FT_BOOLEAN:
12893 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12894 /* If we have true/false strings, emit full - otherwise messages
12895 might look weird */
12896 const struct true_false_string *tfs =
12897 (const struct true_false_string *)hf->strings;
12898
12899 if (tmpval) {
12900 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12901 hf->name, tfs->true_string);
12902 first = false0;
12903 } else if (!(flags & BMT_NO_FALSE0x04)) {
12904 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12905 hf->name, tfs->false_string);
12906 first = false0;
12907 }
12908 } else if (hf->bitmask & value) {
12909 /* If the flag is set, show the name */
12910 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12911 first = false0;
12912 }
12913 break;
12914 default:
12915 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))
12916 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))
12917 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))
12918 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))
;
12919 break;
12920 }
12921
12922 fields++;
12923 }
12924
12925 /* XXX: We don't pass the hfi into this function. Perhaps we should,
12926 * but then again most dissectors don't set the bitmask field for
12927 * the higher level bitmask hfi, so calculate the bitmask from the
12928 * fields present. */
12929 if (item) {
12930 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
12931 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
12932 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)
;
12933 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)
;
12934 }
12935 return first;
12936}
12937
12938/* This function will dissect a sequence of bytes that describe a
12939 * bitmask and supply the value of that sequence through a pointer.
12940 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12941 * to be dissected.
12942 * This field will form an expansion under which the individual fields of the
12943 * bitmask is dissected and displayed.
12944 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12945 *
12946 * fields is an array of pointers to int that lists all the fields of the
12947 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12948 * or another integer of the same type/size as hf_hdr with a mask specified.
12949 * This array is terminated by a NULL entry.
12950 *
12951 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12952 * FT_integer fields that have a value_string attached will have the
12953 * matched string displayed on the expansion line.
12954 */
12955proto_item *
12956proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
12957 const unsigned offset, const int hf_hdr,
12958 const int ett, int * const *fields,
12959 const unsigned encoding, uint64_t *retval)
12960{
12961 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);
12962}
12963
12964/* This function will dissect a sequence of bytes that describe a
12965 * bitmask.
12966 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12967 * to be dissected.
12968 * This field will form an expansion under which the individual fields of the
12969 * bitmask is dissected and displayed.
12970 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12971 *
12972 * fields is an array of pointers to int that lists all the fields of the
12973 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12974 * or another integer of the same type/size as hf_hdr with a mask specified.
12975 * This array is terminated by a NULL entry.
12976 *
12977 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12978 * FT_integer fields that have a value_string attached will have the
12979 * matched string displayed on the expansion line.
12980 */
12981proto_item *
12982proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
12983 const unsigned offset, const int hf_hdr,
12984 const int ett, int * const *fields,
12985 const unsigned encoding)
12986{
12987 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
12988}
12989
12990/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12991 * what data is appended to the header.
12992 */
12993proto_item *
12994proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12995 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
12996 uint64_t *retval)
12997{
12998 proto_item *item = NULL((void*)0);
12999 header_field_info *hf;
13000 int len;
13001 uint64_t value;
13002
13003 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", 13003, __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", 13003
, "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", 13003, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13004 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", 13004, (hf)->abbrev)))
;
13005 len = ftype_wire_size(hf->type);
13006 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13007
13008 if (parent_tree) {
13009 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13010 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13011 flags, false0, false0, NULL((void*)0), value);
13012 }
13013
13014 *retval = value;
13015 if (hf->bitmask) {
13016 /* Mask out irrelevant portions */
13017 *retval &= hf->bitmask;
13018 /* Shift bits */
13019 *retval >>= hfinfo_bitshift(hf);
13020 }
13021
13022 return item;
13023}
13024
13025/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13026 * what data is appended to the header.
13027 */
13028proto_item *
13029proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13030 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13031{
13032 proto_item *item = NULL((void*)0);
13033 header_field_info *hf;
13034 int len;
13035 uint64_t value;
13036
13037 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", 13037, __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", 13037
, "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", 13037, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13038 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", 13038, (hf)->abbrev)))
;
13039
13040 if (parent_tree) {
13041 len = ftype_wire_size(hf->type);
13042 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13043 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13044 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13045 flags, false0, false0, NULL((void*)0), value);
13046 }
13047
13048 return item;
13049}
13050
13051/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13052 can't be retrieved directly from tvb) */
13053proto_item *
13054proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13055 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13056{
13057 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13058 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13059}
13060
13061/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13062WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13063proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13064 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13065{
13066 proto_item *item = NULL((void*)0);
13067 header_field_info *hf;
13068 int len;
13069
13070 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", 13070, __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", 13070
, "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", 13070, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13071 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", 13071, (hf)->abbrev)))
;
13072 /* the proto_tree_add_uint/_uint64() calls below
13073 will fail if tvb==NULL and len!=0 */
13074 len = tvb ? ftype_wire_size(hf->type) : 0;
13075
13076 if (parent_tree) {
13077 if (len <= 4)
13078 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13079 else
13080 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13081
13082 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13083 flags, false0, false0, NULL((void*)0), value);
13084 }
13085
13086 return item;
13087}
13088
13089/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13090void
13091proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13092 const int len, int * const *fields, const unsigned encoding)
13093{
13094 uint64_t value;
13095
13096 if (tree) {
13097 value = get_uint64_value(tree, tvb, offset, len, encoding);
13098 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13099 BMT_NO_APPEND0x01, false0, true1, tree, value);
13100 }
13101}
13102
13103WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13104proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13105 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13106{
13107 uint64_t value;
13108
13109 value = get_uint64_value(tree, tvb, offset, len, encoding);
13110 if (tree) {
13111 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13112 BMT_NO_APPEND0x01, false0, true1, tree, value);
13113 }
13114 if (retval) {
13115 *retval = value;
13116 }
13117}
13118
13119WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13120proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13121 const int len, int * const *fields, const uint64_t value)
13122{
13123 if (tree) {
13124 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13125 BMT_NO_APPEND0x01, false0, true1, tree, value);
13126 }
13127}
13128
13129
13130/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13131 * This is intended to support bitmask fields whose lengths can vary, perhaps
13132 * as the underlying standard evolves over time.
13133 * With this API there is the possibility of being called to display more or
13134 * less data than the dissector was coded to support.
13135 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13136 * Thus when presented with "too much" or "too little" data, MSbits will be
13137 * ignored or MSfields sacrificed.
13138 *
13139 * Only fields for which all defined bits are available are displayed.
13140 */
13141proto_item *
13142proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13143 const unsigned offset, const unsigned len, const int hf_hdr,
13144 const int ett, int * const *fields, struct expert_field* exp,
13145 const unsigned encoding)
13146{
13147 proto_item *item = NULL((void*)0);
13148 header_field_info *hf;
13149 unsigned decodable_len;
13150 unsigned decodable_offset;
13151 uint32_t decodable_value;
13152 uint64_t value;
13153
13154 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", 13154, __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", 13154
, "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", 13154, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13155 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", 13155, (hf)->abbrev)))
;
13156
13157 decodable_offset = offset;
13158 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13159
13160 /* If we are ftype_wire_size-limited,
13161 * make sure we decode as many LSBs as possible.
13162 */
13163 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13164 decodable_offset += (len - decodable_len);
13165 }
13166
13167 if (parent_tree) {
13168 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13169 decodable_len, encoding);
13170
13171 /* The root item covers all the bytes even if we can't decode them all */
13172 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13173 decodable_value);
13174 }
13175
13176 if (decodable_len < len) {
13177 /* Dissector likely requires updating for new protocol revision */
13178 expert_add_info_format(NULL((void*)0), item, exp,
13179 "Only least-significant %d of %d bytes decoded",
13180 decodable_len, len);
13181 }
13182
13183 if (item) {
13184 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13185 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13186 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13187 }
13188
13189 return item;
13190}
13191
13192/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13193proto_item *
13194proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13195 const unsigned offset, const unsigned len,
13196 const char *name, const char *fallback,
13197 const int ett, int * const *fields,
13198 const unsigned encoding, const int flags)
13199{
13200 proto_item *item = NULL((void*)0);
13201 uint64_t value;
13202
13203 if (parent_tree) {
13204 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13205 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13206 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13207 flags, true1, false0, NULL((void*)0), value) && fallback) {
13208 /* Still at first item - append 'fallback' text if any */
13209 proto_item_append_text(item, "%s", fallback);
13210 }
13211 }
13212
13213 return item;
13214}
13215
13216proto_item *
13217proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13218 const unsigned bit_offset, const int no_of_bits,
13219 const unsigned encoding)
13220{
13221 header_field_info *hfinfo;
13222 int octet_length;
13223 int octet_offset;
13224
13225 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", 13225, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13225
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13225, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13226
13227 if (no_of_bits < 0) {
13228 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13229 }
13230 octet_length = (no_of_bits + 7) >> 3;
13231 octet_offset = bit_offset >> 3;
13232 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13233
13234 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13235 * but only after doing a bunch more work (which we can, in the common
13236 * case, shortcut here).
13237 */
13238 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13239 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", 13239
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13239, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13239, "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", 13239, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13240
13241 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13242}
13243
13244/*
13245 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13246 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13247 * Offset should be given in bits from the start of the tvb.
13248 */
13249
13250static proto_item *
13251_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13252 const unsigned bit_offset, const int no_of_bits,
13253 uint64_t *return_value, const unsigned encoding)
13254{
13255 int offset;
13256 unsigned length;
13257 uint8_t tot_no_bits;
13258 char *bf_str;
13259 char lbl_str[ITEM_LABEL_LENGTH240];
13260 uint64_t value = 0;
13261 uint8_t *bytes = NULL((void*)0);
13262 size_t bytes_length = 0;
13263
13264 proto_item *pi;
13265 header_field_info *hf_field;
13266
13267 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13268 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", 13268, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13268
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13268, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13269
13270 if (hf_field->bitmask != 0) {
13271 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)
13272 " 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)
13273 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)
;
13274 }
13275
13276 if (no_of_bits < 0) {
13277 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13278 } else if (no_of_bits == 0) {
13279 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)
13280 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)
;
13281 }
13282
13283 /* Byte align offset */
13284 offset = bit_offset>>3;
13285
13286 /*
13287 * Calculate the number of octets used to hold the bits
13288 */
13289 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13290 length = (tot_no_bits + 7) >> 3;
13291
13292 if (no_of_bits < 65) {
13293 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13294 } else if (hf_field->type != FT_BYTES) {
13295 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)
13296 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)
;
13297 return NULL((void*)0);
13298 }
13299
13300 /* Sign extend for signed types */
13301 switch (hf_field->type) {
13302 case FT_INT8:
13303 case FT_INT16:
13304 case FT_INT24:
13305 case FT_INT32:
13306 case FT_INT40:
13307 case FT_INT48:
13308 case FT_INT56:
13309 case FT_INT64:
13310 value = ws_sign_ext64(value, no_of_bits);
13311 break;
13312
13313 default:
13314 break;
13315 }
13316
13317 if (return_value) {
13318 *return_value = value;
13319 }
13320
13321 /* Coast clear. Try and fake it */
13322 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13323 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", 13323
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13323, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13323, "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", 13323, __func__, "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); } } }
;
13324
13325 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13326
13327 switch (hf_field->type) {
13328 case FT_BOOLEAN:
13329 /* Boolean field */
13330 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13331 "%s = %s: %s",
13332 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13333 break;
13334
13335 case FT_CHAR:
13336 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13337 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13338 break;
13339
13340 case FT_UINT8:
13341 case FT_UINT16:
13342 case FT_UINT24:
13343 case FT_UINT32:
13344 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13345 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13346 break;
13347
13348 case FT_INT8:
13349 case FT_INT16:
13350 case FT_INT24:
13351 case FT_INT32:
13352 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13353 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13354 break;
13355
13356 case FT_UINT40:
13357 case FT_UINT48:
13358 case FT_UINT56:
13359 case FT_UINT64:
13360 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13361 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13362 break;
13363
13364 case FT_INT40:
13365 case FT_INT48:
13366 case FT_INT56:
13367 case FT_INT64:
13368 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13369 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13370 break;
13371
13372 case FT_BYTES:
13373 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13374 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13375 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13376 proto_item_set_text(pi, "%s", lbl_str);
13377 return pi;
13378
13379 /* TODO: should handle FT_UINT_BYTES ? */
13380
13381 default:
13382 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))
13383 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))
13384 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))
13385 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))
;
13386 return NULL((void*)0);
13387 }
13388
13389 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13390 return pi;
13391}
13392
13393proto_item *
13394proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13395 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13396 uint64_t *return_value)
13397{
13398 proto_item *pi;
13399 int no_of_bits;
13400 int octet_offset;
13401 unsigned mask_initial_bit_offset;
13402 unsigned mask_greatest_bit_offset;
13403 unsigned octet_length;
13404 uint8_t i;
13405 char bf_str[256];
13406 char lbl_str[ITEM_LABEL_LENGTH240];
13407 uint64_t value;
13408 uint64_t composite_bitmask;
13409 uint64_t composite_bitmap;
13410
13411 header_field_info *hf_field;
13412
13413 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13414 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", 13414, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13414
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13414, "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
13415
13416 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13417 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)
13418 " 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)
13419 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)
;
13420 }
13421
13422 mask_initial_bit_offset = bit_offset % 8;
13423
13424 no_of_bits = 0;
13425 value = 0;
13426 i = 0;
13427 mask_greatest_bit_offset = 0;
13428 composite_bitmask = 0;
13429 composite_bitmap = 0;
13430
13431 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
13432 uint64_t crumb_mask, crumb_value;
13433 uint8_t crumb_end_bit_offset;
13434
13435 crumb_value = tvb_get_bits64(tvb,
13436 bit_offset + crumb_spec[i].crumb_bit_offset,
13437 crumb_spec[i].crumb_bit_length,
13438 ENC_BIG_ENDIAN0x00000000);
13439 value += crumb_value;
13440 no_of_bits += crumb_spec[i].crumb_bit_length;
13441 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", 13441
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13442
13443 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13444 octet containing the initial offset.
13445 If the mask is beyond 32 bits, then give up on bit map display.
13446 This could be improved in future, probably showing a table
13447 of 32 or 64 bits per row */
13448 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13449 crumb_end_bit_offset = mask_initial_bit_offset
13450 + crumb_spec[i].crumb_bit_offset
13451 + crumb_spec[i].crumb_bit_length;
13452 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'
13453
13454 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13455 mask_greatest_bit_offset = crumb_end_bit_offset;
13456 }
13457 /* Currently the bitmap of the crumbs are only shown if
13458 * smaller than 32 bits. Do not bother calculating the
13459 * mask if it is larger than that. */
13460 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13461 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'
13462 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13463 }
13464 }
13465 /* Shift left for the next segment */
13466 value <<= crumb_spec[++i].crumb_bit_length;
13467 }
13468
13469 /* Sign extend for signed types */
13470 switch (hf_field->type) {
13471 case FT_INT8:
13472 case FT_INT16:
13473 case FT_INT24:
13474 case FT_INT32:
13475 case FT_INT40:
13476 case FT_INT48:
13477 case FT_INT56:
13478 case FT_INT64:
13479 value = ws_sign_ext64(value, no_of_bits);
13480 break;
13481 default:
13482 break;
13483 }
13484
13485 if (return_value) {
13486 *return_value = value;
13487 }
13488
13489 /* Coast clear. Try and fake it */
13490 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13491 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", 13491
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13491, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13491, "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", 13491, __func__, "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); } } }
;
13492
13493 /* initialise the format string */
13494 bf_str[0] = '\0';
13495
13496 octet_offset = bit_offset >> 3;
13497
13498 /* Round up mask length to nearest octet */
13499 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13500 mask_greatest_bit_offset = octet_length << 3;
13501
13502 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13503 It would be a useful enhancement to eliminate this restriction. */
13504 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13505 other_decode_bitfield_value(bf_str,
13506 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13507 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13508 mask_greatest_bit_offset);
13509 } else {
13510 /* If the bitmask is too large, try to describe its contents. */
13511 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13512 }
13513
13514 switch (hf_field->type) {
13515 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13516 /* Boolean field */
13517 return proto_tree_add_boolean_format(tree, hfindex,
13518 tvb, octet_offset, octet_length, value,
13519 "%s = %s: %s",
13520 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13521 break;
13522
13523 case FT_CHAR:
13524 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13525 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13526 break;
13527
13528 case FT_UINT8:
13529 case FT_UINT16:
13530 case FT_UINT24:
13531 case FT_UINT32:
13532 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13533 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13534 break;
13535
13536 case FT_INT8:
13537 case FT_INT16:
13538 case FT_INT24:
13539 case FT_INT32:
13540 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13541 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13542 break;
13543
13544 case FT_UINT40:
13545 case FT_UINT48:
13546 case FT_UINT56:
13547 case FT_UINT64:
13548 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13549 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13550 break;
13551
13552 case FT_INT40:
13553 case FT_INT48:
13554 case FT_INT56:
13555 case FT_INT64:
13556 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13557 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13558 break;
13559
13560 default:
13561 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))
13562 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))
13563 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))
13564 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))
;
13565 return NULL((void*)0);
13566 }
13567 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13568 return pi;
13569}
13570
13571void
13572proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13573 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13574{
13575 header_field_info *hfinfo;
13576 int start = bit_offset >> 3;
13577 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13578
13579 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13580 * so that we can use the tree's memory scope in calculating the string */
13581 if (length == -1) {
13582 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13583 } else {
13584 tvb_ensure_bytes_exist(tvb, start, length);
13585 }
13586 if (!tree) return;
13587
13588 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", 13588, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13588
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13588, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13589 proto_tree_add_text_internal(tree, tvb, start, length,
13590 "%s crumb %d of %s (decoded above)",
13591 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13592 tvb_get_bits32(tvb,
13593 bit_offset,
13594 crumb_spec[crumb_index].crumb_bit_length,
13595 ENC_BIG_ENDIAN0x00000000),
13596 ENC_BIG_ENDIAN0x00000000),
13597 crumb_index,
13598 hfinfo->name);
13599}
13600
13601proto_item *
13602proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13603 const unsigned bit_offset, const int no_of_bits,
13604 uint64_t *return_value, const unsigned encoding)
13605{
13606 proto_item *item;
13607
13608 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13609 bit_offset, no_of_bits,
13610 return_value, encoding))) {
13611 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)
;
13612 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)
;
13613 }
13614 return item;
13615}
13616
13617static proto_item *
13618_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13619 tvbuff_t *tvb, const unsigned bit_offset,
13620 const int no_of_bits, void *value_ptr,
13621 const unsigned encoding, char *value_str)
13622{
13623 int offset;
13624 unsigned length;
13625 uint8_t tot_no_bits;
13626 char *str;
13627 uint64_t value = 0;
13628 header_field_info *hf_field;
13629
13630 /* We do not have to return a value, try to fake it as soon as possible */
13631 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13632 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", 13632
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13632, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13632, "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", 13632, __func__, "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); } } }
;
13633
13634 if (hf_field->bitmask != 0) {
13635 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)
13636 " 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)
13637 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)
;
13638 }
13639
13640 if (no_of_bits < 0) {
13641 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13642 } else if (no_of_bits == 0) {
13643 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)
13644 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)
;
13645 }
13646
13647 /* Byte align offset */
13648 offset = bit_offset>>3;
13649
13650 /*
13651 * Calculate the number of octets used to hold the bits
13652 */
13653 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13654 length = tot_no_bits>>3;
13655 /* If we are using part of the next octet, increase length by 1 */
13656 if (tot_no_bits & 0x07)
13657 length++;
13658
13659 if (no_of_bits < 65) {
13660 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13661 } else {
13662 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)
13663 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)
;
13664 return NULL((void*)0);
13665 }
13666
13667 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13668
13669 (void) g_strlcat(str, " = ", 256+64);
13670 (void) g_strlcat(str, hf_field->name, 256+64);
13671
13672 /*
13673 * This function does not receive an actual value but a dimensionless pointer to that value.
13674 * For this reason, the type of the header field is examined in order to determine
13675 * what kind of value we should read from this address.
13676 * The caller of this function must make sure that for the specific header field type the address of
13677 * a compatible value is provided.
13678 */
13679 switch (hf_field->type) {
13680 case FT_BOOLEAN:
13681 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13682 "%s: %s", str, value_str);
13683 break;
13684
13685 case FT_CHAR:
13686 case FT_UINT8:
13687 case FT_UINT16:
13688 case FT_UINT24:
13689 case FT_UINT32:
13690 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13691 "%s: %s", str, value_str);
13692 break;
13693
13694 case FT_UINT40:
13695 case FT_UINT48:
13696 case FT_UINT56:
13697 case FT_UINT64:
13698 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13699 "%s: %s", str, value_str);
13700 break;
13701
13702 case FT_INT8:
13703 case FT_INT16:
13704 case FT_INT24:
13705 case FT_INT32:
13706 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13707 "%s: %s", str, value_str);
13708 break;
13709
13710 case FT_INT40:
13711 case FT_INT48:
13712 case FT_INT56:
13713 case FT_INT64:
13714 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13715 "%s: %s", str, value_str);
13716 break;
13717
13718 case FT_FLOAT:
13719 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13720 "%s: %s", str, value_str);
13721 break;
13722
13723 default:
13724 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))
13725 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))
13726 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))
13727 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))
;
13728 return NULL((void*)0);
13729 }
13730}
13731
13732static proto_item *
13733proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13734 tvbuff_t *tvb, const unsigned bit_offset,
13735 const int no_of_bits, void *value_ptr,
13736 const unsigned encoding, char *value_str)
13737{
13738 proto_item *item;
13739
13740 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13741 tvb, bit_offset, no_of_bits,
13742 value_ptr, encoding, value_str))) {
13743 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)
;
13744 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)
;
13745 }
13746 return item;
13747}
13748
13749#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);
\
13750 va_start(ap, format)__builtin_va_start(ap, format); \
13751 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13752 va_end(ap)__builtin_va_end(ap);
13753
13754proto_item *
13755proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13756 tvbuff_t *tvb, const unsigned bit_offset,
13757 const int no_of_bits, uint32_t value,
13758 const unsigned encoding,
13759 const char *format, ...)
13760{
13761 va_list ap;
13762 char *dst;
13763 header_field_info *hf_field;
13764
13765 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13766
13767 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", 13767
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13767, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13767, "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", 13767, __func__, "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); } } }
;
13768
13769 switch (hf_field->type) {
13770 case FT_UINT8:
13771 case FT_UINT16:
13772 case FT_UINT24:
13773 case FT_UINT32:
13774 break;
13775
13776 default:
13777 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)
13778 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)
;
13779 return NULL((void*)0);
13780 }
13781
13782 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);
;
13783
13784 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13785}
13786
13787proto_item *
13788proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13789 tvbuff_t *tvb, const unsigned bit_offset,
13790 const int no_of_bits, uint64_t value,
13791 const unsigned encoding,
13792 const char *format, ...)
13793{
13794 va_list ap;
13795 char *dst;
13796 header_field_info *hf_field;
13797
13798 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13799
13800 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", 13800
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13800, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13800, "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", 13800, __func__, "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); } } }
;
13801
13802 switch (hf_field->type) {
13803 case FT_UINT40:
13804 case FT_UINT48:
13805 case FT_UINT56:
13806 case FT_UINT64:
13807 break;
13808
13809 default:
13810 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)
13811 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)
;
13812 return NULL((void*)0);
13813 }
13814
13815 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);
;
13816
13817 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13818}
13819
13820proto_item *
13821proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13822 tvbuff_t *tvb, const unsigned bit_offset,
13823 const int no_of_bits, float value,
13824 const unsigned encoding,
13825 const char *format, ...)
13826{
13827 va_list ap;
13828 char *dst;
13829 header_field_info *hf_field;
13830
13831 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13832
13833 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", 13833
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13833, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13833, "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", 13833, __func__, "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); } } }
;
13834
13835 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",
13835, ((hf_field))->abbrev))))
;
13836
13837 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);
;
13838
13839 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13840}
13841
13842proto_item *
13843proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13844 tvbuff_t *tvb, const unsigned bit_offset,
13845 const int no_of_bits, int32_t value,
13846 const unsigned encoding,
13847 const char *format, ...)
13848{
13849 va_list ap;
13850 char *dst;
13851 header_field_info *hf_field;
13852
13853 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13854
13855 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", 13855
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13855, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13855, "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", 13855, __func__, "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); } } }
;
13856
13857 switch (hf_field->type) {
13858 case FT_INT8:
13859 case FT_INT16:
13860 case FT_INT24:
13861 case FT_INT32:
13862 break;
13863
13864 default:
13865 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)
13866 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)
;
13867 return NULL((void*)0);
13868 }
13869
13870 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);
;
13871
13872 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13873}
13874
13875proto_item *
13876proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13877 tvbuff_t *tvb, const unsigned bit_offset,
13878 const int no_of_bits, int64_t value,
13879 const unsigned encoding,
13880 const char *format, ...)
13881{
13882 va_list ap;
13883 char *dst;
13884 header_field_info *hf_field;
13885
13886 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13887
13888 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", 13888
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13888, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13888, "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", 13888, __func__, "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); } } }
;
13889
13890 switch (hf_field->type) {
13891 case FT_INT40:
13892 case FT_INT48:
13893 case FT_INT56:
13894 case FT_INT64:
13895 break;
13896
13897 default:
13898 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)
13899 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)
;
13900 return NULL((void*)0);
13901 }
13902
13903 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);
;
13904
13905 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13906}
13907
13908proto_item *
13909proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13910 tvbuff_t *tvb, const unsigned bit_offset,
13911 const int no_of_bits, uint64_t value,
13912 const unsigned encoding,
13913 const char *format, ...)
13914{
13915 va_list ap;
13916 char *dst;
13917 header_field_info *hf_field;
13918
13919 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13920
13921 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", 13921
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13921, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13921, "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", 13921, __func__, "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); } } }
;
13922
13923 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"
, 13923, ((hf_field))->abbrev))))
;
13924
13925 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);
;
13926
13927 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13928}
13929
13930proto_item *
13931proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13932 const unsigned bit_offset, const int no_of_chars)
13933{
13934 proto_item *pi;
13935 header_field_info *hfinfo;
13936 int byte_length;
13937 int byte_offset;
13938 char *string;
13939
13940 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13941
13942 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", 13942
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13942, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13942, "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", 13942, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13943
13944 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"
, 13944, ((hfinfo))->abbrev))))
;
13945
13946 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13947 byte_offset = bit_offset >> 3;
13948
13949 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13950
13951 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13952 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13952, "byte_length >= 0"
))))
;
13953 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13954
13955 return pi;
13956}
13957
13958proto_item *
13959proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13960 const unsigned bit_offset, const int no_of_chars)
13961{
13962 proto_item *pi;
13963 header_field_info *hfinfo;
13964 int byte_length;
13965 int byte_offset;
13966 char *string;
13967
13968 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13969
13970 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", 13970
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13970, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13970, "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", 13970, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13971
13972 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"
, 13972, ((hfinfo))->abbrev))))
;
13973
13974 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13975 byte_offset = bit_offset >> 3;
13976
13977 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13978
13979 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13980 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13980, "byte_length >= 0"
))))
;
13981 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13982
13983 return pi;
13984}
13985
13986const value_string proto_checksum_vals[] = {
13987 { PROTO_CHECKSUM_E_BAD, "Bad" },
13988 { PROTO_CHECKSUM_E_GOOD, "Good" },
13989 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
13990 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
13991 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
13992
13993 { 0, NULL((void*)0) }
13994};
13995
13996proto_item *
13997proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13998 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
13999 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14000{
14001 header_field_info *hfinfo;
14002 uint32_t checksum;
14003 uint32_t len;
14004 proto_item* ti = NULL((void*)0);
14005 proto_item* ti2;
14006 bool_Bool incorrect_checksum = true1;
14007
14008 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", 14008, __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", 14008
, "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", 14008, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14009
14010 switch (hfinfo->type) {
14011 case FT_UINT8:
14012 len = 1;
14013 break;
14014 case FT_UINT16:
14015 len = 2;
14016 break;
14017 case FT_UINT24:
14018 len = 3;
14019 break;
14020 case FT_UINT32:
14021 len = 4;
14022 break;
14023 default:
14024 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)
14025 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14026 }
14027
14028 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14029 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14030 proto_item_set_generated(ti);
14031 if (hf_checksum_status != -1) {
14032 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14033 proto_item_set_generated(ti2);
14034 }
14035 return ti;
14036 }
14037
14038 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14039 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14040 proto_item_set_generated(ti);
14041 } else {
14042 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14043 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14044 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14045 if (computed_checksum == 0) {
14046 proto_item_append_text(ti, " [correct]");
14047 if (hf_checksum_status != -1) {
14048 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14049 proto_item_set_generated(ti2);
14050 }
14051 incorrect_checksum = false0;
14052 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14053 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14054 /* XXX - This can't distinguish between "shouldbe"
14055 * 0x0000 and 0xFFFF unless we know whether there
14056 * were any nonzero bits (other than the checksum).
14057 * Protocols should not use this path if they might
14058 * have an all zero packet.
14059 * Some implementations put the wrong zero; maybe
14060 * we should have a special expert info for that?
14061 */
14062 }
14063 } else {
14064 if (checksum == computed_checksum) {
14065 proto_item_append_text(ti, " [correct]");
14066 if (hf_checksum_status != -1) {
14067 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14068 proto_item_set_generated(ti2);
14069 }
14070 incorrect_checksum = false0;
14071 }
14072 }
14073
14074 if (incorrect_checksum) {
14075 if (hf_checksum_status != -1) {
14076 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14077 proto_item_set_generated(ti2);
14078 }
14079 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14080 proto_item_append_text(ti, " [incorrect]");
14081 if (bad_checksum_expert != NULL((void*)0))
14082 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14083 } else {
14084 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14085 if (bad_checksum_expert != NULL((void*)0))
14086 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);
14087 }
14088 }
14089 } else {
14090 if (hf_checksum_status != -1) {
14091 proto_item_append_text(ti, " [unverified]");
14092 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14093 proto_item_set_generated(ti2);
14094 }
14095 }
14096 }
14097
14098 return ti;
14099}
14100
14101proto_item *
14102proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14103 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14104 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14105{
14106 header_field_info *hfinfo;
14107 uint8_t *checksum = NULL((void*)0);
14108 proto_item* ti = NULL((void*)0);
14109 proto_item* ti2;
14110 bool_Bool incorrect_checksum = true1;
14111
14112 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", 14112, __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", 14112
, "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", 14112, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14113
14114 if (hfinfo->type != FT_BYTES) {
14115 REPORT_DISSECTOR_BUG("field %s is not of type FT_BYTES",proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
14116 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14117 }
14118
14119 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14120 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14121 proto_item_set_generated(ti);
14122 if (hf_checksum_status != -1) {
14123 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14124 proto_item_set_generated(ti2);
14125 }
14126 return ti;
14127 }
14128
14129 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14130 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14131 proto_item_set_generated(ti);
14132 } else {
14133 checksum = (uint8_t*)wmem_alloc0_array(pinfo->pool, uint8_t, checksum_len)((uint8_t*)wmem_alloc0((pinfo->pool), (((((checksum_len)) <=
0) || ((size_t)sizeof(uint8_t) > (9223372036854775807L / (
size_t)((checksum_len))))) ? 0 : (sizeof(uint8_t) * ((checksum_len
))))))
;
14134 tvb_memcpy(tvb, checksum, offset, checksum_len);
14135 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14136 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14137 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14138 if (computed_checksum == 0) {
14139 proto_item_append_text(ti, " [correct]");
14140 if (hf_checksum_status != -1) {
14141 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14142 proto_item_set_generated(ti2);
14143 }
14144 incorrect_checksum = false0;
14145 }
14146 } else {
14147 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14148 proto_item_append_text(ti, " [correct]");
14149 if (hf_checksum_status != -1) {
14150 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14151 proto_item_set_generated(ti2);
14152 }
14153 incorrect_checksum = false0;
14154 }
14155 }
14156
14157 if (incorrect_checksum) {
14158 if (hf_checksum_status != -1) {
14159 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14160 proto_item_set_generated(ti2);
14161 }
14162 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14163 proto_item_append_text(ti, " [incorrect]");
14164 if (bad_checksum_expert != NULL((void*)0))
14165 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14166 } else {
14167 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14168 char *computed_checksum_str = (char*)wmem_alloc0_array(pinfo->pool, char, computed_checksum_str_len)((char*)wmem_alloc0((pinfo->pool), (((((computed_checksum_str_len
)) <= 0) || ((size_t)sizeof(char) > (9223372036854775807L
/ (size_t)((computed_checksum_str_len))))) ? 0 : (sizeof(char
) * ((computed_checksum_str_len))))))
;
14169 for (size_t counter = 0; counter < checksum_len; ++counter) {
14170 snprintf(
14171 /* On ecah iteration inserts two characters */
14172 (char*)&computed_checksum_str[counter << 1],
14173 computed_checksum_str_len - (counter << 1),
14174 "%02x",
14175 computed_checksum[counter]);
14176 }
14177 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14178 if (bad_checksum_expert != NULL((void*)0))
14179 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14180 }
14181 }
14182 } else {
14183 if (hf_checksum_status != -1) {
14184 proto_item_append_text(ti, " [unverified]");
14185 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14186 proto_item_set_generated(ti2);
14187 }
14188 }
14189 }
14190
14191 return ti;
14192}
14193
14194unsigned char
14195proto_check_field_name(const char *field_name)
14196{
14197 return module_check_valid_name(field_name, false0);
14198}
14199
14200unsigned char
14201proto_check_field_name_lower(const char *field_name)
14202{
14203 return module_check_valid_name(field_name, true1);
14204}
14205
14206bool_Bool
14207tree_expanded(int tree_type)
14208{
14209 if (tree_type <= 0) {
14210 return false0;
14211 }
14212 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", 14212, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14213 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14214}
14215
14216void
14217tree_expanded_set(int tree_type, bool_Bool value)
14218{
14219 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", 14219, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14220
14221 if (value)
14222 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14223 else
14224 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14225}
14226
14227/*
14228 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14229 *
14230 * Local variables:
14231 * c-basic-offset: 8
14232 * tab-width: 8
14233 * indent-tabs-mode: t
14234 * End:
14235 *
14236 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14237 * :indentSize=8:tabSize=8:noTabs=false:
14238 */