Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13476, 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-07-02-100250-3847-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-07-02-100250-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
244static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
245static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
246static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
247static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
248static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
249static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
250static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251
252static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
253static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
254static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
255static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
256
257static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
258static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
259static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
260static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
261static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
262static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
263static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
264static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
265static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267
268static void proto_cleanup_base(void);
269
270static proto_item *
271proto_tree_add_node(proto_tree *tree, field_info *fi);
272
273static proto_item *
274proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
275
276static void
277get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
278 int *item_length, const unsigned encoding);
279
280static int
281get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
282 int length, unsigned item_length, const int encoding);
283
284static field_info *
285new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
286 const int start, const int item_length);
287
288static proto_item *
289proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
290 int start, int *length);
291
292static void
293proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
294static void
295proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
296
297static void
298proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
299static void
300proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
301static void
302proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
303static void
304proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
305static void
306proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
307static void
308proto_tree_set_string(field_info *fi, const char* value);
309static void
310proto_tree_set_ax25(field_info *fi, const uint8_t* value);
311static void
312proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
313static void
314proto_tree_set_vines(field_info *fi, const uint8_t* value);
315static void
316proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
317static void
318proto_tree_set_ether(field_info *fi, const uint8_t* value);
319static void
320proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
321static void
322proto_tree_set_ipxnet(field_info *fi, uint32_t value);
323static void
324proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
325static void
326proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
327static void
328proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
329static void
330proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
331static void
332proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
333static void
334proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
335static void
336proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
337static void
338proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
339static void
340proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
341static void
342proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
343static void
344proto_tree_set_boolean(field_info *fi, uint64_t value);
345static void
346proto_tree_set_float(field_info *fi, float value);
347static void
348proto_tree_set_double(field_info *fi, double value);
349static void
350proto_tree_set_uint(field_info *fi, uint32_t value);
351static void
352proto_tree_set_int(field_info *fi, int32_t value);
353static void
354proto_tree_set_uint64(field_info *fi, uint64_t value);
355static void
356proto_tree_set_int64(field_info *fi, int64_t value);
357static void
358proto_tree_set_eui64(field_info *fi, const uint64_t value);
359static void
360proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
361
362/* Handle type length mismatch (now filterable) expert info */
363static int proto_type_length_mismatch;
364static expert_field ei_type_length_mismatch_error;
365static expert_field ei_type_length_mismatch_warn;
366static void register_type_length_mismatch(void);
367
368/* Handle byte array string decoding errors with expert info */
369static int proto_byte_array_string_decoding_error;
370static expert_field ei_byte_array_string_decoding_failed_error;
371static void register_byte_array_string_decodinws_error(void);
372
373/* Handle date and time string decoding errors with expert info */
374static int proto_date_time_string_decoding_error;
375static expert_field ei_date_time_string_decoding_failed_error;
376static void register_date_time_string_decodinws_error(void);
377
378/* Handle string errors expert info */
379static int proto_string_errors;
380static expert_field ei_string_trailing_characters;
381static void register_string_errors(void);
382
383static int proto_register_field_init(header_field_info *hfinfo, const int parent);
384
385/* special-case header field used within proto.c */
386static header_field_info hfi_text_only =
387 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
388int hf_text_only;
389
390/* Structure for information about a protocol */
391struct _protocol {
392 const char *name; /* long description */
393 const char *short_name; /* short description */
394 const char *filter_name; /* name of this protocol in filters */
395 GPtrArray *fields; /* fields for this protocol */
396 int proto_id; /* field ID for this protocol */
397 bool_Bool is_enabled; /* true if protocol is enabled */
398 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
399 bool_Bool can_toggle; /* true if is_enabled can be changed */
400 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
401 For dissectors that need a protocol name so they
402 can be added to a dissector table, but use the
403 parent_proto_id for things like enable/disable */
404 GList *heur_list; /* Heuristic dissectors associated with this protocol */
405};
406
407/* List of all protocols */
408static GList *protocols;
409
410/* Structure stored for deregistered g_slice */
411struct g_slice_data {
412 size_t block_size;
413 void *mem_block;
414};
415
416/* Deregistered fields */
417static GPtrArray *deregistered_fields;
418static GPtrArray *deregistered_data;
419static GPtrArray *deregistered_slice;
420
421/* indexed by prefix, contains initializers */
422static GHashTable* prefixes;
423
424/* Contains information about a field when a dissector calls
425 * proto_tree_add_item. */
426#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)))
427#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
428
429/* Contains the space for proto_nodes. */
430#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
431 node->first_child = NULL((void*)0); \
432 node->last_child = NULL((void*)0); \
433 node->next = NULL((void*)0);
434
435#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
436 wmem_free(pool, node)
437
438/* String space for protocol and field items for the GUI */
439#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;
\
440 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
441 il->value_pos = 0; \
442 il->value_len = 0;
443#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
444 wmem_free(pool, il);
445
446#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", 446, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 446, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 446, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
447 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
448 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 448
, __func__, "Unregistered hf! index=%d", hfindex)
; \
449 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", 449, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
450 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", 450, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
451 hfinfo = gpa_hfinfo.hfi[hfindex];
452
453/* List which stores protocols and fields that have been registered */
454typedef struct _gpa_hfinfo_t {
455 uint32_t len;
456 uint32_t allocated_len;
457 header_field_info **hfi;
458} gpa_hfinfo_t;
459
460static gpa_hfinfo_t gpa_hfinfo;
461
462/* Hash table of abbreviations and IDs */
463static GHashTable *gpa_name_map;
464static header_field_info *same_name_hfinfo;
465
466/* Hash table protocol aliases. const char * -> const char * */
467static GHashTable *gpa_protocol_aliases;
468
469/*
470 * We're called repeatedly with the same field name when sorting a column.
471 * Cache our last gpa_name_map hit for faster lookups.
472 */
473static char *last_field_name;
474static header_field_info *last_hfinfo;
475
476static void save_same_name_hfinfo(void *data)
477{
478 same_name_hfinfo = (header_field_info*)data;
479}
480
481/* Points to the first element of an array of bits, indexed by
482 a subtree item type; that array element is true if subtrees of
483 an item of that type are to be expanded. */
484static uint32_t *tree_is_expanded;
485
486/* Number of elements in that array. The entry with index 0 is not used. */
487int num_tree_types = 1;
488
489/* Name hashtables for fast detection of duplicate names */
490static GHashTable* proto_names;
491static GHashTable* proto_short_names;
492static GHashTable* proto_filter_names;
493
494static const char *reserved_filter_names[] = {
495 /* Display filter keywords. */
496 "eq",
497 "ne",
498 "all_eq",
499 "any_eq",
500 "all_ne",
501 "any_ne",
502 "gt",
503 "ge",
504 "lt",
505 "le",
506 "bitand",
507 "bitwise_and",
508 "contains",
509 "matches",
510 "not",
511 "and",
512 "or",
513 "xor",
514 "in",
515 "any",
516 "all",
517 "true",
518 "false",
519 "nan",
520 "inf",
521 "infinity",
522 NULL((void*)0)
523};
524
525static GHashTable *proto_reserved_filter_names;
526
527static int
528proto_compare_name(const void *p1_arg, const void *p2_arg)
529{
530 const protocol_t *p1 = (const protocol_t *)p1_arg;
531 const protocol_t *p2 = (const protocol_t *)p2_arg;
532
533 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
534}
535
536static GSList *dissector_plugins;
537
538#ifdef HAVE_PLUGINS1
539void
540proto_register_plugin(const proto_plugin *plug)
541{
542 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
543}
544#else /* HAVE_PLUGINS */
545void
546proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
547{
548 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 548, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
549}
550#endif /* HAVE_PLUGINS */
551
552static void
553call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
554{
555 proto_plugin *plug = (proto_plugin *)data;
556
557 if (plug->register_protoinfo) {
558 plug->register_protoinfo();
559 }
560}
561
562static void
563call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
564{
565 proto_plugin *plug = (proto_plugin *)data;
566
567 if (plug->register_handoff) {
568 plug->register_handoff();
569 }
570}
571
572/* initialize data structures and register protocols and fields */
573void
574proto_init(GSList *register_all_plugin_protocols_list,
575 GSList *register_all_plugin_handoffs_list,
576 register_cb cb,
577 void *client_data)
578{
579 proto_cleanup_base();
580
581 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
582 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
583 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
584
585 proto_reserved_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
586 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
587 /* GHashTable has no key destructor so the cast is safe. */
588 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
589 }
590
591 gpa_hfinfo.len = 0;
592 gpa_hfinfo.allocated_len = 0;
593 gpa_hfinfo.hfi = NULL((void*)0);
594 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL((void*)0), save_same_name_hfinfo);
595 gpa_protocol_aliases = g_hash_table_new(g_str_hash, g_str_equal);
596 deregistered_fields = g_ptr_array_new();
597 deregistered_data = g_ptr_array_new();
598 deregistered_slice = g_ptr_array_new();
599
600 /* Initialize the ftype subsystem */
601 ftypes_initialize();
602
603 /* Initialize the address type subsystem */
604 address_types_initialize();
605
606 /* Register one special-case FT_TEXT_ONLY field for use when
607 converting wireshark to new-style proto_tree. These fields
608 are merely strings on the GUI tree; they are not filterable */
609 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
610
611 /* Register the pseudo-protocols used for exceptions. */
612 register_show_exception();
613 register_type_length_mismatch();
614 register_byte_array_string_decodinws_error();
615 register_date_time_string_decodinws_error();
616 register_string_errors();
617 ftypes_register_pseudofields();
618 col_register_protocol();
619
620 /* Have each built-in dissector register its protocols, fields,
621 dissector tables, and dissectors to be called through a
622 handle, and do whatever one-time initialization it needs to
623 do. */
624 register_all_protocols(cb, client_data);
625
626 /* Now call the registration routines for all epan plugins. */
627 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
628 ((void (*)(register_cb, void *))l->data)(cb, client_data);
629 }
630
631 /* Now call the registration routines for all dissector plugins. */
632 if (cb)
633 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
634 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
635
636 /* Now call the "handoff registration" routines of all built-in
637 dissectors; those routines register the dissector in other
638 dissectors' handoff tables, and fetch any dissector handles
639 they need. */
640 register_all_protocol_handoffs(cb, client_data);
641
642 /* Now do the same with epan plugins. */
643 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
644 ((void (*)(register_cb, void *))l->data)(cb, client_data);
645 }
646
647 /* Now do the same with dissector plugins. */
648 if (cb)
649 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
650 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
651
652 /* sort the protocols by protocol name */
653 protocols = g_list_sort(protocols, proto_compare_name);
654
655 /* sort the dissector handles in dissector tables (for -G reports
656 * and -d error messages. The GUI sorts the handles itself.) */
657 packet_all_tables_sort_handles();
658
659 /* We've assigned all the subtree type values; allocate the array
660 for them, and zero it out. */
661 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
)))
;
662}
663
664static void
665proto_cleanup_base(void)
666{
667 protocol_t *protocol;
668 header_field_info *hfinfo;
669
670 /* Free the abbrev/ID hash table */
671 if (gpa_name_map) {
672 g_hash_table_destroy(gpa_name_map);
673 gpa_name_map = NULL((void*)0);
674 }
675 if (gpa_protocol_aliases) {
676 g_hash_table_destroy(gpa_protocol_aliases);
677 gpa_protocol_aliases = NULL((void*)0);
678 }
679 g_free(last_field_name);
680 last_field_name = NULL((void*)0);
681
682 while (protocols) {
683 protocol = (protocol_t *)protocols->data;
684 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", 684
, __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", 684, "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", 684, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
685 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", 685, "protocol->proto_id == hfinfo->id"
))))
;
686
687 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)
;
688 if (protocol->parent_proto_id != -1) {
689 // pino protocol
690 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 690, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
691 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"
, 691, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
692 } else {
693 if (protocol->fields) {
694 g_ptr_array_free(protocol->fields, true1);
695 }
696 g_list_free(protocol->heur_list);
697 }
698 protocols = g_list_remove(protocols, protocol);
699 g_free(protocol);
700 }
701
702 if (proto_names) {
703 g_hash_table_destroy(proto_names);
704 proto_names = NULL((void*)0);
705 }
706
707 if (proto_short_names) {
708 g_hash_table_destroy(proto_short_names);
709 proto_short_names = NULL((void*)0);
710 }
711
712 if (proto_filter_names) {
713 g_hash_table_destroy(proto_filter_names);
714 proto_filter_names = NULL((void*)0);
715 }
716
717 if (proto_reserved_filter_names) {
718 g_hash_table_destroy(proto_reserved_filter_names);
719 proto_reserved_filter_names = NULL((void*)0);
720 }
721
722 if (gpa_hfinfo.allocated_len) {
723 gpa_hfinfo.len = 0;
724 gpa_hfinfo.allocated_len = 0;
725 g_free(gpa_hfinfo.hfi);
726 gpa_hfinfo.hfi = NULL((void*)0);
727 }
728
729 if (deregistered_fields) {
730 g_ptr_array_free(deregistered_fields, true1);
731 deregistered_fields = NULL((void*)0);
732 }
733
734 if (deregistered_data) {
735 g_ptr_array_free(deregistered_data, true1);
736 deregistered_data = NULL((void*)0);
737 }
738
739 if (deregistered_slice) {
740 g_ptr_array_free(deregistered_slice, true1);
741 deregistered_slice = NULL((void*)0);
742 }
743
744 g_free(tree_is_expanded);
745 tree_is_expanded = NULL((void*)0);
746
747 if (prefixes)
748 g_hash_table_destroy(prefixes);
749}
750
751void
752proto_cleanup(void)
753{
754 proto_free_deregistered_fields();
755 proto_cleanup_base();
756
757 g_slist_free(dissector_plugins);
758 dissector_plugins = NULL((void*)0);
759}
760
761static bool_Bool
762// NOLINTNEXTLINE(misc-no-recursion)
763proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
764 void *data)
765{
766 proto_node *pnode = tree;
767 proto_node *child;
768 proto_node *current;
769
770 if (func(pnode, data))
771 return true1;
772
773 child = pnode->first_child;
774 while (child != NULL((void*)0)) {
775 /*
776 * The routine we call might modify the child, e.g. by
777 * freeing it, so we get the child's successor before
778 * calling that routine.
779 */
780 current = child;
781 child = current->next;
782 // We recurse here, but we're limited by prefs.gui_max_tree_depth
783 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
784 return true1;
785 }
786
787 return false0;
788}
789
790void
791proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
792 void *data)
793{
794 proto_node *node = tree;
795 proto_node *current;
796
797 if (!node)
798 return;
799
800 node = node->first_child;
801 while (node != NULL((void*)0)) {
802 current = node;
803 node = current->next;
804 func((proto_tree *)current, data);
805 }
806}
807
808static void
809free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
810{
811 GPtrArray *ptrs = (GPtrArray *)value;
812 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
813 header_field_info *hfinfo;
814
815 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", 815, __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", 815, "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", 815, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
816 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
817 /* when a field is referenced by a filter this also
818 affects the refcount for the parent protocol so we need
819 to adjust the refcount for the parent as well
820 */
821 if (hfinfo->parent != -1) {
822 header_field_info *parent_hfinfo;
823 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", 823
, __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", 823, "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", 823, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
824 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
825 }
826 hfinfo->ref_type = HF_REF_TYPE_NONE;
827 }
828
829 g_ptr_array_free(ptrs, true1);
830}
831
832static void
833proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
834{
835 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
836
837 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
838
839 if (finfo) {
840 fvalue_free(finfo->value);
841 finfo->value = NULL((void*)0);
842 }
843}
844
845void
846proto_tree_reset(proto_tree *tree)
847{
848 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
849
850 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
851
852 /* free tree data */
853 if (tree_data->interesting_hfids) {
854 /* Free all the GPtrArray's in the interesting_hfids hash. */
855 g_hash_table_foreach(tree_data->interesting_hfids,
856 free_GPtrArray_value, NULL((void*)0));
857
858 /* And then remove all values. */
859 g_hash_table_remove_all(tree_data->interesting_hfids);
860 }
861
862 /* Reset track of the number of children */
863 tree_data->count = 0;
864
865 /* Reset our loop checks */
866 tree_data->idle_count_ds_tvb = NULL((void*)0);
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 /* add the data source tvbuff */
6837 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6838
6839 // If our start offset hasn't advanced after adding many items it probably
6840 // means we're in a large or infinite loop.
6841 if (fi->start > 0) {
6842 if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6843 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6844 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", 6844, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6845 } else {
6846 PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6847 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6848 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6849 }
6850 }
6851 fi->length = item_length;
6852 fi->tree_type = -1;
6853 fi->flags = 0;
6854 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6855 /* If the tree is not visible, set the item hidden, unless we
6856 * need the representation or length and can't fake them.
6857 */
6858 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6859 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6860 }
6861 }
6862 fi->value = fvalue_new(fi->hfinfo->type);
6863 fi->rep = NULL((void*)0);
6864
6865 fi->appendix_start = 0;
6866 fi->appendix_length = 0;
6867
6868 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6869 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6870
6871 return fi;
6872}
6873
6874static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6875{
6876 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6877 return 0;
6878 }
6879
6880 /* Search for field name */
6881 char *ptr = strstr(representation, hfinfo->name);
6882 if (!ptr) {
6883 return 0;
6884 }
6885
6886 /* Check if field name ends with the ": " delimiter */
6887 ptr += strlen(hfinfo->name);
6888 if (strncmp(ptr, ": ", 2) == 0) {
6889 ptr += 2;
6890 }
6891
6892 /* Return offset to after field name */
6893 return ptr - representation;
6894}
6895
6896static size_t label_find_name_pos(const item_label_t *rep)
6897{
6898 size_t name_pos = 0;
6899
6900 /* Check if the format looks like "label: value", then set name_pos before ':'. */
6901 if (rep->value_pos > 2 && rep->representation[rep->value_pos-2] == ':') {
6902 name_pos = rep->value_pos - 2;
6903 }
6904
6905 return name_pos;
6906}
6907
6908/* If the protocol tree is to be visible, set the representation of a
6909 proto_tree entry with the name of the field for the item and with
6910 the value formatted with the supplied printf-style format and
6911 argument list. */
6912static void
6913proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6914{
6915 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6915, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6916
6917 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6918 * items string representation */
6919 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6920 size_t name_pos, ret = 0;
6921 char *str;
6922 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6923 const header_field_info *hf;
6924
6925 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6925, "fi"))))
;
6926
6927 hf = fi->hfinfo;
6928
6929 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;
;
6930 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))
)) {
6931 uint64_t val;
6932 char *p;
6933
6934 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)
)
6935 val = fvalue_get_uinteger(fi->value);
6936 else
6937 val = fvalue_get_uinteger64(fi->value);
6938
6939 val <<= hfinfo_bitshift(hf);
6940
6941 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6942 ret = (p - fi->rep->representation);
6943 }
6944
6945 /* put in the hf name */
6946 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
6947
6948 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
6949 /* If possible, Put in the value of the string */
6950 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6951 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"
, 6951, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6952 fi->rep->value_pos = ret;
6953 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
6954 if (ret >= ITEM_LABEL_LENGTH240) {
6955 /* Uh oh, we don't have enough room. Tell the user
6956 * that the field is truncated.
6957 */
6958 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6959 }
6960 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6961 }
6962}
6963
6964/* If the protocol tree is to be visible, set the representation of a
6965 proto_tree entry with the representation formatted with the supplied
6966 printf-style format and argument list. */
6967static void
6968proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6969{
6970 size_t ret; /*tmp return value */
6971 char *str;
6972 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6973
6974 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6974, "fi"))))
;
6975
6976 if (!proto_item_is_hidden(pi)) {
6977 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;
;
6978
6979 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6980 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"
, 6980, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6981 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
6982 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
6983 if (ret >= ITEM_LABEL_LENGTH240) {
6984 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
6985 size_t name_pos = label_find_name_pos(fi->rep);
6986 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6987 }
6988 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6989 }
6990}
6991
6992static int
6993proto_strlcpy(char *dest, const char *src, size_t dest_size)
6994{
6995 if (dest_size == 0) return 0;
6996
6997 size_t res = g_strlcpy(dest, src, dest_size);
6998
6999 /* At most dest_size - 1 characters will be copied
7000 * (unless dest_size is 0). */
7001 if (res >= dest_size)
7002 res = dest_size - 1;
7003 return (int) res;
7004}
7005
7006static header_field_info *
7007hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7008{
7009 header_field_info *dup_hfinfo;
7010
7011 if (hfinfo->same_name_prev_id == -1)
7012 return NULL((void*)0);
7013 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", 7013
, __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", 7013, "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", 7013,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7014 return dup_hfinfo;
7015}
7016
7017static void
7018hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7019{
7020 g_free(last_field_name);
7021 last_field_name = NULL((void*)0);
7022
7023 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7024 /* No hfinfo with the same name */
7025 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
7026 return;
7027 }
7028
7029 if (hfinfo->same_name_next) {
7030 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7031 }
7032
7033 if (hfinfo->same_name_prev_id != -1) {
7034 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7035 same_name_prev->same_name_next = hfinfo->same_name_next;
7036 if (!hfinfo->same_name_next) {
7037 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7038 g_hash_table_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7039 }
7040 }
7041}
7042
7043int
7044proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7045{
7046 const header_field_info *hfinfo = finfo->hfinfo;
7047 int label_len = 0;
7048 char *tmp_str;
7049 const char *str;
7050 const uint8_t *bytes;
7051 uint32_t number;
7052 uint64_t number64;
7053 const char *hf_str_val;
7054 char number_buf[NUMBER_LABEL_LENGTH80];
7055 const char *number_out;
7056 address addr;
7057 const ipv4_addr_and_mask *ipv4;
7058 const ipv6_addr_and_prefix *ipv6;
7059
7060 switch (hfinfo->type) {
7061
7062 case FT_NONE:
7063 case FT_PROTOCOL:
7064 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7065
7066 case FT_UINT_BYTES:
7067 case FT_BYTES:
7068 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7069 hfinfo,
7070 fvalue_get_bytes_data(finfo->value),
7071 (unsigned)fvalue_length2(finfo->value),
7072 label_str_size);
7073 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7074 wmem_free(NULL((void*)0), tmp_str);
7075 break;
7076
7077 case FT_ABSOLUTE_TIME:
7078 {
7079 const nstime_t *value = fvalue_get_time(finfo->value);
7080 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7081 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7082 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7083 }
7084 if (hfinfo->strings) {
7085 const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7086 if (time_string != NULL((void*)0)) {
7087 label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7088 break;
7089 }
7090 }
7091 tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7092 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7093 wmem_free(NULL((void*)0), tmp_str);
7094 break;
7095 }
7096
7097 case FT_RELATIVE_TIME:
7098 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7099 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7100 wmem_free(NULL((void*)0), tmp_str);
7101 break;
7102
7103 case FT_BOOLEAN:
7104 number64 = fvalue_get_uinteger64(finfo->value);
7105 label_len = proto_strlcpy(display_label_str,
7106 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7107 break;
7108
7109 case FT_CHAR:
7110 number = fvalue_get_uinteger(finfo->value);
7111
7112 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7113 char tmp[ITEM_LABEL_LENGTH240];
7114 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7115
7116 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7116, "fmtfunc"))))
;
7117 fmtfunc(tmp, number);
7118
7119 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7120
7121 } else if (hfinfo->strings) {
7122 number_out = hf_try_val_to_str(number, hfinfo);
7123
7124 if (!number_out) {
7125 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7126 }
7127
7128 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7129
7130 } else {
7131 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7132
7133 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7134 }
7135
7136 break;
7137
7138 /* XXX - make these just FT_NUMBER? */
7139 case FT_INT8:
7140 case FT_INT16:
7141 case FT_INT24:
7142 case FT_INT32:
7143 case FT_UINT8:
7144 case FT_UINT16:
7145 case FT_UINT24:
7146 case FT_UINT32:
7147 case FT_FRAMENUM:
7148 hf_str_val = NULL((void*)0);
7149 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
))
?
7150 (uint32_t) fvalue_get_sinteger(finfo->value) :
7151 fvalue_get_uinteger(finfo->value);
7152
7153 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7154 char tmp[ITEM_LABEL_LENGTH240];
7155 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7156
7157 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7157, "fmtfunc"))))
;
7158 fmtfunc(tmp, number);
7159
7160 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7161
7162 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7163 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7164 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7165 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7166 hf_str_val = hf_try_val_to_str(number, hfinfo);
7167 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7168 } else {
7169 number_out = hf_try_val_to_str(number, hfinfo);
7170
7171 if (!number_out) {
7172 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7173 }
7174
7175 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7176 }
7177 } else {
7178 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7179
7180 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7181 }
7182
7183 break;
7184
7185 case FT_INT40:
7186 case FT_INT48:
7187 case FT_INT56:
7188 case FT_INT64:
7189 case FT_UINT40:
7190 case FT_UINT48:
7191 case FT_UINT56:
7192 case FT_UINT64:
7193 hf_str_val = NULL((void*)0);
7194 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
))
?
7195 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7196 fvalue_get_uinteger64(finfo->value);
7197
7198 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7199 char tmp[ITEM_LABEL_LENGTH240];
7200 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7201
7202 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7202, "fmtfunc64"
))))
;
7203 fmtfunc64(tmp, number64);
7204
7205 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7206 } else if (hfinfo->strings) {
7207 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7208 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7209 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7210 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7211 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7212 } else {
7213 number_out = hf_try_val64_to_str(number64, hfinfo);
7214
7215 if (!number_out)
7216 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7217
7218 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7219 }
7220 } else {
7221 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7222
7223 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7224 }
7225
7226 break;
7227
7228 case FT_EUI64:
7229 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7230 tmp_str = address_to_display(NULL((void*)0), &addr);
7231 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7232 wmem_free(NULL((void*)0), tmp_str);
7233 break;
7234
7235 case FT_IPv4:
7236 ipv4 = fvalue_get_ipv4(finfo->value);
7237 //XXX: Should we ignore the mask?
7238 set_address_ipv4(&addr, ipv4);
7239 tmp_str = address_to_display(NULL((void*)0), &addr);
7240 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7241 wmem_free(NULL((void*)0), tmp_str);
7242 free_address(&addr);
7243 break;
7244
7245 case FT_IPv6:
7246 ipv6 = fvalue_get_ipv6(finfo->value);
7247 set_address_ipv6(&addr, ipv6);
7248 tmp_str = address_to_display(NULL((void*)0), &addr);
7249 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7250 wmem_free(NULL((void*)0), tmp_str);
7251 free_address(&addr);
7252 break;
7253
7254 case FT_FCWWN:
7255 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7256 tmp_str = address_to_display(NULL((void*)0), &addr);
7257 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7258 wmem_free(NULL((void*)0), tmp_str);
7259 break;
7260
7261 case FT_ETHER:
7262 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7263 tmp_str = address_to_display(NULL((void*)0), &addr);
7264 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7265 wmem_free(NULL((void*)0), tmp_str);
7266 break;
7267
7268 case FT_GUID:
7269 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7270 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7271 wmem_free(NULL((void*)0), tmp_str);
7272 break;
7273
7274 case FT_REL_OID:
7275 bytes = fvalue_get_bytes_data(finfo->value);
7276 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7277 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7278 wmem_free(NULL((void*)0), tmp_str);
7279 break;
7280
7281 case FT_OID:
7282 bytes = fvalue_get_bytes_data(finfo->value);
7283 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7284 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7285 wmem_free(NULL((void*)0), tmp_str);
7286 break;
7287
7288 case FT_SYSTEM_ID:
7289 bytes = fvalue_get_bytes_data(finfo->value);
7290 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7291 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7292 wmem_free(NULL((void*)0), tmp_str);
7293 break;
7294
7295 case FT_FLOAT:
7296 case FT_DOUBLE:
7297 label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7298 break;
7299
7300 case FT_IEEE_11073_SFLOAT:
7301 case FT_IEEE_11073_FLOAT:
7302 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7303 break;
7304
7305 case FT_STRING:
7306 case FT_STRINGZ:
7307 case FT_UINT_STRING:
7308 case FT_STRINGZPAD:
7309 case FT_STRINGZTRUNC:
7310 str = fvalue_get_string(finfo->value);
7311 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7312 if (label_len >= label_str_size) {
7313 /* Truncation occurred. Get the real length
7314 * copied (not including '\0') */
7315 label_len = label_str_size ? label_str_size - 1 : 0;
7316 }
7317 break;
7318
7319 default:
7320 /* First try ftype string representation */
7321 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7322 if (!tmp_str) {
7323 /* Default to show as bytes */
7324 bytes = fvalue_get_bytes_data(finfo->value);
7325 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7326 }
7327 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7328 wmem_free(NULL((void*)0), tmp_str);
7329 break;
7330 }
7331 return label_len;
7332}
7333
7334const char *
7335proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7336 char *result, char *expr, const int size)
7337{
7338 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7339 GPtrArray *finfos;
7340 field_info *finfo = NULL((void*)0);
7341 header_field_info* hfinfo;
7342 const char *abbrev = NULL((void*)0);
7343
7344 char *str;
7345 col_custom_t *field_idx;
7346 int field_id;
7347 int ii = 0;
7348
7349 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7349, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7350 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7351 field_id = field_idx->field_id;
7352 if (field_id == 0) {
7353 GPtrArray *fvals = NULL((void*)0);
7354 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7355 if (fvals != NULL((void*)0)) {
7356
7357 // XXX - Handling occurrences is unusual when more
7358 // than one field is involved, e.g. there's four
7359 // results for tcp.port + tcp.port. We may really
7360 // want to apply it to the operands, not the output.
7361 // Note that occurrences are not quite the same as
7362 // the layer operator (should the grammar support
7363 // both?)
7364 /* Calculate single index or set outer boundaries */
7365 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7366 if (occurrence < 0) {
7367 i = occurrence + len;
7368 last = i;
7369 } else if (occurrence > 0) {
7370 i = occurrence - 1;
7371 last = i;
7372 } else {
7373 i = 0;
7374 last = len - 1;
7375 }
7376 if (i < 0 || i >= len) {
7377 g_ptr_array_unref(fvals);
7378 continue;
7379 }
7380 for (; i <= last; i++) {
7381 /* XXX - We could have a "resolved" result
7382 * for types where the value depends only
7383 * on the type, e.g. FT_IPv4, and not on
7384 * hfinfo->strings. Supporting the latter
7385 * requires knowing which hfinfo matched
7386 * if there are multiple with the same
7387 * abbreviation. In any case, we need to
7388 * know the expected return type of the
7389 * field expression.
7390 */
7391 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7392 if (offset_r && (offset_r < (size - 1)))
7393 result[offset_r++] = ',';
7394 if (offset_e && (offset_e < (size - 1)))
7395 expr[offset_e++] = ',';
7396 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7397 // col_{add,append,set}_* calls ws_label_strcpy
7398 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7399
7400 g_free(str);
7401 }
7402 g_ptr_array_unref(fvals);
7403 } else if (passed) {
7404 // XXX - Occurrence doesn't make sense for a test
7405 // output, it should be applied to the operands.
7406 if (offset_r && (offset_r < (size - 1)))
7407 result[offset_r++] = ',';
7408 if (offset_e && (offset_e < (size - 1)))
7409 expr[offset_e++] = ',';
7410 /* Prevent multiple check marks */
7411 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7412 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7413 } else {
7414 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7415 }
7416 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7417 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7418 } else {
7419 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7420 }
7421 }
7422 continue;
7423 }
7424 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", 7424
, __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", 7424,
"(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", 7424,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7425
7426 /* do we need to rewind ? */
7427 if (!hfinfo)
7428 return "";
7429
7430 if (occurrence < 0) {
7431 /* Search other direction */
7432 while (hfinfo->same_name_prev_id != -1) {
7433 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", 7433
, __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", 7433, "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", 7433,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7434 }
7435 }
7436
7437 prev_len = 0; /* Reset handled occurrences */
7438
7439 while (hfinfo) {
7440 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7441
7442 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7443 if (occurrence < 0) {
7444 hfinfo = hfinfo->same_name_next;
7445 } else {
7446 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7447 }
7448 continue;
7449 }
7450
7451 /* Are there enough occurrences of the field? */
7452 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7453 if (occurrence < 0) {
7454 hfinfo = hfinfo->same_name_next;
7455 } else {
7456 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7457 }
7458 prev_len += len;
7459 continue;
7460 }
7461
7462 /* Calculate single index or set outer boundaries */
7463 if (occurrence < 0) {
7464 i = occurrence + len + prev_len;
7465 last = i;
7466 } else if (occurrence > 0) {
7467 i = occurrence - 1 - prev_len;
7468 last = i;
7469 } else {
7470 i = 0;
7471 last = len - 1;
7472 }
7473
7474 prev_len += len; /* Count handled occurrences */
7475
7476 while (i <= last) {
7477 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7478
7479 if (offset_r && (offset_r < (size - 1)))
7480 result[offset_r++] = ',';
7481
7482 if (display_details) {
7483 char representation[ITEM_LABEL_LENGTH240];
7484 size_t offset = 0;
7485
7486 if (finfo->rep && finfo->rep->value_len) {
7487 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7488 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7489 } else {
7490 proto_item_fill_label(finfo, representation, &offset);
7491 }
7492 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7493 } else {
7494 switch (hfinfo->type) {
7495
7496 case FT_NONE:
7497 case FT_PROTOCOL:
7498 /* Prevent multiple check marks */
7499 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7500 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7501 } else {
7502 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7503 }
7504 break;
7505
7506 default:
7507 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7508 break;
7509 }
7510 }
7511
7512 if (offset_e && (offset_e < (size - 1)))
7513 expr[offset_e++] = ',';
7514
7515 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
))
)) {
7516 const char *hf_str_val;
7517 /* Integer types with BASE_NONE never get the numeric value. */
7518 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7519 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7520 } 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
)
) {
7521 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7522 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7523 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7524 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7525 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7526 }
7527 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7528 offset_e = (int)strlen(expr);
7529 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7530 /* Prevent multiple check marks */
7531 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7532 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7533 } else {
7534 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7535 }
7536 } else {
7537 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7538 // col_{add,append,set}_* calls ws_label_strcpy
7539 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7540 wmem_free(NULL((void*)0), str);
7541 }
7542 i++;
7543 }
7544
7545 /* XXX: Why is only the first abbreviation returned for a multifield
7546 * custom column? */
7547 if (!abbrev) {
7548 /* Store abbrev for return value */
7549 abbrev = hfinfo->abbrev;
7550 }
7551
7552 if (occurrence == 0) {
7553 /* Fetch next hfinfo with same name (abbrev) */
7554 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7555 } else {
7556 hfinfo = NULL((void*)0);
7557 }
7558 }
7559 }
7560
7561 if (offset_r >= (size - 1)) {
7562 mark_truncated(result, 0, size, NULL((void*)0));
7563 }
7564 if (offset_e >= (size - 1)) {
7565 mark_truncated(expr, 0, size, NULL((void*)0));
7566 }
7567 return abbrev ? abbrev : "";
7568}
7569
7570char *
7571proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7572{
7573 int len, prev_len, last, i;
7574 GPtrArray *finfos;
7575 field_info *finfo = NULL((void*)0);
7576 header_field_info* hfinfo;
7577
7578 char *filter = NULL((void*)0);
7579 GPtrArray *filter_array;
7580
7581 col_custom_t *col_custom;
7582 int field_id;
7583
7584 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7584, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7585 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7586 for (GSList *iter = field_ids; iter; iter = iter->next) {
7587 col_custom = (col_custom_t*)iter->data;
7588 field_id = col_custom->field_id;
7589 if (field_id == 0) {
7590 GPtrArray *fvals = NULL((void*)0);
7591 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7592 if (fvals != NULL((void*)0)) {
7593 // XXX - Handling occurrences is unusual when more
7594 // than one field is involved, e.g. there's four
7595 // results for tcp.port + tcp.port. We really
7596 // want to apply it to the operands, not the output.
7597 /* Calculate single index or set outer boundaries */
7598 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7599 if (occurrence < 0) {
7600 i = occurrence + len;
7601 last = i;
7602 } else if (occurrence > 0) {
7603 i = occurrence - 1;
7604 last = i;
7605 } else {
7606 i = 0;
7607 last = len - 1;
7608 }
7609 if (i < 0 || i >= len) {
7610 g_ptr_array_unref(fvals);
7611 continue;
7612 }
7613 for (; i <= last; i++) {
7614 /* XXX - Should multiple values for one
7615 * field use set membership to reduce
7616 * verbosity, here and below? */
7617 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7618 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7619 wmem_free(NULL((void*)0), str);
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 g_ptr_array_unref(fvals);
7625 } else if (passed) {
7626 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7627 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7628 g_ptr_array_add(filter_array, filter);
7629 }
7630 } else {
7631 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7632 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7633 g_ptr_array_add(filter_array, filter);
7634 }
7635 }
7636 continue;
7637 }
7638
7639 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", 7639
, __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", 7639,
"(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", 7639,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7640
7641 /* do we need to rewind ? */
7642 if (!hfinfo)
7643 return NULL((void*)0);
7644
7645 if (occurrence < 0) {
7646 /* Search other direction */
7647 while (hfinfo->same_name_prev_id != -1) {
7648 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", 7648
, __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", 7648, "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", 7648,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7649 }
7650 }
7651
7652 prev_len = 0; /* Reset handled occurrences */
7653
7654 while (hfinfo) {
7655 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7656
7657 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7658 if (occurrence < 0) {
7659 hfinfo = hfinfo->same_name_next;
7660 } else {
7661 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7662 }
7663 continue;
7664 }
7665
7666 /* Are there enough occurrences of the field? */
7667 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7668 if (occurrence < 0) {
7669 hfinfo = hfinfo->same_name_next;
7670 } else {
7671 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7672 }
7673 prev_len += len;
7674 continue;
7675 }
7676
7677 /* Calculate single index or set outer boundaries */
7678 if (occurrence < 0) {
7679 i = occurrence + len + prev_len;
7680 last = i;
7681 } else if (occurrence > 0) {
7682 i = occurrence - 1 - prev_len;
7683 last = i;
7684 } else {
7685 i = 0;
7686 last = len - 1;
7687 }
7688
7689 prev_len += len; /* Count handled occurrences */
7690
7691 while (i <= last) {
7692 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7693
7694 filter = proto_construct_match_selected_string(finfo, edt);
7695 if (filter) {
7696 /* Only add the same expression once (especially for FT_PROTOCOL).
7697 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7698 */
7699 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7700 g_ptr_array_add(filter_array, filter);
7701 }
7702 }
7703 i++;
7704 }
7705
7706 if (occurrence == 0) {
7707 /* Fetch next hfinfo with same name (abbrev) */
7708 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7709 } else {
7710 hfinfo = NULL((void*)0);
7711 }
7712 }
7713 }
7714
7715 g_ptr_array_add(filter_array, NULL((void*)0));
7716
7717 /* XXX: Should this be || or && ? */
7718 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7719
7720 g_ptr_array_free(filter_array, true1);
7721
7722 return output;
7723}
7724
7725/* Set text of proto_item after having already been created. */
7726void
7727proto_item_set_text(proto_item *pi, const char *format, ...)
7728{
7729 field_info *fi = NULL((void*)0);
7730 va_list ap;
7731
7732 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7733
7734 fi = PITEM_FINFO(pi)((pi)->finfo);
7735 if (fi == NULL((void*)0))
7736 return;
7737
7738 if (fi->rep) {
7739 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7740 fi->rep = NULL((void*)0);
7741 }
7742
7743 va_start(ap, format)__builtin_va_start(ap, format);
7744 proto_tree_set_representation(pi, format, ap);
7745 va_end(ap)__builtin_va_end(ap);
7746}
7747
7748/* Append to text of proto_item after having already been created. */
7749void
7750proto_item_append_text(proto_item *pi, const char *format, ...)
7751{
7752 field_info *fi = NULL((void*)0);
7753 size_t curlen;
7754 char *str;
7755 va_list ap;
7756
7757 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7758
7759 fi = PITEM_FINFO(pi)((pi)->finfo);
7760 if (fi == NULL((void*)0)) {
7761 return;
7762 }
7763
7764 if (!proto_item_is_hidden(pi)) {
7765 /*
7766 * If we don't already have a representation,
7767 * generate the default representation.
7768 */
7769 if (fi->rep == NULL((void*)0)) {
7770 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;
;
7771 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7772 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7773 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7774 (strncmp(format, ": ", 2) == 0)) {
7775 fi->rep->value_pos += 2;
7776 }
7777 }
7778 if (fi->rep) {
7779 curlen = strlen(fi->rep->representation);
7780 /* curlen doesn't include the \0 byte.
7781 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7782 * the representation has already been truncated (of an up
7783 * to 4 byte UTF-8 character) or is just at the maximum length
7784 * unless we search for " [truncated]" (which may not be
7785 * at the start.)
7786 * It's safer to do nothing.
7787 */
7788 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7789 va_start(ap, format)__builtin_va_start(ap, format);
7790 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7791 va_end(ap)__builtin_va_end(ap);
7792 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"
, 7792, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7793 /* Keep fi->rep->value_pos */
7794 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7795 if (curlen >= ITEM_LABEL_LENGTH240) {
7796 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7797 size_t name_pos = label_find_name_pos(fi->rep);
7798 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7799 }
7800 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7801 }
7802 }
7803 }
7804}
7805
7806/* Prepend to text of proto_item after having already been created. */
7807void
7808proto_item_prepend_text(proto_item *pi, const char *format, ...)
7809{
7810 field_info *fi = NULL((void*)0);
7811 size_t pos;
7812 char representation[ITEM_LABEL_LENGTH240];
7813 char *str;
7814 va_list ap;
7815
7816 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7817
7818 fi = PITEM_FINFO(pi)((pi)->finfo);
7819 if (fi == NULL((void*)0)) {
7820 return;
7821 }
7822
7823 if (!proto_item_is_hidden(pi)) {
7824 /*
7825 * If we don't already have a representation,
7826 * generate the default representation.
7827 */
7828 if (fi->rep == NULL((void*)0)) {
7829 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;
;
7830 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7831 } else
7832 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7833
7834 va_start(ap, format)__builtin_va_start(ap, format);
7835 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7836 va_end(ap)__builtin_va_end(ap);
7837 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"
, 7837, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7838 fi->rep->value_pos += strlen(str);
7839 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7840 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7841 /* XXX: As above, if the old representation is close to the label
7842 * length, it might already be marked as truncated. */
7843 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7844 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7845 size_t name_pos = label_find_name_pos(fi->rep);
7846 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7847 }
7848 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7849 }
7850}
7851
7852static void
7853finfo_set_len(field_info *fi, const int length)
7854{
7855 int length_remaining;
7856
7857 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", 7857,
"length >= 0", fi->hfinfo->abbrev))))
;
7858 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7859 if (length > length_remaining)
7860 fi->length = length_remaining;
7861 else
7862 fi->length = length;
7863
7864 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7865 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7866 fvalue_set_protocol_length(fi->value, fi->length);
7867 }
7868
7869 /*
7870 * You cannot just make the "len" field of a GByteArray
7871 * larger, if there's no data to back that length;
7872 * you can only make it smaller.
7873 */
7874 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7875 GBytes *bytes = fvalue_get_bytes(fi->value);
7876 size_t size;
7877 const void *data = g_bytes_get_data(bytes, &size);
7878 if ((size_t)fi->length <= size) {
7879 fvalue_set_bytes_data(fi->value, data, fi->length);
7880 }
7881 g_bytes_unref(bytes);
7882 }
7883}
7884
7885void
7886proto_item_set_len(proto_item *pi, const int length)
7887{
7888 field_info *fi;
7889
7890 if (pi == NULL((void*)0))
7891 return;
7892
7893 fi = PITEM_FINFO(pi)((pi)->finfo);
7894 if (fi == NULL((void*)0))
7895 return;
7896
7897 finfo_set_len(fi, length);
7898}
7899
7900/*
7901 * Sets the length of the item based on its start and on the specified
7902 * offset, which is the offset past the end of the item; as the start
7903 * in the item is relative to the beginning of the data source tvbuff,
7904 * we need to pass in a tvbuff - the end offset is relative to the beginning
7905 * of that tvbuff.
7906 */
7907void
7908proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7909{
7910 field_info *fi;
7911 int length;
7912
7913 if (pi == NULL((void*)0))
7914 return;
7915
7916 fi = PITEM_FINFO(pi)((pi)->finfo);
7917 if (fi == NULL((void*)0))
7918 return;
7919
7920 end += tvb_raw_offset(tvb);
7921 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7921, "end >= fi->start"
))))
;
7922 length = end - fi->start;
7923
7924 finfo_set_len(fi, length);
7925}
7926
7927int
7928proto_item_get_len(const proto_item *pi)
7929{
7930 field_info *fi;
7931
7932 if (!pi)
7933 return -1;
7934 fi = PITEM_FINFO(pi)((pi)->finfo);
7935 return fi ? fi->length : -1;
7936}
7937
7938void
7939proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7940 if (!ti) {
7941 return;
7942 }
7943 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)
;
7944 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)
;
7945}
7946
7947char *
7948proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7949{
7950 field_info *fi;
7951
7952 if (!pi)
7953 return wmem_strdup(scope, "");
7954 fi = PITEM_FINFO(pi)((pi)->finfo);
7955 if (!fi)
7956 return wmem_strdup(scope, "");
7957 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7957, "fi->hfinfo != ((void*)0)"
))))
;
7958 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7959}
7960
7961proto_tree *
7962proto_tree_create_root(packet_info *pinfo)
7963{
7964 proto_node *pnode;
7965
7966 /* Initialize the proto_node */
7967 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
7968 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
7969 pnode->parent = NULL((void*)0);
7970 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
7971 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
7972
7973 /* Make sure we can access pinfo everywhere */
7974 pnode->tree_data->pinfo = pinfo;
7975
7976 /* Don't initialize the tree_data_t. Wait until we know we need it */
7977 pnode->tree_data->interesting_hfids = NULL((void*)0);
7978
7979 /* Set the default to false so it's easier to
7980 * find errors; if we expect to see the protocol tree
7981 * but for some reason the default 'visible' is not
7982 * changed, then we'll find out very quickly. */
7983 pnode->tree_data->visible = false0;
7984
7985 /* Make sure that we fake protocols (if possible) */
7986 pnode->tree_data->fake_protocols = true1;
7987
7988 /* Keep track of the number of children */
7989 pnode->tree_data->count = 0;
7990
7991 /* Initialize our loop checks */
7992 pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
7993 pnode->tree_data->max_start = 0;
7994 pnode->tree_data->start_idle_count = 0;
7995
7996 return (proto_tree *)pnode;
7997}
7998
7999
8000/* "prime" a proto_tree with a single hfid that a dfilter
8001 * is interested in. */
8002void
8003proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8004{
8005 header_field_info *hfinfo;
8006
8007 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", 8007, __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", 8007, "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", 8007, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8008 /* this field is referenced by a filter so increase the refcount.
8009 also increase the refcount for the parent, i.e the protocol.
8010 Don't increase the refcount if we're already printing the
8011 type, as that is a superset of direct reference.
8012 */
8013 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8014 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8015 }
8016 /* only increase the refcount if there is a parent.
8017 if this is a protocol and not a field then parent will be -1
8018 and there is no parent to add any refcounting for.
8019 */
8020 if (hfinfo->parent != -1) {
8021 header_field_info *parent_hfinfo;
8022 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", 8022
, __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", 8022,
"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", 8022,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8023
8024 /* Mark parent as indirectly referenced unless it is already directly
8025 * referenced, i.e. the user has specified the parent in a filter.
8026 */
8027 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8028 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8029 }
8030}
8031
8032/* "prime" a proto_tree with a single hfid that a dfilter
8033 * is interested in. */
8034void
8035proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8036{
8037 header_field_info *hfinfo;
8038
8039 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", 8039, __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", 8039, "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", 8039, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8040 /* this field is referenced by an (output) filter so increase the refcount.
8041 also increase the refcount for the parent, i.e the protocol.
8042 */
8043 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8044 /* only increase the refcount if there is a parent.
8045 if this is a protocol and not a field then parent will be -1
8046 and there is no parent to add any refcounting for.
8047 */
8048 if (hfinfo->parent != -1) {
8049 header_field_info *parent_hfinfo;
8050 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", 8050
, __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", 8050,
"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", 8050,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8051
8052 /* Mark parent as indirectly referenced unless it is already directly
8053 * referenced, i.e. the user has specified the parent in a filter.
8054 */
8055 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8056 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8057 }
8058}
8059
8060proto_tree *
8061proto_item_add_subtree(proto_item *pi, const int idx) {
8062 field_info *fi;
8063
8064 if (!pi)
8065 return NULL((void*)0);
8066
8067 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", 8067, "idx >= 0 && idx < num_tree_types"
))))
;
8068
8069 fi = PITEM_FINFO(pi)((pi)->finfo);
8070 if (!fi)
8071 return (proto_tree *)pi;
8072
8073 fi->tree_type = idx;
8074
8075 return (proto_tree *)pi;
8076}
8077
8078proto_tree *
8079proto_item_get_subtree(proto_item *pi) {
8080 field_info *fi;
8081
8082 if (!pi)
8083 return NULL((void*)0);
8084 fi = PITEM_FINFO(pi)((pi)->finfo);
8085 if ( (fi) && (fi->tree_type == -1) )
8086 return NULL((void*)0);
8087 return (proto_tree *)pi;
8088}
8089
8090proto_item *
8091proto_item_get_parent(const proto_item *ti) {
8092 if (!ti)
8093 return NULL((void*)0);
8094 return ti->parent;
8095}
8096
8097proto_item *
8098proto_item_get_parent_nth(proto_item *ti, int gen) {
8099 if (!ti)
8100 return NULL((void*)0);
8101 while (gen--) {
8102 ti = ti->parent;
8103 if (!ti)
8104 return NULL((void*)0);
8105 }
8106 return ti;
8107}
8108
8109
8110proto_item *
8111proto_tree_get_parent(proto_tree *tree) {
8112 if (!tree)
8113 return NULL((void*)0);
8114 return (proto_item *)tree;
8115}
8116
8117proto_tree *
8118proto_tree_get_parent_tree(proto_tree *tree) {
8119 if (!tree)
8120 return NULL((void*)0);
8121
8122 /* we're the root tree, there's no parent
8123 return ourselves so the caller has at least a tree to attach to */
8124 if (!tree->parent)
8125 return tree;
8126
8127 return (proto_tree *)tree->parent;
8128}
8129
8130proto_tree *
8131proto_tree_get_root(proto_tree *tree) {
8132 if (!tree)
8133 return NULL((void*)0);
8134 while (tree->parent) {
8135 tree = tree->parent;
8136 }
8137 return tree;
8138}
8139
8140void
8141proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8142 proto_item *item_to_move)
8143{
8144 /* This function doesn't generate any values. It only reorganizes the prococol tree
8145 * so we can bail out immediately if it isn't visible. */
8146 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8147 return;
8148
8149 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", 8149, "item_to_move->parent == tree"
))))
;
8150 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", 8150, "fixed_item->parent == tree"
))))
;
8151
8152 /*** cut item_to_move out ***/
8153
8154 /* is item_to_move the first? */
8155 if (tree->first_child == item_to_move) {
8156 /* simply change first child to next */
8157 tree->first_child = item_to_move->next;
8158
8159 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", 8159, "tree->last_child != item_to_move"
))))
;
8160 } else {
8161 proto_item *curr_item;
8162 /* find previous and change it's next */
8163 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8164 if (curr_item->next == item_to_move) {
8165 break;
8166 }
8167 }
8168
8169 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8169, "curr_item"
))))
;
8170
8171 curr_item->next = item_to_move->next;
8172
8173 /* fix last_child if required */
8174 if (tree->last_child == item_to_move) {
8175 tree->last_child = curr_item;
8176 }
8177 }
8178
8179 /*** insert to_move after fixed ***/
8180 item_to_move->next = fixed_item->next;
8181 fixed_item->next = item_to_move;
8182 if (tree->last_child == fixed_item) {
8183 tree->last_child = item_to_move;
8184 }
8185}
8186
8187void
8188proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8189 const int length)
8190{
8191 field_info *fi;
8192
8193 if (tree == NULL((void*)0))
8194 return;
8195
8196 fi = PTREE_FINFO(tree)((tree)->finfo);
8197 if (fi == NULL((void*)0))
8198 return;
8199
8200 start += tvb_raw_offset(tvb);
8201 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8201, "start >= 0"
))))
;
8202 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8202, "length >= 0"
))))
;
8203
8204 fi->appendix_start = start;
8205 fi->appendix_length = length;
8206}
8207
8208static void
8209check_protocol_filter_name_or_fail(const char *filter_name)
8210{
8211 /* Require at least two characters. */
8212 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8213 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)
;
8214 }
8215
8216 if (proto_check_field_name(filter_name) != '\0') {
8217 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)
8218 " 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)
8219 " 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)
;
8220 }
8221
8222 /* Check that it doesn't match some very common numeric forms. */
8223 if (filter_name[0] == '0' &&
8224 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8225 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8226 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])
8227 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])
;
8228 }
8229
8230 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8231
8232 /* Check that it contains at least one letter. */
8233 bool_Bool have_letter = false0;
8234 for (const char *s = filter_name; *s != '\0'; s++) {
8235 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8236 have_letter = true1;
8237 break;
8238 }
8239 }
8240 if (!have_letter) {
8241 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)
8242 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8243 }
8244
8245 /* Check for reserved keywords. */
8246 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8247 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)
8248 " 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)
;
8249 }
8250}
8251
8252int
8253proto_register_protocol(const char *name, const char *short_name,
8254 const char *filter_name)
8255{
8256 protocol_t *protocol;
8257 header_field_info *hfinfo;
8258
8259 /*
8260 * Make sure there's not already a protocol with any of those
8261 * names. Crash if there is, as that's an error in the code
8262 * or an inappropriate plugin.
8263 * This situation has to be fixed to not register more than one
8264 * protocol with the same name.
8265 */
8266
8267 if (g_hash_table_lookup(proto_names, name)) {
8268 /* ws_error will terminate the program */
8269 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)
8270 " 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)
;
8271 }
8272
8273 if (g_hash_table_lookup(proto_short_names, short_name)) {
8274 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)
8275 " 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)
;
8276 }
8277
8278 check_protocol_filter_name_or_fail(filter_name);
8279
8280 if (g_hash_table_lookup(proto_filter_names, filter_name)) {
8281 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)
8282 " 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)
;
8283 }
8284
8285 /*
8286 * Add this protocol to the list of known protocols;
8287 * the list is sorted by protocol short name.
8288 */
8289 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8290 protocol->name = name;
8291 protocol->short_name = short_name;
8292 protocol->filter_name = filter_name;
8293 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8294 protocol->is_enabled = true1; /* protocol is enabled by default */
8295 protocol->enabled_by_default = true1; /* see previous comment */
8296 protocol->can_toggle = true1;
8297 protocol->parent_proto_id = -1;
8298 protocol->heur_list = NULL((void*)0);
8299
8300 /* List will be sorted later by name, when all protocols completed registering */
8301 protocols = g_list_prepend(protocols, protocol);
8302 g_hash_table_insert(proto_names, (void *)name, protocol);
8303 g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol);
8304 g_hash_table_insert(proto_short_names, (void *)short_name, protocol);
8305
8306 /* Here we allocate a new header_field_info struct */
8307 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8308 hfinfo->name = name;
8309 hfinfo->abbrev = filter_name;
8310 hfinfo->type = FT_PROTOCOL;
8311 hfinfo->display = BASE_NONE;
8312 hfinfo->strings = protocol;
8313 hfinfo->bitmask = 0;
8314 hfinfo->ref_type = HF_REF_TYPE_NONE;
8315 hfinfo->blurb = NULL((void*)0);
8316 hfinfo->parent = -1; /* This field differentiates protos and fields */
8317
8318 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8319 return protocol->proto_id;
8320}
8321
8322int
8323proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8324{
8325 protocol_t *protocol;
8326 header_field_info *hfinfo;
8327
8328 /*
8329 * Helper protocols don't need the strict rules as a "regular" protocol
8330 * Just register it in a list and make a hf_ field from it
8331 */
8332 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8333 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)
;
8334 }
8335
8336 if (parent_proto <= 0) {
8337 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)
8338 " 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)
;
8339 }
8340
8341 check_protocol_filter_name_or_fail(filter_name);
8342
8343 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8344 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8345 protocol->name = name;
8346 protocol->short_name = short_name;
8347 protocol->filter_name = filter_name;
8348 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8349
8350 /* Enabling and toggling is really determined by parent protocol,
8351 but provide default values here */
8352 protocol->is_enabled = true1;
8353 protocol->enabled_by_default = true1;
8354 protocol->can_toggle = true1;
8355
8356 protocol->parent_proto_id = parent_proto;
8357 protocol->heur_list = NULL((void*)0);
8358
8359 /* List will be sorted later by name, when all protocols completed registering */
8360 protocols = g_list_prepend(protocols, protocol);
8361
8362 /* Here we allocate a new header_field_info struct */
8363 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8364 hfinfo->name = name;
8365 hfinfo->abbrev = filter_name;
8366 hfinfo->type = field_type;
8367 hfinfo->display = BASE_NONE;
8368 if (field_type == FT_BYTES) {
8369 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8370 }
8371 hfinfo->strings = protocol;
8372 hfinfo->bitmask = 0;
8373 hfinfo->ref_type = HF_REF_TYPE_NONE;
8374 hfinfo->blurb = NULL((void*)0);
8375 hfinfo->parent = -1; /* This field differentiates protos and fields */
8376
8377 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8378 return protocol->proto_id;
8379}
8380
8381bool_Bool
8382proto_deregister_protocol(const char *short_name)
8383{
8384 protocol_t *protocol;
8385 header_field_info *hfinfo;
8386 int proto_id;
8387 unsigned i;
8388
8389 proto_id = proto_get_id_by_short_name(short_name);
8390 protocol = find_protocol_by_id(proto_id);
8391 if (protocol == NULL((void*)0))
8392 return false0;
8393
8394 g_hash_table_remove(proto_names, protocol->name);
8395 g_hash_table_remove(proto_short_names, (void *)short_name);
8396 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8397
8398 if (protocol->fields) {
8399 for (i = 0; i < protocol->fields->len; i++) {
8400 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8401 hfinfo_remove_from_gpa_name_map(hfinfo);
8402 expert_deregister_expertinfo(hfinfo->abbrev);
8403 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8404 }
8405 g_ptr_array_free(protocol->fields, true1);
8406 protocol->fields = NULL((void*)0);
8407 }
8408
8409 g_list_free(protocol->heur_list);
8410
8411 /* Remove this protocol from the list of known protocols */
8412 protocols = g_list_remove(protocols, protocol);
8413
8414 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8415 g_hash_table_steal(gpa_name_map, protocol->filter_name);
8416
8417 g_free(last_field_name);
8418 last_field_name = NULL((void*)0);
8419
8420 return true1;
8421}
8422
8423void
8424proto_register_alias(const int proto_id, const char *alias_name)
8425{
8426 protocol_t *protocol;
8427
8428 protocol = find_protocol_by_id(proto_id);
8429 if (alias_name && protocol) {
8430 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8431 }
8432}
8433
8434/*
8435 * Routines to use to iterate over the protocols.
8436 * The argument passed to the iterator routines is an opaque cookie to
8437 * their callers; it's the GList pointer for the current element in
8438 * the list.
8439 * The ID of the protocol is returned, or -1 if there is no protocol.
8440 */
8441int
8442proto_get_first_protocol(void **cookie)
8443{
8444 protocol_t *protocol;
8445
8446 if (protocols == NULL((void*)0))
8447 return -1;
8448 *cookie = protocols;
8449 protocol = (protocol_t *)protocols->data;
8450 return protocol->proto_id;
8451}
8452
8453int
8454proto_get_data_protocol(void *cookie)
8455{
8456 GList *list_item = (GList *)cookie;
8457
8458 protocol_t *protocol = (protocol_t *)list_item->data;
8459 return protocol->proto_id;
8460}
8461
8462int
8463proto_get_next_protocol(void **cookie)
8464{
8465 GList *list_item = (GList *)*cookie;
8466 protocol_t *protocol;
8467
8468 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8469 if (list_item == NULL((void*)0))
8470 return -1;
8471 *cookie = list_item;
8472 protocol = (protocol_t *)list_item->data;
8473 return protocol->proto_id;
8474}
8475
8476header_field_info *
8477proto_get_first_protocol_field(const int proto_id, void **cookie)
8478{
8479 protocol_t *protocol = find_protocol_by_id(proto_id);
8480
8481 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8482 return NULL((void*)0);
8483
8484 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8485 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8486}
8487
8488header_field_info *
8489proto_get_next_protocol_field(const int proto_id, void **cookie)
8490{
8491 protocol_t *protocol = find_protocol_by_id(proto_id);
8492 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8493
8494 i++;
8495
8496 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8497 return NULL((void*)0);
8498
8499 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8500 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8501}
8502
8503protocol_t *
8504find_protocol_by_id(const int proto_id)
8505{
8506 header_field_info *hfinfo;
8507
8508 if (proto_id <= 0)
8509 return NULL((void*)0);
8510
8511 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", 8511, __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", 8511,
"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", 8511, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8512 if (hfinfo->type != FT_PROTOCOL) {
8513 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", 8513, "hfinfo->display & 0x00004000"
))))
;
8514 }
8515 return (protocol_t *)hfinfo->strings;
8516}
8517
8518int
8519proto_get_id(const protocol_t *protocol)
8520{
8521 return protocol->proto_id;
8522}
8523
8524bool_Bool
8525proto_name_already_registered(const char *name)
8526{
8527 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8527, "name", "No name present"))))
;
8528
8529 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8530 return true1;
8531 return false0;
8532}
8533
8534int
8535proto_get_id_by_filter_name(const char *filter_name)
8536{
8537 const protocol_t *protocol = NULL((void*)0);
8538
8539 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", 8539,
"filter_name", "No filter name present"))))
;
8540
8541 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8542
8543 if (protocol == NULL((void*)0))
8544 return -1;
8545 return protocol->proto_id;
8546}
8547
8548int
8549proto_get_id_by_short_name(const char *short_name)
8550{
8551 const protocol_t *protocol = NULL((void*)0);
8552
8553 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", 8553,
"short_name", "No short name present"))))
;
8554
8555 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8556
8557 if (protocol == NULL((void*)0))
8558 return -1;
8559 return protocol->proto_id;
8560}
8561
8562const char *
8563proto_get_protocol_name(const int proto_id)
8564{
8565 protocol_t *protocol;
8566
8567 protocol = find_protocol_by_id(proto_id);
8568
8569 if (protocol == NULL((void*)0))
8570 return NULL((void*)0);
8571 return protocol->name;
8572}
8573
8574const char *
8575proto_get_protocol_short_name(const protocol_t *protocol)
8576{
8577 if (protocol == NULL((void*)0))
8578 return "(none)";
8579 return protocol->short_name;
8580}
8581
8582const char *
8583proto_get_protocol_long_name(const protocol_t *protocol)
8584{
8585 if (protocol == NULL((void*)0))
8586 return "(none)";
8587 return protocol->name;
8588}
8589
8590const char *
8591proto_get_protocol_filter_name(const int proto_id)
8592{
8593 protocol_t *protocol;
8594
8595 protocol = find_protocol_by_id(proto_id);
8596 if (protocol == NULL((void*)0))
8597 return "(none)";
8598 return protocol->filter_name;
8599}
8600
8601void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8602{
8603 heur_dtbl_entry_t* heuristic_dissector;
8604
8605 if (protocol == NULL((void*)0))
8606 return;
8607
8608 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8609 if (heuristic_dissector != NULL((void*)0))
8610 {
8611 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8612 }
8613}
8614
8615void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8616{
8617 if (protocol == NULL((void*)0))
8618 return;
8619
8620 g_list_foreach(protocol->heur_list, func, user_data);
8621}
8622
8623void
8624proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8625 bool_Bool *is_tcp, bool_Bool *is_udp,
8626 bool_Bool *is_sctp, bool_Bool *is_tls,
8627 bool_Bool *is_rtp,
8628 bool_Bool *is_lte_rlc)
8629{
8630 wmem_list_frame_t *protos = wmem_list_head(layers);
8631 int proto_id;
8632 const char *proto_name;
8633
8634 /* Walk the list of a available protocols in the packet and
8635 attempt to find "major" ones. */
8636 /* It might make more sense to assemble and return a bitfield. */
8637 while (protos != NULL((void*)0))
8638 {
8639 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8640 proto_name = proto_get_protocol_filter_name(proto_id);
8641
8642 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8643 (!strcmp(proto_name, "ipv6")))) {
8644 *is_ip = true1;
8645 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8646 *is_tcp = true1;
8647 } else if (is_udp && !strcmp(proto_name, "udp")) {
8648 *is_udp = true1;
8649 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8650 *is_sctp = true1;
8651 } else if (is_tls && !strcmp(proto_name, "tls")) {
8652 *is_tls = true1;
8653 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8654 *is_rtp = true1;
8655 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8656 *is_lte_rlc = true1;
8657 }
8658
8659 protos = wmem_list_frame_next(protos);
8660 }
8661}
8662
8663bool_Bool
8664proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8665{
8666 wmem_list_frame_t *protos = wmem_list_head(layers);
8667 int proto_id;
8668 const char *name;
8669
8670 /* Walk the list of a available protocols in the packet and
8671 attempt to find the specified protocol. */
8672 while (protos != NULL((void*)0))
8673 {
8674 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8675 name = proto_get_protocol_filter_name(proto_id);
8676
8677 if (!strcmp(name, proto_name))
8678 {
8679 return true1;
8680 }
8681
8682 protos = wmem_list_frame_next(protos);
8683 }
8684
8685 return false0;
8686}
8687
8688char *
8689proto_list_layers(const packet_info *pinfo)
8690{
8691 wmem_strbuf_t *buf;
8692 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8693
8694 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8695
8696 /* Walk the list of layers in the packet and
8697 return a string of all entries. */
8698 while (layers != NULL((void*)0))
8699 {
8700 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8701
8702 layers = wmem_list_frame_next(layers);
8703 if (layers != NULL((void*)0)) {
8704 wmem_strbuf_append_c(buf, ':');
8705 }
8706 }
8707
8708 return wmem_strbuf_finalize(buf);
8709}
8710
8711uint8_t
8712proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8713{
8714 int *proto_layer_num_ptr;
8715
8716 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8717 if (proto_layer_num_ptr == NULL((void*)0)) {
8718 return 0;
8719 }
8720
8721 return (uint8_t)*proto_layer_num_ptr;
8722}
8723
8724bool_Bool
8725proto_is_pino(const protocol_t *protocol)
8726{
8727 return (protocol->parent_proto_id != -1);
8728}
8729
8730bool_Bool
8731// NOLINTNEXTLINE(misc-no-recursion)
8732proto_is_protocol_enabled(const protocol_t *protocol)
8733{
8734 if (protocol == NULL((void*)0))
8735 return false0;
8736
8737 //parent protocol determines enable/disable for helper dissectors
8738 if (proto_is_pino(protocol))
8739 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8740
8741 return protocol->is_enabled;
8742}
8743
8744bool_Bool
8745// NOLINTNEXTLINE(misc-no-recursion)
8746proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8747{
8748 //parent protocol determines enable/disable for helper dissectors
8749 if (proto_is_pino(protocol))
8750 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8751
8752 return protocol->enabled_by_default;
8753}
8754
8755bool_Bool
8756// NOLINTNEXTLINE(misc-no-recursion)
8757proto_can_toggle_protocol(const int proto_id)
8758{
8759 protocol_t *protocol;
8760
8761 protocol = find_protocol_by_id(proto_id);
8762 //parent protocol determines toggling for helper dissectors
8763 if (proto_is_pino(protocol))
8764 return proto_can_toggle_protocol(protocol->parent_proto_id);
8765
8766 return protocol->can_toggle;
8767}
8768
8769void
8770proto_disable_by_default(const int proto_id)
8771{
8772 protocol_t *protocol;
8773
8774 protocol = find_protocol_by_id(proto_id);
8775 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8775, "protocol->can_toggle"
))))
;
8776 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", 8776, "proto_is_pino(protocol) == 0"
))))
;
8777 protocol->is_enabled = false0;
8778 protocol->enabled_by_default = false0;
8779}
8780
8781void
8782proto_set_decoding(const int proto_id, const bool_Bool enabled)
8783{
8784 protocol_t *protocol;
8785
8786 protocol = find_protocol_by_id(proto_id);
8787 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8787, "protocol->can_toggle"
))))
;
8788 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", 8788, "proto_is_pino(protocol) == 0"
))))
;
8789 protocol->is_enabled = enabled;
8790}
8791
8792void
8793proto_disable_all(void)
8794{
8795 /* This doesn't explicitly disable heuristic protocols,
8796 * but the heuristic doesn't get called if the parent
8797 * protocol isn't enabled.
8798 */
8799 protocol_t *protocol;
8800 GList *list_item = protocols;
8801
8802 if (protocols == NULL((void*)0))
8803 return;
8804
8805 while (list_item) {
8806 protocol = (protocol_t *)list_item->data;
8807 if (protocol->can_toggle) {
8808 protocol->is_enabled = false0;
8809 }
8810 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8811 }
8812}
8813
8814static void
8815heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8816{
8817 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8818
8819 heur->enabled = heur->enabled_by_default;
8820}
8821
8822void
8823proto_reenable_all(void)
8824{
8825 protocol_t *protocol;
8826 GList *list_item = protocols;
8827
8828 if (protocols == NULL((void*)0))
8829 return;
8830
8831 while (list_item) {
8832 protocol = (protocol_t *)list_item->data;
8833 if (protocol->can_toggle)
8834 protocol->is_enabled = protocol->enabled_by_default;
8835 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8836 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8837 }
8838}
8839
8840void
8841proto_set_cant_toggle(const int proto_id)
8842{
8843 protocol_t *protocol;
8844
8845 protocol = find_protocol_by_id(proto_id);
8846 protocol->can_toggle = false0;
8847}
8848
8849static int
8850proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8851{
8852 if (proto != NULL((void*)0)) {
8853 g_ptr_array_add(proto->fields, hfi);
8854 }
8855
8856 return proto_register_field_init(hfi, parent);
8857}
8858
8859/* for use with static arrays only, since we don't allocate our own copies
8860of the header_field_info struct contained within the hf_register_info struct */
8861void
8862proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8863{
8864 hf_register_info *ptr = hf;
8865 protocol_t *proto;
8866 int i;
8867
8868 proto = find_protocol_by_id(parent);
8869
8870 if (proto->fields == NULL((void*)0)) {
8871 proto->fields = g_ptr_array_sized_new(num_records);
8872 }
8873
8874 for (i = 0; i < num_records; i++, ptr++) {
8875 /*
8876 * Make sure we haven't registered this yet.
8877 * Most fields have variables associated with them
8878 * that are initialized to -1; some have array elements,
8879 * or possibly uninitialized variables, so we also allow
8880 * 0 (which is unlikely to be the field ID we get back
8881 * from "proto_register_field_init()").
8882 */
8883 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8884 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8885 "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)
8886 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8887 return;
8888 }
8889
8890 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8891 }
8892}
8893
8894/* deregister already registered fields */
8895void
8896proto_deregister_field (const int parent, int hf_id)
8897{
8898 header_field_info *hfi;
8899 protocol_t *proto;
8900 unsigned i;
8901
8902 g_free(last_field_name);
8903 last_field_name = NULL((void*)0);
8904
8905 if (hf_id == -1 || hf_id == 0)
8906 return;
8907
8908 proto = find_protocol_by_id (parent);
8909 if (!proto || proto->fields == NULL((void*)0)) {
8910 return;
8911 }
8912
8913 for (i = 0; i < proto->fields->len; i++) {
8914 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8915 if (hfi->id == hf_id) {
8916 /* Found the hf_id in this protocol */
8917 g_hash_table_steal(gpa_name_map, hfi->abbrev);
8918 g_ptr_array_remove_index_fast(proto->fields, i);
8919 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8920 return;
8921 }
8922 }
8923}
8924
8925/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8926void
8927proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8928{
8929 header_field_info *hfinfo;
8930 protocol_t *proto;
8931
8932 g_free(last_field_name);
8933 last_field_name = NULL((void*)0);
8934
8935 proto = find_protocol_by_id(parent);
8936 if (proto && proto->fields && proto->fields->len > 0) {
8937 guint i = proto->fields->len;
8938 do {
8939 i--;
8940
8941 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8942 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) )
) {
8943 hfinfo_remove_from_gpa_name_map(hfinfo);
8944 expert_deregister_expertinfo(hfinfo->abbrev);
8945 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8946 g_ptr_array_remove_index_fast(proto->fields, i);
8947 }
8948 } while (i > 0);
8949 }
8950}
8951
8952void
8953proto_add_deregistered_data (void *data)
8954{
8955 g_ptr_array_add(deregistered_data, data);
8956}
8957
8958void
8959proto_add_deregistered_slice (size_t block_size, void *mem_block)
8960{
8961 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
)))
;
8962
8963 slice_data->block_size = block_size;
8964 slice_data->mem_block = mem_block;
8965
8966 g_ptr_array_add(deregistered_slice, slice_data);
8967}
8968
8969void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8970{
8971 if (field_strings == NULL((void*)0)) {
8972 return;
8973 }
8974
8975 switch (field_type) {
8976 case FT_FRAMENUM:
8977 /* This is just an integer represented as a pointer */
8978 break;
8979 case FT_PROTOCOL: {
8980 protocol_t *protocol = (protocol_t *)field_strings;
8981 g_free((char *)protocol->short_name);
8982 break;
8983 }
8984 case FT_BOOLEAN: {
8985 true_false_string *tf = (true_false_string *)field_strings;
8986 g_free((char *)tf->true_string);
8987 g_free((char *)tf->false_string);
8988 break;
8989 }
8990 case FT_UINT40:
8991 case FT_INT40:
8992 case FT_UINT48:
8993 case FT_INT48:
8994 case FT_UINT56:
8995 case FT_INT56:
8996 case FT_UINT64:
8997 case FT_INT64: {
8998 if (field_display & BASE_UNIT_STRING0x00001000) {
8999 unit_name_string *unit = (unit_name_string *)field_strings;
9000 g_free((char *)unit->singular);
9001 g_free((char *)unit->plural);
9002 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9003 range_string *rs = (range_string *)field_strings;
9004 while (rs->strptr) {
9005 g_free((char *)rs->strptr);
9006 rs++;
9007 }
9008 } else if (field_display & BASE_EXT_STRING0x00000200) {
9009 val64_string_ext *vse = (val64_string_ext *)field_strings;
9010 val64_string *vs = (val64_string *)vse->_vs_p;
9011 while (vs->strptr) {
9012 g_free((char *)vs->strptr);
9013 vs++;
9014 }
9015 val64_string_ext_free(vse);
9016 field_strings = NULL((void*)0);
9017 } else if (field_display == BASE_CUSTOM) {
9018 /* this will be a pointer to a function, don't free that */
9019 field_strings = NULL((void*)0);
9020 } else {
9021 val64_string *vs64 = (val64_string *)field_strings;
9022 while (vs64->strptr) {
9023 g_free((char *)vs64->strptr);
9024 vs64++;
9025 }
9026 }
9027 break;
9028 }
9029 case FT_CHAR:
9030 case FT_UINT8:
9031 case FT_INT8:
9032 case FT_UINT16:
9033 case FT_INT16:
9034 case FT_UINT24:
9035 case FT_INT24:
9036 case FT_UINT32:
9037 case FT_INT32:
9038 case FT_FLOAT:
9039 case FT_DOUBLE: {
9040 if (field_display & BASE_UNIT_STRING0x00001000) {
9041 unit_name_string *unit = (unit_name_string *)field_strings;
9042 g_free((char *)unit->singular);
9043 g_free((char *)unit->plural);
9044 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9045 range_string *rs = (range_string *)field_strings;
9046 while (rs->strptr) {
9047 g_free((char *)rs->strptr);
9048 rs++;
9049 }
9050 } else if (field_display & BASE_EXT_STRING0x00000200) {
9051 value_string_ext *vse = (value_string_ext *)field_strings;
9052 value_string *vs = (value_string *)vse->_vs_p;
9053 while (vs->strptr) {
9054 g_free((char *)vs->strptr);
9055 vs++;
9056 }
9057 value_string_ext_free(vse);
9058 field_strings = NULL((void*)0);
9059 } else if (field_display == BASE_CUSTOM) {
9060 /* this will be a pointer to a function, don't free that */
9061 field_strings = NULL((void*)0);
9062 } else {
9063 value_string *vs = (value_string *)field_strings;
9064 while (vs->strptr) {
9065 g_free((char *)vs->strptr);
9066 vs++;
9067 }
9068 }
9069 break;
9070 default:
9071 break;
9072 }
9073 }
9074
9075 if (field_type != FT_FRAMENUM) {
9076 g_free((void *)field_strings);
9077 }
9078}
9079
9080static void
9081free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9082{
9083 header_field_info *hfi = (header_field_info *) data;
9084 int hf_id = hfi->id;
9085
9086 g_free((char *)hfi->name);
9087 g_free((char *)hfi->abbrev);
9088 g_free((char *)hfi->blurb);
9089
9090 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9091
9092 if (hfi->parent == -1)
9093 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)
;
9094
9095 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9096}
9097
9098static void
9099free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9100{
9101 g_free (data);
9102}
9103
9104static void
9105free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9106{
9107 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9108
9109 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9110 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)
;
9111}
9112
9113/* free deregistered fields and data */
9114void
9115proto_free_deregistered_fields (void)
9116{
9117 expert_free_deregistered_expertinfos();
9118
9119 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9120 g_ptr_array_free(deregistered_fields, true1);
9121 deregistered_fields = g_ptr_array_new();
9122
9123 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9124 g_ptr_array_free(deregistered_data, true1);
9125 deregistered_data = g_ptr_array_new();
9126
9127 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9128 g_ptr_array_free(deregistered_slice, true1);
9129 deregistered_slice = g_ptr_array_new();
9130}
9131
9132static const value_string hf_display[] = {
9133 { BASE_NONE, "BASE_NONE" },
9134 { BASE_DEC, "BASE_DEC" },
9135 { BASE_HEX, "BASE_HEX" },
9136 { BASE_OCT, "BASE_OCT" },
9137 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9138 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9139 { BASE_CUSTOM, "BASE_CUSTOM" },
9140 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9141 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9142 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9143 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9144 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9145 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9146 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9147 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9148 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9149 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9150 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9151 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9152 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9153 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9154 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9155 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9156 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9157 { BASE_PT_UDP, "BASE_PT_UDP" },
9158 { BASE_PT_TCP, "BASE_PT_TCP" },
9159 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9160 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9161 { BASE_OUI, "BASE_OUI" },
9162 { 0, NULL((void*)0) } };
9163
9164const char* proto_field_display_to_string(int field_display)
9165{
9166 return val_to_str_const(field_display, hf_display, "Unknown");
9167}
9168
9169static inline port_type
9170display_to_port_type(field_display_e e)
9171{
9172 switch (e) {
9173 case BASE_PT_UDP:
9174 return PT_UDP;
9175 case BASE_PT_TCP:
9176 return PT_TCP;
9177 case BASE_PT_DCCP:
9178 return PT_DCCP;
9179 case BASE_PT_SCTP:
9180 return PT_SCTP;
9181 default:
9182 break;
9183 }
9184 return PT_NONE;
9185}
9186
9187/* temporary function containing assert part for easier profiling */
9188static void
9189tmp_fld_check_assert(header_field_info *hfinfo)
9190{
9191 char* tmp_str;
9192
9193 /* The field must have a name (with length > 0) */
9194 if (!hfinfo->name || !hfinfo->name[0]) {
9195 if (hfinfo->abbrev)
9196 /* Try to identify the field */
9197 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)
9198 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9199 else
9200 /* Hum, no luck */
9201 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)"
)
;
9202 }
9203
9204 /* fields with an empty string for an abbreviation aren't filterable */
9205 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9206 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)
;
9207
9208 /* These types of fields are allowed to have value_strings,
9209 * true_false_strings or a protocol_t struct
9210 */
9211 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9212 switch (hfinfo->type) {
9213
9214 /*
9215 * These types are allowed to support display value_strings,
9216 * value64_strings, the extended versions of the previous
9217 * two, range strings, or unit strings.
9218 */
9219 case FT_CHAR:
9220 case FT_UINT8:
9221 case FT_UINT16:
9222 case FT_UINT24:
9223 case FT_UINT32:
9224 case FT_UINT40:
9225 case FT_UINT48:
9226 case FT_UINT56:
9227 case FT_UINT64:
9228 case FT_INT8:
9229 case FT_INT16:
9230 case FT_INT24:
9231 case FT_INT32:
9232 case FT_INT40:
9233 case FT_INT48:
9234 case FT_INT56:
9235 case FT_INT64:
9236 case FT_BOOLEAN:
9237 case FT_PROTOCOL:
9238 break;
9239
9240 /*
9241 * This is allowed to have a value of type
9242 * enum ft_framenum_type to indicate what relationship
9243 * the frame in question has to the frame in which
9244 * the field is put.
9245 */
9246 case FT_FRAMENUM:
9247 break;
9248
9249 /*
9250 * These types are allowed to support only unit strings.
9251 */
9252 case FT_FLOAT:
9253 case FT_DOUBLE:
9254 case FT_IEEE_11073_SFLOAT:
9255 case FT_IEEE_11073_FLOAT:
9256 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9257 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))
9258 " (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))
9259 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))
;
9260 }
9261 break;
9262
9263 /*
9264 * These types are allowed to support display
9265 * time_value_strings.
9266 */
9267 case FT_ABSOLUTE_TIME:
9268 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9269 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9270 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9271 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9272 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))
9273 " (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))
9274 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))
;
9275 }
9276 break;
9277
9278 /*
9279 * This type is only allowed to support a string if it's
9280 * a protocol (for pinos).
9281 */
9282 case FT_BYTES:
9283 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9284 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))
9285 " (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))
9286 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))
;
9287 }
9288 break;
9289
9290 default:
9291 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))
9292 " (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))
9293 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))
;
9294 }
9295 }
9296
9297 /* TODO: This check may slow down startup, and output quite a few warnings.
9298 It would be good to be able to enable this (and possibly other checks?)
9299 in non-release builds. */
9300#ifdef ENABLE_CHECK_FILTER
9301 /* Check for duplicate value_string values.
9302 There are lots that have the same value *and* string, so for now only
9303 report those that have same value but different string. */
9304 if ((hfinfo->strings != NULL((void*)0)) &&
9305 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9306 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9307 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9308 (
9309 (hfinfo->type == FT_CHAR) ||
9310 (hfinfo->type == FT_UINT8) ||
9311 (hfinfo->type == FT_UINT16) ||
9312 (hfinfo->type == FT_UINT24) ||
9313 (hfinfo->type == FT_UINT32) ||
9314 (hfinfo->type == FT_INT8) ||
9315 (hfinfo->type == FT_INT16) ||
9316 (hfinfo->type == FT_INT24) ||
9317 (hfinfo->type == FT_INT32) )) {
9318
9319 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9320 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9321 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9322 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9323 } else {
9324 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9325 CHECK_HF_VALUE(value_string, "u", start_values);
9326 }
9327 } else {
9328 const value_string *start_values = (const value_string*)hfinfo->strings;
9329 CHECK_HF_VALUE(value_string, "u", start_values);
9330 }
9331 }
9332
9333 if (hfinfo->type == FT_BOOLEAN) {
9334 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9335 if (tfs) {
9336 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9337 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"
, 9339, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9338 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9339, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9339 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9339, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9340 }
9341 }
9342 }
9343
9344 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9345 const range_string *rs = (const range_string*)(hfinfo->strings);
9346 if (rs) {
9347 const range_string *this_it = rs;
9348
9349 do {
9350 if (this_it->value_max < this_it->value_min) {
9351 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"
, 9355, __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)
9352 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9355, __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)
9353 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9355, __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)
9354 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9355, __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)
9355 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9355, __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)
;
9356 ++this_it;
9357 continue;
9358 }
9359
9360 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9361 /* Not OK if this one is completely hidden by an earlier one! */
9362 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9363 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"
, 9369, __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)
9364 "(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"
, 9369, __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)
9365 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9369, __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)
9366 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9369, __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)
9367 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9369, __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)
9368 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9369, __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)
9369 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9369, __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)
;
9370 }
9371 }
9372 ++this_it;
9373 } while (this_it->strptr);
9374 }
9375 }
9376#endif
9377
9378 switch (hfinfo->type) {
9379
9380 case FT_CHAR:
9381 /* Require the char type to have BASE_HEX, BASE_OCT,
9382 * BASE_CUSTOM, or BASE_NONE as its base.
9383 *
9384 * If the display value is BASE_NONE and there is a
9385 * strings conversion then the dissector writer is
9386 * telling us that the field's numerical value is
9387 * meaningless; we'll avoid showing the value to the
9388 * user.
9389 */
9390 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9391 case BASE_HEX:
9392 case BASE_OCT:
9393 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9394 break;
9395 case BASE_NONE:
9396 if (hfinfo->strings == NULL((void*)0))
9397 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
))
9398 " 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
))
9399 " 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
))
9400 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
))
9401 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
))
;
9402 break;
9403 default:
9404 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9405 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)
9406 " 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)
9407 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)
9408 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)
;
9409 //wmem_free(NULL, tmp_str);
9410 }
9411 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9412 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
))
9413 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
))
9414 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
))
;
9415 }
9416 break;
9417 case FT_INT8:
9418 case FT_INT16:
9419 case FT_INT24:
9420 case FT_INT32:
9421 case FT_INT40:
9422 case FT_INT48:
9423 case FT_INT56:
9424 case FT_INT64:
9425 /* Hexadecimal and octal are, in printf() and everywhere
9426 * else, unsigned so don't allow dissectors to register a
9427 * signed field to be displayed unsigned. (Else how would
9428 * we display negative values?)
9429 */
9430 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9431 case BASE_HEX:
9432 case BASE_OCT:
9433 case BASE_DEC_HEX:
9434 case BASE_HEX_DEC:
9435 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9436 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)
9437 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)
9438 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)
;
9439 //wmem_free(NULL, tmp_str);
9440 }
9441 /* FALL THROUGH */
9442 case FT_UINT8:
9443 case FT_UINT16:
9444 case FT_UINT24:
9445 case FT_UINT32:
9446 case FT_UINT40:
9447 case FT_UINT48:
9448 case FT_UINT56:
9449 case FT_UINT64:
9450 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
))
) {
9451 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9452 if (hfinfo->type != FT_UINT16) {
9453 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))
9454 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))
9455 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))
;
9456 }
9457 if (hfinfo->strings != NULL((void*)0)) {
9458 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)
9459 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)
9460 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)
;
9461 }
9462 if (hfinfo->bitmask != 0) {
9463 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)
9464 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)
9465 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)
;
9466 }
9467 wmem_free(NULL((void*)0), tmp_str);
9468 break;
9469 }
9470
9471 if (hfinfo->display == BASE_OUI) {
9472 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9473 if (hfinfo->type != FT_UINT24) {
9474 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))
9475 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))
9476 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))
;
9477 }
9478 if (hfinfo->strings != NULL((void*)0)) {
9479 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)
9480 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)
9481 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)
;
9482 }
9483 if (hfinfo->bitmask != 0) {
9484 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)
9485 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)
9486 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)
;
9487 }
9488 wmem_free(NULL((void*)0), tmp_str);
9489 break;
9490 }
9491
9492 /* Require integral types (other than frame number,
9493 * which is always displayed in decimal) to have a
9494 * number base.
9495 *
9496 * If the display value is BASE_NONE and there is a
9497 * strings conversion then the dissector writer is
9498 * telling us that the field's numerical value is
9499 * meaningless; we'll avoid showing the value to the
9500 * user.
9501 */
9502 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9503 case BASE_DEC:
9504 case BASE_HEX:
9505 case BASE_OCT:
9506 case BASE_DEC_HEX:
9507 case BASE_HEX_DEC:
9508 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9509 break;
9510 case BASE_NONE:
9511 if (hfinfo->strings == NULL((void*)0)) {
9512 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
))
9513 " 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
))
9514 " 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
))
9515 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
))
9516 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
))
;
9517 }
9518 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9519 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
))
9520 " 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
))
9521 " 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
))
9522 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
))
9523 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
))
;
9524 }
9525 break;
9526
9527 default:
9528 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9529 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)
9530 " 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)
9531 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)
9532 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)
;
9533 //wmem_free(NULL, tmp_str);
9534 }
9535 break;
9536 case FT_BYTES:
9537 case FT_UINT_BYTES:
9538 /* Require bytes to have a "display type" that could
9539 * add a character between displayed bytes.
9540 */
9541 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9542 case BASE_NONE:
9543 case SEP_DOT:
9544 case SEP_DASH:
9545 case SEP_COLON:
9546 case SEP_SPACE:
9547 break;
9548 default:
9549 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9550 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)
9551 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)
;
9552 //wmem_free(NULL, tmp_str);
9553 }
9554 if (hfinfo->bitmask != 0)
9555 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
))
9556 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
))
9557 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
))
;
9558 //allowed to support string if its a protocol (for pinos)
9559 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9560 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
))
9561 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
))
9562 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
))
;
9563 break;
9564
9565 case FT_PROTOCOL:
9566 case FT_FRAMENUM:
9567 if (hfinfo->display != BASE_NONE) {
9568 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9569 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)
9570 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)
9571 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)
;
9572 //wmem_free(NULL, tmp_str);
9573 }
9574 if (hfinfo->bitmask != 0)
9575 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
))
9576 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
))
9577 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
))
;
9578 break;
9579
9580 case FT_BOOLEAN:
9581 break;
9582
9583 case FT_ABSOLUTE_TIME:
9584 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9585 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9586 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)
9587 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)
;
9588 //wmem_free(NULL, tmp_str);
9589 }
9590 if (hfinfo->bitmask != 0)
9591 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
))
9592 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
))
9593 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
))
;
9594 break;
9595
9596 case FT_STRING:
9597 case FT_STRINGZ:
9598 case FT_UINT_STRING:
9599 case FT_STRINGZPAD:
9600 case FT_STRINGZTRUNC:
9601 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9602 case BASE_NONE:
9603 case BASE_STR_WSP:
9604 break;
9605
9606 default:
9607 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9608 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)
9609 " 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)
9610 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)
9611 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)
;
9612 //wmem_free(NULL, tmp_str);
9613 }
9614
9615 if (hfinfo->bitmask != 0)
9616 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
))
9617 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
))
9618 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
))
;
9619 if (hfinfo->strings != NULL((void*)0))
9620 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
))
9621 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
))
9622 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
))
;
9623 break;
9624
9625 case FT_IPv4:
9626 switch (hfinfo->display) {
9627 case BASE_NONE:
9628 case BASE_NETMASK:
9629 break;
9630
9631 default:
9632 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9633 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)
9634 " 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)
9635 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)
9636 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)
;
9637 //wmem_free(NULL, tmp_str);
9638 break;
9639 }
9640 break;
9641 case FT_FLOAT:
9642 case FT_DOUBLE:
9643 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9644 case BASE_NONE:
9645 case BASE_DEC:
9646 case BASE_HEX:
9647 case BASE_EXP:
9648 case BASE_CUSTOM:
9649 break;
9650 default:
9651 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9652 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)
9653 " 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)
9654 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)
9655 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)
;
9656 //wmem_free(NULL, tmp_str);
9657 }
9658 if (hfinfo->bitmask != 0)
9659 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
))
9660 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
))
9661 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
))
;
9662 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9663 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
))
9664 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
))
9665 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
))
;
9666 break;
9667 case FT_IEEE_11073_SFLOAT:
9668 case FT_IEEE_11073_FLOAT:
9669 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9670 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9671 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)
9672 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)
9673 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)
9674 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)
;
9675 //wmem_free(NULL, tmp_str);
9676 }
9677 if (hfinfo->bitmask != 0)
9678 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
))
9679 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
))
9680 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
))
;
9681 if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9682 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
))
9683 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
))
9684 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
))
;
9685 break;
9686 default:
9687 if (hfinfo->display != BASE_NONE) {
9688 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9689 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)
9690 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)
9691 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)
9692 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)
;
9693 //wmem_free(NULL, tmp_str);
9694 }
9695 if (hfinfo->bitmask != 0)
9696 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
))
9697 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
))
9698 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
))
;
9699 if (hfinfo->strings != NULL((void*)0))
9700 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
))
9701 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
))
9702 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
))
;
9703 break;
9704 }
9705}
9706
9707static void
9708register_type_length_mismatch(void)
9709{
9710 static ei_register_info ei[] = {
9711 { &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)}}
}},
9712 { &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)}}
}},
9713 };
9714
9715 expert_module_t* expert_type_length_mismatch;
9716
9717 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9718
9719 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9720 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9721
9722 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9723 disabling them makes no sense. */
9724 proto_set_cant_toggle(proto_type_length_mismatch);
9725}
9726
9727static void
9728register_byte_array_string_decodinws_error(void)
9729{
9730 static ei_register_info ei[] = {
9731 { &ei_byte_array_string_decoding_failed_error,
9732 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9733 "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)}}
9734 }
9735 },
9736 };
9737
9738 expert_module_t* expert_byte_array_string_decoding_error;
9739
9740 proto_byte_array_string_decoding_error =
9741 proto_register_protocol("Byte Array-String Decoding Error",
9742 "Byte Array-string decoding error",
9743 "_ws.byte_array_string.decoding_error");
9744
9745 expert_byte_array_string_decoding_error =
9746 expert_register_protocol(proto_byte_array_string_decoding_error);
9747 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9748
9749 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9750 disabling them makes no sense. */
9751 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9752}
9753
9754static void
9755register_date_time_string_decodinws_error(void)
9756{
9757 static ei_register_info ei[] = {
9758 { &ei_date_time_string_decoding_failed_error,
9759 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9760 "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)}}
9761 }
9762 },
9763 };
9764
9765 expert_module_t* expert_date_time_string_decoding_error;
9766
9767 proto_date_time_string_decoding_error =
9768 proto_register_protocol("Date and Time-String Decoding Error",
9769 "Date and Time-string decoding error",
9770 "_ws.date_time_string.decoding_error");
9771
9772 expert_date_time_string_decoding_error =
9773 expert_register_protocol(proto_date_time_string_decoding_error);
9774 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9775
9776 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9777 disabling them makes no sense. */
9778 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9779}
9780
9781static void
9782register_string_errors(void)
9783{
9784 static ei_register_info ei[] = {
9785 { &ei_string_trailing_characters,
9786 { "_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)}}
}
9787 },
9788 };
9789
9790 expert_module_t* expert_string_errors;
9791
9792 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9793
9794 expert_string_errors = expert_register_protocol(proto_string_errors);
9795 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9796
9797 /* "String Errors" isn't really a protocol, it's an error indication;
9798 disabling them makes no sense. */
9799 proto_set_cant_toggle(proto_string_errors);
9800}
9801
9802#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
9803static int
9804proto_register_field_init(header_field_info *hfinfo, const int parent)
9805{
9806
9807 tmp_fld_check_assert(hfinfo);
9808
9809 hfinfo->parent = parent;
9810 hfinfo->same_name_next = NULL((void*)0);
9811 hfinfo->same_name_prev_id = -1;
9812
9813 /* if we always add and never delete, then id == len - 1 is correct */
9814 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9815 if (!gpa_hfinfo.hfi) {
9816 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9817 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9818 /* The entry with index 0 is not used. */
9819 gpa_hfinfo.hfi[0] = NULL((void*)0);
9820 gpa_hfinfo.len = 1;
9821 } else {
9822 gpa_hfinfo.allocated_len += 1000;
9823 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9824 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9825 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9826 }
9827 }
9828 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9829 gpa_hfinfo.len++;
9830 hfinfo->id = gpa_hfinfo.len - 1;
9831
9832 /* if we have real names, enter this field in the name tree */
9833 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
9834
9835 header_field_info *same_name_next_hfinfo;
9836 unsigned char c;
9837
9838 /* Check that the filter name (abbreviation) is legal;
9839 * it must contain only alphanumerics, '-', "_", and ".". */
9840 c = proto_check_field_name(hfinfo->abbrev);
9841 if (c) {
9842 if (c == '.') {
9843 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)
;
9844 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9845 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)
;
9846 } else {
9847 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)
;
9848 }
9849 }
9850
9851 /* We allow multiple hfinfo's to be registered under the same
9852 * abbreviation. This was done for X.25, as, depending
9853 * on whether it's modulo-8 or modulo-128 operation,
9854 * some bitfield fields may be in different bits of
9855 * a byte, and we want to be able to refer to that field
9856 * with one name regardless of whether the packets
9857 * are modulo-8 or modulo-128 packets. */
9858
9859 same_name_hfinfo = NULL((void*)0);
9860
9861 g_hash_table_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9862 /* GLIB 2.x - if it is already present
9863 * the previous hfinfo with the same name is saved
9864 * to same_name_hfinfo by value destroy callback */
9865 if (same_name_hfinfo) {
9866 /* There's already a field with this name.
9867 * Put the current field *before* that field
9868 * in the list of fields with this name, Thus,
9869 * we end up with an effectively
9870 * doubly-linked-list of same-named hfinfo's,
9871 * with the head of the list (stored in the
9872 * hash) being the last seen hfinfo.
9873 */
9874 same_name_next_hfinfo =
9875 same_name_hfinfo->same_name_next;
9876
9877 hfinfo->same_name_next = same_name_next_hfinfo;
9878 if (same_name_next_hfinfo)
9879 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9880
9881 same_name_hfinfo->same_name_next = hfinfo;
9882 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9883#ifdef ENABLE_CHECK_FILTER
9884 while (same_name_hfinfo) {
9885 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9886 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"
, 9886, __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)
;
9887 same_name_hfinfo = same_name_hfinfo->same_name_next;
9888 }
9889#endif
9890 }
9891 }
9892
9893 return hfinfo->id;
9894}
9895
9896void
9897proto_register_subtree_array(int * const *indices, const int num_indices)
9898{
9899 int i;
9900 int *const *ptr = indices;
9901
9902 /*
9903 * If we've already allocated the array of tree types, expand
9904 * it; this lets plugins such as mate add tree types after
9905 * the initial startup. (If we haven't already allocated it,
9906 * we don't allocate it; on the first pass, we just assign
9907 * ett values and keep track of how many we've assigned, and
9908 * when we're finished registering all dissectors we allocate
9909 * the array, so that we do only one allocation rather than
9910 * wasting CPU time and memory by growing the array for each
9911 * dissector that registers ett values.)
9912 */
9913 if (tree_is_expanded != NULL((void*)0)) {
9914 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9915
9916 /* set new items to 0 */
9917 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9918 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9919 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9920 }
9921
9922 /*
9923 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9924 * returning the indices through the pointers in the array whose
9925 * first element is pointed to by "indices", and update
9926 * "num_tree_types" appropriately.
9927 */
9928 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9929 if (**ptr != -1 && **ptr != 0) {
9930 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.")
9931 " 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.")
9932 " 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.")
9933 " 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.")
;
9934 }
9935 **ptr = num_tree_types;
9936 }
9937}
9938
9939static void
9940mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
9941{
9942 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
9943 const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
9944 char *last_char;
9945
9946 /* ..... field_name: dataaaaaaaaaaaaa
9947 * |
9948 * ^^^^^ name_pos
9949 *
9950 * ..... field_name […]: dataaaaaaaaaaaaa
9951 *
9952 * name_pos==0 means that we have only data or only a field_name
9953 */
9954
9955 if (name_pos < size - trunc_len) {
9956 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
9957 if (name_pos == 0) {
9958 /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
9959 memcpy(label_str, trunc_str + 1, trunc_len);
9960 } else {
9961 memcpy(label_str + name_pos, trunc_str, trunc_len);
9962 }
9963 /* in general, label_str is UTF-8
9964 we can truncate it only at the beginning of a new character
9965 we go backwards from the byte right after our buffer and
9966 find the next starting byte of a UTF-8 character, this is
9967 where we cut
9968 there's no need to use g_utf8_find_prev_char(), the search
9969 will always succeed since we copied trunc_str into the
9970 buffer */
9971 /* g_utf8_prev_char does not deference the memory address
9972 * passed in (until after decrementing it, so it is perfectly
9973 * legal to pass in a pointer one past the last element.
9974 */
9975 last_char = g_utf8_prev_char(label_str + size);
9976 *last_char = '\0';
9977
9978 if (value_pos && *value_pos > 0) {
9979 if (name_pos == 0) {
9980 *value_pos += trunc_len;
9981 } else {
9982 /* Move one back to include trunc_str in the value. */
9983 *value_pos -= 1;
9984 }
9985 }
9986 } else if (name_pos < size)
9987 (void) g_strlcpy(label_str + name_pos, trunc_str, size - name_pos);
9988}
9989
9990static void
9991label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
9992{
9993 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
9994}
9995
9996static size_t
9997label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
9998{
9999 size_t name_pos;
10000
10001 /* "%s: %s", hfinfo->name, text */
10002 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10003 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10004 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10005 if (value_pos) {
10006 *value_pos = pos;
10007 }
10008 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
10009 }
10010
10011 if (pos >= ITEM_LABEL_LENGTH240) {
10012 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10013 label_mark_truncated(label_str, name_pos, value_pos);
10014 }
10015
10016 return pos;
10017}
10018
10019static size_t
10020label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10021{
10022 size_t name_pos;
10023
10024 /* "%s: %s (%s)", hfinfo->name, text, descr */
10025 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10026 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10027 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10028 if (value_pos) {
10029 *value_pos = pos;
10030 }
10031 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10032 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10033 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10034 } else {
10035 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10036 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10037 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10038 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10039 }
10040 }
10041
10042 if (pos >= ITEM_LABEL_LENGTH240) {
10043 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10044 label_mark_truncated(label_str, name_pos, value_pos);
10045 }
10046
10047 return pos;
10048}
10049
10050void
10051proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10052{
10053 const header_field_info *hfinfo;
10054 const char *str;
10055 const uint8_t *bytes;
10056 uint32_t integer;
10057 const ipv4_addr_and_mask *ipv4;
10058 const ipv6_addr_and_prefix *ipv6;
10059 const e_guid_t *guid;
10060 char *name;
10061 address addr;
10062 char *addr_str;
10063 char *tmp;
10064
10065 if (!label_str) {
10066 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10066, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10067 return;
10068 }
10069
10070 label_str[0]= '\0';
10071
10072 if (!fi) {
10073 return;
10074 }
10075
10076 hfinfo = fi->hfinfo;
10077
10078 switch (hfinfo->type) {
10079 case FT_NONE:
10080 case FT_PROTOCOL:
10081 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10082 if (value_pos) {
10083 *value_pos = strlen(hfinfo->name);
10084 }
10085 break;
10086
10087 case FT_BOOLEAN:
10088 fill_label_boolean(fi, label_str, value_pos);
10089 break;
10090
10091 case FT_BYTES:
10092 case FT_UINT_BYTES:
10093 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10094 fvalue_get_bytes_data(fi->value),
10095 (unsigned)fvalue_length2(fi->value));
10096 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10097 wmem_free(NULL((void*)0), tmp);
10098 break;
10099
10100 case FT_CHAR:
10101 if (hfinfo->bitmask) {
10102 fill_label_bitfield_char(fi, label_str, value_pos);
10103 } else {
10104 fill_label_char(fi, label_str, value_pos);
10105 }
10106 break;
10107
10108 /* Four types of integers to take care of:
10109 * Bitfield, with val_string
10110 * Bitfield, w/o val_string
10111 * Non-bitfield, with val_string
10112 * Non-bitfield, w/o val_string
10113 */
10114 case FT_UINT8:
10115 case FT_UINT16:
10116 case FT_UINT24:
10117 case FT_UINT32:
10118 if (hfinfo->bitmask) {
10119 fill_label_bitfield(fi, label_str, value_pos, false0);
10120 } else {
10121 fill_label_number(fi, label_str, value_pos, false0);
10122 }
10123 break;
10124
10125 case FT_FRAMENUM:
10126 fill_label_number(fi, label_str, value_pos, false0);
10127 break;
10128
10129 case FT_UINT40:
10130 case FT_UINT48:
10131 case FT_UINT56:
10132 case FT_UINT64:
10133 if (hfinfo->bitmask) {
10134 fill_label_bitfield64(fi, label_str, value_pos, false0);
10135 } else {
10136 fill_label_number64(fi, label_str, value_pos, false0);
10137 }
10138 break;
10139
10140 case FT_INT8:
10141 case FT_INT16:
10142 case FT_INT24:
10143 case FT_INT32:
10144 if (hfinfo->bitmask) {
10145 fill_label_bitfield(fi, label_str, value_pos, true1);
10146 } else {
10147 fill_label_number(fi, label_str, value_pos, true1);
10148 }
10149 break;
10150
10151 case FT_INT40:
10152 case FT_INT48:
10153 case FT_INT56:
10154 case FT_INT64:
10155 if (hfinfo->bitmask) {
10156 fill_label_bitfield64(fi, label_str, value_pos, true1);
10157 } else {
10158 fill_label_number64(fi, label_str, value_pos, true1);
10159 }
10160 break;
10161
10162 case FT_FLOAT:
10163 case FT_DOUBLE:
10164 fill_label_float(fi, label_str, value_pos);
10165 break;
10166
10167 case FT_ABSOLUTE_TIME:
10168 {
10169 const nstime_t *value = fvalue_get_time(fi->value);
10170 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10171 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10172 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10173 }
10174 if (hfinfo->strings) {
10175 /*
10176 * Table of time valus to be displayed
10177 * specially.
10178 */
10179 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10180 if (time_string != NULL((void*)0)) {
10181 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10182 break;
10183 }
10184 }
10185 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10186 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10187 wmem_free(NULL((void*)0), tmp);
10188 break;
10189 }
10190 case FT_RELATIVE_TIME:
10191 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10192 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10193 wmem_free(NULL((void*)0), tmp);
10194 break;
10195
10196 case FT_IPXNET:
10197 integer = fvalue_get_uinteger(fi->value);
10198 tmp = get_ipxnet_name(NULL((void*)0), integer);
10199 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10200 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10201 wmem_free(NULL((void*)0), tmp);
10202 wmem_free(NULL((void*)0), addr_str);
10203 break;
10204
10205 case FT_VINES:
10206 addr.type = AT_VINES;
10207 addr.len = VINES_ADDR_LEN6;
10208 addr.data = fvalue_get_bytes_data(fi->value);
10209
10210 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10211 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10212 wmem_free(NULL((void*)0), addr_str);
10213 break;
10214
10215 case FT_ETHER:
10216 bytes = fvalue_get_bytes_data(fi->value);
10217
10218 addr.type = AT_ETHER;
10219 addr.len = 6;
10220 addr.data = bytes;
10221
10222 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10223 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10224 wmem_free(NULL((void*)0), addr_str);
10225 break;
10226
10227 case FT_IPv4:
10228 ipv4 = fvalue_get_ipv4(fi->value);
10229 set_address_ipv4(&addr, ipv4);
10230
10231 if (hfinfo->display == BASE_NETMASK) {
10232 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10233 } else {
10234 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10235 }
10236 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10237 wmem_free(NULL((void*)0), addr_str);
10238 free_address(&addr);
10239 break;
10240
10241 case FT_IPv6:
10242 ipv6 = fvalue_get_ipv6(fi->value);
10243 set_address_ipv6(&addr, ipv6);
10244
10245 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10246 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10247 wmem_free(NULL((void*)0), addr_str);
10248 free_address(&addr);
10249 break;
10250
10251 case FT_FCWWN:
10252 bytes = fvalue_get_bytes_data(fi->value);
10253 addr.type = AT_FCWWN;
10254 addr.len = FCWWN_ADDR_LEN8;
10255 addr.data = bytes;
10256
10257 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10258 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10259 wmem_free(NULL((void*)0), addr_str);
10260 break;
10261
10262 case FT_GUID:
10263 guid = fvalue_get_guid(fi->value);
10264 tmp = guid_to_str(NULL((void*)0), guid);
10265 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10266 wmem_free(NULL((void*)0), tmp);
10267 break;
10268
10269 case FT_OID:
10270 bytes = fvalue_get_bytes_data(fi->value);
10271 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10272 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10273 if (name) {
10274 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10275 wmem_free(NULL((void*)0), name);
10276 } else {
10277 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10278 }
10279 wmem_free(NULL((void*)0), tmp);
10280 break;
10281
10282 case FT_REL_OID:
10283 bytes = fvalue_get_bytes_data(fi->value);
10284 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10285 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10286 if (name) {
10287 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10288 wmem_free(NULL((void*)0), name);
10289 } else {
10290 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10291 }
10292 wmem_free(NULL((void*)0), tmp);
10293 break;
10294
10295 case FT_SYSTEM_ID:
10296 bytes = fvalue_get_bytes_data(fi->value);
10297 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10298 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10299 wmem_free(NULL((void*)0), tmp);
10300 break;
10301
10302 case FT_EUI64:
10303 bytes = fvalue_get_bytes_data(fi->value);
10304 addr.type = AT_EUI64;
10305 addr.len = EUI64_ADDR_LEN8;
10306 addr.data = bytes;
10307
10308 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10309 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10310 wmem_free(NULL((void*)0), addr_str);
10311 break;
10312 case FT_STRING:
10313 case FT_STRINGZ:
10314 case FT_UINT_STRING:
10315 case FT_STRINGZPAD:
10316 case FT_STRINGZTRUNC:
10317 case FT_AX25:
10318 str = fvalue_get_string(fi->value);
10319 label_fill(label_str, 0, hfinfo, str, value_pos);
10320 break;
10321
10322 case FT_IEEE_11073_SFLOAT:
10323 case FT_IEEE_11073_FLOAT:
10324 fill_label_ieee_11073_float(fi, label_str, value_pos);
10325 break;
10326
10327 default:
10328 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
))
10329 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
))
10330 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
))
10331 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
))
;
10332 break;
10333 }
10334}
10335
10336static void
10337fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10338{
10339 char *p;
10340 int bitfield_byte_length = 0, bitwidth;
10341 uint64_t unshifted_value;
10342 uint64_t value;
10343
10344 const header_field_info *hfinfo = fi->hfinfo;
10345
10346 value = fvalue_get_uinteger64(fi->value);
10347 if (hfinfo->bitmask) {
10348 /* Figure out the bit width */
10349 bitwidth = hfinfo_container_bitwidth(hfinfo);
10350
10351 /* Un-shift bits */
10352 unshifted_value = value;
10353 unshifted_value <<= hfinfo_bitshift(hfinfo);
10354
10355 /* Create the bitfield first */
10356 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10357 bitfield_byte_length = (int) (p - label_str);
10358 }
10359
10360 /* Fill in the textual info */
10361 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10362}
10363
10364static const char *
10365hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10366{
10367 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10368 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10369
10370 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10371 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10372 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10373 else
10374 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10375 }
10376
10377 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10378 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10379
10380 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10381 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10382
10383 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10384}
10385
10386static const char *
10387hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10388{
10389 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10390 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10391 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10392 else
10393 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10394 }
10395
10396 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10397 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10398
10399 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10400 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10401
10402 /* If this is reached somebody registered a 64-bit field with a 32-bit
10403 * value-string, which isn't right. */
10404 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)
10405 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10406
10407 /* This is necessary to squelch MSVC errors; is there
10408 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10409 never returns? */
10410 return NULL((void*)0);
10411}
10412
10413static const char *
10414hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10415{
10416 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10417 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10418
10419 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)
;
10420
10421 /* This is necessary to squelch MSVC errors; is there
10422 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10423 never returns? */
10424 return NULL((void*)0);
10425}
10426
10427static const char *
10428hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10429{
10430 const char *str = hf_try_val_to_str(value, hfinfo);
10431
10432 return (str) ? str : unknown_str;
10433}
10434
10435static const char *
10436hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10437{
10438 const char *str = hf_try_val64_to_str(value, hfinfo);
10439
10440 return (str) ? str : unknown_str;
10441}
10442
10443/* Fills data for bitfield chars with val_strings */
10444static void
10445fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10446{
10447 char *p;
10448 int bitfield_byte_length, bitwidth;
10449 uint32_t unshifted_value;
10450 uint32_t value;
10451
10452 char buf[32];
10453 const char *out;
10454
10455 const header_field_info *hfinfo = fi->hfinfo;
10456
10457 /* Figure out the bit width */
10458 bitwidth = hfinfo_container_bitwidth(hfinfo);
10459
10460 /* Un-shift bits */
10461 value = fvalue_get_uinteger(fi->value);
10462
10463 unshifted_value = value;
10464 if (hfinfo->bitmask) {
10465 unshifted_value <<= hfinfo_bitshift(hfinfo);
10466 }
10467
10468 /* Create the bitfield first */
10469 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10470 bitfield_byte_length = (int) (p - label_str);
10471
10472 /* Fill in the textual info using stored (shifted) value */
10473 if (hfinfo->display == BASE_CUSTOM) {
10474 char tmp[ITEM_LABEL_LENGTH240];
10475 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10476
10477 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10477, "fmtfunc"))))
;
10478 fmtfunc(tmp, value);
10479 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10480 }
10481 else if (hfinfo->strings) {
10482 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10483
10484 out = hfinfo_char_vals_format(hfinfo, buf, value);
10485 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10486 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10487 else
10488 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10489 }
10490 else {
10491 out = hfinfo_char_value_format(hfinfo, buf, value);
10492
10493 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10494 }
10495}
10496
10497/* Fills data for bitfield ints with val_strings */
10498static void
10499fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10500{
10501 char *p;
10502 int bitfield_byte_length, bitwidth;
10503 uint32_t value, unshifted_value;
10504 char buf[NUMBER_LABEL_LENGTH80];
10505 const char *out;
10506
10507 const header_field_info *hfinfo = fi->hfinfo;
10508
10509 /* Figure out the bit width */
10510 if (fi->flags & FI_VARINT0x00040000)
10511 bitwidth = fi->length*8;
10512 else
10513 bitwidth = hfinfo_container_bitwidth(hfinfo);
10514
10515 /* Un-shift bits */
10516 if (is_signed)
10517 value = fvalue_get_sinteger(fi->value);
10518 else
10519 value = fvalue_get_uinteger(fi->value);
10520
10521 unshifted_value = value;
10522 if (hfinfo->bitmask) {
10523 unshifted_value <<= hfinfo_bitshift(hfinfo);
10524 }
10525
10526 /* Create the bitfield first */
10527 if (fi->flags & FI_VARINT0x00040000)
10528 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10529 else
10530 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10531 bitfield_byte_length = (int) (p - label_str);
10532
10533 /* Fill in the textual info using stored (shifted) value */
10534 if (hfinfo->display == BASE_CUSTOM) {
10535 char tmp[ITEM_LABEL_LENGTH240];
10536 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10537
10538 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10538, "fmtfunc"))))
;
10539 fmtfunc(tmp, value);
10540 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10541 }
10542 else if (hfinfo->strings) {
10543 const char *val_str = hf_try_val_to_str(value, hfinfo);
10544
10545 out = hfinfo_number_vals_format(hfinfo, buf, value);
10546 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10547 /*
10548 * Unique values only display value_string string
10549 * if there is a match. Otherwise it's just a number
10550 */
10551 if (val_str) {
10552 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10553 } else {
10554 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10555 }
10556 } else {
10557 if (val_str == NULL((void*)0))
10558 val_str = "Unknown";
10559
10560 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10561 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10562 else
10563 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10564 }
10565 }
10566 else {
10567 out = hfinfo_number_value_format(hfinfo, buf, value);
10568
10569 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10570 }
10571}
10572
10573static void
10574fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10575{
10576 char *p;
10577 int bitfield_byte_length, bitwidth;
10578 uint64_t value, unshifted_value;
10579 char buf[NUMBER_LABEL_LENGTH80];
10580 const char *out;
10581
10582 const header_field_info *hfinfo = fi->hfinfo;
10583
10584 /* Figure out the bit width */
10585 if (fi->flags & FI_VARINT0x00040000)
10586 bitwidth = fi->length*8;
10587 else
10588 bitwidth = hfinfo_container_bitwidth(hfinfo);
10589
10590 /* Un-shift bits */
10591 if (is_signed)
10592 value = fvalue_get_sinteger64(fi->value);
10593 else
10594 value = fvalue_get_uinteger64(fi->value);
10595
10596 unshifted_value = value;
10597 if (hfinfo->bitmask) {
10598 unshifted_value <<= hfinfo_bitshift(hfinfo);
10599 }
10600
10601 /* Create the bitfield first */
10602 if (fi->flags & FI_VARINT0x00040000)
10603 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10604 else
10605 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10606 bitfield_byte_length = (int) (p - label_str);
10607
10608 /* Fill in the textual info using stored (shifted) value */
10609 if (hfinfo->display == BASE_CUSTOM) {
10610 char tmp[ITEM_LABEL_LENGTH240];
10611 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10612
10613 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10613, "fmtfunc64"
))))
;
10614 fmtfunc64(tmp, value);
10615 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10616 }
10617 else if (hfinfo->strings) {
10618 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10619
10620 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10621 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10622 /*
10623 * Unique values only display value_string string
10624 * if there is a match. Otherwise it's just a number
10625 */
10626 if (val_str) {
10627 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10628 } else {
10629 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10630 }
10631 } else {
10632 if (val_str == NULL((void*)0))
10633 val_str = "Unknown";
10634
10635 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10636 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10637 else
10638 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10639 }
10640 }
10641 else {
10642 out = hfinfo_number_value_format64(hfinfo, buf, value);
10643
10644 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10645 }
10646}
10647
10648static void
10649fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10650{
10651 const header_field_info *hfinfo = fi->hfinfo;
10652 uint32_t value;
10653
10654 char buf[32];
10655 const char *out;
10656
10657 value = fvalue_get_uinteger(fi->value);
10658
10659 /* Fill in the textual info */
10660 if (hfinfo->display == BASE_CUSTOM) {
10661 char tmp[ITEM_LABEL_LENGTH240];
10662 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10663
10664 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10664, "fmtfunc"))))
;
10665 fmtfunc(tmp, value);
10666 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10667 }
10668 else if (hfinfo->strings) {
10669 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10670
10671 out = hfinfo_char_vals_format(hfinfo, buf, value);
10672 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10673 }
10674 else {
10675 out = hfinfo_char_value_format(hfinfo, buf, value);
10676
10677 label_fill(label_str, 0, hfinfo, out, value_pos);
10678 }
10679}
10680
10681static void
10682fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10683{
10684 const header_field_info *hfinfo = fi->hfinfo;
10685 uint32_t value;
10686
10687 char buf[NUMBER_LABEL_LENGTH80];
10688 const char *out;
10689
10690 if (is_signed)
10691 value = fvalue_get_sinteger(fi->value);
10692 else
10693 value = fvalue_get_uinteger(fi->value);
10694
10695 /* Fill in the textual info */
10696 if (hfinfo->display == BASE_CUSTOM) {
10697 char tmp[ITEM_LABEL_LENGTH240];
10698 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10699
10700 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10700, "fmtfunc"))))
;
10701 fmtfunc(tmp, value);
10702 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10703 }
10704 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10705 /*
10706 * It makes no sense to have a value-string table for a
10707 * frame-number field - they're just integers giving
10708 * the ordinal frame number.
10709 */
10710 const char *val_str = hf_try_val_to_str(value, hfinfo);
10711
10712 out = hfinfo_number_vals_format(hfinfo, buf, value);
10713 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10714 /*
10715 * Unique values only display value_string string
10716 * if there is a match. Otherwise it's just a number
10717 */
10718 if (val_str) {
10719 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10720 } else {
10721 label_fill(label_str, 0, hfinfo, out, value_pos);
10722 }
10723 } else {
10724 if (val_str == NULL((void*)0))
10725 val_str = "Unknown";
10726
10727 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10728 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10729 else
10730 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10731 }
10732 }
10733 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
))
) {
10734 char tmp[ITEM_LABEL_LENGTH240];
10735
10736 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10737 display_to_port_type((field_display_e)hfinfo->display), value);
10738 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10739 }
10740 else {
10741 out = hfinfo_number_value_format(hfinfo, buf, value);
10742
10743 label_fill(label_str, 0, hfinfo, out, value_pos);
10744 }
10745}
10746
10747static void
10748fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10749{
10750 const header_field_info *hfinfo = fi->hfinfo;
10751 uint64_t value;
10752
10753 char buf[NUMBER_LABEL_LENGTH80];
10754 const char *out;
10755
10756 if (is_signed)
10757 value = fvalue_get_sinteger64(fi->value);
10758 else
10759 value = fvalue_get_uinteger64(fi->value);
10760
10761 /* Fill in the textual info */
10762 if (hfinfo->display == BASE_CUSTOM) {
10763 char tmp[ITEM_LABEL_LENGTH240];
10764 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10765
10766 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10766, "fmtfunc64"
))))
;
10767 fmtfunc64(tmp, value);
10768 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10769 }
10770 else if (hfinfo->strings) {
10771 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10772
10773 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10774 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10775 /*
10776 * Unique values only display value_string string
10777 * if there is a match. Otherwise it's just a number
10778 */
10779 if (val_str) {
10780 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10781 } else {
10782 label_fill(label_str, 0, hfinfo, out, value_pos);
10783 }
10784 } else {
10785 if (val_str == NULL((void*)0))
10786 val_str = "Unknown";
10787
10788 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10789 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10790 else
10791 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10792 }
10793 }
10794 else {
10795 out = hfinfo_number_value_format64(hfinfo, buf, value);
10796
10797 label_fill(label_str, 0, hfinfo, out, value_pos);
10798 }
10799}
10800
10801static size_t
10802fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10803{
10804 int display;
10805 int n;
10806 double value;
10807
10808 if (label_str_size < 12) {
10809 /* Not enough room to write an entire floating point value. */
10810 return 0;
10811 }
10812
10813 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10814 value = fvalue_get_floating(fi->value);
10815
10816 if (display == BASE_CUSTOM) {
10817 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10818 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10818, "fmtfunc"))))
;
10819 fmtfunc(label_str, value);
10820 return strlen(label_str);
10821 }
10822
10823 switch (display) {
10824 case BASE_NONE:
10825 if (fi->hfinfo->type == FT_FLOAT) {
10826 n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10827 } else {
10828 n = (int)strlen(dtoa_g_fmt(label_str, value));
10829 }
10830 break;
10831 case BASE_DEC:
10832 n = snprintf(label_str, label_str_size, "%f", value);
10833 break;
10834 case BASE_HEX:
10835 n = snprintf(label_str, label_str_size, "%a", value);
10836 break;
10837 case BASE_EXP:
10838 n = snprintf(label_str, label_str_size, "%e", value);
10839 break;
10840 default:
10841 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10841
, __func__, "assertion \"not reached\" failed")
;
10842 }
10843 if (n < 0) {
10844 return 0; /* error */
10845 }
10846 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10847 const char *hf_str_val;
10848 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10849 n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10850 }
10851 if (n > label_str_size) {
10852 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10852, __func__, "label length too small"); } } while (0)
;
10853 return strlen(label_str);
10854 }
10855
10856 return n;
10857}
10858
10859void
10860fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10861{
10862 char tmp[ITEM_LABEL_LENGTH240];
10863
10864 fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10865 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10866}
10867
10868static size_t
10869fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10870{
10871 int display;
10872 size_t pos = 0;
10873 double value;
10874 char* tmp_str;
10875
10876 if (label_str_size < 12) {
10877 /* Not enough room to write an entire floating point value. */
10878 return 0;
10879 }
10880
10881 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10882 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10883 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10884 wmem_free(NULL((void*)0), tmp_str);
10885
10886 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10887 const char *hf_str_val;
10888 fvalue_to_double(fi->value, &value);
10889 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10890 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10891 }
10892 if ((int)pos > label_str_size) {
10893 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10893, __func__, "label length too small"); } } while (0)
;
10894 return strlen(label_str);
10895 }
10896
10897 return pos;
10898}
10899
10900void
10901fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10902{
10903 char tmp[ITEM_LABEL_LENGTH240];
10904
10905 fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10906 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10907}
10908
10909int
10910hfinfo_bitshift(const header_field_info *hfinfo)
10911{
10912 return ws_ctz(hfinfo->bitmask);
10913}
10914
10915
10916static int
10917hfinfo_bitoffset(const header_field_info *hfinfo)
10918{
10919 if (!hfinfo->bitmask) {
10920 return 0;
10921 }
10922
10923 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10924 * as the first bit */
10925 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10926}
10927
10928static int
10929hfinfo_mask_bitwidth(const header_field_info *hfinfo)
10930{
10931 if (!hfinfo->bitmask) {
10932 return 0;
10933 }
10934
10935 /* ilog2 = first set bit, ctz = last set bit */
10936 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
10937}
10938
10939static int
10940hfinfo_type_bitwidth(enum ftenum type)
10941{
10942 int bitwidth = 0;
10943
10944 switch (type) {
10945 case FT_CHAR:
10946 case FT_UINT8:
10947 case FT_INT8:
10948 bitwidth = 8;
10949 break;
10950 case FT_UINT16:
10951 case FT_INT16:
10952 bitwidth = 16;
10953 break;
10954 case FT_UINT24:
10955 case FT_INT24:
10956 bitwidth = 24;
10957 break;
10958 case FT_UINT32:
10959 case FT_INT32:
10960 bitwidth = 32;
10961 break;
10962 case FT_UINT40:
10963 case FT_INT40:
10964 bitwidth = 40;
10965 break;
10966 case FT_UINT48:
10967 case FT_INT48:
10968 bitwidth = 48;
10969 break;
10970 case FT_UINT56:
10971 case FT_INT56:
10972 bitwidth = 56;
10973 break;
10974 case FT_UINT64:
10975 case FT_INT64:
10976 bitwidth = 64;
10977 break;
10978 default:
10979 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 10979))
;
10980 ;
10981 }
10982 return bitwidth;
10983}
10984
10985
10986static int
10987hfinfo_container_bitwidth(const header_field_info *hfinfo)
10988{
10989 if (!hfinfo->bitmask) {
10990 return 0;
10991 }
10992
10993 if (hfinfo->type == FT_BOOLEAN) {
10994 return hfinfo->display; /* hacky? :) */
10995 }
10996
10997 return hfinfo_type_bitwidth(hfinfo->type);
10998}
10999
11000static int
11001hfinfo_hex_digits(const header_field_info *hfinfo)
11002{
11003 int bitwidth;
11004
11005 /* If we have a bitmask, hfinfo->type is the width of the container, so not
11006 * appropriate to determine the number of hex digits for the field.
11007 * So instead, we compute it from the bitmask.
11008 */
11009 if (hfinfo->bitmask != 0) {
11010 bitwidth = hfinfo_mask_bitwidth(hfinfo);
11011 } else {
11012 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11013 }
11014
11015 /* Divide by 4, rounding up, to get number of hex digits. */
11016 return (bitwidth + 3) / 4;
11017}
11018
11019const char *
11020hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11021{
11022 char *ptr = &buf[6];
11023 static const char hex_digits[16] =
11024 { '0', '1', '2', '3', '4', '5', '6', '7',
11025 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11026
11027 *ptr = '\0';
11028 *(--ptr) = '\'';
11029 /* Properly format value */
11030 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11031 /*
11032 * Printable, so just show the character, and, if it needs
11033 * to be escaped, escape it.
11034 */
11035 *(--ptr) = value;
11036 if (value == '\\' || value == '\'')
11037 *(--ptr) = '\\';
11038 } else {
11039 /*
11040 * Non-printable; show it as an escape sequence.
11041 */
11042 switch (value) {
11043
11044 case '\0':
11045 /*
11046 * Show a NUL with only one digit.
11047 */
11048 *(--ptr) = '0';
11049 break;
11050
11051 case '\a':
11052 case '\b':
11053 case '\f':
11054 case '\n':
11055 case '\r':
11056 case '\t':
11057 case '\v':
11058 *(--ptr) = value - '\a' + 'a';
11059 break;
11060
11061 default:
11062 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11063
11064 case BASE_OCT:
11065 *(--ptr) = (value & 0x7) + '0';
11066 value >>= 3;
11067 *(--ptr) = (value & 0x7) + '0';
11068 value >>= 3;
11069 *(--ptr) = (value & 0x7) + '0';
11070 break;
11071
11072 case BASE_HEX:
11073 *(--ptr) = hex_digits[value & 0x0F];
11074 value >>= 4;
11075 *(--ptr) = hex_digits[value & 0x0F];
11076 *(--ptr) = 'x';
11077 break;
11078
11079 default:
11080 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11081 }
11082 }
11083 *(--ptr) = '\\';
11084 }
11085 *(--ptr) = '\'';
11086 return ptr;
11087}
11088
11089static const char *
11090hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11091{
11092 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11093 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
))
;
11094
11095 *ptr = '\0';
11096 /* Properly format value */
11097 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11098 case BASE_DEC:
11099 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11100
11101 case BASE_DEC_HEX:
11102 *(--ptr) = ')';
11103 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11104 *(--ptr) = '(';
11105 *(--ptr) = ' ';
11106 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11107 return ptr;
11108
11109 case BASE_OCT:
11110 return oct_to_str_back(ptr, value);
11111
11112 case BASE_HEX:
11113 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11114
11115 case BASE_HEX_DEC:
11116 *(--ptr) = ')';
11117 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11118 *(--ptr) = '(';
11119 *(--ptr) = ' ';
11120 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11121 return ptr;
11122
11123 case BASE_PT_UDP:
11124 case BASE_PT_TCP:
11125 case BASE_PT_DCCP:
11126 case BASE_PT_SCTP:
11127 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11128 display_to_port_type((field_display_e)display), value);
11129 return buf;
11130 case BASE_OUI:
11131 {
11132 uint8_t p_oui[3];
11133 const char *manuf_name;
11134
11135 p_oui[0] = value >> 16 & 0xFF;
11136 p_oui[1] = value >> 8 & 0xFF;
11137 p_oui[2] = value & 0xFF;
11138
11139 /* Attempt an OUI lookup. */
11140 manuf_name = uint_get_manuf_name_if_known(value);
11141 if (manuf_name == NULL((void*)0)) {
11142 /* Could not find an OUI. */
11143 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11144 }
11145 else {
11146 /* Found an address string. */
11147 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11148 }
11149 return buf;
11150 }
11151
11152 default:
11153 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11154 }
11155 return ptr;
11156}
11157
11158static const char *
11159hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11160{
11161 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11162 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
))
;
11163
11164 *ptr = '\0';
11165 /* Properly format value */
11166 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11167 case BASE_DEC:
11168 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11169
11170 case BASE_DEC_HEX:
11171 *(--ptr) = ')';
11172 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11173 *(--ptr) = '(';
11174 *(--ptr) = ' ';
11175 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11176 return ptr;
11177
11178 case BASE_OCT:
11179 return oct64_to_str_back(ptr, value);
11180
11181 case BASE_HEX:
11182 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11183
11184 case BASE_HEX_DEC:
11185 *(--ptr) = ')';
11186 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11187 *(--ptr) = '(';
11188 *(--ptr) = ' ';
11189 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11190 return ptr;
11191
11192 default:
11193 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11194 }
11195
11196 return ptr;
11197}
11198
11199static const char *
11200hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_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_display(hfinfo, display, buf, value);
11212}
11213
11214static const char *
11215hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11216{
11217 int display = hfinfo->display;
11218
11219 if (hfinfo->type == FT_FRAMENUM) {
11220 /*
11221 * Frame numbers are always displayed in decimal.
11222 */
11223 display = BASE_DEC;
11224 }
11225
11226 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11227}
11228
11229static const char *
11230hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11231{
11232 /* Get the underlying BASE_ value */
11233 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11234
11235 return hfinfo_char_value_format_display(display, buf, value);
11236}
11237
11238static const char *
11239hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11240{
11241 /* Get the underlying BASE_ value */
11242 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11243
11244 if (hfinfo->type == FT_FRAMENUM) {
11245 /*
11246 * Frame numbers are always displayed in decimal.
11247 */
11248 display = BASE_DEC;
11249 }
11250
11251 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11252 display = BASE_DEC;
11253 } else if (display == BASE_OUI) {
11254 display = BASE_HEX;
11255 }
11256
11257 switch (display) {
11258 case BASE_NONE:
11259 /* case BASE_DEC: */
11260 case BASE_DEC_HEX:
11261 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11262 case BASE_CUSTOM:
11263 display = BASE_DEC;
11264 break;
11265
11266 /* case BASE_HEX: */
11267 case BASE_HEX_DEC:
11268 display = BASE_HEX;
11269 break;
11270 }
11271
11272 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11273}
11274
11275static const char *
11276hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11277{
11278 /* Get the underlying BASE_ value */
11279 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11280
11281 if (hfinfo->type == FT_FRAMENUM) {
11282 /*
11283 * Frame numbers are always displayed in decimal.
11284 */
11285 display = BASE_DEC;
11286 }
11287
11288 switch (display) {
11289 case BASE_NONE:
11290 /* case BASE_DEC: */
11291 case BASE_DEC_HEX:
11292 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11293 case BASE_CUSTOM:
11294 display = BASE_DEC;
11295 break;
11296
11297 /* case BASE_HEX: */
11298 case BASE_HEX_DEC:
11299 display = BASE_HEX;
11300 break;
11301 }
11302
11303 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11304}
11305
11306static const char *
11307hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11308{
11309 /* Get the underlying BASE_ value */
11310 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11311
11312 return hfinfo_char_value_format_display(display, buf, value);
11313}
11314
11315static const char *
11316hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11317{
11318 /* Get the underlying BASE_ value */
11319 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11320
11321 if (display == BASE_NONE)
11322 return NULL((void*)0);
11323
11324 if (display == BASE_DEC_HEX)
11325 display = BASE_DEC;
11326 if (display == BASE_HEX_DEC)
11327 display = BASE_HEX;
11328
11329 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11330}
11331
11332static const char *
11333hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11334{
11335 /* Get the underlying BASE_ value */
11336 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11337
11338 if (display == BASE_NONE)
11339 return NULL((void*)0);
11340
11341 if (display == BASE_DEC_HEX)
11342 display = BASE_DEC;
11343 if (display == BASE_HEX_DEC)
11344 display = BASE_HEX;
11345
11346 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11347}
11348
11349const char *
11350proto_registrar_get_name(const int n)
11351{
11352 header_field_info *hfinfo;
11353
11354 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", 11354
, __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", 11354
, "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", 11354, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11355 return hfinfo->name;
11356}
11357
11358const char *
11359proto_registrar_get_abbrev(const int n)
11360{
11361 header_field_info *hfinfo;
11362
11363 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", 11363
, __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", 11363
, "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", 11363, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11364 return hfinfo->abbrev;
11365}
11366
11367enum ftenum
11368proto_registrar_get_ftype(const int n)
11369{
11370 header_field_info *hfinfo;
11371
11372 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", 11372
, __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", 11372
, "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", 11372, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11373 return hfinfo->type;
11374}
11375
11376int
11377proto_registrar_get_parent(const int n)
11378{
11379 header_field_info *hfinfo;
11380
11381 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", 11381
, __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", 11381
, "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", 11381, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11382 return hfinfo->parent;
11383}
11384
11385bool_Bool
11386proto_registrar_is_protocol(const int n)
11387{
11388 header_field_info *hfinfo;
11389
11390 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", 11390
, __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", 11390
, "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", 11390, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11391 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11392}
11393
11394/* Returns length of field in packet (not necessarily the length
11395 * in our internal representation, as in the case of IPv4).
11396 * 0 means undeterminable at time of registration
11397 * -1 means the field is not registered. */
11398int
11399proto_registrar_get_length(const int n)
11400{
11401 header_field_info *hfinfo;
11402
11403 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", 11403
, __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", 11403
, "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", 11403, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11404 return ftype_wire_size(hfinfo->type);
11405}
11406
11407/* Looks for a protocol or a field in a proto_tree. Returns true if
11408 * it exists anywhere, or false if it exists nowhere. */
11409bool_Bool
11410proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11411{
11412 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11413
11414 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11415 return true1;
11416 }
11417 else {
11418 return false0;
11419 }
11420}
11421
11422/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11423 * This only works if the hfindex was "primed" before the dissection
11424 * took place, as we just pass back the already-created GPtrArray*.
11425 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11426 * handles that. */
11427GPtrArray *
11428proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11429{
11430 if (!tree)
11431 return NULL((void*)0);
11432
11433 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11434 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11435 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11436 else
11437 return NULL((void*)0);
11438}
11439
11440bool_Bool
11441proto_tracking_interesting_fields(const proto_tree *tree)
11442{
11443 GHashTable *interesting_hfids;
11444
11445 if (!tree)
11446 return false0;
11447
11448 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11449
11450 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11451}
11452
11453/* Helper struct for proto_find_info() and proto_all_finfos() */
11454typedef struct {
11455 GPtrArray *array;
11456 int id;
11457} ffdata_t;
11458
11459/* Helper function for proto_find_info() */
11460static bool_Bool
11461find_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 }
11469
11470 /* Don't stop traversing. */
11471 return false0;
11472}
11473
11474/* Helper function for proto_find_first_info() */
11475static bool_Bool
11476find_first_finfo(proto_node *node, void *data)
11477{
11478 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11479 if (fi && fi->hfinfo) {
11480 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11481 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11482
11483 /* Stop traversing. */
11484 return true1;
11485 }
11486 }
11487
11488 /* Continue traversing. */
11489 return false0;
11490}
11491
11492/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11493* This works on any proto_tree, primed or unprimed, but actually searches
11494* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11495* The caller does need to free the returned GPtrArray with
11496* g_ptr_array_free(<array>, true).
11497*/
11498GPtrArray *
11499proto_find_finfo(proto_tree *tree, const int id)
11500{
11501 ffdata_t ffdata;
11502
11503 ffdata.array = g_ptr_array_new();
11504 ffdata.id = id;
11505
11506 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11507
11508 return ffdata.array;
11509}
11510
11511/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11512* This works on any proto_tree, primed or unprimed, but actually searches
11513* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11514* The caller does need to free the returned GPtrArray with
11515* g_ptr_array_free(<array>, true).
11516*/
11517GPtrArray *
11518proto_find_first_finfo(proto_tree *tree, const int id)
11519{
11520 ffdata_t ffdata;
11521
11522 ffdata.array = g_ptr_array_new();
11523 ffdata.id = id;
11524
11525 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11526
11527 return ffdata.array;
11528}
11529
11530/* Helper function for proto_all_finfos() */
11531static bool_Bool
11532every_finfo(proto_node *node, void * data)
11533{
11534 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11535 if (fi && fi->hfinfo) {
11536 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11537 }
11538
11539 /* Don't stop traversing. */
11540 return false0;
11541}
11542
11543/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11544 * The caller does need to free the returned GPtrArray with
11545 * g_ptr_array_free(<array>, true).
11546 */
11547GPtrArray *
11548proto_all_finfos(proto_tree *tree)
11549{
11550 ffdata_t ffdata;
11551
11552 /* Pre allocate enough space to hold all fields in most cases */
11553 ffdata.array = g_ptr_array_sized_new(512);
11554 ffdata.id = 0;
11555
11556 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11557
11558 return ffdata.array;
11559}
11560
11561
11562typedef struct {
11563 unsigned offset;
11564 field_info *finfo;
11565 tvbuff_t *tvb;
11566} offset_search_t;
11567
11568static bool_Bool
11569check_for_offset(proto_node *node, void * data)
11570{
11571 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11572 offset_search_t *offsearch = (offset_search_t *)data;
11573
11574 /* !fi == the top most container node which holds nothing */
11575 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11576 if (offsearch->offset >= (unsigned) fi->start &&
11577 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11578
11579 offsearch->finfo = fi;
11580 return false0; /* keep traversing */
11581 }
11582 }
11583 return false0; /* keep traversing */
11584}
11585
11586/* Search a proto_tree backwards (from leaves to root) looking for the field
11587 * whose start/length occupies 'offset' */
11588/* XXX - I couldn't find an easy way to search backwards, so I search
11589 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11590 * the one I want to return to the user. This algorithm is inefficient
11591 * and could be re-done, but I'd have to handle all the children and
11592 * siblings of each node myself. When I have more time I'll do that.
11593 * (yeah right) */
11594field_info *
11595proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11596{
11597 offset_search_t offsearch;
11598
11599 offsearch.offset = offset;
11600 offsearch.finfo = NULL((void*)0);
11601 offsearch.tvb = tvb;
11602
11603 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11604
11605 return offsearch.finfo;
11606}
11607
11608typedef struct {
11609 int length;
11610 char *buf;
11611} decoded_data_t;
11612
11613static bool_Bool
11614check_for_undecoded(proto_node *node, void * data)
11615{
11616 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11617 decoded_data_t* decoded = (decoded_data_t*)data;
11618 int i;
11619 unsigned byte;
11620 unsigned bit;
11621
11622 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11623 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11624 byte = i / 8;
11625 bit = i % 8;
11626 decoded->buf[byte] |= (1 << bit);
11627 }
11628 }
11629
11630 return false0;
11631}
11632
11633char*
11634proto_find_undecoded_data(proto_tree *tree, unsigned length)
11635{
11636 decoded_data_t decoded;
11637 decoded.length = length;
11638 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11639
11640 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11641 return decoded.buf;
11642}
11643
11644/* Dumps the protocols in the registration database to stdout. An independent
11645 * program can take this output and format it into nice tables or HTML or
11646 * whatever.
11647 *
11648 * There is one record per line. The fields are tab-delimited.
11649 *
11650 * Field 1 = protocol name
11651 * Field 2 = protocol short name
11652 * Field 3 = protocol filter name
11653 * Field 4 = protocol enabled
11654 * Field 5 = protocol enabled by default
11655 * Field 6 = protocol can toggle
11656 */
11657void
11658proto_registrar_dump_protocols(void)
11659{
11660 protocol_t *protocol;
11661 int i;
11662 void *cookie = NULL((void*)0);
11663
11664
11665 i = proto_get_first_protocol(&cookie);
11666 while (i != -1) {
11667 protocol = find_protocol_by_id(i);
11668 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11669 protocol->name,
11670 protocol->short_name,
11671 protocol->filter_name,
11672 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11673 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11674 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11675 i = proto_get_next_protocol(&cookie);
11676 }
11677}
11678
11679/* Dumps the value_strings, extended value string headers, range_strings
11680 * or true/false strings for fields that have them.
11681 * There is one record per line. Fields are tab-delimited.
11682 * There are four types of records: Value String, Extended Value String Header,
11683 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11684 * the type of record.
11685 *
11686 * Note that a record will be generated only if the value_string,... is referenced
11687 * in a registered hfinfo entry.
11688 *
11689 *
11690 * Value Strings
11691 * -------------
11692 * Field 1 = 'V'
11693 * Field 2 = Field abbreviation to which this value string corresponds
11694 * Field 3 = Integer value
11695 * Field 4 = String
11696 *
11697 * Extended Value String Headers
11698 * -----------------------------
11699 * Field 1 = 'E'
11700 * Field 2 = Field abbreviation to which this extended value string header corresponds
11701 * Field 3 = Extended Value String "Name"
11702 * Field 4 = Number of entries in the associated value_string array
11703 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11704 *
11705 * Range Strings
11706 * -------------
11707 * Field 1 = 'R'
11708 * Field 2 = Field abbreviation to which this range string corresponds
11709 * Field 3 = Integer value: lower bound
11710 * Field 4 = Integer value: upper bound
11711 * Field 5 = String
11712 *
11713 * True/False Strings
11714 * ------------------
11715 * Field 1 = 'T'
11716 * Field 2 = Field abbreviation to which this true/false string corresponds
11717 * Field 3 = True String
11718 * Field 4 = False String
11719 */
11720void
11721proto_registrar_dump_values(void)
11722{
11723 header_field_info *hfinfo;
11724 int i, len, vi;
11725 const value_string *vals;
11726 const val64_string *vals64;
11727 const range_string *range;
11728 const true_false_string *tfs;
11729 const unit_name_string *units;
11730
11731 len = gpa_hfinfo.len;
11732 for (i = 0; i < len ; i++) {
11733 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11734 continue; /* This is a deregistered protocol or field */
11735
11736 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", 11736
, __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", 11736
, "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", 11736, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11737
11738 if (hfinfo->id == hf_text_only) {
11739 continue;
11740 }
11741
11742 /* ignore protocols */
11743 if (proto_registrar_is_protocol(i)) {
11744 continue;
11745 }
11746 /* process header fields */
11747#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11748 /*
11749 * If this field isn't at the head of the list of
11750 * fields with this name, skip this field - all
11751 * fields with the same name are really just versions
11752 * of the same field stored in different bits, and
11753 * should have the same type/radix/value list, and
11754 * just differ in their bit masks. (If a field isn't
11755 * a bitfield, but can be, say, 1 or 2 bytes long,
11756 * it can just be made FT_UINT16, meaning the
11757 * *maximum* length is 2 bytes, and be used
11758 * for all lengths.)
11759 */
11760 if (hfinfo->same_name_prev_id != -1)
11761 continue;
11762#endif
11763 vals = NULL((void*)0);
11764 vals64 = NULL((void*)0);
11765 range = NULL((void*)0);
11766 tfs = NULL((void*)0);
11767 units = NULL((void*)0);
11768
11769 if (hfinfo->strings != NULL((void*)0)) {
11770 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11771 (hfinfo->type == FT_CHAR ||
11772 hfinfo->type == FT_UINT8 ||
11773 hfinfo->type == FT_UINT16 ||
11774 hfinfo->type == FT_UINT24 ||
11775 hfinfo->type == FT_UINT32 ||
11776 hfinfo->type == FT_UINT40 ||
11777 hfinfo->type == FT_UINT48 ||
11778 hfinfo->type == FT_UINT56 ||
11779 hfinfo->type == FT_UINT64 ||
11780 hfinfo->type == FT_INT8 ||
11781 hfinfo->type == FT_INT16 ||
11782 hfinfo->type == FT_INT24 ||
11783 hfinfo->type == FT_INT32 ||
11784 hfinfo->type == FT_INT40 ||
11785 hfinfo->type == FT_INT48 ||
11786 hfinfo->type == FT_INT56 ||
11787 hfinfo->type == FT_INT64 ||
11788 hfinfo->type == FT_FLOAT ||
11789 hfinfo->type == FT_DOUBLE)) {
11790
11791 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11792 range = (const range_string *)hfinfo->strings;
11793 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11794 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11795 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11796 } else {
11797 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11798 }
11799 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11800 vals64 = (const val64_string *)hfinfo->strings;
11801 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11802 units = (const unit_name_string *)hfinfo->strings;
11803 } else {
11804 vals = (const value_string *)hfinfo->strings;
11805 }
11806 }
11807 else if (hfinfo->type == FT_BOOLEAN) {
11808 tfs = (const struct true_false_string *)hfinfo->strings;
11809 }
11810 }
11811
11812 /* Print value strings? */
11813 if (vals) {
11814 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11815 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11816 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11817 if (!val64_string_ext_validate(vse_p)) {
11818 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11818, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11819 continue;
11820 }
11821 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11822 printf("E\t%s\t%u\t%s\t%s\n",
11823 hfinfo->abbrev,
11824 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11825 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11826 val64_string_ext_match_type_str(vse_p));
11827 } else {
11828 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11829 if (!value_string_ext_validate(vse_p)) {
11830 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11830, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11831 continue;
11832 }
11833 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11834 printf("E\t%s\t%u\t%s\t%s\n",
11835 hfinfo->abbrev,
11836 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11837 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11838 value_string_ext_match_type_str(vse_p));
11839 }
11840 }
11841 vi = 0;
11842 while (vals[vi].strptr) {
11843 /* Print in the proper base */
11844 if (hfinfo->type == FT_CHAR) {
11845 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11846 printf("V\t%s\t'%c'\t%s\n",
11847 hfinfo->abbrev,
11848 vals[vi].value,
11849 vals[vi].strptr);
11850 } else {
11851 if (hfinfo->display == BASE_HEX) {
11852 printf("V\t%s\t'\\x%02x'\t%s\n",
11853 hfinfo->abbrev,
11854 vals[vi].value,
11855 vals[vi].strptr);
11856 }
11857 else {
11858 printf("V\t%s\t'\\%03o'\t%s\n",
11859 hfinfo->abbrev,
11860 vals[vi].value,
11861 vals[vi].strptr);
11862 }
11863 }
11864 } else {
11865 if (hfinfo->display == BASE_HEX) {
11866 printf("V\t%s\t0x%x\t%s\n",
11867 hfinfo->abbrev,
11868 vals[vi].value,
11869 vals[vi].strptr);
11870 }
11871 else {
11872 printf("V\t%s\t%u\t%s\n",
11873 hfinfo->abbrev,
11874 vals[vi].value,
11875 vals[vi].strptr);
11876 }
11877 }
11878 vi++;
11879 }
11880 }
11881 else if (vals64) {
11882 vi = 0;
11883 while (vals64[vi].strptr) {
11884 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11885 hfinfo->abbrev,
11886 vals64[vi].value,
11887 vals64[vi].strptr);
11888 vi++;
11889 }
11890 }
11891
11892 /* print range strings? */
11893 else if (range) {
11894 vi = 0;
11895 while (range[vi].strptr) {
11896 /* Print in the proper base */
11897 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11898 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11899 hfinfo->abbrev,
11900 range[vi].value_min,
11901 range[vi].value_max,
11902 range[vi].strptr);
11903 }
11904 else {
11905 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11906 hfinfo->abbrev,
11907 range[vi].value_min,
11908 range[vi].value_max,
11909 range[vi].strptr);
11910 }
11911 vi++;
11912 }
11913 }
11914
11915 /* Print true/false strings? */
11916 else if (tfs) {
11917 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11918 tfs->true_string, tfs->false_string);
11919 }
11920 /* Print unit strings? */
11921 else if (units) {
11922 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11923 units->singular, units->plural ? units->plural : "(no plural)");
11924 }
11925 }
11926}
11927
11928/* Prints the number of registered fields.
11929 * Useful for determining an appropriate value for
11930 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
11931 *
11932 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
11933 * the number of fields, true otherwise.
11934 */
11935bool_Bool
11936proto_registrar_dump_fieldcount(void)
11937{
11938 uint32_t i;
11939 header_field_info *hfinfo;
11940 uint32_t deregistered_count = 0;
11941 uint32_t same_name_count = 0;
11942 uint32_t protocol_count = 0;
11943
11944 for (i = 0; i < gpa_hfinfo.len; i++) {
11945 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
11946 deregistered_count++;
11947 continue; /* This is a deregistered protocol or header field */
11948 }
11949
11950 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", 11950
, __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", 11950
, "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", 11950, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11951
11952 if (proto_registrar_is_protocol(i))
11953 protocol_count++;
11954
11955 if (hfinfo->same_name_prev_id != -1)
11956 same_name_count++;
11957 }
11958
11959 printf("There are %u header fields registered, of which:\n"
11960 "\t%u are deregistered\n"
11961 "\t%u are protocols\n"
11962 "\t%u have the same name as another field\n\n",
11963 gpa_hfinfo.len, deregistered_count, protocol_count,
11964 same_name_count);
11965
11966 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
11967 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
11968 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
11969 "\n");
11970
11971 printf("The header field table consumes %u KiB of memory.\n",
11972 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
11973 printf("The fields themselves consume %u KiB of memory.\n",
11974 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
11975
11976 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
11977}
11978
11979static void
11980elastic_add_base_mapping(json_dumper *dumper)
11981{
11982 json_dumper_set_member_name(dumper, "index_patterns");
11983 json_dumper_begin_array(dumper);
11984 // The index names from write_json_index() in print.c
11985 json_dumper_value_string(dumper, "packets-*");
11986 json_dumper_end_array(dumper);
11987
11988 json_dumper_set_member_name(dumper, "settings");
11989 json_dumper_begin_object(dumper);
11990 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
11991 json_dumper_value_anyf(dumper, "%d", 1000000);
11992 json_dumper_end_object(dumper);
11993}
11994
11995static char*
11996ws_type_to_elastic(unsigned type)
11997{
11998 switch(type) {
11999 case FT_INT8:
12000 return "byte";
12001 case FT_UINT8:
12002 case FT_INT16:
12003 return "short";
12004 case FT_UINT16:
12005 case FT_INT32:
12006 case FT_UINT24:
12007 case FT_INT24:
12008 return "integer";
12009 case FT_FRAMENUM:
12010 case FT_UINT32:
12011 case FT_UINT40:
12012 case FT_UINT48:
12013 case FT_UINT56:
12014 case FT_INT40:
12015 case FT_INT48:
12016 case FT_INT56:
12017 case FT_INT64:
12018 return "long";
12019 case FT_UINT64:
12020 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12021 case FT_FLOAT:
12022 return "float";
12023 case FT_DOUBLE:
12024 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12025 return "double";
12026 case FT_IPv6:
12027 case FT_IPv4:
12028 return "ip";
12029 case FT_ABSOLUTE_TIME:
12030 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12031 case FT_BOOLEAN:
12032 return "boolean";
12033 default:
12034 return NULL((void*)0);
12035 }
12036}
12037
12038static char*
12039dot_to_underscore(char* str)
12040{
12041 unsigned i;
12042 for (i = 0; i < strlen(str); i++) {
12043 if (str[i] == '.')
12044 str[i] = '_';
12045 }
12046 return str;
12047}
12048
12049/* Dumps a mapping file for ElasticSearch
12050 * This is the v1 (legacy) _template API.
12051 * At some point it may need to be updated with the composable templates
12052 * introduced in Elasticsearch 7.8 (_index_template)
12053 */
12054void
12055proto_registrar_dump_elastic(const char* filter)
12056{
12057 header_field_info *hfinfo;
12058 header_field_info *parent_hfinfo;
12059 unsigned i;
12060 bool_Bool open_object = true1;
12061 const char* prev_proto = NULL((void*)0);
12062 char* str;
12063 char** protos = NULL((void*)0);
12064 char* proto;
12065 bool_Bool found;
12066 unsigned j;
12067 char* type;
12068 char* prev_item = NULL((void*)0);
12069
12070 /* We have filtering protocols. Extract them. */
12071 if (filter) {
12072 protos = g_strsplit(filter, ",", -1);
12073 }
12074
12075 /*
12076 * To help tracking down the json tree, objects have been appended with a comment:
12077 * n.label -> where n is the indentation level and label the name of the object
12078 */
12079
12080 json_dumper dumper = {
12081 .output_file = stdoutstdout,
12082 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12083 };
12084 json_dumper_begin_object(&dumper); // 1.root
12085 elastic_add_base_mapping(&dumper);
12086
12087 json_dumper_set_member_name(&dumper, "mappings");
12088 json_dumper_begin_object(&dumper); // 2.mappings
12089
12090 json_dumper_set_member_name(&dumper, "properties");
12091 json_dumper_begin_object(&dumper); // 3.properties
12092 json_dumper_set_member_name(&dumper, "timestamp");
12093 json_dumper_begin_object(&dumper); // 4.timestamp
12094 json_dumper_set_member_name(&dumper, "type");
12095 json_dumper_value_string(&dumper, "date");
12096 json_dumper_end_object(&dumper); // 4.timestamp
12097
12098 json_dumper_set_member_name(&dumper, "layers");
12099 json_dumper_begin_object(&dumper); // 4.layers
12100 json_dumper_set_member_name(&dumper, "properties");
12101 json_dumper_begin_object(&dumper); // 5.properties
12102
12103 for (i = 0; i < gpa_hfinfo.len; i++) {
12104 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12105 continue; /* This is a deregistered protocol or header field */
12106
12107 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", 12107
, __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", 12107
, "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", 12107, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12108
12109 /*
12110 * Skip the pseudo-field for "proto_tree_add_text()" since
12111 * we don't want it in the list of filterable protocols.
12112 */
12113 if (hfinfo->id == hf_text_only)
12114 continue;
12115
12116 if (!proto_registrar_is_protocol(i)) {
12117 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", 12117
, __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", 12117
, "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", 12117
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12118
12119 /*
12120 * Skip the field if filter protocols have been set and this one's
12121 * parent is not listed.
12122 */
12123 if (protos) {
12124 found = false0;
12125 j = 0;
12126 proto = protos[0];
12127 while(proto) {
12128 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12129 found = true1;
12130 break;
12131 }
12132 j++;
12133 proto = protos[j];
12134 }
12135 if (!found)
12136 continue;
12137 }
12138
12139 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12140 json_dumper_end_object(&dumper); // 7.properties
12141 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12142 open_object = true1;
12143 }
12144
12145 prev_proto = parent_hfinfo->abbrev;
12146
12147 if (open_object) {
12148 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12149 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12150 json_dumper_set_member_name(&dumper, "properties");
12151 json_dumper_begin_object(&dumper); // 7.properties
12152 open_object = false0;
12153 }
12154 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12155 type = ws_type_to_elastic(hfinfo->type);
12156 /* when type is NULL, we have the default mapping: string */
12157 if (type) {
12158 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12159 dot_to_underscore(str);
12160 if (g_strcmp0(prev_item, str)) {
12161 json_dumper_set_member_name(&dumper, str);
12162 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12163 json_dumper_set_member_name(&dumper, "type");
12164 json_dumper_value_string(&dumper, type);
12165 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12166 }
12167 g_free(prev_item);
12168 prev_item = str;
12169 }
12170 }
12171 }
12172 g_free(prev_item);
12173
12174 if (prev_proto) {
12175 json_dumper_end_object(&dumper); // 7.properties
12176 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12177 }
12178
12179 json_dumper_end_object(&dumper); // 5.properties
12180 json_dumper_end_object(&dumper); // 4.layers
12181 json_dumper_end_object(&dumper); // 3.properties
12182 json_dumper_end_object(&dumper); // 2.mappings
12183 json_dumper_end_object(&dumper); // 1.root
12184 bool_Bool ret = json_dumper_finish(&dumper);
12185 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12185, "ret"))))
;
12186
12187 g_strfreev(protos);
12188}
12189
12190/* Dumps the contents of the registration database to stdout. An independent
12191 * program can take this output and format it into nice tables or HTML or
12192 * whatever.
12193 *
12194 * There is one record per line. Each record is either a protocol or a header
12195 * field, differentiated by the first field. The fields are tab-delimited.
12196 *
12197 * Protocols
12198 * ---------
12199 * Field 1 = 'P'
12200 * Field 2 = descriptive protocol name
12201 * Field 3 = protocol abbreviation
12202 *
12203 * Header Fields
12204 * -------------
12205 * Field 1 = 'F'
12206 * Field 2 = descriptive field name
12207 * Field 3 = field abbreviation
12208 * Field 4 = type ( textual representation of the ftenum type )
12209 * Field 5 = parent protocol abbreviation
12210 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12211 * Field 7 = bitmask: format: hex: 0x....
12212 * Field 8 = blurb describing field
12213 */
12214void
12215proto_registrar_dump_fields(void)
12216{
12217 header_field_info *hfinfo, *parent_hfinfo;
12218 int i, len;
12219 const char *enum_name;
12220 const char *base_name;
12221 const char *blurb;
12222 char width[5];
12223
12224 len = gpa_hfinfo.len;
12225 for (i = 0; i < len ; i++) {
12226 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12227 continue; /* This is a deregistered protocol or header field */
12228
12229 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", 12229
, __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", 12229
, "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", 12229, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12230
12231 /*
12232 * Skip the pseudo-field for "proto_tree_add_text()" since
12233 * we don't want it in the list of filterable fields.
12234 */
12235 if (hfinfo->id == hf_text_only)
12236 continue;
12237
12238 /* format for protocols */
12239 if (proto_registrar_is_protocol(i)) {
12240 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12241 }
12242 /* format for header fields */
12243 else {
12244 /*
12245 * If this field isn't at the head of the list of
12246 * fields with this name, skip this field - all
12247 * fields with the same name are really just versions
12248 * of the same field stored in different bits, and
12249 * should have the same type/radix/value list, and
12250 * just differ in their bit masks. (If a field isn't
12251 * a bitfield, but can be, say, 1 or 2 bytes long,
12252 * it can just be made FT_UINT16, meaning the
12253 * *maximum* length is 2 bytes, and be used
12254 * for all lengths.)
12255 */
12256 if (hfinfo->same_name_prev_id != -1)
12257 continue;
12258
12259 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", 12259
, __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", 12259
, "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", 12259
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12260
12261 enum_name = ftype_name(hfinfo->type);
12262 base_name = "";
12263
12264 if (hfinfo->type == FT_CHAR ||
12265 hfinfo->type == FT_UINT8 ||
12266 hfinfo->type == FT_UINT16 ||
12267 hfinfo->type == FT_UINT24 ||
12268 hfinfo->type == FT_UINT32 ||
12269 hfinfo->type == FT_UINT40 ||
12270 hfinfo->type == FT_UINT48 ||
12271 hfinfo->type == FT_UINT56 ||
12272 hfinfo->type == FT_UINT64 ||
12273 hfinfo->type == FT_INT8 ||
12274 hfinfo->type == FT_INT16 ||
12275 hfinfo->type == FT_INT24 ||
12276 hfinfo->type == FT_INT32 ||
12277 hfinfo->type == FT_INT40 ||
12278 hfinfo->type == FT_INT48 ||
12279 hfinfo->type == FT_INT56 ||
12280 hfinfo->type == FT_INT64) {
12281
12282 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12283 case BASE_NONE:
12284 case BASE_DEC:
12285 case BASE_HEX:
12286 case BASE_OCT:
12287 case BASE_DEC_HEX:
12288 case BASE_HEX_DEC:
12289 case BASE_CUSTOM:
12290 case BASE_PT_UDP:
12291 case BASE_PT_TCP:
12292 case BASE_PT_DCCP:
12293 case BASE_PT_SCTP:
12294 case BASE_OUI:
12295 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12296 break;
12297 default:
12298 base_name = "????";
12299 break;
12300 }
12301 } else if (hfinfo->type == FT_BOOLEAN) {
12302 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12303 snprintf(width, sizeof(width), "%d", hfinfo->display);
12304 base_name = width;
12305 }
12306
12307 blurb = hfinfo->blurb;
12308 if (blurb == NULL((void*)0))
12309 blurb = "";
12310 else if (strlen(blurb) == 0)
12311 blurb = "\"\"";
12312
12313 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12314 hfinfo->name, hfinfo->abbrev, enum_name,
12315 parent_hfinfo->abbrev, base_name,
12316 hfinfo->bitmask, blurb);
12317 }
12318 }
12319}
12320
12321/* Dumps all abbreviated field and protocol completions of the given string to
12322 * stdout. An independent program may use this for command-line tab completion
12323 * of fields.
12324 */
12325bool_Bool
12326proto_registrar_dump_field_completions(const char *prefix)
12327{
12328 header_field_info *hfinfo;
12329 int i, len;
12330 size_t prefix_len;
12331 bool_Bool matched = false0;
12332
12333 prefix_len = strlen(prefix);
12334 len = gpa_hfinfo.len;
12335 for (i = 0; i < len ; i++) {
12336 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12337 continue; /* This is a deregistered protocol or header field */
12338
12339 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", 12339
, __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", 12339
, "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", 12339, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12340
12341 /*
12342 * Skip the pseudo-field for "proto_tree_add_text()" since
12343 * we don't want it in the list of filterable fields.
12344 */
12345 if (hfinfo->id == hf_text_only)
12346 continue;
12347
12348 /* format for protocols */
12349 if (proto_registrar_is_protocol(i)) {
12350 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12351 matched = true1;
12352 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12353 }
12354 }
12355 /* format for header fields */
12356 else {
12357 /*
12358 * If this field isn't at the head of the list of
12359 * fields with this name, skip this field - all
12360 * fields with the same name are really just versions
12361 * of the same field stored in different bits, and
12362 * should have the same type/radix/value list, and
12363 * just differ in their bit masks. (If a field isn't
12364 * a bitfield, but can be, say, 1 or 2 bytes long,
12365 * it can just be made FT_UINT16, meaning the
12366 * *maximum* length is 2 bytes, and be used
12367 * for all lengths.)
12368 */
12369 if (hfinfo->same_name_prev_id != -1)
12370 continue;
12371
12372 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12373 matched = true1;
12374 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12375 }
12376 }
12377 }
12378 return matched;
12379}
12380
12381/* Dumps field types and descriptive names to stdout. An independent
12382 * program can take this output and format it into nice tables or HTML or
12383 * whatever.
12384 *
12385 * There is one record per line. The fields are tab-delimited.
12386 *
12387 * Field 1 = field type name, e.g. FT_UINT8
12388 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12389 */
12390void
12391proto_registrar_dump_ftypes(void)
12392{
12393 int fte;
12394
12395 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12396 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12397 }
12398}
12399
12400/* This function indicates whether it's possible to construct a
12401 * "match selected" display filter string for the specified field,
12402 * returns an indication of whether it's possible, and, if it's
12403 * possible and "filter" is non-null, constructs the filter and
12404 * sets "*filter" to point to it.
12405 * You do not need to [g_]free() this string since it will be automatically
12406 * freed once the next packet is dissected.
12407 */
12408static bool_Bool
12409construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12410 char **filter)
12411{
12412 const header_field_info *hfinfo;
12413 char *ptr;
12414 int buf_len;
12415 int i;
12416 int start, length, length_remaining;
12417 uint8_t c;
12418
12419 if (!finfo)
12420 return false0;
12421
12422 hfinfo = finfo->hfinfo;
12423 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12423, "hfinfo"))))
;
12424
12425 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12426 * then "the numeric value ... is not used when preparing
12427 * filters for the field in question." If it's any other
12428 * base, we'll generate the filter normally (which will
12429 * be numeric, even though the human-readable string does
12430 * work for filtering.)
12431 *
12432 * XXX - It might be nice to use fvalue_to_string_repr() in
12433 * "proto_item_fill_label()" as well, although, there, you'd
12434 * have to deal with the base *and* with resolved values for
12435 * addresses.
12436 *
12437 * Perhaps in addition to taking the repr type (DISPLAY
12438 * or DFILTER) and the display (base), fvalue_to_string_repr()
12439 * should have the the "strings" values in the header_field_info
12440 * structure for the field as a parameter, so it can have
12441 * if the field is Boolean or an enumerated integer type,
12442 * the tables used to generate human-readable values.
12443 */
12444 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12445 const char *str = NULL((void*)0);
12446
12447 switch (hfinfo->type) {
12448
12449 case FT_INT8:
12450 case FT_INT16:
12451 case FT_INT24:
12452 case FT_INT32:
12453 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12454 break;
12455
12456 case FT_CHAR:
12457 case FT_UINT8:
12458 case FT_UINT16:
12459 case FT_UINT24:
12460 case FT_UINT32:
12461 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12462 break;
12463
12464 default:
12465 break;
12466 }
12467
12468 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12469 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12470 return true1;
12471 }
12472 }
12473
12474 switch (hfinfo->type) {
12475
12476 case FT_PROTOCOL:
12477 if (filter != NULL((void*)0))
12478 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12479 break;
12480
12481 case FT_NONE:
12482 /*
12483 * If the length is 0, just match the name of the
12484 * field.
12485 *
12486 * (Also check for negative values, just in case,
12487 * as we'll cast it to an unsigned value later.)
12488 */
12489 length = finfo->length;
12490 if (length == 0) {
12491 if (filter != NULL((void*)0))
12492 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12493 break;
12494 }
12495 if (length < 0)
12496 return false0;
12497
12498 /*
12499 * This doesn't have a value, so we'd match
12500 * on the raw bytes at this address.
12501 *
12502 * Should we be allowed to access to the raw bytes?
12503 * If "edt" is NULL, the answer is "no".
12504 */
12505 if (edt == NULL((void*)0))
12506 return false0;
12507
12508 /*
12509 * Is this field part of the raw frame tvbuff?
12510 * If not, we can't use "frame[N:M]" to match
12511 * it.
12512 *
12513 * XXX - should this be frame-relative, or
12514 * protocol-relative?
12515 *
12516 * XXX - does this fallback for non-registered
12517 * fields even make sense?
12518 */
12519 if (finfo->ds_tvb != edt->tvb)
12520 return false0; /* you lose */
12521
12522 /*
12523 * Don't go past the end of that tvbuff.
12524 */
12525 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12526 if (length > length_remaining)
12527 length = length_remaining;
12528 if (length <= 0)
12529 return false0;
12530
12531 if (filter != NULL((void*)0)) {
12532 start = finfo->start;
12533 buf_len = 32 + length * 3;
12534 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12535 ptr = *filter;
12536
12537 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12538 "frame[%d:%d] == ", finfo->start, length);
12539 for (i=0; i<length; i++) {
12540 c = tvb_get_uint8(finfo->ds_tvb, start);
12541 start++;
12542 if (i == 0 ) {
12543 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12544 }
12545 else {
12546 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12547 }
12548 }
12549 }
12550 break;
12551
12552 /* By default, use the fvalue's "to_string_repr" method. */
12553 default:
12554 if (filter != NULL((void*)0)) {
12555 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12556 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12557 wmem_free(NULL((void*)0), str);
12558 }
12559 break;
12560 }
12561
12562 return true1;
12563}
12564
12565/*
12566 * Returns true if we can do a "match selected" on the field, false
12567 * otherwise.
12568 */
12569bool_Bool
12570proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12571{
12572 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12573}
12574
12575/* This function attempts to construct a "match selected" display filter
12576 * string for the specified field; if it can do so, it returns a pointer
12577 * to the string, otherwise it returns NULL.
12578 *
12579 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12580 */
12581char *
12582proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12583{
12584 char *filter = NULL((void*)0);
12585
12586 if (!construct_match_selected_string(finfo, edt, &filter))
12587 {
12588 wmem_free(NULL((void*)0), filter);
12589 return NULL((void*)0);
12590 }
12591 return filter;
12592}
12593
12594/* This function is common code for all proto_tree_add_bitmask... functions.
12595 */
12596
12597static bool_Bool
12598proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12599 const int len, const int ett, int * const *fields,
12600 const int flags, bool_Bool first,
12601 bool_Bool use_parent_tree,
12602 proto_tree* tree, uint64_t value)
12603{
12604 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12605 uint64_t bitmask = 0;
12606 uint64_t tmpval;
12607 header_field_info *hf;
12608 uint32_t integer32;
12609 int bit_offset;
12610 int no_of_bits;
12611
12612 if (!*fields)
12613 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"
)
;
12614
12615 if (len < 0 || len > 8)
12616 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12617 /**
12618 * packet-frame.c uses len=0 since the value is taken from the packet
12619 * metadata, not the packet bytes. In that case, assume that all bits
12620 * in the provided value are valid.
12621 */
12622 if (len > 0) {
12623 available_bits >>= (8 - (unsigned)len)*8;
12624 }
12625
12626 if (use_parent_tree == false0)
12627 tree = proto_item_add_subtree(item, ett);
12628
12629 while (*fields) {
12630 uint64_t present_bits;
12631 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", 12631, __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", 12631
, "**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", 12631, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12632 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", 12632
, "hf->bitmask != 0", hf->abbrev))))
;
12633
12634 bitmask |= hf->bitmask;
12635
12636 /* Skip fields that aren't fully present */
12637 present_bits = available_bits & hf->bitmask;
12638 if (present_bits != hf->bitmask) {
12639 fields++;
12640 continue;
12641 }
12642
12643 switch (hf->type) {
12644 case FT_CHAR:
12645 case FT_UINT8:
12646 case FT_UINT16:
12647 case FT_UINT24:
12648 case FT_UINT32:
12649 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12650 break;
12651
12652 case FT_INT8:
12653 case FT_INT16:
12654 case FT_INT24:
12655 case FT_INT32:
12656 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12657 break;
12658
12659 case FT_UINT40:
12660 case FT_UINT48:
12661 case FT_UINT56:
12662 case FT_UINT64:
12663 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12664 break;
12665
12666 case FT_INT40:
12667 case FT_INT48:
12668 case FT_INT56:
12669 case FT_INT64:
12670 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12671 break;
12672
12673 case FT_BOOLEAN:
12674 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12675 break;
12676
12677 default:
12678 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))
12679 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))
12680 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))
12681 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))
;
12682 break;
12683 }
12684 if (flags & BMT_NO_APPEND0x01) {
12685 fields++;
12686 continue;
12687 }
12688 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12689
12690 /* XXX: README.developer and the comments have always defined
12691 * BMT_NO_INT as "only boolean flags are added to the title /
12692 * don't add non-boolean (integral) fields", but the
12693 * implementation has always added BASE_CUSTOM and fields with
12694 * value_strings, though not fields with unit_strings.
12695 * Possibly this is because some dissectors use a FT_UINT8
12696 * with a value_string for fields that should be a FT_BOOLEAN.
12697 */
12698 switch (hf->type) {
12699 case FT_CHAR:
12700 if (hf->display == BASE_CUSTOM) {
12701 char lbl[ITEM_LABEL_LENGTH240];
12702 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12703
12704 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12704, "fmtfunc"))))
;
12705 fmtfunc(lbl, (uint32_t) tmpval);
12706 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12707 hf->name, lbl);
12708 first = false0;
12709 }
12710 else if (hf->strings) {
12711 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12712 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12713 first = false0;
12714 }
12715 else if (!(flags & BMT_NO_INT0x02)) {
12716 char buf[32];
12717 const char *out;
12718
12719 if (!first) {
12720 proto_item_append_text(item, ", ");
12721 }
12722
12723 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12724 proto_item_append_text(item, "%s: %s", hf->name, out);
12725 first = false0;
12726 }
12727
12728 break;
12729
12730 case FT_UINT8:
12731 case FT_UINT16:
12732 case FT_UINT24:
12733 case FT_UINT32:
12734 if (hf->display == BASE_CUSTOM) {
12735 char lbl[ITEM_LABEL_LENGTH240];
12736 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12737
12738 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12738, "fmtfunc"))))
;
12739 fmtfunc(lbl, (uint32_t) tmpval);
12740 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12741 hf->name, lbl);
12742 first = false0;
12743 }
12744 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12745 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12746 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12747 first = false0;
12748 }
12749 else if (!(flags & BMT_NO_INT0x02)) {
12750 char buf[NUMBER_LABEL_LENGTH80];
12751 const char *out = NULL((void*)0);
12752
12753 if (!first) {
12754 proto_item_append_text(item, ", ");
12755 }
12756
12757 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12758 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12759 }
12760 if (out == NULL((void*)0)) {
12761 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12762 }
12763 proto_item_append_text(item, "%s: %s", hf->name, out);
12764 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12765 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12766 }
12767 first = false0;
12768 }
12769
12770 break;
12771
12772 case FT_INT8:
12773 case FT_INT16:
12774 case FT_INT24:
12775 case FT_INT32:
12776 integer32 = (uint32_t) tmpval;
12777 if (hf->bitmask) {
12778 no_of_bits = ws_count_ones(hf->bitmask);
12779 integer32 = ws_sign_ext32(integer32, no_of_bits);
12780 }
12781 if (hf->display == BASE_CUSTOM) {
12782 char lbl[ITEM_LABEL_LENGTH240];
12783 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12784
12785 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12785, "fmtfunc"))))
;
12786 fmtfunc(lbl, (int32_t) integer32);
12787 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12788 hf->name, lbl);
12789 first = false0;
12790 }
12791 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12792 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12793 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12794 first = false0;
12795 }
12796 else if (!(flags & BMT_NO_INT0x02)) {
12797 char buf[NUMBER_LABEL_LENGTH80];
12798 const char *out = NULL((void*)0);
12799
12800 if (!first) {
12801 proto_item_append_text(item, ", ");
12802 }
12803
12804 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12805 out = hf_try_val_to_str((int32_t) integer32, hf);
12806 }
12807 if (out == NULL((void*)0)) {
12808 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12809 }
12810 proto_item_append_text(item, "%s: %s", hf->name, out);
12811 if (hf->display & BASE_UNIT_STRING0x00001000) {
12812 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12813 }
12814 first = false0;
12815 }
12816
12817 break;
12818
12819 case FT_UINT40:
12820 case FT_UINT48:
12821 case FT_UINT56:
12822 case FT_UINT64:
12823 if (hf->display == BASE_CUSTOM) {
12824 char lbl[ITEM_LABEL_LENGTH240];
12825 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12826
12827 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12827, "fmtfunc"))))
;
12828 fmtfunc(lbl, tmpval);
12829 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12830 hf->name, lbl);
12831 first = false0;
12832 }
12833 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12834 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12835 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12836 first = false0;
12837 }
12838 else if (!(flags & BMT_NO_INT0x02)) {
12839 char buf[NUMBER_LABEL_LENGTH80];
12840 const char *out = NULL((void*)0);
12841
12842 if (!first) {
12843 proto_item_append_text(item, ", ");
12844 }
12845
12846 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12847 out = hf_try_val64_to_str(tmpval, hf);
12848 }
12849 if (out == NULL((void*)0)) {
12850 out = hfinfo_number_value_format64(hf, buf, tmpval);
12851 }
12852 proto_item_append_text(item, "%s: %s", hf->name, out);
12853 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12854 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12855 }
12856 first = false0;
12857 }
12858
12859 break;
12860
12861 case FT_INT40:
12862 case FT_INT48:
12863 case FT_INT56:
12864 case FT_INT64:
12865 if (hf->bitmask) {
12866 no_of_bits = ws_count_ones(hf->bitmask);
12867 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12868 }
12869 if (hf->display == BASE_CUSTOM) {
12870 char lbl[ITEM_LABEL_LENGTH240];
12871 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12872
12873 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12873, "fmtfunc"))))
;
12874 fmtfunc(lbl, (int64_t) tmpval);
12875 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12876 hf->name, lbl);
12877 first = false0;
12878 }
12879 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12880 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12881 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12882 first = false0;
12883 }
12884 else if (!(flags & BMT_NO_INT0x02)) {
12885 char buf[NUMBER_LABEL_LENGTH80];
12886 const char *out = NULL((void*)0);
12887
12888 if (!first) {
12889 proto_item_append_text(item, ", ");
12890 }
12891
12892 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12893 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12894 }
12895 if (out == NULL((void*)0)) {
12896 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12897 }
12898 proto_item_append_text(item, "%s: %s", hf->name, out);
12899 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12900 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12901 }
12902 first = false0;
12903 }
12904
12905 break;
12906
12907 case FT_BOOLEAN:
12908 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12909 /* If we have true/false strings, emit full - otherwise messages
12910 might look weird */
12911 const struct true_false_string *tfs =
12912 (const struct true_false_string *)hf->strings;
12913
12914 if (tmpval) {
12915 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12916 hf->name, tfs->true_string);
12917 first = false0;
12918 } else if (!(flags & BMT_NO_FALSE0x04)) {
12919 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12920 hf->name, tfs->false_string);
12921 first = false0;
12922 }
12923 } else if (hf->bitmask & value) {
12924 /* If the flag is set, show the name */
12925 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12926 first = false0;
12927 }
12928 break;
12929 default:
12930 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))
12931 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))
12932 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))
12933 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))
;
12934 break;
12935 }
12936
12937 fields++;
12938 }
12939
12940 /* XXX: We don't pass the hfi into this function. Perhaps we should,
12941 * but then again most dissectors don't set the bitmask field for
12942 * the higher level bitmask hfi, so calculate the bitmask from the
12943 * fields present. */
12944 if (item) {
12945 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
12946 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
12947 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)
;
12948 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)
;
12949 }
12950 return first;
12951}
12952
12953/* This function will dissect a sequence of bytes that describe a
12954 * bitmask and supply the value of that sequence through a pointer.
12955 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12956 * to be dissected.
12957 * This field will form an expansion under which the individual fields of the
12958 * bitmask is dissected and displayed.
12959 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12960 *
12961 * fields is an array of pointers to int that lists all the fields of the
12962 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12963 * or another integer of the same type/size as hf_hdr with a mask specified.
12964 * This array is terminated by a NULL entry.
12965 *
12966 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12967 * FT_integer fields that have a value_string attached will have the
12968 * matched string displayed on the expansion line.
12969 */
12970proto_item *
12971proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
12972 const unsigned offset, const int hf_hdr,
12973 const int ett, int * const *fields,
12974 const unsigned encoding, uint64_t *retval)
12975{
12976 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);
12977}
12978
12979/* This function will dissect a sequence of bytes that describe a
12980 * bitmask.
12981 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12982 * to be dissected.
12983 * This field will form an expansion under which the individual fields of the
12984 * bitmask is dissected and displayed.
12985 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12986 *
12987 * fields is an array of pointers to int that lists all the fields of the
12988 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12989 * or another integer of the same type/size as hf_hdr with a mask specified.
12990 * This array is terminated by a NULL entry.
12991 *
12992 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12993 * FT_integer fields that have a value_string attached will have the
12994 * matched string displayed on the expansion line.
12995 */
12996proto_item *
12997proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
12998 const unsigned offset, const int hf_hdr,
12999 const int ett, int * const *fields,
13000 const unsigned encoding)
13001{
13002 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13003}
13004
13005/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13006 * what data is appended to the header.
13007 */
13008proto_item *
13009proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13010 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13011 uint64_t *retval)
13012{
13013 proto_item *item = NULL((void*)0);
13014 header_field_info *hf;
13015 int len;
13016 uint64_t value;
13017
13018 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", 13018, __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", 13018
, "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", 13018, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13019 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", 13019, (hf)->abbrev)))
;
13020 len = ftype_wire_size(hf->type);
13021 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13022
13023 if (parent_tree) {
13024 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13025 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13026 flags, false0, false0, NULL((void*)0), value);
13027 }
13028
13029 *retval = value;
13030 if (hf->bitmask) {
13031 /* Mask out irrelevant portions */
13032 *retval &= hf->bitmask;
13033 /* Shift bits */
13034 *retval >>= hfinfo_bitshift(hf);
13035 }
13036
13037 return item;
13038}
13039
13040/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13041 * what data is appended to the header.
13042 */
13043proto_item *
13044proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13045 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13046{
13047 proto_item *item = NULL((void*)0);
13048 header_field_info *hf;
13049 int len;
13050 uint64_t value;
13051
13052 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", 13052, __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", 13052
, "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", 13052, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13053 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", 13053, (hf)->abbrev)))
;
13054
13055 if (parent_tree) {
13056 len = ftype_wire_size(hf->type);
13057 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13058 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13059 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13060 flags, false0, false0, NULL((void*)0), value);
13061 }
13062
13063 return item;
13064}
13065
13066/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13067 can't be retrieved directly from tvb) */
13068proto_item *
13069proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13070 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13071{
13072 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13073 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13074}
13075
13076/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13077WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13078proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13079 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13080{
13081 proto_item *item = NULL((void*)0);
13082 header_field_info *hf;
13083 int len;
13084
13085 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", 13085, __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", 13085
, "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", 13085, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13086 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", 13086, (hf)->abbrev)))
;
13087 /* the proto_tree_add_uint/_uint64() calls below
13088 will fail if tvb==NULL and len!=0 */
13089 len = tvb ? ftype_wire_size(hf->type) : 0;
13090
13091 if (parent_tree) {
13092 if (len <= 4)
13093 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13094 else
13095 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13096
13097 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13098 flags, false0, false0, NULL((void*)0), value);
13099 }
13100
13101 return item;
13102}
13103
13104/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13105void
13106proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13107 const int len, int * const *fields, const unsigned encoding)
13108{
13109 uint64_t value;
13110
13111 if (tree) {
13112 value = get_uint64_value(tree, tvb, offset, len, encoding);
13113 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13114 BMT_NO_APPEND0x01, false0, true1, tree, value);
13115 }
13116}
13117
13118WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13119proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13120 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13121{
13122 uint64_t value;
13123
13124 value = get_uint64_value(tree, tvb, offset, len, encoding);
13125 if (tree) {
13126 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13127 BMT_NO_APPEND0x01, false0, true1, tree, value);
13128 }
13129 if (retval) {
13130 *retval = value;
13131 }
13132}
13133
13134WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13135proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13136 const int len, int * const *fields, const uint64_t value)
13137{
13138 if (tree) {
13139 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13140 BMT_NO_APPEND0x01, false0, true1, tree, value);
13141 }
13142}
13143
13144
13145/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13146 * This is intended to support bitmask fields whose lengths can vary, perhaps
13147 * as the underlying standard evolves over time.
13148 * With this API there is the possibility of being called to display more or
13149 * less data than the dissector was coded to support.
13150 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13151 * Thus when presented with "too much" or "too little" data, MSbits will be
13152 * ignored or MSfields sacrificed.
13153 *
13154 * Only fields for which all defined bits are available are displayed.
13155 */
13156proto_item *
13157proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13158 const unsigned offset, const unsigned len, const int hf_hdr,
13159 const int ett, int * const *fields, struct expert_field* exp,
13160 const unsigned encoding)
13161{
13162 proto_item *item = NULL((void*)0);
13163 header_field_info *hf;
13164 unsigned decodable_len;
13165 unsigned decodable_offset;
13166 uint32_t decodable_value;
13167 uint64_t value;
13168
13169 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", 13169, __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", 13169
, "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", 13169, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13170 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", 13170, (hf)->abbrev)))
;
13171
13172 decodable_offset = offset;
13173 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13174
13175 /* If we are ftype_wire_size-limited,
13176 * make sure we decode as many LSBs as possible.
13177 */
13178 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13179 decodable_offset += (len - decodable_len);
13180 }
13181
13182 if (parent_tree) {
13183 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13184 decodable_len, encoding);
13185
13186 /* The root item covers all the bytes even if we can't decode them all */
13187 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13188 decodable_value);
13189 }
13190
13191 if (decodable_len < len) {
13192 /* Dissector likely requires updating for new protocol revision */
13193 expert_add_info_format(NULL((void*)0), item, exp,
13194 "Only least-significant %d of %d bytes decoded",
13195 decodable_len, len);
13196 }
13197
13198 if (item) {
13199 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13200 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13201 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13202 }
13203
13204 return item;
13205}
13206
13207/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13208proto_item *
13209proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13210 const unsigned offset, const unsigned len,
13211 const char *name, const char *fallback,
13212 const int ett, int * const *fields,
13213 const unsigned encoding, const int flags)
13214{
13215 proto_item *item = NULL((void*)0);
13216 uint64_t value;
13217
13218 if (parent_tree) {
13219 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13220 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13221 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13222 flags, true1, false0, NULL((void*)0), value) && fallback) {
13223 /* Still at first item - append 'fallback' text if any */
13224 proto_item_append_text(item, "%s", fallback);
13225 }
13226 }
13227
13228 return item;
13229}
13230
13231proto_item *
13232proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13233 const unsigned bit_offset, const int no_of_bits,
13234 const unsigned encoding)
13235{
13236 header_field_info *hfinfo;
13237 int octet_length;
13238 int octet_offset;
13239
13240 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", 13240, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13240
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13240, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13241
13242 if (no_of_bits < 0) {
13243 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13244 }
13245 octet_length = (no_of_bits + 7) >> 3;
13246 octet_offset = bit_offset >> 3;
13247 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13248
13249 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13250 * but only after doing a bunch more work (which we can, in the common
13251 * case, shortcut here).
13252 */
13253 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13254 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", 13254
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13254, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13254, "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", 13254, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13255
13256 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13257}
13258
13259/*
13260 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13261 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13262 * Offset should be given in bits from the start of the tvb.
13263 */
13264
13265static proto_item *
13266_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13267 const unsigned bit_offset, const int no_of_bits,
13268 uint64_t *return_value, const unsigned encoding)
13269{
13270 int offset;
13271 unsigned length;
13272 uint8_t tot_no_bits;
13273 char *bf_str;
13274 char lbl_str[ITEM_LABEL_LENGTH240];
13275 uint64_t value = 0;
13276 uint8_t *bytes = NULL((void*)0);
13277 size_t bytes_length = 0;
13278
13279 proto_item *pi;
13280 header_field_info *hf_field;
13281
13282 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13283 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", 13283, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13283
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13283, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13284
13285 if (hf_field->bitmask != 0) {
13286 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)
13287 " 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)
13288 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)
;
13289 }
13290
13291 if (no_of_bits < 0) {
13292 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13293 } else if (no_of_bits == 0) {
13294 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)
13295 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)
;
13296 }
13297
13298 /* Byte align offset */
13299 offset = bit_offset>>3;
13300
13301 /*
13302 * Calculate the number of octets used to hold the bits
13303 */
13304 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13305 length = (tot_no_bits + 7) >> 3;
13306
13307 if (no_of_bits < 65) {
13308 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13309 } else if (hf_field->type != FT_BYTES) {
13310 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)
13311 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)
;
13312 return NULL((void*)0);
13313 }
13314
13315 /* Sign extend for signed types */
13316 switch (hf_field->type) {
13317 case FT_INT8:
13318 case FT_INT16:
13319 case FT_INT24:
13320 case FT_INT32:
13321 case FT_INT40:
13322 case FT_INT48:
13323 case FT_INT56:
13324 case FT_INT64:
13325 value = ws_sign_ext64(value, no_of_bits);
13326 break;
13327
13328 default:
13329 break;
13330 }
13331
13332 if (return_value) {
13333 *return_value = value;
13334 }
13335
13336 /* Coast clear. Try and fake it */
13337 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13338 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", 13338
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13338, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13338, "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", 13338, __func__, "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); } } }
;
13339
13340 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13341
13342 switch (hf_field->type) {
13343 case FT_BOOLEAN:
13344 /* Boolean field */
13345 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13346 "%s = %s: %s",
13347 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13348 break;
13349
13350 case FT_CHAR:
13351 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13352 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13353 break;
13354
13355 case FT_UINT8:
13356 case FT_UINT16:
13357 case FT_UINT24:
13358 case FT_UINT32:
13359 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13360 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13361 break;
13362
13363 case FT_INT8:
13364 case FT_INT16:
13365 case FT_INT24:
13366 case FT_INT32:
13367 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13368 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13369 break;
13370
13371 case FT_UINT40:
13372 case FT_UINT48:
13373 case FT_UINT56:
13374 case FT_UINT64:
13375 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13376 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13377 break;
13378
13379 case FT_INT40:
13380 case FT_INT48:
13381 case FT_INT56:
13382 case FT_INT64:
13383 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13384 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13385 break;
13386
13387 case FT_BYTES:
13388 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13389 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13390 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13391 proto_item_set_text(pi, "%s", lbl_str);
13392 return pi;
13393
13394 /* TODO: should handle FT_UINT_BYTES ? */
13395
13396 default:
13397 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))
13398 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))
13399 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))
13400 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))
;
13401 return NULL((void*)0);
13402 }
13403
13404 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13405 return pi;
13406}
13407
13408proto_item *
13409proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13410 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13411 uint64_t *return_value)
13412{
13413 proto_item *pi;
13414 int no_of_bits;
13415 int octet_offset;
13416 unsigned mask_initial_bit_offset;
13417 unsigned mask_greatest_bit_offset;
13418 unsigned octet_length;
13419 uint8_t i;
13420 char bf_str[256];
13421 char lbl_str[ITEM_LABEL_LENGTH240];
13422 uint64_t value;
13423 uint64_t composite_bitmask;
13424 uint64_t composite_bitmap;
13425
13426 header_field_info *hf_field;
13427
13428 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13429 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", 13429, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13429
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13429, "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
13430
13431 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13432 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)
13433 " 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)
13434 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)
;
13435 }
13436
13437 mask_initial_bit_offset = bit_offset % 8;
13438
13439 no_of_bits = 0;
13440 value = 0;
13441 i = 0;
13442 mask_greatest_bit_offset = 0;
13443 composite_bitmask = 0;
13444 composite_bitmap = 0;
13445
13446 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
13447 uint64_t crumb_mask, crumb_value;
13448 uint8_t crumb_end_bit_offset;
13449
13450 crumb_value = tvb_get_bits64(tvb,
13451 bit_offset + crumb_spec[i].crumb_bit_offset,
13452 crumb_spec[i].crumb_bit_length,
13453 ENC_BIG_ENDIAN0x00000000);
13454 value += crumb_value;
13455 no_of_bits += crumb_spec[i].crumb_bit_length;
13456 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", 13456
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13457
13458 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13459 octet containing the initial offset.
13460 If the mask is beyond 32 bits, then give up on bit map display.
13461 This could be improved in future, probably showing a table
13462 of 32 or 64 bits per row */
13463 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13464 crumb_end_bit_offset = mask_initial_bit_offset
13465 + crumb_spec[i].crumb_bit_offset
13466 + crumb_spec[i].crumb_bit_length;
13467 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'
13468
13469 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13470 mask_greatest_bit_offset = crumb_end_bit_offset;
13471 }
13472 /* Currently the bitmap of the crumbs are only shown if
13473 * smaller than 32 bits. Do not bother calculating the
13474 * mask if it is larger than that. */
13475 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13476 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'
13477 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13478 }
13479 }
13480 /* Shift left for the next segment */
13481 value <<= crumb_spec[++i].crumb_bit_length;
13482 }
13483
13484 /* Sign extend for signed types */
13485 switch (hf_field->type) {
13486 case FT_INT8:
13487 case FT_INT16:
13488 case FT_INT24:
13489 case FT_INT32:
13490 case FT_INT40:
13491 case FT_INT48:
13492 case FT_INT56:
13493 case FT_INT64:
13494 value = ws_sign_ext64(value, no_of_bits);
13495 break;
13496 default:
13497 break;
13498 }
13499
13500 if (return_value) {
13501 *return_value = value;
13502 }
13503
13504 /* Coast clear. Try and fake it */
13505 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13506 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", 13506
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13506, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13506, "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", 13506, __func__, "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); } } }
;
13507
13508 /* initialise the format string */
13509 bf_str[0] = '\0';
13510
13511 octet_offset = bit_offset >> 3;
13512
13513 /* Round up mask length to nearest octet */
13514 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13515 mask_greatest_bit_offset = octet_length << 3;
13516
13517 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13518 It would be a useful enhancement to eliminate this restriction. */
13519 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13520 other_decode_bitfield_value(bf_str,
13521 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13522 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13523 mask_greatest_bit_offset);
13524 } else {
13525 /* If the bitmask is too large, try to describe its contents. */
13526 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13527 }
13528
13529 switch (hf_field->type) {
13530 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13531 /* Boolean field */
13532 return proto_tree_add_boolean_format(tree, hfindex,
13533 tvb, octet_offset, octet_length, value,
13534 "%s = %s: %s",
13535 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13536 break;
13537
13538 case FT_CHAR:
13539 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13540 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13541 break;
13542
13543 case FT_UINT8:
13544 case FT_UINT16:
13545 case FT_UINT24:
13546 case FT_UINT32:
13547 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13548 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13549 break;
13550
13551 case FT_INT8:
13552 case FT_INT16:
13553 case FT_INT24:
13554 case FT_INT32:
13555 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13556 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13557 break;
13558
13559 case FT_UINT40:
13560 case FT_UINT48:
13561 case FT_UINT56:
13562 case FT_UINT64:
13563 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13564 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13565 break;
13566
13567 case FT_INT40:
13568 case FT_INT48:
13569 case FT_INT56:
13570 case FT_INT64:
13571 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13572 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13573 break;
13574
13575 default:
13576 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))
13577 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))
13578 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))
13579 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))
;
13580 return NULL((void*)0);
13581 }
13582 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13583 return pi;
13584}
13585
13586void
13587proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13588 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13589{
13590 header_field_info *hfinfo;
13591 int start = bit_offset >> 3;
13592 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13593
13594 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13595 * so that we can use the tree's memory scope in calculating the string */
13596 if (length == -1) {
13597 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13598 } else {
13599 tvb_ensure_bytes_exist(tvb, start, length);
13600 }
13601 if (!tree) return;
13602
13603 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", 13603, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13603
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13603, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13604 proto_tree_add_text_internal(tree, tvb, start, length,
13605 "%s crumb %d of %s (decoded above)",
13606 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13607 tvb_get_bits32(tvb,
13608 bit_offset,
13609 crumb_spec[crumb_index].crumb_bit_length,
13610 ENC_BIG_ENDIAN0x00000000),
13611 ENC_BIG_ENDIAN0x00000000),
13612 crumb_index,
13613 hfinfo->name);
13614}
13615
13616proto_item *
13617proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13618 const unsigned bit_offset, const int no_of_bits,
13619 uint64_t *return_value, const unsigned encoding)
13620{
13621 proto_item *item;
13622
13623 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13624 bit_offset, no_of_bits,
13625 return_value, encoding))) {
13626 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)
;
13627 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)
;
13628 }
13629 return item;
13630}
13631
13632static proto_item *
13633_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13634 tvbuff_t *tvb, const unsigned bit_offset,
13635 const int no_of_bits, void *value_ptr,
13636 const unsigned encoding, char *value_str)
13637{
13638 int offset;
13639 unsigned length;
13640 uint8_t tot_no_bits;
13641 char *str;
13642 uint64_t value = 0;
13643 header_field_info *hf_field;
13644
13645 /* We do not have to return a value, try to fake it as soon as possible */
13646 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13647 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", 13647
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13647, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13647, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; 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", 13647, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, 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); } } }
;
13648
13649 if (hf_field->bitmask != 0) {
13650 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)
13651 " 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)
13652 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)
;
13653 }
13654
13655 if (no_of_bits < 0) {
13656 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13657 } else if (no_of_bits == 0) {
13658 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)
13659 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)
;
13660 }
13661
13662 /* Byte align offset */
13663 offset = bit_offset>>3;
13664
13665 /*
13666 * Calculate the number of octets used to hold the bits
13667 */
13668 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13669 length = tot_no_bits>>3;
13670 /* If we are using part of the next octet, increase length by 1 */
13671 if (tot_no_bits & 0x07)
13672 length++;
13673
13674 if (no_of_bits < 65) {
13675 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13676 } else {
13677 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)
13678 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)
;
13679 return NULL((void*)0);
13680 }
13681
13682 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13683
13684 (void) g_strlcat(str, " = ", 256+64);
13685 (void) g_strlcat(str, hf_field->name, 256+64);
13686
13687 /*
13688 * This function does not receive an actual value but a dimensionless pointer to that value.
13689 * For this reason, the type of the header field is examined in order to determine
13690 * what kind of value we should read from this address.
13691 * The caller of this function must make sure that for the specific header field type the address of
13692 * a compatible value is provided.
13693 */
13694 switch (hf_field->type) {
13695 case FT_BOOLEAN:
13696 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13697 "%s: %s", str, value_str);
13698 break;
13699
13700 case FT_CHAR:
13701 case FT_UINT8:
13702 case FT_UINT16:
13703 case FT_UINT24:
13704 case FT_UINT32:
13705 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13706 "%s: %s", str, value_str);
13707 break;
13708
13709 case FT_UINT40:
13710 case FT_UINT48:
13711 case FT_UINT56:
13712 case FT_UINT64:
13713 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13714 "%s: %s", str, value_str);
13715 break;
13716
13717 case FT_INT8:
13718 case FT_INT16:
13719 case FT_INT24:
13720 case FT_INT32:
13721 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13722 "%s: %s", str, value_str);
13723 break;
13724
13725 case FT_INT40:
13726 case FT_INT48:
13727 case FT_INT56:
13728 case FT_INT64:
13729 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13730 "%s: %s", str, value_str);
13731 break;
13732
13733 case FT_FLOAT:
13734 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13735 "%s: %s", str, value_str);
13736 break;
13737
13738 default:
13739 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))
13740 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))
13741 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))
13742 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))
;
13743 return NULL((void*)0);
13744 }
13745}
13746
13747static proto_item *
13748proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13749 tvbuff_t *tvb, const unsigned bit_offset,
13750 const int no_of_bits, void *value_ptr,
13751 const unsigned encoding, char *value_str)
13752{
13753 proto_item *item;
13754
13755 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13756 tvb, bit_offset, no_of_bits,
13757 value_ptr, encoding, value_str))) {
13758 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)
;
13759 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)
;
13760 }
13761 return item;
13762}
13763
13764#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);
\
13765 va_start(ap, format)__builtin_va_start(ap, format); \
13766 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13767 va_end(ap)__builtin_va_end(ap);
13768
13769proto_item *
13770proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13771 tvbuff_t *tvb, const unsigned bit_offset,
13772 const int no_of_bits, uint32_t value,
13773 const unsigned encoding,
13774 const char *format, ...)
13775{
13776 va_list ap;
13777 char *dst;
13778 header_field_info *hf_field;
13779
13780 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13781
13782 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", 13782
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13782, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13782, "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", 13782, __func__, "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); } } }
;
13783
13784 switch (hf_field->type) {
13785 case FT_UINT8:
13786 case FT_UINT16:
13787 case FT_UINT24:
13788 case FT_UINT32:
13789 break;
13790
13791 default:
13792 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)
13793 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)
;
13794 return NULL((void*)0);
13795 }
13796
13797 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);
;
13798
13799 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13800}
13801
13802proto_item *
13803proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13804 tvbuff_t *tvb, const unsigned bit_offset,
13805 const int no_of_bits, uint64_t value,
13806 const unsigned encoding,
13807 const char *format, ...)
13808{
13809 va_list ap;
13810 char *dst;
13811 header_field_info *hf_field;
13812
13813 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13814
13815 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", 13815
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13815, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13815, "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", 13815, __func__, "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); } } }
;
13816
13817 switch (hf_field->type) {
13818 case FT_UINT40:
13819 case FT_UINT48:
13820 case FT_UINT56:
13821 case FT_UINT64:
13822 break;
13823
13824 default:
13825 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)
13826 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)
;
13827 return NULL((void*)0);
13828 }
13829
13830 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);
;
13831
13832 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13833}
13834
13835proto_item *
13836proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13837 tvbuff_t *tvb, const unsigned bit_offset,
13838 const int no_of_bits, float value,
13839 const unsigned encoding,
13840 const char *format, ...)
13841{
13842 va_list ap;
13843 char *dst;
13844 header_field_info *hf_field;
13845
13846 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13847
13848 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", 13848
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13848, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13848, "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", 13848, __func__, "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); } } }
;
13849
13850 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",
13850, ((hf_field))->abbrev))))
;
13851
13852 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);
;
13853
13854 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13855}
13856
13857proto_item *
13858proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13859 tvbuff_t *tvb, const unsigned bit_offset,
13860 const int no_of_bits, int32_t value,
13861 const unsigned encoding,
13862 const char *format, ...)
13863{
13864 va_list ap;
13865 char *dst;
13866 header_field_info *hf_field;
13867
13868 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13869
13870 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", 13870
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13870, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13870, "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", 13870, __func__, "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); } } }
;
13871
13872 switch (hf_field->type) {
13873 case FT_INT8:
13874 case FT_INT16:
13875 case FT_INT24:
13876 case FT_INT32:
13877 break;
13878
13879 default:
13880 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)
13881 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)
;
13882 return NULL((void*)0);
13883 }
13884
13885 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);
;
13886
13887 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13888}
13889
13890proto_item *
13891proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13892 tvbuff_t *tvb, const unsigned bit_offset,
13893 const int no_of_bits, int64_t value,
13894 const unsigned encoding,
13895 const char *format, ...)
13896{
13897 va_list ap;
13898 char *dst;
13899 header_field_info *hf_field;
13900
13901 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13902
13903 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", 13903
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13903, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13903, "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", 13903, __func__, "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); } } }
;
13904
13905 switch (hf_field->type) {
13906 case FT_INT40:
13907 case FT_INT48:
13908 case FT_INT56:
13909 case FT_INT64:
13910 break;
13911
13912 default:
13913 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)
13914 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)
;
13915 return NULL((void*)0);
13916 }
13917
13918 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);
;
13919
13920 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13921}
13922
13923proto_item *
13924proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13925 tvbuff_t *tvb, const unsigned bit_offset,
13926 const int no_of_bits, uint64_t value,
13927 const unsigned encoding,
13928 const char *format, ...)
13929{
13930 va_list ap;
13931 char *dst;
13932 header_field_info *hf_field;
13933
13934 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13935
13936 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", 13936
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13936, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13936, "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", 13936, __func__, "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); } } }
;
13937
13938 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"
, 13938, ((hf_field))->abbrev))))
;
13939
13940 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);
;
13941
13942 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13943}
13944
13945proto_item *
13946proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13947 const unsigned bit_offset, const int no_of_chars)
13948{
13949 proto_item *pi;
13950 header_field_info *hfinfo;
13951 int byte_length;
13952 int byte_offset;
13953 char *string;
13954
13955 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13956
13957 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", 13957
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13957, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13957, "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", 13957, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13958
13959 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"
, 13959, ((hfinfo))->abbrev))))
;
13960
13961 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13962 byte_offset = bit_offset >> 3;
13963
13964 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13965
13966 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13967 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13967, "byte_length >= 0"
))))
;
13968 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13969
13970 return pi;
13971}
13972
13973proto_item *
13974proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13975 const unsigned bit_offset, const int no_of_chars)
13976{
13977 proto_item *pi;
13978 header_field_info *hfinfo;
13979 int byte_length;
13980 int byte_offset;
13981 char *string;
13982
13983 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13984
13985 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", 13985
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13985, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13985, "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", 13985, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13986
13987 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"
, 13987, ((hfinfo))->abbrev))))
;
13988
13989 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13990 byte_offset = bit_offset >> 3;
13991
13992 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13993
13994 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13995 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13995, "byte_length >= 0"
))))
;
13996 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13997
13998 return pi;
13999}
14000
14001const value_string proto_checksum_vals[] = {
14002 { PROTO_CHECKSUM_E_BAD, "Bad" },
14003 { PROTO_CHECKSUM_E_GOOD, "Good" },
14004 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14005 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14006 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14007
14008 { 0, NULL((void*)0) }
14009};
14010
14011proto_item *
14012proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14013 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14014 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14015{
14016 header_field_info *hfinfo;
14017 uint32_t checksum;
14018 uint32_t len;
14019 proto_item* ti = NULL((void*)0);
14020 proto_item* ti2;
14021 bool_Bool incorrect_checksum = true1;
14022
14023 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", 14023, __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", 14023
, "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", 14023, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14024
14025 switch (hfinfo->type) {
14026 case FT_UINT8:
14027 len = 1;
14028 break;
14029 case FT_UINT16:
14030 len = 2;
14031 break;
14032 case FT_UINT24:
14033 len = 3;
14034 break;
14035 case FT_UINT32:
14036 len = 4;
14037 break;
14038 default:
14039 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)
14040 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14041 }
14042
14043 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14044 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14045 proto_item_set_generated(ti);
14046 if (hf_checksum_status != -1) {
14047 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14048 proto_item_set_generated(ti2);
14049 }
14050 return ti;
14051 }
14052
14053 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14054 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14055 proto_item_set_generated(ti);
14056 } else {
14057 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14058 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14059 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14060 if (computed_checksum == 0) {
14061 proto_item_append_text(ti, " [correct]");
14062 if (hf_checksum_status != -1) {
14063 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14064 proto_item_set_generated(ti2);
14065 }
14066 incorrect_checksum = false0;
14067 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14068 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14069 /* XXX - This can't distinguish between "shouldbe"
14070 * 0x0000 and 0xFFFF unless we know whether there
14071 * were any nonzero bits (other than the checksum).
14072 * Protocols should not use this path if they might
14073 * have an all zero packet.
14074 * Some implementations put the wrong zero; maybe
14075 * we should have a special expert info for that?
14076 */
14077 }
14078 } else {
14079 if (checksum == computed_checksum) {
14080 proto_item_append_text(ti, " [correct]");
14081 if (hf_checksum_status != -1) {
14082 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14083 proto_item_set_generated(ti2);
14084 }
14085 incorrect_checksum = false0;
14086 }
14087 }
14088
14089 if (incorrect_checksum) {
14090 if (hf_checksum_status != -1) {
14091 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14092 proto_item_set_generated(ti2);
14093 }
14094 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14095 proto_item_append_text(ti, " [incorrect]");
14096 if (bad_checksum_expert != NULL((void*)0))
14097 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14098 } else {
14099 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14100 if (bad_checksum_expert != NULL((void*)0))
14101 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);
14102 }
14103 }
14104 } else {
14105 if (hf_checksum_status != -1) {
14106 proto_item_append_text(ti, " [unverified]");
14107 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14108 proto_item_set_generated(ti2);
14109 }
14110 }
14111 }
14112
14113 return ti;
14114}
14115
14116proto_item *
14117proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14118 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14119 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14120{
14121 header_field_info *hfinfo;
14122 uint8_t *checksum = NULL((void*)0);
14123 proto_item* ti = NULL((void*)0);
14124 proto_item* ti2;
14125 bool_Bool incorrect_checksum = true1;
14126
14127 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", 14127, __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", 14127
, "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", 14127, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14128
14129 if (hfinfo->type != FT_BYTES) {
14130 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)
14131 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14132 }
14133
14134 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14135 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14136 proto_item_set_generated(ti);
14137 if (hf_checksum_status != -1) {
14138 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14139 proto_item_set_generated(ti2);
14140 }
14141 return ti;
14142 }
14143
14144 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14145 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14146 proto_item_set_generated(ti);
14147 } else {
14148 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
))))))
;
14149 tvb_memcpy(tvb, checksum, offset, checksum_len);
14150 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14151 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14152 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14153 if (computed_checksum == 0) {
14154 proto_item_append_text(ti, " [correct]");
14155 if (hf_checksum_status != -1) {
14156 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14157 proto_item_set_generated(ti2);
14158 }
14159 incorrect_checksum = false0;
14160 }
14161 } else {
14162 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14163 proto_item_append_text(ti, " [correct]");
14164 if (hf_checksum_status != -1) {
14165 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14166 proto_item_set_generated(ti2);
14167 }
14168 incorrect_checksum = false0;
14169 }
14170 }
14171
14172 if (incorrect_checksum) {
14173 if (hf_checksum_status != -1) {
14174 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14175 proto_item_set_generated(ti2);
14176 }
14177 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14178 proto_item_append_text(ti, " [incorrect]");
14179 if (bad_checksum_expert != NULL((void*)0))
14180 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14181 } else {
14182 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14183 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))))))
;
14184 for (size_t counter = 0; counter < checksum_len; ++counter) {
14185 snprintf(
14186 /* On ecah iteration inserts two characters */
14187 (char*)&computed_checksum_str[counter << 1],
14188 computed_checksum_str_len - (counter << 1),
14189 "%02x",
14190 computed_checksum[counter]);
14191 }
14192 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14193 if (bad_checksum_expert != NULL((void*)0))
14194 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14195 }
14196 }
14197 } else {
14198 if (hf_checksum_status != -1) {
14199 proto_item_append_text(ti, " [unverified]");
14200 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14201 proto_item_set_generated(ti2);
14202 }
14203 }
14204 }
14205
14206 return ti;
14207}
14208
14209unsigned char
14210proto_check_field_name(const char *field_name)
14211{
14212 return module_check_valid_name(field_name, false0);
14213}
14214
14215unsigned char
14216proto_check_field_name_lower(const char *field_name)
14217{
14218 return module_check_valid_name(field_name, true1);
14219}
14220
14221bool_Bool
14222tree_expanded(int tree_type)
14223{
14224 if (tree_type <= 0) {
14225 return false0;
14226 }
14227 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", 14227, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14228 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14229}
14230
14231void
14232tree_expanded_set(int tree_type, bool_Bool value)
14233{
14234 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", 14234, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14235
14236 if (value)
14237 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14238 else
14239 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14240}
14241
14242/*
14243 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14244 *
14245 * Local variables:
14246 * c-basic-offset: 8
14247 * tab-width: 8
14248 * indent-tabs-mode: t
14249 * End:
14250 *
14251 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14252 * :indentSize=8:tabSize=8:noTabs=false:
14253 */