Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13443, 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-05-05-100256-3825-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-05-05-100256-3825-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13#include "wireshark.h"
14
15#include <float.h>
16#include <errno(*__errno_location ()).h>
17
18#include <epan/tfs.h>
19#include <epan/unit_strings.h>
20
21#include <wsutil/array.h>
22#include <wsutil/bits_ctz.h>
23#include <wsutil/bits_count_ones.h>
24#include <wsutil/sign_ext.h>
25#include <wsutil/utf8_entities.h>
26#include <wsutil/json_dumper.h>
27#include <wsutil/pint.h>
28#include <wsutil/unicode-utils.h>
29#include <wsutil/dtoa.h>
30
31#include <ftypes/ftypes.h>
32
33#include "packet.h"
34#include "exceptions.h"
35#include "ptvcursor.h"
36#include "strutil.h"
37#include "addr_resolv.h"
38#include "address_types.h"
39#include "oids.h"
40#include "proto.h"
41#include "epan_dissect.h"
42#include "dfilter/dfilter.h"
43#include "tvbuff.h"
44#include "charsets.h"
45#include "column-info.h"
46#include "to_str.h"
47#include "osi-utils.h"
48#include "expert.h"
49#include "show_exception.h"
50#include "in_cksum.h"
51#include "register-int.h"
52
53#include <wsutil/crash_info.h>
54#include <wsutil/epochs.h>
55
56/* Ptvcursor limits */
57#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
58#define SUBTREE_MAX_LEVELS256 256
59
60typedef struct __subtree_lvl {
61 int cursor_offset;
62 proto_item *it;
63 proto_tree *tree;
64} subtree_lvl;
65
66struct ptvcursor {
67 wmem_allocator_t *scope;
68 subtree_lvl *pushed_tree;
69 uint8_t pushed_tree_index;
70 uint8_t pushed_tree_max;
71 proto_tree *tree;
72 tvbuff_t *tvb;
73 int offset;
74};
75
76#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
77
78/** See inlined comments.
79 @param tree the tree to append this item to
80 @param free_block a code block to call to free resources if this returns
81 @return NULL if 'tree' is null */
82#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
83 if (!tree) { \
84 free_block; \
85 return NULL((void*)0); \
86 }
87
88/** See inlined comments.
89 @param tree the tree to append this item to
90 @return NULL if 'tree' is null */
91#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
92 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
93
94/** See inlined comments.
95 @param length the length of this item
96 @param cleanup_block a code block to call to free resources if this returns
97 @return NULL if 'length' is lower -1 or equal 0 */
98#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
99 if (length < -1 || length == 0 ) { \
100 cleanup_block; \
101 return NULL((void*)0); \
102 }
103
104/** See inlined comments.
105 @param length the length of this item
106 @return NULL if 'length' is lower -1 or equal 0 */
107#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
108 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
109
110/** See inlined comments.
111 @param tree the tree to append this item to
112 @param hfindex field index
113 @param hfinfo header_field
114 @param free_block a code block to call to free resources if this returns
115 @return the header field matching 'hfinfo' */
116#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 116
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 116, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 116, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 116, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return proto_tree_add_fake_node(tree, hfinfo
); } } }
\
117 /* If the tree is not visible and this item is not referenced \
118 we don't have to do much work at all but we should still \
119 return a node so that referenced field items below this node \
120 (think proto_item_add_subtree()) will still have somewhere \
121 to attach to or else filtering will not work (they would be \
122 ignored since tree would be NULL). \
123 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
124 because that means we can change its length or repr, and we \
125 don't want to do so with calls intended for this faked new \
126 item, so this item needs a new (hidden) child node. \
127 We fake FT_PROTOCOL unless some clients have requested us \
128 not to do so. \
129 */ \
130 PTREE_DATA(tree)((tree)->tree_data)->count++; \
131 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 131, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 131, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 131, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
132 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
133 free_block; \
134 if (wireshark_abort_on_too_many_items) \
135 ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 136
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
136 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 136
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
137 /* Let the exception handler add items to the tree */ \
138 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
139 THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
140 wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
141 "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
142 hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)))
; \
143 } \
144 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
145 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
146 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
147 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
148 && (hfinfo->type != FT_PROTOCOL || \
149 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
150 free_block; \
151 /* return fake node with no field info */\
152 return proto_tree_add_fake_node(tree, hfinfo); \
153 } \
154 } \
155 }
156
157/** See inlined comments.
158 @param tree the tree to append this item to
159 @param hfindex field index
160 @param hfinfo header_field
161 @return the header field matching 'hfinfo' */
162#define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 162
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 162, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 162, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 162, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
163 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 163
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 163, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 163, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 163, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
164
165
166/** See inlined comments.
167 @param pi the created protocol item we're about to return */
168#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 168, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
169 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 169, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
170 if (!PITEM_FINFO(pi)((pi)->finfo)) \
171 return pi; \
172 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
173 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
174 /* If the tree (GUI) or item isn't visible it's pointless for \
175 * us to generate the protocol item's string representation */ \
176 return pi; \
177 }
178/* Same as above but returning void */
179#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
180 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
181 return; \
182 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
183 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
184 /* If the tree (GUI) or item isn't visible it's pointless for \
185 * us to generate the protocol item's string representation */ \
186 return; \
187 }
188/* Similar to above, but allows a NULL tree */
189#define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
\
190 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
191 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
192 /* If the tree (GUI) or item isn't visible it's pointless for \
193 * us to generate the protocol item's string representation */ \
194 return pi; \
195 }
196
197#ifdef ENABLE_CHECK_FILTER
198#define CHECK_HF_VALUE(type, spec, start_values) \
199{ \
200 const type *current; \
201 int n, m; \
202 current = start_values; \
203 for (n=0; current; n++, current++) { \
204 /* Drop out if we reached the end. */ \
205 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
206 break; \
207 } \
208 /* Check value against all previous */ \
209 for (m=0; m < n; m++) { \
210 /* There are lots of duplicates with the same string, \
211 so only report if different... */ \
212 if ((start_values[m].value == current->value) && \
213 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
214 ws_warning("Field '%s' (%s) has a conflicting entry in its" \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 217, __func__, "Field '%s' (%s) has a conflicting entry in its"
" value_string: %" spec " is at indices %u (%s) and %u (%s)"
, hfinfo->name, hfinfo->abbrev, current->value, m, start_values
[m].strptr, n, current->strptr); } } while (0)
215 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 217, __func__, "Field '%s' (%s) has a conflicting entry in its"
" value_string: %" spec " is at indices %u (%s) and %u (%s)"
, hfinfo->name, hfinfo->abbrev, current->value, m, start_values
[m].strptr, n, current->strptr); } } while (0)
216 hfinfo->name, hfinfo->abbrev, \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 217, __func__, "Field '%s' (%s) has a conflicting entry in its"
" value_string: %" spec " is at indices %u (%s) and %u (%s)"
, hfinfo->name, hfinfo->abbrev, current->value, m, start_values
[m].strptr, n, current->strptr); } } while (0)
217 current->value, m, start_values[m].strptr, n, current->strptr)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 217, __func__, "Field '%s' (%s) has a conflicting entry in its"
" value_string: %" spec " is at indices %u (%s) and %u (%s)"
, hfinfo->name, hfinfo->abbrev, current->value, m, start_values
[m].strptr, n, current->strptr); } } while (0)
; \
218 } \
219 } \
220 } \
221}
222#endif
223
224/* The longest NUMBER-like field label we have is for BASE_OUI, which
225 * can have up to 64 bytes for the manufacturer name if resolved plus
226 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
227 */
228#define NUMBER_LABEL_LENGTH80 80
229
230static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
231static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
232static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
233static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
234static int hfinfo_bitoffset(const header_field_info *hfinfo);
235static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
236static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
237
238#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
239 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
240
241static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
242static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
243#define LABEL_MARK_TRUNCATED_START(label_str, value_pos)label_mark_truncated(label_str, 0, value_pos) label_mark_truncated(label_str, 0, value_pos)
244
245static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
246static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
247static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
248static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
249static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
250static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252
253static size_t fill_display_label_float(const field_info *fi, char *label_str);
254static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
255static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str);
256static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
257
258static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
259static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
260static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
261static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
264static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
265static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
266static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
267static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
268
269static void proto_cleanup_base(void);
270
271static proto_item *
272proto_tree_add_node(proto_tree *tree, field_info *fi);
273
274static proto_item *
275proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
276
277static void
278get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
279 int *item_length, const unsigned encoding);
280
281static int
282get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
283 int length, unsigned item_length, const int encoding);
284
285static field_info *
286new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
287 const int start, const int item_length);
288
289static proto_item *
290proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
291 int start, int *length);
292
293static void
294proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
295static void
296proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
297
298static void
299proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
300static void
301proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
302static void
303proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
304static void
305proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
306static void
307proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
308static void
309proto_tree_set_string(field_info *fi, const char* value);
310static void
311proto_tree_set_ax25(field_info *fi, const uint8_t* value);
312static void
313proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
314static void
315proto_tree_set_vines(field_info *fi, const uint8_t* value);
316static void
317proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
318static void
319proto_tree_set_ether(field_info *fi, const uint8_t* value);
320static void
321proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
322static void
323proto_tree_set_ipxnet(field_info *fi, uint32_t value);
324static void
325proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
326static void
327proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
328static void
329proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
330static void
331proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
332static void
333proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
334static void
335proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
336static void
337proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
338static void
339proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
340static void
341proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
342static void
343proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
344static void
345proto_tree_set_boolean(field_info *fi, uint64_t value);
346static void
347proto_tree_set_float(field_info *fi, float value);
348static void
349proto_tree_set_double(field_info *fi, double value);
350static void
351proto_tree_set_uint(field_info *fi, uint32_t value);
352static void
353proto_tree_set_int(field_info *fi, int32_t value);
354static void
355proto_tree_set_uint64(field_info *fi, uint64_t value);
356static void
357proto_tree_set_int64(field_info *fi, int64_t value);
358static void
359proto_tree_set_eui64(field_info *fi, const uint64_t value);
360static void
361proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
362
363/* Handle type length mismatch (now filterable) expert info */
364static int proto_type_length_mismatch;
365static expert_field ei_type_length_mismatch_error;
366static expert_field ei_type_length_mismatch_warn;
367static void register_type_length_mismatch(void);
368
369/* Handle byte array string decoding errors with expert info */
370static int proto_byte_array_string_decoding_error;
371static expert_field ei_byte_array_string_decoding_failed_error;
372static void register_byte_array_string_decodinws_error(void);
373
374/* Handle date and time string decoding errors with expert info */
375static int proto_date_time_string_decoding_error;
376static expert_field ei_date_time_string_decoding_failed_error;
377static void register_date_time_string_decodinws_error(void);
378
379/* Handle string errors expert info */
380static int proto_string_errors;
381static expert_field ei_string_trailing_characters;
382static void register_string_errors(void);
383
384static int proto_register_field_init(header_field_info *hfinfo, const int parent);
385
386/* special-case header field used within proto.c */
387static header_field_info hfi_text_only =
388 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
389int hf_text_only;
390
391/* Structure for information about a protocol */
392struct _protocol {
393 const char *name; /* long description */
394 const char *short_name; /* short description */
395 const char *filter_name; /* name of this protocol in filters */
396 GPtrArray *fields; /* fields for this protocol */
397 int proto_id; /* field ID for this protocol */
398 bool_Bool is_enabled; /* true if protocol is enabled */
399 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
400 bool_Bool can_toggle; /* true if is_enabled can be changed */
401 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
402 For dissectors that need a protocol name so they
403 can be added to a dissector table, but use the
404 parent_proto_id for things like enable/disable */
405 GList *heur_list; /* Heuristic dissectors associated with this protocol */
406};
407
408/* List of all protocols */
409static GList *protocols;
410
411/* Structure stored for deregistered g_slice */
412struct g_slice_data {
413 size_t block_size;
414 void *mem_block;
415};
416
417/* Deregistered fields */
418static GPtrArray *deregistered_fields;
419static GPtrArray *deregistered_data;
420static GPtrArray *deregistered_slice;
421
422/* indexed by prefix, contains initializers */
423static GHashTable* prefixes;
424
425/* Contains information about a field when a dissector calls
426 * proto_tree_add_item. */
427#define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
428#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
429
430/* Contains the space for proto_nodes. */
431#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
432 node->first_child = NULL((void*)0); \
433 node->last_child = NULL((void*)0); \
434 node->next = NULL((void*)0);
435
436#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
437 wmem_free(pool, node)
438
439/* String space for protocol and field items for the GUI */
440#define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))
); il->value_pos = 0; il->value_len = 0;
\
441 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
442 il->value_pos = 0; \
443 il->value_len = 0;
444#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
445 wmem_free(pool, il);
446
447#define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 447, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 447, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 447, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
448 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
449 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 449
, __func__, "Unregistered hf! index=%d", hfindex)
; \
450 DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 450, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
451 DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 451, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
452 hfinfo = gpa_hfinfo.hfi[hfindex];
453
454/* List which stores protocols and fields that have been registered */
455typedef struct _gpa_hfinfo_t {
456 uint32_t len;
457 uint32_t allocated_len;
458 header_field_info **hfi;
459} gpa_hfinfo_t;
460
461static gpa_hfinfo_t gpa_hfinfo;
462
463/* Hash table of abbreviations and IDs */
464static GHashTable *gpa_name_map;
465static header_field_info *same_name_hfinfo;
466
467/* Hash table protocol aliases. const char * -> const char * */
468static GHashTable *gpa_protocol_aliases;
469
470/*
471 * We're called repeatedly with the same field name when sorting a column.
472 * Cache our last gpa_name_map hit for faster lookups.
473 */
474static char *last_field_name;
475static header_field_info *last_hfinfo;
476
477static void save_same_name_hfinfo(void *data)
478{
479 same_name_hfinfo = (header_field_info*)data;
480}
481
482/* Points to the first element of an array of bits, indexed by
483 a subtree item type; that array element is true if subtrees of
484 an item of that type are to be expanded. */
485static uint32_t *tree_is_expanded;
486
487/* Number of elements in that array. The entry with index 0 is not used. */
488int num_tree_types = 1;
489
490/* Name hashtables for fast detection of duplicate names */
491static GHashTable* proto_names;
492static GHashTable* proto_short_names;
493static GHashTable* proto_filter_names;
494
495static const char *reserved_filter_names[] = {
496 /* Display filter keywords. */
497 "eq",
498 "ne",
499 "all_eq",
500 "any_eq",
501 "all_ne",
502 "any_ne",
503 "gt",
504 "ge",
505 "lt",
506 "le",
507 "bitand",
508 "bitwise_and",
509 "contains",
510 "matches",
511 "not",
512 "and",
513 "or",
514 "xor",
515 "in",
516 "any",
517 "all",
518 "true",
519 "false",
520 "nan",
521 "inf",
522 "infinity",
523 NULL((void*)0)
524};
525
526static GHashTable *proto_reserved_filter_names;
527
528static int
529proto_compare_name(const void *p1_arg, const void *p2_arg)
530{
531 const protocol_t *p1 = (const protocol_t *)p1_arg;
532 const protocol_t *p2 = (const protocol_t *)p2_arg;
533
534 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
535}
536
537static GSList *dissector_plugins;
538
539#ifdef HAVE_PLUGINS1
540void
541proto_register_plugin(const proto_plugin *plug)
542{
543 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
544}
545#else /* HAVE_PLUGINS */
546void
547proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
548{
549 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 549, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
550}
551#endif /* HAVE_PLUGINS */
552
553static void
554call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
555{
556 proto_plugin *plug = (proto_plugin *)data;
557
558 if (plug->register_protoinfo) {
559 plug->register_protoinfo();
560 }
561}
562
563static void
564call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
565{
566 proto_plugin *plug = (proto_plugin *)data;
567
568 if (plug->register_handoff) {
569 plug->register_handoff();
570 }
571}
572
573/* initialize data structures and register protocols and fields */
574void
575proto_init(GSList *register_all_plugin_protocols_list,
576 GSList *register_all_plugin_handoffs_list,
577 register_cb cb,
578 void *client_data)
579{
580 proto_cleanup_base();
581
582 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
583 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
584 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
585
586 proto_reserved_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
587 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
588 /* GHashTable has no key destructor so the cast is safe. */
589 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
590 }
591
592 gpa_hfinfo.len = 0;
593 gpa_hfinfo.allocated_len = 0;
594 gpa_hfinfo.hfi = NULL((void*)0);
595 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL((void*)0), save_same_name_hfinfo);
596 gpa_protocol_aliases = g_hash_table_new(g_str_hash, g_str_equal);
597 deregistered_fields = g_ptr_array_new();
598 deregistered_data = g_ptr_array_new();
599 deregistered_slice = g_ptr_array_new();
600
601 /* Initialize the ftype subsystem */
602 ftypes_initialize();
603
604 /* Initialize the address type subsystem */
605 address_types_initialize();
606
607 /* Register one special-case FT_TEXT_ONLY field for use when
608 converting wireshark to new-style proto_tree. These fields
609 are merely strings on the GUI tree; they are not filterable */
610 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
611
612 /* Register the pseudo-protocols used for exceptions. */
613 register_show_exception();
614 register_type_length_mismatch();
615 register_byte_array_string_decodinws_error();
616 register_date_time_string_decodinws_error();
617 register_string_errors();
618 ftypes_register_pseudofields();
619 col_register_protocol();
620
621 /* Have each built-in dissector register its protocols, fields,
622 dissector tables, and dissectors to be called through a
623 handle, and do whatever one-time initialization it needs to
624 do. */
625 register_all_protocols(cb, client_data);
626
627 /* Now call the registration routines for all epan plugins. */
628 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
629 ((void (*)(register_cb, void *))l->data)(cb, client_data);
630 }
631
632 /* Now call the registration routines for all dissector plugins. */
633 if (cb)
634 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
635 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
636
637 /* Now call the "handoff registration" routines of all built-in
638 dissectors; those routines register the dissector in other
639 dissectors' handoff tables, and fetch any dissector handles
640 they need. */
641 register_all_protocol_handoffs(cb, client_data);
642
643 /* Now do the same with epan plugins. */
644 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
645 ((void (*)(register_cb, void *))l->data)(cb, client_data);
646 }
647
648 /* Now do the same with dissector plugins. */
649 if (cb)
650 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
651 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
652
653 /* sort the protocols by protocol name */
654 protocols = g_list_sort(protocols, proto_compare_name);
655
656 /* sort the dissector handles in dissector tables (for -G reports
657 * and -d error messages. The GUI sorts the handles itself.) */
658 packet_all_tables_sort_handles();
659
660 /* We've assigned all the subtree type values; allocate the array
661 for them, and zero it out. */
662 tree_is_expanded = g_new0(uint32_t, (num_tree_types/32)+1)((uint32_t *) g_malloc0_n (((num_tree_types/32)+1), sizeof (uint32_t
)))
;
663}
664
665static void
666proto_cleanup_base(void)
667{
668 protocol_t *protocol;
669 header_field_info *hfinfo;
670
671 /* Free the abbrev/ID hash table */
672 if (gpa_name_map) {
673 g_hash_table_destroy(gpa_name_map);
674 gpa_name_map = NULL((void*)0);
675 }
676 if (gpa_protocol_aliases) {
677 g_hash_table_destroy(gpa_protocol_aliases);
678 gpa_protocol_aliases = NULL((void*)0);
679 }
680 g_free(last_field_name);
681 last_field_name = NULL((void*)0);
682
683 while (protocols) {
684 protocol = (protocol_t *)protocols->data;
685 PROTO_REGISTRAR_GET_NTH(protocol->proto_id, hfinfo)if((protocol->proto_id == 0 || (unsigned)protocol->proto_id
> gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 685
, __func__, "Unregistered hf! index=%d", protocol->proto_id
); ((void) ((protocol->proto_id > 0 && (unsigned
)protocol->proto_id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 685, "protocol->proto_id > 0 && (unsigned)protocol->proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[protocol->
proto_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 685, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
686 DISSECTOR_ASSERT(protocol->proto_id == hfinfo->id)((void) ((protocol->proto_id == hfinfo->id) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 686, "protocol->proto_id == hfinfo->id"
))))
;
687
688 g_slice_free(header_field_info, hfinfo)do { if (1) g_slice_free1 (sizeof (header_field_info), (hfinfo
)); else (void) ((header_field_info*) 0 == (hfinfo)); } while
(0)
;
689 if (protocol->parent_proto_id != -1) {
690 // pino protocol
691 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 691, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
692 DISSECTOR_ASSERT(protocol->heur_list == NULL)((void) ((protocol->heur_list == ((void*)0)) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 692, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
693 } else {
694 if (protocol->fields) {
695 g_ptr_array_free(protocol->fields, true1);
696 }
697 g_list_free(protocol->heur_list);
698 }
699 protocols = g_list_remove(protocols, protocol);
700 g_free(protocol);
701 }
702
703 if (proto_names) {
704 g_hash_table_destroy(proto_names);
705 proto_names = NULL((void*)0);
706 }
707
708 if (proto_short_names) {
709 g_hash_table_destroy(proto_short_names);
710 proto_short_names = NULL((void*)0);
711 }
712
713 if (proto_filter_names) {
714 g_hash_table_destroy(proto_filter_names);
715 proto_filter_names = NULL((void*)0);
716 }
717
718 if (proto_reserved_filter_names) {
719 g_hash_table_destroy(proto_reserved_filter_names);
720 proto_reserved_filter_names = NULL((void*)0);
721 }
722
723 if (gpa_hfinfo.allocated_len) {
724 gpa_hfinfo.len = 0;
725 gpa_hfinfo.allocated_len = 0;
726 g_free(gpa_hfinfo.hfi);
727 gpa_hfinfo.hfi = NULL((void*)0);
728 }
729
730 if (deregistered_fields) {
731 g_ptr_array_free(deregistered_fields, true1);
732 deregistered_fields = NULL((void*)0);
733 }
734
735 if (deregistered_data) {
736 g_ptr_array_free(deregistered_data, true1);
737 deregistered_data = NULL((void*)0);
738 }
739
740 if (deregistered_slice) {
741 g_ptr_array_free(deregistered_slice, true1);
742 deregistered_slice = NULL((void*)0);
743 }
744
745 g_free(tree_is_expanded);
746 tree_is_expanded = NULL((void*)0);
747
748 if (prefixes)
749 g_hash_table_destroy(prefixes);
750}
751
752void
753proto_cleanup(void)
754{
755 proto_free_deregistered_fields();
756 proto_cleanup_base();
757
758 g_slist_free(dissector_plugins);
759 dissector_plugins = NULL((void*)0);
760}
761
762static bool_Bool
763// NOLINTNEXTLINE(misc-no-recursion)
764proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
765 void *data)
766{
767 proto_node *pnode = tree;
768 proto_node *child;
769 proto_node *current;
770
771 if (func(pnode, data))
772 return true1;
773
774 child = pnode->first_child;
775 while (child != NULL((void*)0)) {
776 /*
777 * The routine we call might modify the child, e.g. by
778 * freeing it, so we get the child's successor before
779 * calling that routine.
780 */
781 current = child;
782 child = current->next;
783 // We recurse here, but we're limited by prefs.gui_max_tree_depth
784 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
785 return true1;
786 }
787
788 return false0;
789}
790
791void
792proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
793 void *data)
794{
795 proto_node *node = tree;
796 proto_node *current;
797
798 if (!node)
799 return;
800
801 node = node->first_child;
802 while (node != NULL((void*)0)) {
803 current = node;
804 node = current->next;
805 func((proto_tree *)current, data);
806 }
807}
808
809static void
810free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
811{
812 GPtrArray *ptrs = (GPtrArray *)value;
813 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
814 header_field_info *hfinfo;
815
816 PROTO_REGISTRAR_GET_NTH(hfid, hfinfo)if((hfid == 0 || (unsigned)hfid > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 816, __func__, "Unregistered hf! index=%d",
hfid); ((void) ((hfid > 0 && (unsigned)hfid < gpa_hfinfo
.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 816, "hfid > 0 && (unsigned)hfid < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfid] != (
(void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 816, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
817 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
818 /* when a field is referenced by a filter this also
819 affects the refcount for the parent protocol so we need
820 to adjust the refcount for the parent as well
821 */
822 if (hfinfo->parent != -1) {
823 header_field_info *parent_hfinfo;
824 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 824
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 824, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 824, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
825 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
826 }
827 hfinfo->ref_type = HF_REF_TYPE_NONE;
828 }
829
830 g_ptr_array_free(ptrs, true1);
831}
832
833static void
834proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
835{
836 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
837
838 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
839
840 if (finfo) {
841 fvalue_free(finfo->value);
842 finfo->value = NULL((void*)0);
843 }
844}
845
846void
847proto_tree_reset(proto_tree *tree)
848{
849 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
850
851 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
852
853 /* free tree data */
854 if (tree_data->interesting_hfids) {
855 /* Free all the GPtrArray's in the interesting_hfids hash. */
856 g_hash_table_foreach(tree_data->interesting_hfids,
857 free_GPtrArray_value, NULL((void*)0));
858
859 /* And then remove all values. */
860 g_hash_table_remove_all(tree_data->interesting_hfids);
861 }
862
863 /* Reset track of the number of children */
864 tree_data->count = 0;
865
866 /* Reset our loop checks */
867 tree_data->max_start = 0;
868 tree_data->start_idle_count = 0;
869
870 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
871}
872
873/* frees the resources that the dissection a proto_tree uses */
874void
875proto_tree_free(proto_tree *tree)
876{
877 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
878
879 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
880
881 /* free tree data */
882 if (tree_data->interesting_hfids) {
883 /* Free all the GPtrArray's in the interesting_hfids hash. */
884 g_hash_table_foreach(tree_data->interesting_hfids,
885 free_GPtrArray_value, NULL((void*)0));
886
887 /* And then destroy the hash. */
888 g_hash_table_destroy(tree_data->interesting_hfids);
889 }
890
891 g_slice_free(tree_data_t, tree_data)do { if (1) g_slice_free1 (sizeof (tree_data_t), (tree_data))
; else (void) ((tree_data_t*) 0 == (tree_data)); } while (0)
;
892
893 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
894}
895
896/* Is the parsing being done for a visible proto_tree or an invisible one?
897 * By setting this correctly, the proto_tree creation is sped up by not
898 * having to call vsnprintf and copy strings around.
899 */
900bool_Bool
901proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
902{
903 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
904
905 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
906
907 return old_visible;
908}
909
910void
911proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
912{
913 if (tree)
914 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
915}
916
917/* Assume dissector set only its protocol fields.
918 This function is called by dissectors and allows the speeding up of filtering
919 in wireshark; if this function returns false it is safe to reset tree to NULL
920 and thus skip calling most of the expensive proto_tree_add_...()
921 functions.
922 If the tree is visible we implicitly assume the field is referenced.
923*/
924bool_Bool
925proto_field_is_referenced(proto_tree *tree, int proto_id)
926{
927 register header_field_info *hfinfo;
928
929
930 if (!tree)
931 return false0;
932
933 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
934 return true1;
935
936 PROTO_REGISTRAR_GET_NTH(proto_id, hfinfo)if((proto_id == 0 || (unsigned)proto_id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 936, __func__, "Unregistered hf! index=%d",
proto_id); ((void) ((proto_id > 0 && (unsigned)proto_id
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 936, "proto_id > 0 && (unsigned)proto_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[proto_id]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 936, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
937 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
938 return true1;
939
940 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
941 return true1;
942
943 return false0;
944}
945
946
947/* Finds a record in the hfinfo array by id. */
948header_field_info *
949proto_registrar_get_nth(unsigned hfindex)
950{
951 register header_field_info *hfinfo;
952
953 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 953, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 953, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 953, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
954 return hfinfo;
955}
956
957
958/* Prefix initialization
959 * this allows for a dissector to register a display filter name prefix
960 * so that it can delay the initialization of the hf array as long as
961 * possible.
962 */
963
964/* compute a hash for the part before the dot of a display filter */
965static unsigned
966prefix_hash (const void *key) {
967 /* end the string at the dot and compute its hash */
968 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
969 char* c = copy;
970 unsigned tmp;
971
972 for (; *c; c++) {
973 if (*c == '.') {
974 *c = 0;
975 break;
976 }
977 }
978
979 tmp = g_str_hash(copy);
980 g_free(copy);
981 return tmp;
982}
983
984/* are both strings equal up to the end or the dot? */
985static gboolean
986prefix_equal (const void *ap, const void *bp) {
987 const char* a = (const char *)ap;
988 const char* b = (const char *)bp;
989
990 do {
991 char ac = *a++;
992 char bc = *b++;
993
994 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
995
996 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
997 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
998
999 if (ac != bc) return FALSE(0);
1000 } while (1);
1001
1002 return FALSE(0);
1003}
1004
1005/* Register a new prefix for "delayed" initialization of field arrays */
1006void
1007proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1008 if (! prefixes ) {
1009 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1010 }
1011
1012 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1013}
1014
1015/* helper to call all prefix initializers */
1016static gboolean
1017initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1018 ((prefix_initializer_t)v)((const char *)k);
1019 return TRUE(!(0));
1020}
1021
1022/** Initialize every remaining uninitialized prefix. */
1023void
1024proto_initialize_all_prefixes(void) {
1025 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1026}
1027
1028/* Finds a record in the hfinfo array by name.
1029 * If it fails to find it in the already registered fields,
1030 * it tries to find and call an initializer in the prefixes
1031 * table and if so it looks again.
1032 */
1033
1034header_field_info *
1035proto_registrar_get_byname(const char *field_name)
1036{
1037 header_field_info *hfinfo;
1038 prefix_initializer_t pi;
1039
1040 if (!field_name)
1041 return NULL((void*)0);
1042
1043 if (g_strcmp0(field_name, last_field_name) == 0) {
1044 return last_hfinfo;
1045 }
1046
1047 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1048
1049 if (hfinfo) {
1050 g_free(last_field_name);
1051 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1052 last_hfinfo = hfinfo;
1053 return hfinfo;
1054 }
1055
1056 if (!prefixes)
1057 return NULL((void*)0);
1058
1059 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1060 pi(field_name);
1061 g_hash_table_remove(prefixes, field_name);
1062 } else {
1063 return NULL((void*)0);
1064 }
1065
1066 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1067
1068 if (hfinfo) {
1069 g_free(last_field_name);
1070 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1071 last_hfinfo = hfinfo;
1072 }
1073 return hfinfo;
1074}
1075
1076header_field_info*
1077proto_registrar_get_byalias(const char *alias_name)
1078{
1079 if (!alias_name) {
1080 return NULL((void*)0);
1081 }
1082
1083 /* Find our aliased protocol. */
1084 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1085 char *dot = strchr(an_copy, '.');
1086 if (dot) {
1087 *dot = '\0';
1088 }
1089 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1090 if (!proto_pfx) {
1091 g_free(an_copy);
1092 return NULL((void*)0);
1093 }
1094
1095 /* Construct our aliased field and look it up. */
1096 GString *filter_name = g_string_new(proto_pfx);
1097 if (dot) {
1098 g_string_append_printf(filter_name, ".%s", dot+1);
1099 }
1100 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1101 g_free(an_copy);
1102 g_string_free(filter_name, TRUE)(__builtin_constant_p ((!(0))) ? (((!(0))) ? (g_string_free) (
(filter_name), ((!(0)))) : g_string_free_and_steal (filter_name
)) : (g_string_free) ((filter_name), ((!(0)))))
;
1103
1104 return hfinfo;
1105}
1106
1107int
1108proto_registrar_get_id_byname(const char *field_name)
1109{
1110 header_field_info *hfinfo;
1111
1112 hfinfo = proto_registrar_get_byname(field_name);
1113
1114 if (!hfinfo)
1115 return -1;
1116
1117 return hfinfo->id;
1118}
1119
1120static int
1121label_strcat_flags(const header_field_info *hfinfo)
1122{
1123 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1124 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1125
1126 return 0;
1127}
1128
1129static char *
1130format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1131 const uint8_t *bytes, unsigned length, size_t max_str_len)
1132{
1133 char *str = NULL((void*)0);
1134 const uint8_t *p;
1135 bool_Bool is_printable;
1136
1137 if (bytes) {
1138 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1139 /*
1140 * If all bytes are valid and printable UTF-8, show the
1141 * bytes as a string - in quotes to indicate that it's
1142 * a string.
1143 */
1144 if (isprint_utf8_string(bytes, length)) {
1145 str = wmem_strdup_printf(scope, "\"%.*s\"",
1146 (int)length, bytes);
1147 return str;
1148 }
1149 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1150 /*
1151 * Check whether all bytes are printable.
1152 */
1153 is_printable = true1;
1154 for (p = bytes; p < bytes+length; p++) {
1155 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1156 /* Not printable. */
1157 is_printable = false0;
1158 break;
1159 }
1160 }
1161
1162 /*
1163 * If all bytes are printable ASCII, show the bytes
1164 * as a string - in quotes to indicate that it's
1165 * a string.
1166 */
1167 if (is_printable) {
1168 str = wmem_strdup_printf(scope, "\"%.*s\"",
1169 (int)length, bytes);
1170 return str;
1171 }
1172 }
1173
1174 /*
1175 * Either it's not printable ASCII, or we don't care whether
1176 * it's printable ASCII; show it as hex bytes.
1177 */
1178 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1179 case SEP_DOT:
1180 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1181 break;
1182 case SEP_DASH:
1183 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1184 break;
1185 case SEP_COLON:
1186 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1187 break;
1188 case SEP_SPACE:
1189 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1190 break;
1191 case BASE_NONE:
1192 default:
1193 if (prefs.display_byte_fields_with_spaces) {
1194 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1195 } else {
1196 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1197 }
1198 break;
1199 }
1200 }
1201 else {
1202 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1203 str = wmem_strdup(scope, "<none>");
1204 } else {
1205 str = wmem_strdup(scope, "<MISSING>");
1206 }
1207 }
1208 return str;
1209}
1210
1211static char *
1212format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1213 const uint8_t *bytes, unsigned length)
1214{
1215 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1216}
1217
1218static void
1219ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1220{
1221 subtree_lvl *pushed_tree;
1222
1223 DISSECTOR_ASSERT(ptvc->pushed_tree_max <= SUBTREE_MAX_LEVELS-SUBTREE_ONCE_ALLOCATION_NUMBER)((void) ((ptvc->pushed_tree_max <= 256 -8) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c"
, 1223, "ptvc->pushed_tree_max <= 256-8"))))
;
1224 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1225
1226 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1227 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1227, "pushed_tree != ((void*)0)"
))))
;
1228 ptvc->pushed_tree = pushed_tree;
1229}
1230
1231static void
1232ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1233{
1234 ptvc->pushed_tree = NULL((void*)0);
1235 ptvc->pushed_tree_max = 0;
1236 DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0)((void) ((ptvc->pushed_tree_index == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1236, "ptvc->pushed_tree_index == 0"
))))
;
1237 ptvc->pushed_tree_index = 0;
1238}
1239
1240/* Allocates an initializes a ptvcursor_t with 3 variables:
1241 * proto_tree, tvbuff, and offset. */
1242ptvcursor_t *
1243ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1244{
1245 ptvcursor_t *ptvc;
1246
1247 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1248 ptvc->scope = scope;
1249 ptvc->tree = tree;
1250 ptvc->tvb = tvb;
1251 ptvc->offset = offset;
1252 ptvc->pushed_tree = NULL((void*)0);
1253 ptvc->pushed_tree_max = 0;
1254 ptvc->pushed_tree_index = 0;
1255 return ptvc;
1256}
1257
1258
1259/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1260void
1261ptvcursor_free(ptvcursor_t *ptvc)
1262{
1263 ptvcursor_free_subtree_levels(ptvc);
1264 /*g_free(ptvc);*/
1265}
1266
1267/* Returns tvbuff. */
1268tvbuff_t *
1269ptvcursor_tvbuff(ptvcursor_t *ptvc)
1270{
1271 return ptvc->tvb;
1272}
1273
1274/* Returns current offset. */
1275int
1276ptvcursor_current_offset(ptvcursor_t *ptvc)
1277{
1278 return ptvc->offset;
1279}
1280
1281proto_tree *
1282ptvcursor_tree(ptvcursor_t *ptvc)
1283{
1284 if (!ptvc)
1285 return NULL((void*)0);
1286
1287 return ptvc->tree;
1288}
1289
1290void
1291ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1292{
1293 ptvc->tree = tree;
1294}
1295
1296/* creates a subtree, sets it as the working tree and pushes the old working tree */
1297proto_tree *
1298ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1299{
1300 subtree_lvl *subtree;
1301 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1302 ptvcursor_new_subtree_levels(ptvc);
1303
1304 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1305 subtree->tree = ptvc->tree;
1306 subtree->it= NULL((void*)0);
1307 ptvc->pushed_tree_index++;
1308 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1309}
1310
1311/* pops a subtree */
1312void
1313ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1314{
1315 subtree_lvl *subtree;
1316
1317 if (ptvc->pushed_tree_index <= 0)
1318 return;
1319
1320 ptvc->pushed_tree_index--;
1321 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1322 if (subtree->it != NULL((void*)0))
1323 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1324
1325 ptvc->tree = subtree->tree;
1326}
1327
1328/* saves the current tvb offset and the item in the current subtree level */
1329static void
1330ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1331{
1332 subtree_lvl *subtree;
1333
1334 DISSECTOR_ASSERT(ptvc->pushed_tree_index > 0)((void) ((ptvc->pushed_tree_index > 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1334, "ptvc->pushed_tree_index > 0"
))))
;
1335
1336 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1337 subtree->it = it;
1338 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1339}
1340
1341/* Creates a subtree and adds it to the cursor as the working tree but does not
1342 * save the old working tree */
1343proto_tree *
1344ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1345{
1346 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1347 return ptvc->tree;
1348}
1349
1350static proto_tree *
1351ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1352{
1353 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1354 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1355 ptvcursor_subtree_set_item(ptvc, it);
1356 return ptvcursor_tree(ptvc);
1357}
1358
1359/* Add an item to the tree and create a subtree
1360 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1361 * In this case, when the subtree will be closed, the parent item length will
1362 * be equal to the advancement of the cursor since the creation of the subtree.
1363 */
1364proto_tree *
1365ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1366 const unsigned encoding, int ett_subtree)
1367{
1368 proto_item *it;
1369
1370 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1371 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1372}
1373
1374static proto_item *
1375proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1376
1377/* Add a text node to the tree and create a subtree
1378 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1379 * In this case, when the subtree will be closed, the item length will be equal
1380 * to the advancement of the cursor since the creation of the subtree.
1381 */
1382proto_tree *
1383ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1384 int ett_subtree, const char *format, ...)
1385{
1386 proto_item *pi;
1387 va_list ap;
1388 header_field_info *hfinfo;
1389 proto_tree *tree;
1390
1391 tree = ptvcursor_tree(ptvc);
1392
1393 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1394
1395 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1395
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1395, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1395, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1395, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1396
1397 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1398 ptvcursor_current_offset(ptvc), length);
1399
1400 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1400, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1401
1402 va_start(ap, format)__builtin_va_start(ap, format);
1403 proto_tree_set_representation(pi, format, ap);
1404 va_end(ap)__builtin_va_end(ap);
1405
1406 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1407}
1408
1409/* Add a text-only node, leaving it to our caller to fill the text in */
1410static proto_item *
1411proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1412{
1413 proto_item *pi;
1414
1415 if (tree == NULL((void*)0))
1416 return NULL((void*)0);
1417
1418 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1419
1420 return pi;
1421}
1422
1423/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1424proto_item *
1425proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1426 const char *format, ...)
1427{
1428 proto_item *pi;
1429 va_list ap;
1430 header_field_info *hfinfo;
1431
1432 if (length == -1) {
1433 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1434 } else {
1435 tvb_ensure_bytes_exist(tvb, start, length);
1436 }
1437
1438 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1439
1440 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1440
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1440, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1440, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1440, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1441
1442 pi = proto_tree_add_text_node(tree, tvb, start, length);
1443
1444 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1444, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1445
1446 va_start(ap, format)__builtin_va_start(ap, format);
1447 proto_tree_set_representation(pi, format, ap);
1448 va_end(ap)__builtin_va_end(ap);
1449
1450 return pi;
1451}
1452
1453/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1454proto_item *
1455proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1456 int length, const char *format, va_list ap)
1457{
1458 proto_item *pi;
1459 header_field_info *hfinfo;
1460
1461 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1462 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1463 * the length to be what's in the tvbuff if length is -1, and the
1464 * minimum of length and what's in the tvbuff if not.
1465 */
1466
1467 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1468
1469 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1469
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1469, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1469, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1469, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1470
1471 pi = proto_tree_add_text_node(tree, tvb, start, length);
1472
1473 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1473, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1474
1475 proto_tree_set_representation(pi, format, ap);
1476
1477 return pi;
1478}
1479
1480/* Add a text-only node that creates a subtree underneath.
1481 */
1482proto_tree *
1483proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1484{
1485 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1486}
1487
1488/* Add a text-only node that creates a subtree underneath.
1489 */
1490proto_tree *
1491proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1492{
1493 proto_tree *pt;
1494 proto_item *pi;
1495 va_list ap;
1496
1497 va_start(ap, format)__builtin_va_start(ap, format);
1498 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1499 va_end(ap)__builtin_va_end(ap);
1500
1501 if (tree_item != NULL((void*)0))
1502 *tree_item = pi;
1503
1504 pt = proto_item_add_subtree(pi, idx);
1505
1506 return pt;
1507}
1508
1509/* Add a text-only node for debugging purposes. The caller doesn't need
1510 * to worry about tvbuff, start, or length. Debug message gets sent to
1511 * STDOUT, too */
1512proto_item *
1513proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1514{
1515 proto_item *pi;
1516 va_list ap;
1517
1518 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1519
1520 if (pi) {
1521 va_start(ap, format)__builtin_va_start(ap, format);
1522 proto_tree_set_representation(pi, format, ap);
1523 va_end(ap)__builtin_va_end(ap);
1524 }
1525 va_start(ap, format)__builtin_va_start(ap, format);
1526 vprintf(format, ap);
1527 va_end(ap)__builtin_va_end(ap);
1528 printf("\n");
1529
1530 return pi;
1531}
1532
1533proto_item *
1534proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1535{
1536 proto_item *pi;
1537 header_field_info *hfinfo;
1538
1539 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1540
1541 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1541
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1541, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1541, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1541, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1542
1543 pi = proto_tree_add_text_node(tree, tvb, start, length);
1544
1545 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1545, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1546
1547 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1548
1549 return pi;
1550}
1551
1552proto_item *
1553proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1554{
1555 proto_item *pi;
1556 header_field_info *hfinfo;
1557 char *str;
1558
1559 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1560
1561 TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || (
unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1561
, __func__, "Unregistered hf! index=%d", hf_text_only); ((void
) ((hf_text_only > 0 && (unsigned)hf_text_only <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1561, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 1561, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only
];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1561, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
1562
1563 pi = proto_tree_add_text_node(tree, tvb, start, length);
1564
1565 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1565, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1566
1567 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1568 proto_item_set_text(pi, "%s", str);
1569 wmem_free(NULL((void*)0), str);
1570
1571 return pi;
1572}
1573
1574void proto_report_dissector_bug(const char *format, ...)
1575{
1576 va_list args;
1577
1578 if (wireshark_abort_on_dissector_bug) {
1579 /*
1580 * Try to have the error message show up in the crash
1581 * information.
1582 */
1583 va_start(args, format)__builtin_va_start(args, format);
1584 ws_vadd_crash_info(format, args);
1585 va_end(args)__builtin_va_end(args);
1586
1587 /*
1588 * Print the error message.
1589 */
1590 va_start(args, format)__builtin_va_start(args, format);
1591 vfprintf(stderrstderr, format, args);
1592 va_end(args)__builtin_va_end(args);
1593 putc('\n', stderrstderr);
1594
1595 /*
1596 * And crash.
1597 */
1598 abort();
1599 } else {
1600 va_start(args, format)__builtin_va_start(args, format);
1601 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1602 va_end(args)__builtin_va_end(args);
1603 }
1604}
1605
1606/* We could probably get away with changing is_error to a minimum length value. */
1607static void
1608report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1609{
1610 if (is_error) {
1611 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1612 } else {
1613 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1614 }
1615
1616 if (is_error) {
1617 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1618 }
1619}
1620
1621static uint32_t
1622get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1623{
1624 uint32_t value;
1625 bool_Bool length_error;
1626
1627 switch (length) {
1628
1629 case 1:
1630 value = tvb_get_uint8(tvb, offset);
1631 if (encoding & ENC_ZIGBEE0x40000000) {
1632 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1633 value = 0;
1634 }
1635 }
1636 break;
1637
1638 case 2:
1639 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1640 : tvb_get_ntohs(tvb, offset);
1641 if (encoding & ENC_ZIGBEE0x40000000) {
1642 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1643 value = 0;
1644 }
1645 }
1646 break;
1647
1648 case 3:
1649 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1650 : tvb_get_ntoh24(tvb, offset);
1651 break;
1652
1653 case 4:
1654 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1655 : tvb_get_ntohl(tvb, offset);
1656 break;
1657
1658 default:
1659 if (length < 1) {
1660 length_error = true1;
1661 value = 0;
1662 } else {
1663 length_error = false0;
1664 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1665 : tvb_get_ntohl(tvb, offset);
1666 }
1667 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1668 break;
1669 }
1670 return value;
1671}
1672
1673static inline uint64_t
1674get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1675{
1676 uint64_t value;
1677
1678 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1679
1680 if (length < 1 || length > 8) {
1681 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1682 }
1683
1684 return value;
1685}
1686
1687static int32_t
1688get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1689{
1690 int32_t value;
1691 bool_Bool length_error;
1692
1693 switch (length) {
1694
1695 case 1:
1696 value = tvb_get_int8(tvb, offset);
1697 break;
1698
1699 case 2:
1700 value = encoding ? tvb_get_letohis(tvb, offset)
1701 : tvb_get_ntohis(tvb, offset);
1702 break;
1703
1704 case 3:
1705 value = encoding ? tvb_get_letohi24(tvb, offset)
1706 : tvb_get_ntohi24(tvb, offset);
1707 break;
1708
1709 case 4:
1710 value = encoding ? tvb_get_letohil(tvb, offset)
1711 : tvb_get_ntohil(tvb, offset);
1712 break;
1713
1714 default:
1715 if (length < 1) {
1716 length_error = true1;
1717 value = 0;
1718 } else {
1719 length_error = false0;
1720 value = encoding ? tvb_get_letohil(tvb, offset)
1721 : tvb_get_ntohil(tvb, offset);
1722 }
1723 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1724 break;
1725 }
1726 return value;
1727}
1728
1729/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1730 * be cast-able as a int64_t. This is weird, but what the code has always done.
1731 */
1732static inline uint64_t
1733get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1734{
1735 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1736
1737 switch (length) {
1738 case 7:
1739 value = ws_sign_ext64(value, 56);
1740 break;
1741 case 6:
1742 value = ws_sign_ext64(value, 48);
1743 break;
1744 case 5:
1745 value = ws_sign_ext64(value, 40);
1746 break;
1747 case 4:
1748 value = ws_sign_ext64(value, 32);
1749 break;
1750 case 3:
1751 value = ws_sign_ext64(value, 24);
1752 break;
1753 case 2:
1754 value = ws_sign_ext64(value, 16);
1755 break;
1756 case 1:
1757 value = ws_sign_ext64(value, 8);
1758 break;
1759 }
1760
1761 return value;
1762}
1763
1764/* For FT_STRING */
1765static inline const uint8_t *
1766get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1767 int length, int *ret_length, const unsigned encoding)
1768{
1769 if (length == -1) {
1770 length = tvb_ensure_captured_length_remaining(tvb, start);
1771 }
1772 *ret_length = length;
1773 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1774}
1775
1776/* For FT_STRINGZ */
1777static inline const uint8_t *
1778get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1779 int start, int length, int *ret_length, const unsigned encoding)
1780{
1781 const uint8_t *value;
1782
1783 if (length < -1) {
1784 report_type_length_mismatch(tree, "a string", length, true1);
1785 }
1786 if (length == -1) {
1787 /* This can throw an exception */
1788 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1789 } else {
1790 /* In this case, length signifies the length of the string.
1791 *
1792 * This could either be a null-padded string, which doesn't
1793 * necessarily have a '\0' at the end, or a null-terminated
1794 * string, with a trailing '\0'. (Yes, there are cases
1795 * where you have a string that's both counted and null-
1796 * terminated.)
1797 *
1798 * In the first case, we must allocate a buffer of length
1799 * "length+1", to make room for a trailing '\0'.
1800 *
1801 * In the second case, we don't assume that there is a
1802 * trailing '\0' there, as the packet might be malformed.
1803 * (XXX - should we throw an exception if there's no
1804 * trailing '\0'?) Therefore, we allocate a buffer of
1805 * length "length+1", and put in a trailing '\0', just to
1806 * be safe.
1807 *
1808 * (XXX - this would change if we made string values counted
1809 * rather than null-terminated.)
1810 */
1811 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1812 }
1813 *ret_length = length;
1814 return value;
1815}
1816
1817/* For FT_UINT_STRING */
1818static inline const uint8_t *
1819get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1820 tvbuff_t *tvb, int start, int length, int *ret_length,
1821 const unsigned encoding)
1822{
1823 uint32_t n;
1824 const uint8_t *value;
1825
1826 /* I believe it's ok if this is called with a NULL tree */
1827 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1828 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1829 length += n;
1830 *ret_length = length;
1831 return value;
1832}
1833
1834/* For FT_STRINGZPAD */
1835static inline const uint8_t *
1836get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1837 int length, int *ret_length, const unsigned encoding)
1838{
1839 /*
1840 * XXX - currently, string values are null-
1841 * terminated, so a "zero-padded" string
1842 * isn't special. If we represent string
1843 * values as something that includes a counted
1844 * array of bytes, we'll need to strip the
1845 * trailing NULs.
1846 */
1847 if (length == -1) {
1848 length = tvb_ensure_captured_length_remaining(tvb, start);
1849 }
1850 *ret_length = length;
1851 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1852}
1853
1854/* For FT_STRINGZTRUNC */
1855static inline const uint8_t *
1856get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1857 int length, int *ret_length, const unsigned encoding)
1858{
1859 /*
1860 * XXX - currently, string values are null-
1861 * terminated, so a "zero-truncated" string
1862 * isn't special. If we represent string
1863 * values as something that includes a counted
1864 * array of bytes, we'll need to strip everything
1865 * starting with the terminating NUL.
1866 */
1867 if (length == -1) {
1868 length = tvb_ensure_captured_length_remaining(tvb, start);
1869 }
1870 *ret_length = length;
1871 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1872}
1873
1874/*
1875 * Deltas between the epochs for various non-UN*X time stamp formats and
1876 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1877 * stamp format.
1878 */
1879
1880/*
1881 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1882 * XXX - if it's OK if this is unsigned, can we just use
1883 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1884 */
1885#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1886
1887/*
1888 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1889 */
1890#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1891
1892/* this can be called when there is no tree, so tree may be null */
1893static void
1894get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1895 const int length, const unsigned encoding, nstime_t *time_stamp,
1896 const bool_Bool is_relative)
1897{
1898 uint32_t tmpsecs;
1899 uint64_t tmp64secs;
1900 uint64_t todusecs;
1901
1902 switch (encoding) {
1903
1904 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1905 /*
1906 * If the length is 16, 8-byte seconds, followed
1907 * by 8-byte fractional time in nanoseconds,
1908 * both big-endian.
1909 *
1910 * If the length is 12, 8-byte seconds, followed
1911 * by 4-byte fractional time in nanoseconds,
1912 * both big-endian.
1913 *
1914 * If the length is 8, 4-byte seconds, followed
1915 * by 4-byte fractional time in nanoseconds,
1916 * both big-endian.
1917 *
1918 * For absolute times, the seconds are seconds
1919 * since the UN*X epoch.
1920 */
1921 if (length == 16) {
1922 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1923 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1924 } else if (length == 12) {
1925 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1926 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1927 } else if (length == 8) {
1928 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1929 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1930 } else if (length == 4) {
1931 /*
1932 * Backwards compatibility.
1933 * ENC_TIME_SECS_NSECS is 0; using
1934 * ENC_BIG_ENDIAN by itself with a 4-byte
1935 * time-in-seconds value was done in the
1936 * past.
1937 */
1938 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1939 time_stamp->nsecs = 0;
1940 } else {
1941 time_stamp->secs = 0;
1942 time_stamp->nsecs = 0;
1943 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1944 }
1945 break;
1946
1947 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
1948 /*
1949 * If the length is 16, 8-byte seconds, followed
1950 * by 8-byte fractional time in nanoseconds,
1951 * both little-endian.
1952 *
1953 * If the length is 12, 8-byte seconds, followed
1954 * by 4-byte fractional time in nanoseconds,
1955 * both little-endian.
1956 *
1957 * If the length is 8, 4-byte seconds, followed
1958 * by 4-byte fractional time in nanoseconds,
1959 * both little-endian.
1960 *
1961 * For absolute times, the seconds are seconds
1962 * since the UN*X epoch.
1963 */
1964 if (length == 16) {
1965 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1966 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
1967 } else if (length == 12) {
1968 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1969 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1970 } else if (length == 8) {
1971 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1972 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1973 } else if (length == 4) {
1974 /*
1975 * Backwards compatibility.
1976 * ENC_TIME_SECS_NSECS is 0; using
1977 * ENC_LITTLE_ENDIAN by itself with a 4-byte
1978 * time-in-seconds value was done in the
1979 * past.
1980 */
1981 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1982 time_stamp->nsecs = 0;
1983 } else {
1984 time_stamp->secs = 0;
1985 time_stamp->nsecs = 0;
1986 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1987 }
1988 break;
1989
1990 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
1991 /*
1992 * NTP time stamp, big-endian.
1993 * Only supported for absolute times.
1994 */
1995 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1995, "!is_relative"
))))
;
1996
1997 /* We need a temporary variable here so the unsigned math
1998 * works correctly (for years > 2036 according to RFC 2030
1999 * chapter 3).
2000 *
2001 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2002 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2003 * If bit 0 is not set, the time is in the range 2036-2104 and
2004 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2005 */
2006 tmpsecs = tvb_get_ntohl(tvb, start);
2007 if ((tmpsecs & 0x80000000) != 0)
2008 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2009 else
2010 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2011
2012 if (length == 8) {
2013 tmp64secs = tvb_get_ntoh64(tvb, start);
2014 if (tmp64secs == 0) {
2015 //This is "NULL" time
2016 time_stamp->secs = 0;
2017 time_stamp->nsecs = 0;
2018 } else {
2019 /*
2020 * Convert 1/2^32s of a second to
2021 * nanoseconds.
2022 */
2023 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2024 }
2025 } else if (length == 4) {
2026 /*
2027 * Backwards compatibility.
2028 */
2029 if (tmpsecs == 0) {
2030 //This is "NULL" time
2031 time_stamp->secs = 0;
2032 }
2033 time_stamp->nsecs = 0;
2034 } else {
2035 time_stamp->secs = 0;
2036 time_stamp->nsecs = 0;
2037 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2038 }
2039 break;
2040
2041 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2042 /*
2043 * NTP time stamp, little-endian.
2044 * Only supported for absolute times.
2045 *
2046 * NTP doesn't use this, because it's an Internet format
2047 * and hence big-endian. Any implementation must decide
2048 * whether the NTP timestamp is a 64-bit unsigned fixed
2049 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2050 * with a 32-bit unsigned seconds field followed by a
2051 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2052 * the previous two).
2053 *
2054 * XXX: We do the latter, but no dissector uses this format.
2055 * OTOH, ERF timestamps do the former, so perhaps we
2056 * should switch the interpretation so that packet-erf.c
2057 * could use this directly?
2058 */
2059 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2059, "!is_relative"
))))
;
2060
2061 /* We need a temporary variable here so the unsigned math
2062 * works correctly (for years > 2036 according to RFC 2030
2063 * chapter 3).
2064 *
2065 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2066 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2067 * If bit 0 is not set, the time is in the range 2036-2104 and
2068 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2069 */
2070 tmpsecs = tvb_get_letohl(tvb, start);
2071 if ((tmpsecs & 0x80000000) != 0)
2072 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2073 else
2074 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2075
2076 if (length == 8) {
2077 tmp64secs = tvb_get_letoh64(tvb, start);
2078 if (tmp64secs == 0) {
2079 //This is "NULL" time
2080 time_stamp->secs = 0;
2081 time_stamp->nsecs = 0;
2082 } else {
2083 /*
2084 * Convert 1/2^32s of a second to
2085 * nanoseconds.
2086 */
2087 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2088 }
2089 } else if (length == 4) {
2090 /*
2091 * Backwards compatibility.
2092 */
2093 if (tmpsecs == 0) {
2094 //This is "NULL" time
2095 time_stamp->secs = 0;
2096 }
2097 time_stamp->nsecs = 0;
2098 } else {
2099 time_stamp->secs = 0;
2100 time_stamp->nsecs = 0;
2101 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2102 }
2103 break;
2104
2105 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2106 /*
2107 * S/3x0 and z/Architecture TOD clock time stamp,
2108 * big-endian. The epoch is January 1, 1900,
2109 * 00:00:00 (proleptic?) UTC.
2110 *
2111 * Only supported for absolute times.
2112 */
2113 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2113, "!is_relative"
))))
;
2114 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2114, "length == 8"
))))
;
2115
2116 if (length == 8) {
2117 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2118 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2119 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2120 } else {
2121 time_stamp->secs = 0;
2122 time_stamp->nsecs = 0;
2123 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2124 }
2125 break;
2126
2127 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2128 /*
2129 * S/3x0 and z/Architecture TOD clock time stamp,
2130 * little-endian. The epoch is January 1, 1900,
2131 * 00:00:00 (proleptic?) UTC.
2132 *
2133 * Only supported for absolute times.
2134 */
2135 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2135, "!is_relative"
))))
;
2136
2137 if (length == 8) {
2138 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2139 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2140 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2141 } else {
2142 time_stamp->secs = 0;
2143 time_stamp->nsecs = 0;
2144 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2145 }
2146 break;
2147
2148 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2149 /*
2150 * Time stamp using the same seconds/fraction format
2151 * as NTP, but with the origin of the time stamp being
2152 * the UNIX epoch rather than the NTP epoch; big-
2153 * endian.
2154 *
2155 * Only supported for absolute times.
2156 */
2157 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2157, "!is_relative"
))))
;
2158
2159 if (length == 8) {
2160 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2161 /*
2162 * Convert 1/2^32s of a second to nanoseconds.
2163 */
2164 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2165 } else {
2166 time_stamp->secs = 0;
2167 time_stamp->nsecs = 0;
2168 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2169 }
2170 break;
2171
2172 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2173 /*
2174 * Time stamp using the same seconds/fraction format
2175 * as NTP, but with the origin of the time stamp being
2176 * the UNIX epoch rather than the NTP epoch; little-
2177 * endian.
2178 *
2179 * Only supported for absolute times.
2180 *
2181 * The RTPS specification explicitly supports Little
2182 * Endian encoding. In one place, it states that its
2183 * Time_t representation "is the one defined by ...
2184 * RFC 1305", but in another explicitly defines it as
2185 * a struct consisting of an 32 bit unsigned seconds
2186 * field and a 32 bit unsigned fraction field, not a 64
2187 * bit fixed point, so we do that here.
2188 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2189 */
2190 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2190, "!is_relative"
))))
;
2191
2192 if (length == 8) {
2193 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2194 /*
2195 * Convert 1/2^32s of a second to nanoseconds.
2196 */
2197 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2198 } else {
2199 time_stamp->secs = 0;
2200 time_stamp->nsecs = 0;
2201 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2202 }
2203 break;
2204
2205 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2206 /*
2207 * MIP6 time stamp, big-endian.
2208 * A 64-bit unsigned integer field containing a timestamp. The
2209 * value indicates the number of seconds since January 1, 1970,
2210 * 00:00 UTC, by using a fixed point format. In this format, the
2211 * integer number of seconds is contained in the first 48 bits of
2212 * the field, and the remaining 16 bits indicate the number of
2213 * 1/65536 fractions of a second.
2214
2215 * Only supported for absolute times.
2216 */
2217 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2217, "!is_relative"
))))
;
2218
2219 if (length == 8) {
2220 /* We need a temporary variable here so the casting and fractions
2221 * of a second work correctly.
2222 */
2223 tmp64secs = tvb_get_ntoh48(tvb, start);
2224 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2225 tmpsecs <<= 16;
2226
2227 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2228 //This is "NULL" time
2229 time_stamp->secs = 0;
2230 time_stamp->nsecs = 0;
2231 } else {
2232 time_stamp->secs = (time_t)tmp64secs;
2233 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2234 }
2235 } else {
2236 time_stamp->secs = 0;
2237 time_stamp->nsecs = 0;
2238 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2239 }
2240 break;
2241
2242 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2243 /*
2244 * If the length is 16, 8-byte seconds, followed
2245 * by 8-byte fractional time in microseconds,
2246 * both big-endian.
2247 *
2248 * If the length is 12, 8-byte seconds, followed
2249 * by 4-byte fractional time in microseconds,
2250 * both big-endian.
2251 *
2252 * If the length is 8, 4-byte seconds, followed
2253 * by 4-byte fractional time in microseconds,
2254 * both big-endian.
2255 *
2256 * For absolute times, the seconds are seconds
2257 * since the UN*X epoch.
2258 */
2259 if (length == 16) {
2260 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2261 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2262 } else if (length == 12) {
2263 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2264 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2265 } else if (length == 8) {
2266 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2267 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2268 } else {
2269 time_stamp->secs = 0;
2270 time_stamp->nsecs = 0;
2271 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2272 }
2273 break;
2274
2275 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2276 /*
2277 * If the length is 16, 8-byte seconds, followed
2278 * by 8-byte fractional time in microseconds,
2279 * both little-endian.
2280 *
2281 * If the length is 12, 8-byte seconds, followed
2282 * by 4-byte fractional time in microseconds,
2283 * both little-endian.
2284 *
2285 * If the length is 8, 4-byte seconds, followed
2286 * by 4-byte fractional time in microseconds,
2287 * both little-endian.
2288 *
2289 * For absolute times, the seconds are seconds
2290 * since the UN*X epoch.
2291 */
2292 if (length == 16) {
2293 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2294 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2295 } else if (length == 12) {
2296 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2297 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2298 } else if (length == 8) {
2299 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2300 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2301 } else {
2302 time_stamp->secs = 0;
2303 time_stamp->nsecs = 0;
2304 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2305 }
2306 break;
2307
2308 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2309 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2310 /*
2311 * Seconds, 1 to 8 bytes.
2312 * For absolute times, it's seconds since the
2313 * UN*X epoch.
2314 */
2315 if (length >= 1 && length <= 8) {
2316 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2317 time_stamp->nsecs = 0;
2318 } else {
2319 time_stamp->secs = 0;
2320 time_stamp->nsecs = 0;
2321 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2322 }
2323 break;
2324
2325 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2326 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2327 /*
2328 * Milliseconds, 1 to 8 bytes.
2329 * For absolute times, it's milliseconds since the
2330 * UN*X epoch.
2331 */
2332 if (length >= 1 && length <= 8) {
2333 uint64_t msecs;
2334
2335 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2336 time_stamp->secs = (time_t)(msecs / 1000);
2337 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2338 } else {
2339 time_stamp->secs = 0;
2340 time_stamp->nsecs = 0;
2341 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2342 }
2343 break;
2344
2345 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2346 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2347 /*
2348 * Microseconds, 1 to 8 bytes.
2349 * For absolute times, it's microseconds since the
2350 * UN*X epoch.
2351 */
2352 if (length >= 1 && length <= 8) {
2353 uint64_t usecs;
2354
2355 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2356 time_stamp->secs = (time_t)(usecs / 1000000);
2357 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2358 } else {
2359 time_stamp->secs = 0;
2360 time_stamp->nsecs = 0;
2361 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2362 }
2363 break;
2364
2365 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2366 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2367 /*
2368 * nanoseconds, 1 to 8 bytes.
2369 * For absolute times, it's nanoseconds since the
2370 * UN*X epoch.
2371 */
2372
2373 if (length >= 1 && length <= 8) {
2374 uint64_t nsecs;
2375
2376 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2377 time_stamp->secs = (time_t)(nsecs / 1000000000);
2378 time_stamp->nsecs = (int)(nsecs % 1000000000);
2379 } else {
2380 time_stamp->secs = 0;
2381 time_stamp->nsecs = 0;
2382 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2383 }
2384 break;
2385
2386 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2387 /*
2388 * 1/64ths of a second since the UN*X epoch,
2389 * big-endian.
2390 *
2391 * Only supported for absolute times.
2392 */
2393 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2393, "!is_relative"
))))
;
2394
2395 if (length == 8) {
2396 /*
2397 * The upper 48 bits are seconds since the
2398 * UN*X epoch.
2399 */
2400 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2401 /*
2402 * The lower 16 bits are 1/2^16s of a second;
2403 * convert them to nanoseconds.
2404 *
2405 * XXX - this may give the impression of higher
2406 * precision than you actually get.
2407 */
2408 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2409 } else {
2410 time_stamp->secs = 0;
2411 time_stamp->nsecs = 0;
2412 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2413 }
2414 break;
2415
2416 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2417 /*
2418 * 1/64ths of a second since the UN*X epoch,
2419 * little-endian.
2420 *
2421 * Only supported for absolute times.
2422 */
2423 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2423, "!is_relative"
))))
;
2424
2425 if (length == 8) {
2426 /*
2427 * XXX - this is assuming that, if anybody
2428 * were ever to use this format - RFC 3971
2429 * doesn't, because that's an Internet
2430 * protocol, and those use network byte
2431 * order, i.e. big-endian - they'd treat it
2432 * as a 64-bit count of 1/2^16s of a second,
2433 * putting the upper 48 bits at the end.
2434 *
2435 * The lower 48 bits are seconds since the
2436 * UN*X epoch.
2437 */
2438 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2439 /*
2440 * The upper 16 bits are 1/2^16s of a second;
2441 * convert them to nanoseconds.
2442 *
2443 * XXX - this may give the impression of higher
2444 * precision than you actually get.
2445 */
2446 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2447 } else {
2448 time_stamp->secs = 0;
2449 time_stamp->nsecs = 0;
2450 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2451 }
2452 break;
2453
2454 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2455 /*
2456 * NTP time stamp, with 1-second resolution (i.e.,
2457 * seconds since the NTP epoch), big-endian.
2458 * Only supported for absolute times.
2459 */
2460 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2460, "!is_relative"
))))
;
2461
2462 if (length == 4) {
2463 /*
2464 * We need a temporary variable here so the unsigned math
2465 * works correctly (for years > 2036 according to RFC 2030
2466 * chapter 3).
2467 *
2468 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2469 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2470 * If bit 0 is not set, the time is in the range 2036-2104 and
2471 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2472 */
2473 tmpsecs = tvb_get_ntohl(tvb, start);
2474 if ((tmpsecs & 0x80000000) != 0)
2475 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2476 else
2477 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2478 time_stamp->nsecs = 0;
2479 } else {
2480 time_stamp->secs = 0;
2481 time_stamp->nsecs = 0;
2482 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2483 }
2484 break;
2485
2486 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2487 /*
2488 * NTP time stamp, with 1-second resolution (i.e.,
2489 * seconds since the NTP epoch), little-endian.
2490 * Only supported for absolute times.
2491 */
2492 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2492, "!is_relative"
))))
;
2493
2494 /*
2495 * We need a temporary variable here so the unsigned math
2496 * works correctly (for years > 2036 according to RFC 2030
2497 * chapter 3).
2498 *
2499 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2500 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2501 * If bit 0 is not set, the time is in the range 2036-2104 and
2502 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2503 */
2504 if (length == 4) {
2505 tmpsecs = tvb_get_letohl(tvb, start);
2506 if ((tmpsecs & 0x80000000) != 0)
2507 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2508 else
2509 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2510 time_stamp->nsecs = 0;
2511 } else {
2512 time_stamp->secs = 0;
2513 time_stamp->nsecs = 0;
2514 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2515 }
2516 break;
2517
2518 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2519 /*
2520 * Milliseconds, 6 to 8 bytes.
2521 * For absolute times, it's milliseconds since the
2522 * NTP epoch.
2523 *
2524 * ETSI TS 129.274 8.119 defines this as:
2525 * "a 48 bit unsigned integer in network order format
2526 * ...encoded as the number of milliseconds since
2527 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2528 * rounded value of 1000 x the value of the 64-bit
2529 * timestamp (Seconds + (Fraction / (1<<32))) defined
2530 * in clause 6 of IETF RFC 5905."
2531 *
2532 * Taken literally, the part after "i.e." would
2533 * mean that the value rolls over before reaching
2534 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2535 * when the 64 bit timestamp rolls over, and we have
2536 * to pick an NTP Era equivalence class to support
2537 * (such as 1968-01-20 to 2104-02-06).
2538 *
2539 * OTOH, the extra room might be used to store Era
2540 * information instead, in which case times until
2541 * 10819-08-03 can be represented with 6 bytes without
2542 * ambiguity. We handle both implementations, and assume
2543 * that times before 1968-01-20 are not represented.
2544 *
2545 * Only 6 bytes or more makes sense as an absolute
2546 * time. 5 bytes or fewer could express a span of
2547 * less than 35 years, either 1900-1934 or 2036-2070.
2548 */
2549 if (length >= 6 && length <= 8) {
2550 uint64_t msecs;
2551
2552 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2553 tmp64secs = (msecs / 1000);
2554 /*
2555 * Assume that times in the first half of NTP
2556 * Era 0 really represent times in the NTP
2557 * Era 1.
2558 */
2559 if (tmp64secs >= 0x80000000)
2560 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2561 else
2562 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2563 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2564 }
2565 else {
2566 time_stamp->secs = 0;
2567 time_stamp->nsecs = 0;
2568 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2569 }
2570 break;
2571
2572 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2573 /*
2574 * MP4 file time stamps, big-endian.
2575 * Only supported for absolute times.
2576 */
2577 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2577, "!is_relative"
))))
;
2578
2579 if (length == 8) {
2580 tmp64secs = tvb_get_ntoh64(tvb, start);
2581 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2582 time_stamp->nsecs = 0;
2583 } else if (length == 4) {
2584 tmpsecs = tvb_get_ntohl(tvb, start);
2585 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2586 time_stamp->nsecs = 0;
2587 } else {
2588 time_stamp->secs = 0;
2589 time_stamp->nsecs = 0;
2590 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2591 }
2592 break;
2593
2594 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2595 /*
2596 * Zigbee ZCL time stamps, big-endian.
2597 * Only supported for absolute times.
2598 */
2599 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2599, "!is_relative"
))))
;
2600
2601 if (length == 8) {
2602 tmp64secs = tvb_get_ntoh64(tvb, start);
2603 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2604 time_stamp->nsecs = 0;
2605 } else if (length == 4) {
2606 tmpsecs = tvb_get_ntohl(tvb, start);
2607 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2608 time_stamp->nsecs = 0;
2609 } else {
2610 time_stamp->secs = 0;
2611 time_stamp->nsecs = 0;
2612 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2613 }
2614 break;
2615
2616 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2617 /*
2618 * Zigbee ZCL time stamps, little-endian.
2619 * Only supported for absolute times.
2620 */
2621 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2621, "!is_relative"
))))
;
2622
2623 if (length == 8) {
2624 tmp64secs = tvb_get_letoh64(tvb, start);
2625 time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2626 time_stamp->nsecs = 0;
2627 } else if (length == 4) {
2628 tmpsecs = tvb_get_letohl(tvb, start);
2629 time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2630 time_stamp->nsecs = 0;
2631 } else {
2632 time_stamp->secs = 0;
2633 time_stamp->nsecs = 0;
2634 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2635 }
2636 break;
2637
2638 default:
2639 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2639))
;
2640 break;
2641 }
2642}
2643
2644static void
2645tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2646{
2647 const header_field_info *hfinfo = fi->hfinfo;
2648
2649 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2650 GPtrArray *ptrs = NULL((void*)0);
2651
2652 if (tree_data->interesting_hfids == NULL((void*)0)) {
2653 /* Initialize the hash because we now know that it is needed */
2654 tree_data->interesting_hfids =
2655 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2656 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2657 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2658 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2659 }
2660
2661 if (!ptrs) {
2662 /* First element triggers the creation of pointer array */
2663 ptrs = g_ptr_array_new();
2664 g_hash_table_insert(tree_data->interesting_hfids,
2665 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2666 }
2667
2668 g_ptr_array_add(ptrs, fi);
2669 }
2670}
2671
2672
2673/*
2674 * Validates that field length bytes are available starting from
2675 * start (pos/neg). Throws an exception if they aren't.
2676 */
2677static void
2678test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2679 int start, int length, const unsigned encoding)
2680{
2681 int size = length;
2682
2683 if (!tvb)
2684 return;
2685
2686 if ((hfinfo->type == FT_STRINGZ) ||
2687 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2688 (FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
|| FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
))) {
2689 /* If we're fetching until the end of the TVB, only validate
2690 * that the offset is within range.
2691 */
2692 if (length == -1)
2693 size = 0;
2694 }
2695
2696 tvb_ensure_bytes_exist(tvb, start, size);
2697}
2698
2699static void
2700detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2701{
2702 bool_Bool found_stray_character = false0;
2703
2704 if (!string)
2705 return;
2706
2707 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2708 case ENC_ASCII0x00000000:
2709 case ENC_UTF_80x00000002:
2710 for (int i = (int)strlen(string); i < length; i++) {
2711 if (string[i] != '\0') {
2712 found_stray_character = true1;
2713 break;
2714 }
2715 }
2716 break;
2717
2718 default:
2719 break;
2720 }
2721
2722 if (found_stray_character) {
2723 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2724 }
2725}
2726
2727static void
2728free_fvalue_cb(void *data)
2729{
2730 fvalue_t *fv = (fvalue_t*)data;
2731 fvalue_free(fv);
2732}
2733
2734/* Add an item to a proto_tree, using the text label registered to that item;
2735 the item is extracted from the tvbuff handed to it. */
2736static proto_item *
2737proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2738 tvbuff_t *tvb, int start, int length,
2739 unsigned encoding)
2740{
2741 proto_item *pi;
2742 uint32_t value, n;
2743 uint64_t value64;
2744 ws_in4_addr ipv4_value;
2745 float floatval;
2746 double doubleval;
2747 const char *stringval = NULL((void*)0);
2748 nstime_t time_stamp;
2749 bool_Bool length_error;
2750
2751 /* Ensure that the newly created fvalue_t is freed if we throw an
2752 * exception before adding it to the tree. (gcc creates clobbering
2753 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2754 * XXX: Move the new_field_info() call inside here?
2755 */
2756 CLEANUP_PUSH(free_fvalue_cb, new_fi->value){ struct except_stacknode except_sn; struct except_cleanup except_cl
; except_setup_clean(&except_sn, &except_cl, (free_fvalue_cb
), (new_fi->value))
;
2757
2758 switch (new_fi->hfinfo->type) {
2759 case FT_NONE:
2760 /* no value to set for FT_NONE */
2761 break;
2762
2763 case FT_PROTOCOL:
2764 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2765 break;
2766
2767 case FT_BYTES:
2768 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2769 break;
2770
2771 case FT_UINT_BYTES:
2772 n = get_uint_value(tree, tvb, start, length, encoding);
2773 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2774
2775 /* Instead of calling proto_item_set_len(), since we don't yet
2776 * have a proto_item, we set the field_info's length ourselves. */
2777 new_fi->length = n + length;
2778 break;
2779
2780 case FT_BOOLEAN:
2781 /*
2782 * Map all non-zero values to little-endian for
2783 * backwards compatibility.
2784 */
2785 if (encoding)
2786 encoding = ENC_LITTLE_ENDIAN0x80000000;
2787 proto_tree_set_boolean(new_fi,
2788 get_uint64_value(tree, tvb, start, length, encoding));
2789 break;
2790
2791 case FT_CHAR:
2792 /* XXX - make these just FT_UINT? */
2793 case FT_UINT8:
2794 case FT_UINT16:
2795 case FT_UINT24:
2796 case FT_UINT32:
2797 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2798 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2799 value = (uint32_t)value64;
2800 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2801 new_fi->flags |= FI_VARINT0x00040000;
2802 }
2803 }
2804 else {
2805 /*
2806 * Map all non-zero values to little-endian for
2807 * backwards compatibility.
2808 */
2809 if (encoding)
2810 encoding = ENC_LITTLE_ENDIAN0x80000000;
2811
2812 value = get_uint_value(tree, tvb, start, length, encoding);
2813 }
2814 proto_tree_set_uint(new_fi, value);
2815 break;
2816
2817 case FT_UINT40:
2818 case FT_UINT48:
2819 case FT_UINT56:
2820 case FT_UINT64:
2821 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2822 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2823 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2824 new_fi->flags |= FI_VARINT0x00040000;
2825 }
2826 }
2827 else {
2828 /*
2829 * Map all other non-zero values to little-endian for
2830 * backwards compatibility.
2831 */
2832 if (encoding)
2833 encoding = ENC_LITTLE_ENDIAN0x80000000;
2834
2835 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2836 }
2837 proto_tree_set_uint64(new_fi, value64);
2838 break;
2839
2840 /* XXX - make these just FT_INT? */
2841 case FT_INT8:
2842 case FT_INT16:
2843 case FT_INT24:
2844 case FT_INT32:
2845 /*
2846 * Map all non-zero values to little-endian for
2847 * backwards compatibility.
2848 */
2849 if (encoding)
2850 encoding = ENC_LITTLE_ENDIAN0x80000000;
2851 proto_tree_set_int(new_fi,
2852 get_int_value(tree, tvb, start, length, encoding));
2853 break;
2854
2855 case FT_INT40:
2856 case FT_INT48:
2857 case FT_INT56:
2858 case FT_INT64:
2859 /*
2860 * Map all non-zero values to little-endian for
2861 * backwards compatibility.
2862 */
2863 if (encoding)
2864 encoding = ENC_LITTLE_ENDIAN0x80000000;
2865 proto_tree_set_int64(new_fi,
2866 get_int64_value(tree, tvb, start, length, encoding));
2867 break;
2868
2869 case FT_IPv4:
2870 /*
2871 * Map all non-zero values to little-endian for
2872 * backwards compatibility.
2873 */
2874 if (encoding)
2875 encoding = ENC_LITTLE_ENDIAN0x80000000;
2876 if (length != FT_IPv4_LEN4) {
2877 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2878 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2879 }
2880 ipv4_value = tvb_get_ipv4(tvb, start);
2881 /*
2882 * NOTE: to support code written when
2883 * proto_tree_add_item() took a bool as its
2884 * last argument, with false meaning "big-endian"
2885 * and true meaning "little-endian", we treat any
2886 * non-zero value of "encoding" as meaning
2887 * "little-endian".
2888 */
2889 proto_tree_set_ipv4(new_fi, encoding ? GUINT32_SWAP_LE_BE(ipv4_value)(((guint32) ( (((guint32) (ipv4_value) & (guint32) 0x000000ffU
) << 24) | (((guint32) (ipv4_value) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (ipv4_value) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (ipv4_value) & (guint32) 0xff000000U
) >> 24))))
: ipv4_value);
2890 break;
2891
2892 case FT_IPXNET:
2893 if (length != FT_IPXNET_LEN4) {
2894 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2895 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2896 }
2897 proto_tree_set_ipxnet(new_fi,
2898 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2899 break;
2900
2901 case FT_IPv6:
2902 if (length != FT_IPv6_LEN16) {
2903 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2904 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2905 }
2906 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2907 break;
2908
2909 case FT_FCWWN:
2910 if (length != FT_FCWWN_LEN8) {
2911 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2912 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2913 }
2914 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2915 break;
2916
2917 case FT_AX25:
2918 if (length != 7) {
2919 length_error = length < 7 ? true1 : false0;
2920 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2921 }
2922 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2923 break;
2924
2925 case FT_VINES:
2926 if (length != VINES_ADDR_LEN6) {
2927 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2928 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2929 }
2930 proto_tree_set_vines_tvb(new_fi, tvb, start);
2931 break;
2932
2933 case FT_ETHER:
2934 if (length != FT_ETHER_LEN6) {
2935 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2936 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2937 }
2938 proto_tree_set_ether_tvb(new_fi, tvb, start);
2939 break;
2940
2941 case FT_EUI64:
2942 /*
2943 * Map all non-zero values to little-endian for
2944 * backwards compatibility.
2945 */
2946 if (encoding)
2947 encoding = ENC_LITTLE_ENDIAN0x80000000;
2948 if (length != FT_EUI64_LEN8) {
2949 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
2950 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2951 }
2952 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2953 break;
2954 case FT_GUID:
2955 /*
2956 * Map all non-zero values to little-endian for
2957 * backwards compatibility.
2958 */
2959 if (encoding)
2960 encoding = ENC_LITTLE_ENDIAN0x80000000;
2961 if (length != FT_GUID_LEN16) {
2962 length_error = length < FT_GUID_LEN16 ? true1 : false0;
2963 report_type_length_mismatch(tree, "a GUID", length, length_error);
2964 }
2965 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2966 break;
2967
2968 case FT_OID:
2969 case FT_REL_OID:
2970 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2971 break;
2972
2973 case FT_SYSTEM_ID:
2974 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2975 break;
2976
2977 case FT_FLOAT:
2978 /*
2979 * NOTE: to support code written when
2980 * proto_tree_add_item() took a bool as its
2981 * last argument, with false meaning "big-endian"
2982 * and true meaning "little-endian", we treat any
2983 * non-zero value of "encoding" as meaning
2984 * "little-endian".
2985 *
2986 * At some point in the future, we might
2987 * support non-IEEE-binary floating-point
2988 * formats in the encoding as well
2989 * (IEEE decimal, System/3x0, VAX).
2990 */
2991 if (encoding)
2992 encoding = ENC_LITTLE_ENDIAN0x80000000;
2993 if (length != 4) {
2994 length_error = length < 4 ? true1 : false0;
2995 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2996 }
2997 if (encoding)
2998 floatval = tvb_get_letohieee_float(tvb, start);
2999 else
3000 floatval = tvb_get_ntohieee_float(tvb, start);
3001 proto_tree_set_float(new_fi, floatval);
3002 break;
3003
3004 case FT_DOUBLE:
3005 /*
3006 * NOTE: to support code written when
3007 * proto_tree_add_item() took a bool as its
3008 * last argument, with false meaning "big-endian"
3009 * and true meaning "little-endian", we treat any
3010 * non-zero value of "encoding" as meaning
3011 * "little-endian".
3012 *
3013 * At some point in the future, we might
3014 * support non-IEEE-binary floating-point
3015 * formats in the encoding as well
3016 * (IEEE decimal, System/3x0, VAX).
3017 */
3018 if (encoding == true1)
3019 encoding = ENC_LITTLE_ENDIAN0x80000000;
3020 if (length != 8) {
3021 length_error = length < 8 ? true1 : false0;
3022 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3023 }
3024 if (encoding)
3025 doubleval = tvb_get_letohieee_double(tvb, start);
3026 else
3027 doubleval = tvb_get_ntohieee_double(tvb, start);
3028 proto_tree_set_double(new_fi, doubleval);
3029 break;
3030
3031 case FT_STRING:
3032 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3033 tvb, start, length, &length, encoding);
3034 proto_tree_set_string(new_fi, stringval);
3035
3036 /* Instead of calling proto_item_set_len(), since we
3037 * don't yet have a proto_item, we set the
3038 * field_info's length ourselves.
3039 *
3040 * XXX - our caller can't use that length to
3041 * advance an offset unless they arrange that
3042 * there always be a protocol tree into which
3043 * we're putting this item.
3044 */
3045 new_fi->length = length;
3046 break;
3047
3048 case FT_STRINGZ:
3049 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3050 tree, tvb, start, length, &length, encoding);
3051 proto_tree_set_string(new_fi, stringval);
3052
3053 /* Instead of calling proto_item_set_len(),
3054 * since we don't yet have a proto_item, we
3055 * set the field_info's length ourselves.
3056 *
3057 * XXX - our caller can't use that length to
3058 * advance an offset unless they arrange that
3059 * there always be a protocol tree into which
3060 * we're putting this item.
3061 */
3062 new_fi->length = length;
3063 break;
3064
3065 case FT_UINT_STRING:
3066 /*
3067 * NOTE: to support code written when
3068 * proto_tree_add_item() took a bool as its
3069 * last argument, with false meaning "big-endian"
3070 * and true meaning "little-endian", if the
3071 * encoding value is true, treat that as
3072 * ASCII with a little-endian length.
3073 *
3074 * This won't work for code that passes
3075 * arbitrary non-zero values; that code
3076 * will need to be fixed.
3077 */
3078 if (encoding == true1)
3079 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3080 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3081 tree, tvb, start, length, &length, encoding);
3082 proto_tree_set_string(new_fi, stringval);
3083
3084 /* Instead of calling proto_item_set_len(), since we
3085 * don't yet have a proto_item, we set the
3086 * field_info's length ourselves.
3087 *
3088 * XXX - our caller can't use that length to
3089 * advance an offset unless they arrange that
3090 * there always be a protocol tree into which
3091 * we're putting this item.
3092 */
3093 new_fi->length = length;
3094 break;
3095
3096 case FT_STRINGZPAD:
3097 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3098 tvb, start, length, &length, encoding);
3099 proto_tree_set_string(new_fi, stringval);
3100
3101 /* Instead of calling proto_item_set_len(), since we
3102 * don't yet have a proto_item, we set the
3103 * field_info's length ourselves.
3104 *
3105 * XXX - our caller can't use that length to
3106 * advance an offset unless they arrange that
3107 * there always be a protocol tree into which
3108 * we're putting this item.
3109 */
3110 new_fi->length = length;
3111 break;
3112
3113 case FT_STRINGZTRUNC:
3114 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3115 tvb, start, length, &length, encoding);
3116 proto_tree_set_string(new_fi, stringval);
3117
3118 /* Instead of calling proto_item_set_len(), since we
3119 * don't yet have a proto_item, we set the
3120 * field_info's length ourselves.
3121 *
3122 * XXX - our caller can't use that length to
3123 * advance an offset unless they arrange that
3124 * there always be a protocol tree into which
3125 * we're putting this item.
3126 */
3127 new_fi->length = length;
3128 break;
3129
3130 case FT_ABSOLUTE_TIME:
3131 /*
3132 * Absolute times can be in any of a number of
3133 * formats, and they can be big-endian or
3134 * little-endian.
3135 *
3136 * Historically FT_TIMEs were only timespecs;
3137 * the only question was whether they were stored
3138 * in big- or little-endian format.
3139 *
3140 * For backwards compatibility, we interpret an
3141 * encoding of 1 as meaning "little-endian timespec",
3142 * so that passing true is interpreted as that.
3143 */
3144 if (encoding == true1)
3145 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3146
3147 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3148
3149 proto_tree_set_time(new_fi, &time_stamp);
3150 break;
3151
3152 case FT_RELATIVE_TIME:
3153 /*
3154 * Relative times can be in any of a number of
3155 * formats, and they can be big-endian or
3156 * little-endian.
3157 *
3158 * Historically FT_TIMEs were only timespecs;
3159 * the only question was whether they were stored
3160 * in big- or little-endian format.
3161 *
3162 * For backwards compatibility, we interpret an
3163 * encoding of 1 as meaning "little-endian timespec",
3164 * so that passing true is interpreted as that.
3165 */
3166 if (encoding == true1)
3167 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3168
3169 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3170
3171 proto_tree_set_time(new_fi, &time_stamp);
3172 break;
3173 case FT_IEEE_11073_SFLOAT:
3174 if (encoding)
3175 encoding = ENC_LITTLE_ENDIAN0x80000000;
3176 if (length != 2) {
3177 length_error = length < 2 ? true1 : false0;
3178 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3179 }
3180
3181 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3182
3183 break;
3184 case FT_IEEE_11073_FLOAT:
3185 if (encoding)
3186 encoding = ENC_LITTLE_ENDIAN0x80000000;
3187 if (length != 4) {
3188 length_error = length < 4 ? true1 : false0;
3189 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3190 }
3191 fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3192
3193 break;
3194 default:
3195 REPORT_DISSECTOR_BUG("field %s is of unknown type %d (%s)",proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3196 new_fi->hfinfo->abbrev,proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3197 new_fi->hfinfo->type,proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
3198 ftype_name(new_fi->hfinfo->type))proto_report_dissector_bug("field %s is of unknown type %d (%s)"
, new_fi->hfinfo->abbrev, new_fi->hfinfo->type, ftype_name
(new_fi->hfinfo->type))
;
3199 break;
3200 }
3201 FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN)do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
;
3202
3203 /* Don't add new node to proto_tree until now so that any exceptions
3204 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3205 /* XXX. wouldn't be better to add this item to tree, with some special
3206 * flag (FI_EXCEPTION?) to know which item caused exception? For
3207 * strings and bytes, we would have to set new_fi->value to something
3208 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3209 * could handle NULL values. */
3210 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3211 pi = proto_tree_add_node(tree, new_fi);
3212
3213 switch (new_fi->hfinfo->type) {
3214
3215 case FT_STRING:
3216 /* XXX: trailing stray character detection should be done
3217 * _before_ conversion to UTF-8, because conversion can change
3218 * the length, or else get_string_length should return a value
3219 * for the "length in bytes of the string after conversion
3220 * including internal nulls." (Noting that we do, for other
3221 * reasons, still need the "length in bytes in the field",
3222 * especially for FT_STRINGZ.)
3223 *
3224 * This is true even for ASCII and UTF-8, because
3225 * substituting REPLACEMENT CHARACTERS for illegal characters
3226 * can also do so (and for UTF-8 possibly even make the
3227 * string _shorter_).
3228 */
3229 detect_trailing_stray_characters(encoding, stringval, length, pi);
3230 break;
3231
3232 default:
3233 break;
3234 }
3235
3236 return pi;
3237}
3238
3239proto_item *
3240proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3241 const int start, int length,
3242 const unsigned encoding, int32_t *retval)
3243{
3244 header_field_info *hfinfo;
3245 field_info *new_fi;
3246 int32_t value;
3247
3248 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3248, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3248,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3248, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3249
3250 switch (hfinfo->type) {
3251 case FT_INT8:
3252 case FT_INT16:
3253 case FT_INT24:
3254 case FT_INT32:
3255 break;
3256 case FT_INT64:
3257 REPORT_DISSECTOR_BUG("64-bit signed integer field %s used with proto_tree_add_item_ret_int()",proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
3258 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3259 default:
3260 REPORT_DISSECTOR_BUG("Non-signed-integer field %s used with proto_tree_add_item_ret_int()",proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
3261 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3262 }
3263
3264 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3265 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3266 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3267 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3268 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3269 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3270 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3271
3272 if (encoding & ENC_STRING0x03000000) {
3273 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3274 }
3275 /* I believe it's ok if this is called with a NULL tree */
3276 value = get_int_value(tree, tvb, start, length, encoding);
3277
3278 if (retval) {
3279 int no_of_bits;
3280 *retval = value;
3281 if (hfinfo->bitmask) {
3282 /* Mask out irrelevant portions */
3283 *retval &= (uint32_t)(hfinfo->bitmask);
3284 /* Shift bits */
3285 *retval >>= hfinfo_bitshift(hfinfo);
3286 }
3287 no_of_bits = ws_count_ones(hfinfo->bitmask);
3288 *retval = ws_sign_ext32(*retval, no_of_bits);
3289 }
3290
3291 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3292
3293 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3293
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3293, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3293, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3293, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3294
3295 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3296
3297 proto_tree_set_int(new_fi, value);
3298
3299 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3300
3301 return proto_tree_add_node(tree, new_fi);
3302}
3303
3304proto_item *
3305proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3306 const int start, int length,
3307 const unsigned encoding, uint32_t *retval)
3308{
3309 header_field_info *hfinfo;
3310 field_info *new_fi;
3311 uint32_t value;
3312
3313 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3313, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3313,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3313, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3314
3315 switch (hfinfo->type) {
3316 case FT_CHAR:
3317 case FT_UINT8:
3318 case FT_UINT16:
3319 case FT_UINT24:
3320 case FT_UINT32:
3321 break;
3322 default:
3323 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
3324 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
3325 }
3326
3327 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3328 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3329 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3330 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3331 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3332 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3333 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3334
3335 if (encoding & ENC_STRING0x03000000) {
3336 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3337 }
3338 /* I believe it's ok if this is called with a NULL tree */
3339 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3340 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3341 uint64_t temp64;
3342 tvb_get_varint(tvb, start, length, &temp64, encoding);
3343 value = (uint32_t)temp64;
3344 } else {
3345 value = get_uint_value(tree, tvb, start, length, encoding);
3346 }
3347
3348 if (retval) {
3349 *retval = value;
3350 if (hfinfo->bitmask) {
3351 /* Mask out irrelevant portions */
3352 *retval &= (uint32_t)(hfinfo->bitmask);
3353 /* Shift bits */
3354 *retval >>= hfinfo_bitshift(hfinfo);
3355 }
3356 }
3357
3358 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3359
3360 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3360
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3360, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3360, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3360, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3361
3362 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3363
3364 proto_tree_set_uint(new_fi, value);
3365
3366 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3367 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3368 new_fi->flags |= FI_VARINT0x00040000;
3369 }
3370 return proto_tree_add_node(tree, new_fi);
3371}
3372
3373/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3374 * and returns proto_item* and uint value retreived*/
3375proto_item *
3376ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3377 const unsigned encoding, uint32_t *retval)
3378{
3379 field_info *new_fi;
3380 header_field_info *hfinfo;
3381 int item_length;
3382 int offset;
3383 uint32_t value;
3384
3385 offset = ptvc->offset;
3386 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3386, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3386,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3386, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3387
3388 switch (hfinfo->type) {
3389 case FT_CHAR:
3390 case FT_UINT8:
3391 case FT_UINT16:
3392 case FT_UINT24:
3393 case FT_UINT32:
3394 break;
3395 default:
3396 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
3397 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
3398 }
3399
3400 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3401 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3402
3403 /* I believe it's ok if this is called with a NULL tree */
3404 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3405 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3406
3407 if (retval) {
3408 *retval = value;
3409 if (hfinfo->bitmask) {
3410 /* Mask out irrelevant portions */
3411 *retval &= (uint32_t)(hfinfo->bitmask);
3412 /* Shift bits */
3413 *retval >>= hfinfo_bitshift(hfinfo);
3414 }
3415 }
3416
3417 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3418 item_length, encoding);
3419
3420 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3421
3422 /* Coast clear. Try and fake it */
3423 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfindex == 0
|| (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3423
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3423, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3423, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((ptvc->tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3423, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3424
3425 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3426
3427 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3428 offset, length, encoding);
3429}
3430
3431/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3432 * and returns proto_item* and int value retreived*/
3433proto_item *
3434ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3435 const unsigned encoding, int32_t *retval)
3436{
3437 field_info *new_fi;
3438 header_field_info *hfinfo;
3439 int item_length;
3440 int offset;
3441 uint32_t value;
3442
3443 offset = ptvc->offset;
3444 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3444, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3444,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3444, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3445
3446 switch (hfinfo->type) {
3447 case FT_INT8:
3448 case FT_INT16:
3449 case FT_INT24:
3450 case FT_INT32:
3451 break;
3452 default:
3453 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
3454 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3455 }
3456
3457 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3458 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3459
3460 /* I believe it's ok if this is called with a NULL tree */
3461 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3462 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3463
3464 if (retval) {
3465 int no_of_bits;
3466 *retval = value;
3467 if (hfinfo->bitmask) {
3468 /* Mask out irrelevant portions */
3469 *retval &= (uint32_t)(hfinfo->bitmask);
3470 /* Shift bits */
3471 *retval >>= hfinfo_bitshift(hfinfo);
3472 }
3473 no_of_bits = ws_count_ones(hfinfo->bitmask);
3474 *retval = ws_sign_ext32(*retval, no_of_bits);
3475 }
3476
3477 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3478 item_length, encoding);
3479
3480 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3481
3482 /* Coast clear. Try and fake it */
3483 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfindex == 0
|| (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3483
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3483, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3483, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((ptvc->tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3483, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3484
3485 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3486
3487 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3488 offset, length, encoding);
3489}
3490
3491/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3492 * and returns proto_item* and string value retreived */
3493proto_item*
3494ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3495{
3496 header_field_info *hfinfo;
3497 field_info *new_fi;
3498 const uint8_t *value;
3499 int item_length;
3500 int offset;
3501
3502 offset = ptvc->offset;
3503
3504 PROTO_REGISTRAR_GET_NTH(hf, hfinfo)if((hf == 0 || (unsigned)hf > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3504
, __func__, "Unregistered hf! index=%d", hf); ((void) ((hf >
0 && (unsigned)hf < gpa_hfinfo.len) ? (void)0 : (
proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3504, "hf > 0 && (unsigned)hf < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf] != ((
void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3504, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3505
3506 switch (hfinfo->type) {
3507 case FT_STRING:
3508 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3509 break;
3510 case FT_STRINGZ:
3511 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3512 break;
3513 case FT_UINT_STRING:
3514 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3515 break;
3516 case FT_STRINGZPAD:
3517 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3518 break;
3519 case FT_STRINGZTRUNC:
3520 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3521 break;
3522 default:
3523 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC"
, hfinfo->abbrev)
3524 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC"
, hfinfo->abbrev)
;
3525 }
3526
3527 if (retval)
3528 *retval = value;
3529
3530 ptvc->offset += item_length;
3531
3532 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3533
3534 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfinfo->id
== 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3534, __func__, "Unregistered hf! index=%d"
, hfinfo->id); ((void) ((hfinfo->id > 0 && (
unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3534,
"hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3534, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((ptvc->tree)->tree_data)->count > prefs
.gui_max_tree_items) { ((void)0); if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3534
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3535
3536 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3537
3538 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3539 offset, length, encoding);
3540}
3541
3542/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3543 * and returns proto_item* and boolean value retreived */
3544proto_item*
3545ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3546{
3547 header_field_info *hfinfo;
3548 field_info *new_fi;
3549 int item_length;
3550 int offset;
3551 uint64_t value, bitval;
3552
3553 offset = ptvc->offset;
3554 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3554, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3554,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3554, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3555
3556 if (hfinfo->type != FT_BOOLEAN) {
3557 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
3558 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3559 }
3560
3561 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3562 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3563 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3564 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3565 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3566 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3567 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3568
3569 if (encoding & ENC_STRING0x03000000) {
3570 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3571 }
3572
3573 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3574 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3575
3576 /* I believe it's ok if this is called with a NULL tree */
3577 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3578
3579 if (retval) {
3580 bitval = value;
3581 if (hfinfo->bitmask) {
3582 /* Mask out irrelevant portions */
3583 bitval &= hfinfo->bitmask;
3584 }
3585 *retval = (bitval != 0);
3586 }
3587
3588 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3589 item_length, encoding);
3590
3591 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3592
3593 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfinfo->id, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfinfo->id
== 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3593, __func__, "Unregistered hf! index=%d"
, hfinfo->id); ((void) ((hfinfo->id > 0 && (
unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3593,
"hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3593, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((ptvc->tree)->tree_data)->count > prefs
.gui_max_tree_items) { ((void)0); if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3593
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
3594
3595 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3596
3597 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3598 offset, length, encoding);
3599}
3600
3601proto_item *
3602proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3603 const int start, int length, const unsigned encoding, uint64_t *retval)
3604{
3605 header_field_info *hfinfo;
3606 field_info *new_fi;
3607 uint64_t value;
3608
3609 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3609, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3609,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3609, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3610
3611 switch (hfinfo->type) {
3612 case FT_UINT40:
3613 case FT_UINT48:
3614 case FT_UINT56:
3615 case FT_UINT64:
3616 break;
3617 default:
3618 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
3619 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3620 }
3621
3622 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3623 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3624 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3625 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3626 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3627 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3628 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3629
3630 if (encoding & ENC_STRING0x03000000) {
3631 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3632 }
3633 /* I believe it's ok if this is called with a NULL tree */
3634 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3635 tvb_get_varint(tvb, start, length, &value, encoding);
3636 } else {
3637 value = get_uint64_value(tree, tvb, start, length, encoding);
3638 }
3639
3640 if (retval) {
3641 *retval = value;
3642 if (hfinfo->bitmask) {
3643 /* Mask out irrelevant portions */
3644 *retval &= hfinfo->bitmask;
3645 /* Shift bits */
3646 *retval >>= hfinfo_bitshift(hfinfo);
3647 }
3648 }
3649
3650 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3651
3652 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3652
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3652, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3652, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3652, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3653
3654 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3655
3656 proto_tree_set_uint64(new_fi, value);
3657
3658 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3659 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3660 new_fi->flags |= FI_VARINT0x00040000;
3661 }
3662
3663 return proto_tree_add_node(tree, new_fi);
3664}
3665
3666proto_item *
3667proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3668 const int start, int length, const unsigned encoding, int64_t *retval)
3669{
3670 header_field_info *hfinfo;
3671 field_info *new_fi;
3672 int64_t value;
3673
3674 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3674, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3674,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3674, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3675
3676 switch (hfinfo->type) {
3677 case FT_INT40:
3678 case FT_INT48:
3679 case FT_INT56:
3680 case FT_INT64:
3681 break;
3682 default:
3683 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
3684 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3685 }
3686
3687 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3688 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3689 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3690 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3691 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3692 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3693 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3694
3695 if (encoding & ENC_STRING0x03000000) {
3696 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3697 }
3698 /* I believe it's ok if this is called with a NULL tree */
3699 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3700 tvb_get_varint(tvb, start, length, &value, encoding);
3701 }
3702 else {
3703 value = get_int64_value(tree, tvb, start, length, encoding);
3704 }
3705
3706 if (retval) {
3707 *retval = value;
3708 }
3709
3710 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3711
3712 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3712
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3712, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3712, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3712, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3713
3714 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3715
3716 proto_tree_set_int64(new_fi, value);
3717
3718 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3719 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3720 new_fi->flags |= FI_VARINT0x00040000;
3721 }
3722
3723 return proto_tree_add_node(tree, new_fi);
3724}
3725
3726proto_item *
3727proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3728 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3729{
3730 header_field_info *hfinfo;
3731 field_info *new_fi;
3732 uint64_t value;
3733
3734 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3734, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3734,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3734, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3735
3736 if ((!FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
) && (!FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
)) {
3737 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT or FT_INT",proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
3738 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3739 }
3740
3741 /* length validation for native number encoding caught by get_uint64_value() */
3742 /* length has to be -1 or > 0 regardless of encoding */
3743 if (length == 0)
3744 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
3745 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3746
3747 if (encoding & ENC_STRING0x03000000) {
3748 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3749 }
3750
3751 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3752
3753 if (retval) {
3754 *retval = value;
3755 if (hfinfo->bitmask) {
3756 /* Mask out irrelevant portions */
3757 *retval &= hfinfo->bitmask;
3758 /* Shift bits */
3759 *retval >>= hfinfo_bitshift(hfinfo);
3760 }
3761 }
3762
3763 if (lenretval) {
3764 *lenretval = length;
3765 }
3766
3767 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3768
3769 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3769
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3769, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3769, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3769, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3770
3771 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3772
3773 proto_tree_set_uint64(new_fi, value);
3774
3775 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3776 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3777 new_fi->flags |= FI_VARINT0x00040000;
3778 }
3779
3780 return proto_tree_add_node(tree, new_fi);
3781
3782}
3783
3784proto_item *
3785proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3786 const int start, int length,
3787 const unsigned encoding, bool_Bool *retval)
3788{
3789 header_field_info *hfinfo;
3790 field_info *new_fi;
3791 uint64_t value, bitval;
3792
3793 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3793, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3793,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3793, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3794
3795 if (hfinfo->type != FT_BOOLEAN) {
3796 REPORT_DISSECTOR_BUG("field %s is not of type FT_BOOLEAN",proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
3797 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3798 }
3799
3800 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3801 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3802 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3803 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3804 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3805 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3806 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3807
3808 if (encoding & ENC_STRING0x03000000) {
3809 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3810 }
3811 /* I believe it's ok if this is called with a NULL tree */
3812 value = get_uint64_value(tree, tvb, start, length, encoding);
3813
3814 if (retval) {
3815 bitval = value;
3816 if (hfinfo->bitmask) {
3817 /* Mask out irrelevant portions */
3818 bitval &= hfinfo->bitmask;
3819 }
3820 *retval = (bitval != 0);
3821 }
3822
3823 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3824
3825 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3825
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3825, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3825, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3825, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3826
3827 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3828
3829 proto_tree_set_boolean(new_fi, value);
3830
3831 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3832
3833 return proto_tree_add_node(tree, new_fi);
3834}
3835
3836proto_item *
3837proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3838 const int start, int length,
3839 const unsigned encoding, float *retval)
3840{
3841 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3842 field_info *new_fi;
3843 float value;
3844
3845 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3845,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3846
3847 if (hfinfo->type != FT_FLOAT) {
3848 REPORT_DISSECTOR_BUG("field %s is not of type FT_FLOAT", hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_FLOAT"
, hfinfo->abbrev)
;
3849 }
3850
3851 if (length != 4) {
3852 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3853 }
3854
3855 /* treat any nonzero encoding as little endian for backwards compatibility */
3856 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3857 if (retval) {
3858 *retval = value;
3859 }
3860
3861 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3862
3863 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3863
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3863, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3863, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3863, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3864
3865 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3866 if (encoding) {
3867 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3868 }
3869
3870 proto_tree_set_float(new_fi, value);
3871
3872 return proto_tree_add_node(tree, new_fi);
3873}
3874
3875proto_item *
3876proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3877 const int start, int length,
3878 const unsigned encoding, double *retval)
3879{
3880 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3881 field_info *new_fi;
3882 double value;
3883
3884 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3884,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3885
3886 if (hfinfo->type != FT_DOUBLE) {
3887 REPORT_DISSECTOR_BUG("field %s is not of type FT_DOUBLE", hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_DOUBLE"
, hfinfo->abbrev)
;
3888 }
3889
3890 if (length != 8) {
3891 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3892 }
3893
3894 /* treat any nonzero encoding as little endian for backwards compatibility */
3895 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3896 if (retval) {
3897 *retval = value;
3898 }
3899
3900 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3901
3902 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3902
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3902, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3902, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3902, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3903
3904 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3905 if (encoding) {
3906 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3907 }
3908
3909 proto_tree_set_double(new_fi, value);
3910
3911 return proto_tree_add_node(tree, new_fi);
3912}
3913
3914proto_item *
3915proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3916 const int start, int length,
3917 const unsigned encoding, ws_in4_addr *retval)
3918{
3919 header_field_info *hfinfo;
3920 field_info *new_fi;
3921 ws_in4_addr value;
3922
3923 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 3923, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3923,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3923, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3924
3925 switch (hfinfo->type) {
3926 case FT_IPv4:
3927 break;
3928 default:
3929 REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv4",proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
3930 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3931 }
3932
3933 if (length != FT_IPv4_LEN4)
3934 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv4",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
3935 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3936
3937 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3938 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3939 }
3940
3941 /*
3942 * NOTE: to support code written when proto_tree_add_item() took
3943 * a bool as its last argument, with false meaning "big-endian"
3944 * and true meaning "little-endian", we treat any non-zero value
3945 * of "encoding" as meaning "little-endian".
3946 */
3947 value = tvb_get_ipv4(tvb, start);
3948 if (encoding)
3949 value = GUINT32_SWAP_LE_BE(value)(((guint32) ( (((guint32) (value) & (guint32) 0x000000ffU
) << 24) | (((guint32) (value) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (value) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (value) & (guint32) 0xff000000U
) >> 24))))
;
3950
3951 if (retval) {
3952 *retval = value;
3953 }
3954
3955 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3956
3957 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3957
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3957, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3957, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3957, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3958
3959 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3960
3961 proto_tree_set_ipv4(new_fi, value);
3962
3963 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3964 return proto_tree_add_node(tree, new_fi);
3965}
3966
3967proto_item *
3968proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3969 const int start, int length,
3970 const unsigned encoding, ws_in6_addr *addr)
3971{
3972 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3973 field_info *new_fi;
3974
3975 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3975,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3976
3977 switch (hfinfo->type) {
3978 case FT_IPv6:
3979 break;
3980 default:
3981 REPORT_DISSECTOR_BUG("field %s is not of type FT_IPv6",proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
3982 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
3983 }
3984
3985 if (length != FT_IPv6_LEN16)
3986 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ipv6",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
3987 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
3988
3989 if (encoding) {
3990 REPORT_DISSECTOR_BUG("Encodings not yet implemented for proto_tree_add_item_ret_ipv6")proto_report_dissector_bug("Encodings not yet implemented for proto_tree_add_item_ret_ipv6"
)
;
3991 }
3992
3993 tvb_get_ipv6(tvb, start, addr);
3994
3995 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3996
3997 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3997
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3997, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3997, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3997, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
3998
3999 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4000
4001 proto_tree_set_ipv6(new_fi, addr);
4002
4003 return proto_tree_add_node(tree, new_fi);
4004}
4005
4006proto_item *
4007proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4008 const int start, int length, const unsigned encoding, uint8_t *retval) {
4009
4010 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4011 field_info *new_fi;
4012
4013 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4013,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4014
4015 switch (hfinfo->type) {
4016 case FT_ETHER:
4017 break;
4018 default:
4019 REPORT_DISSECTOR_BUG("field %s is not of type FT_ETHER",proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
4020 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4021 }
4022
4023 if (length != FT_ETHER_LEN6)
4024 REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_ether",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
4025 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4026
4027 if (encoding) {
4028 REPORT_DISSECTOR_BUG("Encodings not yet implemented for proto_tree_add_item_ret_ether")proto_report_dissector_bug("Encodings not yet implemented for proto_tree_add_item_ret_ether"
)
;
4029 }
4030
4031 tvb_memcpy(tvb, retval, start, length);
4032
4033 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4034
4035 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4035
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4035, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4035, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4035, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4036
4037 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4038
4039 proto_tree_set_ether(new_fi, retval);
4040
4041 return proto_tree_add_node(tree, new_fi);
4042}
4043
4044
4045proto_item *
4046proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4047 tvbuff_t *tvb,
4048 const int start, int length,
4049 const unsigned encoding,
4050 wmem_allocator_t *scope,
4051 const uint8_t **retval,
4052 int *lenretval)
4053{
4054 proto_item *pi;
4055 header_field_info *hfinfo;
4056 field_info *new_fi;
4057 const uint8_t *value;
4058
4059 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4059, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4059,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4059, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4060
4061 switch (hfinfo->type) {
4062 case FT_STRING:
4063 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4064 break;
4065 case FT_STRINGZ:
4066 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4067 break;
4068 case FT_UINT_STRING:
4069 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4070 break;
4071 case FT_STRINGZPAD:
4072 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4073 break;
4074 case FT_STRINGZTRUNC:
4075 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4076 break;
4077 default:
4078 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC",proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC"
, hfinfo->abbrev)
4079 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, or FT_STRINGZTRUNC"
, hfinfo->abbrev)
;
4080 }
4081
4082 if (retval)
4083 *retval = value;
4084
4085 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4086
4087 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4087
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4087, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4087, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4087, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4088
4089 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4090
4091 proto_tree_set_string(new_fi, value);
4092
4093 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4094
4095 pi = proto_tree_add_node(tree, new_fi);
4096
4097 switch (hfinfo->type) {
4098
4099 case FT_STRINGZ:
4100 case FT_STRINGZPAD:
4101 case FT_STRINGZTRUNC:
4102 case FT_UINT_STRING:
4103 break;
4104
4105 case FT_STRING:
4106 detect_trailing_stray_characters(encoding, value, length, pi);
4107 break;
4108
4109 default:
4110 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4110
, __func__, "assertion \"not reached\" failed")
;
4111 }
4112
4113 return pi;
4114}
4115
4116proto_item *
4117proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4118 const int start, int length,
4119 const unsigned encoding, wmem_allocator_t *scope,
4120 const uint8_t **retval)
4121{
4122 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4123 tvb, start, length, encoding, scope, retval, &length);
4124}
4125
4126proto_item *
4127proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4128 tvbuff_t *tvb,
4129 const int start, int length,
4130 const unsigned encoding,
4131 wmem_allocator_t *scope,
4132 char **retval,
4133 int *lenretval)
4134{
4135 proto_item *pi;
4136 header_field_info *hfinfo;
4137 field_info *new_fi;
4138 const uint8_t *value;
4139 uint32_t n = 0;
4140
4141 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4141, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4141,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4141, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4142
4143 switch (hfinfo->type) {
4144 case FT_STRING:
4145 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4146 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4147 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4148 break;
4149 case FT_STRINGZ:
4150 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4151 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4152 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4153 break;
4154 case FT_UINT_STRING:
4155 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4156 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4157 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4158 break;
4159 case FT_STRINGZPAD:
4160 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4161 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4162 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4163 break;
4164 case FT_STRINGZTRUNC:
4165 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4166 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4167 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4168 break;
4169 case FT_BYTES:
4170 tvb_ensure_bytes_exist(tvb, start, length);
4171 value = tvb_get_ptr(tvb, start, length);
4172 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4173 *lenretval = length;
4174 break;
4175 case FT_UINT_BYTES:
4176 n = get_uint_value(tree, tvb, start, length, encoding);
4177 tvb_ensure_bytes_exist(tvb, start + length, n);
4178 value = tvb_get_ptr(tvb, start + length, n);
4179 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4180 *lenretval = length + n;
4181 break;
4182 default:
4183 REPORT_DISSECTOR_BUG("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, FT_BYTES, or FT_UINT_BYTES",proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, FT_BYTES, or FT_UINT_BYTES"
, hfinfo->abbrev)
4184 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_STRING, FT_STRINGZ, FT_UINT_STRING, FT_STRINGZPAD, FT_STRINGZTRUNC, FT_BYTES, or FT_UINT_BYTES"
, hfinfo->abbrev)
;
4185 }
4186
4187 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4188
4189 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4189
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4189, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4189, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4189, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4190
4191 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4192
4193 switch (hfinfo->type) {
4194
4195 case FT_STRING:
4196 case FT_STRINGZ:
4197 case FT_UINT_STRING:
4198 case FT_STRINGZPAD:
4199 case FT_STRINGZTRUNC:
4200 proto_tree_set_string(new_fi, value);
4201 break;
4202
4203 case FT_BYTES:
4204 proto_tree_set_bytes(new_fi, value, length);
4205 break;
4206
4207 case FT_UINT_BYTES:
4208 proto_tree_set_bytes(new_fi, value, n);
4209 break;
4210
4211 default:
4212 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4212
, __func__, "assertion \"not reached\" failed")
;
4213 }
4214
4215 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4216
4217 pi = proto_tree_add_node(tree, new_fi);
4218
4219 switch (hfinfo->type) {
4220
4221 case FT_STRINGZ:
4222 case FT_STRINGZPAD:
4223 case FT_STRINGZTRUNC:
4224 case FT_UINT_STRING:
4225 break;
4226
4227 case FT_STRING:
4228 detect_trailing_stray_characters(encoding, value, length, pi);
4229 break;
4230
4231 case FT_BYTES:
4232 case FT_UINT_BYTES:
4233 break;
4234
4235 default:
4236 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4236
, __func__, "assertion \"not reached\" failed")
;
4237 }
4238
4239 return pi;
4240}
4241
4242proto_item *
4243proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4244 tvbuff_t *tvb,
4245 const int start, int length,
4246 const unsigned encoding,
4247 wmem_allocator_t *scope,
4248 char **retval)
4249{
4250 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4251 tvb, start, length, encoding, scope, retval, &length);
4252}
4253
4254proto_item *
4255proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4256 tvbuff_t *tvb,
4257 const int start, int length, const unsigned encoding,
4258 wmem_allocator_t *scope, char **retval)
4259{
4260 header_field_info *hfinfo;
4261 field_info *new_fi;
4262 nstime_t time_stamp;
4263 int flags;
4264
4265 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4265, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4265,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4265, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4266
4267 switch (hfinfo->type) {
4268 case FT_ABSOLUTE_TIME:
4269 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4270 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4271 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4272 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4273 }
4274 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4275 break;
4276 case FT_RELATIVE_TIME:
4277 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4278 *retval = rel_time_to_secs_str(scope, &time_stamp);
4279 break;
4280 default:
4281 REPORT_DISSECTOR_BUG("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME",proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
4282 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4283 }
4284
4285 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4286
4287 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4287
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4287, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4287, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4287, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4288
4289 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4290
4291 switch (hfinfo->type) {
4292
4293 case FT_ABSOLUTE_TIME:
4294 case FT_RELATIVE_TIME:
4295 proto_tree_set_time(new_fi, &time_stamp);
4296 break;
4297 default:
4298 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4298
, __func__, "assertion \"not reached\" failed")
;
4299 }
4300
4301 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4302
4303 return proto_tree_add_node(tree, new_fi);
4304}
4305
4306/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4307 and returns proto_item* */
4308proto_item *
4309ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4310 const unsigned encoding)
4311{
4312 field_info *new_fi;
4313 header_field_info *hfinfo;
4314 int item_length;
4315 int offset;
4316
4317 offset = ptvc->offset;
4318 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4318, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4318,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4318, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4319 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4320 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4321
4322 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
4323 item_length, encoding);
4324
4325 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4326
4327 /* Coast clear. Try and fake it */
4328 TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo)((ptvc->tree)->tree_data)->count++; if((hfindex == 0
|| (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4328
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4328, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4328, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((ptvc->tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4328, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree
)->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc
->tree)->tree_data)->visible)) { if (proto_item_is_hidden
((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT
) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) &&
(hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data
)->fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(ptvc->tree, hfinfo); } } }
;
4329
4330 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4331
4332 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4333 offset, length, encoding);
4334}
4335
4336/* Add an item to a proto_tree, using the text label registered to that item;
4337 the item is extracted from the tvbuff handed to it. */
4338proto_item *
4339proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4340 const int start, int length, const unsigned encoding)
4341{
4342 field_info *new_fi;
4343 int item_length;
4344
4345 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4345,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4346
4347 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4348 test_length(hfinfo, tvb, start, item_length, encoding);
4349
4350 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4351
4352 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4352
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4352, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4352, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4352, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4353
4354 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4355
4356 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4357}
4358
4359proto_item *
4360proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4361 const int start, int length, const unsigned encoding)
4362{
4363 register header_field_info *hfinfo;
4364
4365 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4365, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4365,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4365, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4366 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4367}
4368
4369/* Add an item to a proto_tree, using the text label registered to that item;
4370 the item is extracted from the tvbuff handed to it.
4371
4372 Return the length of the item through the pointer. */
4373proto_item *
4374proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4375 tvbuff_t *tvb, const int start,
4376 int length, const unsigned encoding,
4377 int *lenretval)
4378{
4379 field_info *new_fi;
4380 int item_length;
4381 proto_item *item;
4382
4383 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4383,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4384
4385 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4386 test_length(hfinfo, tvb, start, item_length, encoding);
4387
4388 if (!tree) {
4389 /*
4390 * We need to get the correct item length here.
4391 * That's normally done by proto_tree_new_item(),
4392 * but we won't be calling it.
4393 */
4394 *lenretval = get_full_length(hfinfo, tvb, start, length,
4395 item_length, encoding);
4396 return NULL((void*)0);
4397 }
4398
4399 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4400 /*((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4401 * Even if the tree item is not referenced (and thus faked),((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4402 * the caller must still be informed of the actual length.((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4403 */((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4404 *lenretval = get_full_length(hfinfo, tvb, start, length,((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4405 item_length, encoding);((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4406 })((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4406, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4406
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
;
4407
4408 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4409
4410 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4411 *lenretval = new_fi->length;
4412 return item;
4413}
4414
4415proto_item *
4416proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4417 const int start, int length,
4418 const unsigned encoding, int *lenretval)
4419{
4420 register header_field_info *hfinfo;
4421
4422 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4422, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4422,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4422, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4423 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4424}
4425
4426/* which FT_ types can use proto_tree_add_bytes_item() */
4427static inline bool_Bool
4428validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4429{
4430 return (type == FT_BYTES ||
4431 type == FT_UINT_BYTES ||
4432 type == FT_OID ||
4433 type == FT_REL_OID ||
4434 type == FT_SYSTEM_ID );
4435}
4436
4437/* Note: this does no validation that the byte array of an FT_OID or
4438 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4439 so I think it's ok to continue not validating it?
4440 */
4441proto_item *
4442proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4443 const int start, int length, const unsigned encoding,
4444 GByteArray *retval, int *endoff, int *err)
4445{
4446 field_info *new_fi;
4447 GByteArray *bytes = retval;
4448 GByteArray *created_bytes = NULL((void*)0);
4449 bool_Bool failed = false0;
4450 uint32_t n = 0;
4451 header_field_info *hfinfo;
4452 bool_Bool generate = (bytes || tree) ? true1 : false0;
4453
4454 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4454, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4454,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4454, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4455
4456 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4456,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4457
4458 DISSECTOR_ASSERT_HINT(validate_proto_tree_add_bytes_ftype(hfinfo->type),((void) ((validate_proto_tree_add_bytes_ftype(hfinfo->type
)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4459, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4459 "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type")((void) ((validate_proto_tree_add_bytes_ftype(hfinfo->type
)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4459, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4460
4461 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4462
4463 if (encoding & ENC_STR_NUM0x01000000) {
4464 REPORT_DISSECTOR_BUG("Decoding number strings for byte arrays is not supported")proto_report_dissector_bug("Decoding number strings for byte arrays is not supported"
)
;
4465 }
4466
4467 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4468 if (hfinfo->type == FT_UINT_BYTES) {
4469 /* can't decode FT_UINT_BYTES from strings */
4470 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called for "proto_report_dissector_bug("proto_tree_add_bytes_item called for "
"FT_UINT_BYTES type, but as ENC_STR_HEX")
4471 "FT_UINT_BYTES type, but as ENC_STR_HEX")proto_report_dissector_bug("proto_tree_add_bytes_item called for "
"FT_UINT_BYTES type, but as ENC_STR_HEX")
;
4472 }
4473
4474 unsigned hex_encoding = encoding;
4475 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4476 /* If none of the separator values are used,
4477 * assume no separator (the common case). */
4478 hex_encoding |= ENC_SEP_NONE0x00010000;
4479#if 0
4480 REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called "proto_report_dissector_bug("proto_tree_add_bytes_item called "
"with ENC_STR_HEX but no ENC_SEP_XXX value")
4481 "with ENC_STR_HEX but no ENC_SEP_XXX value")proto_report_dissector_bug("proto_tree_add_bytes_item called "
"with ENC_STR_HEX but no ENC_SEP_XXX value")
;
4482#endif
4483 }
4484
4485 if (!bytes) {
4486 /* caller doesn't care about return value, but we need it to
4487 call tvb_get_string_bytes() and set the tree later */
4488 bytes = created_bytes = g_byte_array_new();
4489 }
4490
4491 /*
4492 * bytes might be NULL after this, but can't add expert
4493 * error until later; if it's NULL, just note that
4494 * it failed.
4495 */
4496 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4497 if (bytes == NULL((void*)0))
4498 failed = true1;
4499 }
4500 else if (generate) {
4501 tvb_ensure_bytes_exist(tvb, start, length);
4502
4503 if (hfinfo->type == FT_UINT_BYTES) {
4504 n = length; /* n is now the "header" length */
4505 length = get_uint_value(tree, tvb, start, n, encoding);
4506 /* length is now the value's length; only store the value in the array */
4507 tvb_ensure_bytes_exist(tvb, start + n, length);
4508 if (!bytes) {
4509 /* caller doesn't care about return value, but
4510 * we may need it to set the tree later */
4511 bytes = created_bytes = g_byte_array_new();
4512 }
4513 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4514 }
4515 else if (length > 0) {
4516 if (!bytes) {
4517 /* caller doesn't care about return value, but
4518 * we may need it to set the tree later */
4519 bytes = created_bytes = g_byte_array_new();
4520 }
4521 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4522 }
4523
4524 if (endoff)
4525 *endoff = start + n + length;
4526 }
4527
4528 if (err)
4529 *err = failed ? EINVAL22 : 0;
4530
4531 CHECK_FOR_NULL_TREE_AND_FREE(tree,if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4532 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4533 if (created_bytes)if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4534 g_byte_array_free(created_bytes, true);if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4535 created_bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4536 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4537 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4538
4539 TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo,((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4540 {((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4541 if (created_bytes)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4542 g_byte_array_free(created_bytes, true);((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4543 created_bytes = NULL;((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4544 bytes = NULL;((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4545 } )((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4545, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { { if (created_bytes) g_byte_array_free(created_bytes, 1);
created_bytes = ((void*)0); bytes = ((void*)0); }; if (wireshark_abort_on_too_many_items
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4545
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
;
4546
4547 /* n will be zero except when it's a FT_UINT_BYTES */
4548 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4549
4550 if (encoding & ENC_STRING0x03000000) {
4551 if (failed)
4552 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4553
4554 if (bytes)
4555 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4556 else
4557 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4558
4559 if (created_bytes)
4560 g_byte_array_free(created_bytes, true1);
4561 }
4562 else {
4563 /* n will be zero except when it's a FT_UINT_BYTES */
4564 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4565
4566 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4567 * use the byte array created above in this case.
4568 */
4569 if (created_bytes)
4570 g_byte_array_free(created_bytes, true1);
4571
4572 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4573 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN)do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
;
4574 }
4575
4576 return proto_tree_add_node(tree, new_fi);
4577}
4578
4579
4580proto_item *
4581proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4582 const int start, int length, const unsigned encoding,
4583 nstime_t *retval, int *endoff, int *err)
4584{
4585 field_info *new_fi;
4586 nstime_t time_stamp;
4587 int saved_err = 0;
4588 header_field_info *hfinfo;
4589
4590 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4590, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4590,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4590, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4591
4592 DISSECTOR_ASSERT_HINT(hfinfo != NULL, "Not passed hfi!")((void) ((hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4592,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4593
4594 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4595 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4596 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4597 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4598 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4599 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4600 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4601
4602 nstime_set_zero(&time_stamp);
4603
4604 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4605 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ABSOLUTE_TIME)((void) (((hfinfo)->type == FT_ABSOLUTE_TIME) ? (void)0 : (
proto_report_dissector_bug("%s:%u: field %s is not of type ""FT_ABSOLUTE_TIME"
, "epan/proto.c", 4605, ((hfinfo))->abbrev))))
;
4606 /* The only string format that could be a relative time is
4607 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4608 * relative to "now" currently.
4609 */
4610 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4611 saved_err = EINVAL22;
4612 }
4613 else {
4614 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo)((void) (((hfinfo)->type == FT_ABSOLUTE_TIME || (hfinfo)->
type == FT_RELATIVE_TIME) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, "epan/proto.c", 4614, ((hfinfo))->abbrev))))
;
4615 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4616
4617 tvb_ensure_bytes_exist(tvb, start, length);
4618 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4619 if (endoff) *endoff = start + length;
4620 }
4621
4622 if (err) *err = saved_err;
4623
4624 if (retval) {
4625 retval->secs = time_stamp.secs;
4626 retval->nsecs = time_stamp.nsecs;
4627 }
4628
4629 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4630
4631 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4631
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4631, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4631, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4631, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4632
4633 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4634
4635 proto_tree_set_time(new_fi, &time_stamp);
4636
4637 if (encoding & ENC_STRING0x03000000) {
4638 if (saved_err)
4639 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4640 }
4641 else {
4642 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4643 (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN)do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
;
4644 }
4645
4646 return proto_tree_add_node(tree, new_fi);
4647}
4648
4649/* Add a FT_NONE to a proto_tree */
4650proto_item *
4651proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4652 const int start, int length, const char *format,
4653 ...)
4654{
4655 proto_item *pi;
4656 va_list ap;
4657 header_field_info *hfinfo;
4658
4659 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4660
4661 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4661
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4661, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4661, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4661, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4662
4663 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_NONE)((void) (((hfinfo)->type == FT_NONE) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_NONE", "epan/proto.c", 4663
, ((hfinfo))->abbrev))))
;
4664
4665 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4666
4667 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4667, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4668
4669 va_start(ap, format)__builtin_va_start(ap, format);
4670 proto_tree_set_representation(pi, format, ap);
4671 va_end(ap)__builtin_va_end(ap);
4672
4673 /* no value to set for FT_NONE */
4674 return pi;
4675}
4676
4677/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4678 * offset, and returns proto_item* */
4679proto_item *
4680ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4681 const unsigned encoding)
4682{
4683 proto_item *item;
4684
4685 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4686 length, encoding);
4687
4688 return item;
4689}
4690
4691/* Advance the ptvcursor's offset within its tvbuff without
4692 * adding anything to the proto_tree. */
4693void
4694ptvcursor_advance(ptvcursor_t* ptvc, int length)
4695{
4696 ptvc->offset += length;
4697}
4698
4699
4700static void
4701proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4702{
4703 fvalue_set_protocol(fi->value, tvb, field_data, length);
4704}
4705
4706/* Add a FT_PROTOCOL to a proto_tree */
4707proto_item *
4708proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4709 int start, int length, const char *format, ...)
4710{
4711 proto_item *pi;
4712 tvbuff_t *protocol_tvb;
4713 va_list ap;
4714 header_field_info *hfinfo;
4715 char* protocol_rep;
4716
4717 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4718
4719 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4719
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4719, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4719, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4719, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4720
4721 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_PROTOCOL)((void) (((hfinfo)->type == FT_PROTOCOL) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_PROTOCOL", "epan/proto.c"
, 4721, ((hfinfo))->abbrev))))
;
4722
4723 /*
4724 * This can throw an exception, so do it before we allocate anything.
4725 */
4726 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4727
4728 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4729
4730 va_start(ap, format)__builtin_va_start(ap, format);
4731 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4732 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4733 g_free(protocol_rep);
4734 va_end(ap)__builtin_va_end(ap);
4735
4736 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4736, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4737
4738 va_start(ap, format)__builtin_va_start(ap, format);
4739 proto_tree_set_representation(pi, format, ap);
4740 va_end(ap)__builtin_va_end(ap);
4741
4742 return pi;
4743}
4744
4745/* Add a FT_BYTES to a proto_tree */
4746proto_item *
4747proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4748 int length, const uint8_t *start_ptr)
4749{
4750 proto_item *pi;
4751 header_field_info *hfinfo;
4752 int item_length;
4753
4754 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4754, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4754,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4754, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4755 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4756 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4757
4758 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4759
4760 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4760
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4760, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4760, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4760, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4761
4762 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES)((void) (((hfinfo)->type == FT_BYTES) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_BYTES", "epan/proto.c",
4762, ((hfinfo))->abbrev))))
;
4763
4764 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4765 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4766
4767 return pi;
4768}
4769
4770/* Add a FT_BYTES to a proto_tree */
4771proto_item *
4772proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4773 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4774{
4775 proto_item *pi;
4776 header_field_info *hfinfo;
4777 int item_length;
4778
4779 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4779, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4779,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4779, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4780 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4781 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4782
4783 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4784
4785 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4785
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4785, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4785, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4785, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4786
4787 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BYTES)((void) (((hfinfo)->type == FT_BYTES) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_BYTES", "epan/proto.c",
4787, ((hfinfo))->abbrev))))
;
4788
4789 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4790 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4791
4792 return pi;
4793}
4794
4795proto_item *
4796proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4797 int start, int length,
4798 const uint8_t *start_ptr,
4799 const char *format, ...)
4800{
4801 proto_item *pi;
4802 va_list ap;
4803
4804 if (start_ptr == NULL((void*)0))
4805 start_ptr = tvb_get_ptr(tvb, start, length);
4806
4807 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4808
4809 TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
;
4810
4811 va_start(ap, format)__builtin_va_start(ap, format);
4812 proto_tree_set_representation_value(pi, format, ap);
4813 va_end(ap)__builtin_va_end(ap);
4814
4815 return pi;
4816}
4817
4818proto_item *
4819proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4820 int start, int length, const uint8_t *start_ptr,
4821 const char *format, ...)
4822{
4823 proto_item *pi;
4824 va_list ap;
4825
4826 if (start_ptr == NULL((void*)0))
4827 start_ptr = tvb_get_ptr(tvb, start, length);
4828
4829 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4830
4831 TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) ||
(!(((pi)->tree_data)->visible) && proto_item_is_hidden
((pi)))) { return pi; }
;
4832
4833 va_start(ap, format)__builtin_va_start(ap, format);
4834 proto_tree_set_representation(pi, format, ap);
4835 va_end(ap)__builtin_va_end(ap);
4836
4837 return pi;
4838}
4839
4840static void
4841proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4842{
4843 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4843, "length >= 0"
))))
;
4844 DISSECTOR_ASSERT(start_ptr != NULL || length == 0)((void) ((start_ptr != ((void*)0) || length == 0) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 4844, "start_ptr != ((void*)0) || length == 0"
))))
;
4845
4846 fvalue_set_bytes_data(fi->value, start_ptr, length);
4847}
4848
4849
4850static void
4851proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4852{
4853 tvb_ensure_bytes_exist(tvb, offset, length);
4854 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4855}
4856
4857static void
4858proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4859{
4860 GByteArray *bytes;
4861
4862 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4862, "value != ((void*)0)"
))))
;
4863
4864 bytes = byte_array_dup(value);
4865
4866 fvalue_set_byte_array(fi->value, bytes);
4867}
4868
4869/* Add a FT_*TIME to a proto_tree */
4870proto_item *
4871proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4872 int length, const nstime_t *value_ptr)
4873{
4874 proto_item *pi;
4875 header_field_info *hfinfo;
4876
4877 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4878
4879 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4879
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4879, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4879, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4879, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4880
4881 DISSECTOR_ASSERT_FIELD_TYPE_IS_TIME(hfinfo)((void) (((hfinfo)->type == FT_ABSOLUTE_TIME || (hfinfo)->
type == FT_RELATIVE_TIME) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, "epan/proto.c", 4881, ((hfinfo))->abbrev))))
;
4882
4883 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4884 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4885
4886 return pi;
4887}
4888
4889proto_item *
4890proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4891 int start, int length, nstime_t *value_ptr,
4892 const char *format, ...)
4893{
4894 proto_item *pi;
4895 va_list ap;
4896
4897 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4898 if (pi != tree) {
4899 va_start(ap, format)__builtin_va_start(ap, format);
4900 proto_tree_set_representation_value(pi, format, ap);
4901 va_end(ap)__builtin_va_end(ap);
4902 }
4903
4904 return pi;
4905}
4906
4907proto_item *
4908proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4909 int start, int length, nstime_t *value_ptr,
4910 const char *format, ...)
4911{
4912 proto_item *pi;
4913 va_list ap;
4914
4915 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4916 if (pi != tree) {
4917 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4917, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4918
4919 va_start(ap, format)__builtin_va_start(ap, format);
4920 proto_tree_set_representation(pi, format, ap);
4921 va_end(ap)__builtin_va_end(ap);
4922 }
4923
4924 return pi;
4925}
4926
4927/* Set the FT_*TIME value */
4928static void
4929proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4930{
4931 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4931, "value_ptr != ((void*)0)"
))))
;
4932
4933 fvalue_set_time(fi->value, value_ptr);
4934}
4935
4936/* Add a FT_IPXNET to a proto_tree */
4937proto_item *
4938proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4939 int length, uint32_t value)
4940{
4941 proto_item *pi;
4942 header_field_info *hfinfo;
4943
4944 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4945
4946 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4946
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4946, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4946, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4946, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
4947
4948 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPXNET)((void) (((hfinfo)->type == FT_IPXNET) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_IPXNET", "epan/proto.c"
, 4948, ((hfinfo))->abbrev))))
;
4949
4950 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4951 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
4952
4953 return pi;
4954}
4955
4956proto_item *
4957proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4958 int start, int length, uint32_t value,
4959 const char *format, ...)
4960{
4961 proto_item *pi;
4962 va_list ap;
4963
4964 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4965 if (pi != tree) {
4966 va_start(ap, format)__builtin_va_start(ap, format);
4967 proto_tree_set_representation_value(pi, format, ap);
4968 va_end(ap)__builtin_va_end(ap);
4969 }
4970
4971 return pi;
4972}
4973
4974proto_item *
4975proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4976 int start, int length, uint32_t value,
4977 const char *format, ...)
4978{
4979 proto_item *pi;
4980 va_list ap;
4981
4982 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4983 if (pi != tree) {
4984 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4984, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4985
4986 va_start(ap, format)__builtin_va_start(ap, format);
4987 proto_tree_set_representation(pi, format, ap);
4988 va_end(ap)__builtin_va_end(ap);
4989 }
4990
4991 return pi;
4992}
4993
4994/* Set the FT_IPXNET value */
4995static void
4996proto_tree_set_ipxnet(field_info *fi, uint32_t value)
4997{
4998 fvalue_set_uinteger(fi->value, value);
4999}
5000
5001/* Add a FT_IPv4 to a proto_tree */
5002proto_item *
5003proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5004 int length, ws_in4_addr value)
5005{
5006 proto_item *pi;
5007 header_field_info *hfinfo;
5008
5009 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5010
5011 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5011
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5011, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5011, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5011, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5012
5013 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv4)((void) (((hfinfo)->type == FT_IPv4) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_IPv4", "epan/proto.c", 5013
, ((hfinfo))->abbrev))))
;
5014
5015 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5016 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5017
5018 return pi;
5019}
5020
5021proto_item *
5022proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5023 int start, int length, ws_in4_addr value,
5024 const char *format, ...)
5025{
5026 proto_item *pi;
5027 va_list ap;
5028
5029 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5030 if (pi != tree) {
5031 va_start(ap, format)__builtin_va_start(ap, format);
5032 proto_tree_set_representation_value(pi, format, ap);
5033 va_end(ap)__builtin_va_end(ap);
5034 }
5035
5036 return pi;
5037}
5038
5039proto_item *
5040proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5041 int start, int length, ws_in4_addr value,
5042 const char *format, ...)
5043{
5044 proto_item *pi;
5045 va_list ap;
5046
5047 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5048 if (pi != tree) {
5049 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5049, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5050
5051 va_start(ap, format)__builtin_va_start(ap, format);
5052 proto_tree_set_representation(pi, format, ap);
5053 va_end(ap)__builtin_va_end(ap);
5054 }
5055
5056 return pi;
5057}
5058
5059/* Set the FT_IPv4 value */
5060static void
5061proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5062{
5063 ipv4_addr_and_mask ipv4;
5064 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5065 fvalue_set_ipv4(fi->value, &ipv4);
5066}
5067
5068/* Add a FT_IPv6 to a proto_tree */
5069proto_item *
5070proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5071 int length, const ws_in6_addr *value)
5072{
5073 proto_item *pi;
5074 header_field_info *hfinfo;
5075
5076 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5077
5078 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5078
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5078, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5078, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5078, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5079
5080 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_IPv6)((void) (((hfinfo)->type == FT_IPv6) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_IPv6", "epan/proto.c", 5080
, ((hfinfo))->abbrev))))
;
5081
5082 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5083 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5084
5085 return pi;
5086}
5087
5088proto_item *
5089proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5090 int start, int length,
5091 const ws_in6_addr *value_ptr,
5092 const char *format, ...)
5093{
5094 proto_item *pi;
5095 va_list ap;
5096
5097 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5098 if (pi != tree) {
5099 va_start(ap, format)__builtin_va_start(ap, format);
5100 proto_tree_set_representation_value(pi, format, ap);
5101 va_end(ap)__builtin_va_end(ap);
5102 }
5103
5104 return pi;
5105}
5106
5107proto_item *
5108proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5109 int start, int length,
5110 const ws_in6_addr *value_ptr,
5111 const char *format, ...)
5112{
5113 proto_item *pi;
5114 va_list ap;
5115
5116 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5117 if (pi != tree) {
5118 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5118, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5119
5120 va_start(ap, format)__builtin_va_start(ap, format);
5121 proto_tree_set_representation(pi, format, ap);
5122 va_end(ap)__builtin_va_end(ap);
5123 }
5124
5125 return pi;
5126}
5127
5128/* Set the FT_IPv6 value */
5129static void
5130proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5131{
5132 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5132, "value != ((void*)0)"
))))
;
5133 ipv6_addr_and_prefix ipv6;
5134 ipv6.addr = *value;
5135 ipv6.prefix = 128;
5136 fvalue_set_ipv6(fi->value, &ipv6);
5137}
5138
5139static void
5140proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5141{
5142 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5143}
5144
5145/* Set the FT_FCWWN value */
5146static void
5147proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5148{
5149 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5149, "value_ptr != ((void*)0)"
))))
;
5150 fvalue_set_fcwwn(fi->value, value_ptr);
5151}
5152
5153static void
5154proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5155{
5156 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5157}
5158
5159/* Add a FT_GUID to a proto_tree */
5160proto_item *
5161proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5162 int length, const e_guid_t *value_ptr)
5163{
5164 proto_item *pi;
5165 header_field_info *hfinfo;
5166
5167 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5168
5169 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5169
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5169, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5169, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5169, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5170
5171 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_GUID)((void) (((hfinfo)->type == FT_GUID) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_GUID", "epan/proto.c", 5171
, ((hfinfo))->abbrev))))
;
5172
5173 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5174 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5175
5176 return pi;
5177}
5178
5179proto_item *
5180proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5181 int start, int length,
5182 const e_guid_t *value_ptr,
5183 const char *format, ...)
5184{
5185 proto_item *pi;
5186 va_list ap;
5187
5188 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5189 if (pi != tree) {
5190 va_start(ap, format)__builtin_va_start(ap, format);
5191 proto_tree_set_representation_value(pi, format, ap);
5192 va_end(ap)__builtin_va_end(ap);
5193 }
5194
5195 return pi;
5196}
5197
5198proto_item *
5199proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5200 int start, int length, const e_guid_t *value_ptr,
5201 const char *format, ...)
5202{
5203 proto_item *pi;
5204 va_list ap;
5205
5206 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5207 if (pi != tree) {
5208 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5208, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5209
5210 va_start(ap, format)__builtin_va_start(ap, format);
5211 proto_tree_set_representation(pi, format, ap);
5212 va_end(ap)__builtin_va_end(ap);
5213 }
5214
5215 return pi;
5216}
5217
5218/* Set the FT_GUID value */
5219static void
5220proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5221{
5222 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5222, "value_ptr != ((void*)0)"
))))
;
5223 fvalue_set_guid(fi->value, value_ptr);
5224}
5225
5226static void
5227proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5228 const unsigned encoding)
5229{
5230 e_guid_t guid;
5231
5232 tvb_get_guid(tvb, start, &guid, encoding);
5233 proto_tree_set_guid(fi, &guid);
5234}
5235
5236/* Add a FT_OID to a proto_tree */
5237proto_item *
5238proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5239 int length, const uint8_t* value_ptr)
5240{
5241 proto_item *pi;
5242 header_field_info *hfinfo;
5243
5244 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5245
5246 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5246
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5246, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5246, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5246, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5247
5248 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_OID)((void) (((hfinfo)->type == FT_OID) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_OID", "epan/proto.c", 5248
, ((hfinfo))->abbrev))))
;
5249
5250 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5251 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5252
5253 return pi;
5254}
5255
5256proto_item *
5257proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5258 int start, int length,
5259 const uint8_t* value_ptr,
5260 const char *format, ...)
5261{
5262 proto_item *pi;
5263 va_list ap;
5264
5265 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5266 if (pi != tree) {
5267 va_start(ap, format)__builtin_va_start(ap, format);
5268 proto_tree_set_representation_value(pi, format, ap);
5269 va_end(ap)__builtin_va_end(ap);
5270 }
5271
5272 return pi;
5273}
5274
5275proto_item *
5276proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5277 int start, int length, const uint8_t* value_ptr,
5278 const char *format, ...)
5279{
5280 proto_item *pi;
5281 va_list ap;
5282
5283 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5284 if (pi != tree) {
5285 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5285, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5286
5287 va_start(ap, format)__builtin_va_start(ap, format);
5288 proto_tree_set_representation(pi, format, ap);
5289 va_end(ap)__builtin_va_end(ap);
5290 }
5291
5292 return pi;
5293}
5294
5295/* Set the FT_OID value */
5296static void
5297proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5298{
5299 GByteArray *bytes;
5300
5301 DISSECTOR_ASSERT(value_ptr != NULL || length == 0)((void) ((value_ptr != ((void*)0) || length == 0) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 5301, "value_ptr != ((void*)0) || length == 0"
))))
;
5302
5303 bytes = g_byte_array_new();
5304 if (length > 0) {
5305 g_byte_array_append(bytes, value_ptr, length);
5306 }
5307 fvalue_set_byte_array(fi->value, bytes);
5308}
5309
5310static void
5311proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5312{
5313 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5314}
5315
5316/* Set the FT_SYSTEM_ID value */
5317static void
5318proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5319{
5320 GByteArray *bytes;
5321
5322 DISSECTOR_ASSERT(value_ptr != NULL || length == 0)((void) ((value_ptr != ((void*)0) || length == 0) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 5322, "value_ptr != ((void*)0) || length == 0"
))))
;
5323
5324 bytes = g_byte_array_new();
5325 if (length > 0) {
5326 g_byte_array_append(bytes, value_ptr, length);
5327 }
5328 fvalue_set_byte_array(fi->value, bytes);
5329}
5330
5331static void
5332proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5333{
5334 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5335}
5336
5337/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5338 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5339 * is destroyed. */
5340proto_item *
5341proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5342 int length, const char* value)
5343{
5344 proto_item *pi;
5345 header_field_info *hfinfo;
5346 int item_length;
5347
5348 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5348, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5348,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5348, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5349 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5350 /*
5351 * Special case - if the length is 0, skip the test, so that
5352 * we can have an empty string right after the end of the
5353 * packet. (This handles URL-encoded forms where the last field
5354 * has no value so the form ends right after the =.)
5355 */
5356 if (item_length != 0)
5357 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5358
5359 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5360
5361 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5361
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5361, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5361, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5361, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5362
5363 DISSECTOR_ASSERT_FIELD_TYPE_IS_STRING(hfinfo)((void) ((((hfinfo)->type) == FT_STRING || ((hfinfo)->type
) == FT_STRINGZ || ((hfinfo)->type) == FT_STRINGZPAD || ((
hfinfo)->type) == FT_STRINGZTRUNC || ((hfinfo)->type) ==
FT_UINT_STRING || ((hfinfo)->type) == FT_AX25) ? (void)0 :
(proto_report_dissector_bug("%s:%u: field %s is not of type FT_STRING, FT_STRINGZ, FT_STRINGZPAD, FT_STRINGZTRUNC, or FT_UINT_STRING"
, "epan/proto.c", 5363, ((hfinfo))->abbrev))))
;
5364
5365 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5366 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5366, "length >= 0"
))))
;
5367
5368 WS_UTF_8_CHECK(value, -1)do { const char *__uni_endptr; if (1 && (value) != ((
void*)0) && !g_utf8_validate(value, -1, &__uni_endptr
)) { do { if (1) { ws_log_utf8_full("UTF-8", LOG_LEVEL_DEBUG,
"epan/proto.c", 5368, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5369 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5370
5371 return pi;
5372}
5373
5374proto_item *
5375proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5376 int start, int length, const char* value,
5377 const char *format,
5378 ...)
5379{
5380 proto_item *pi;
5381 va_list ap;
5382
5383 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5384 if (pi != tree) {
5385 va_start(ap, format)__builtin_va_start(ap, format);
5386 proto_tree_set_representation_value(pi, format, ap);
5387 va_end(ap)__builtin_va_end(ap);
5388 }
5389
5390 return pi;
5391}
5392
5393proto_item *
5394proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5395 int start, int length, const char* value,
5396 const char *format, ...)
5397{
5398 proto_item *pi;
5399 va_list ap;
5400
5401 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5402 if (pi != tree) {
5403 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5403, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5404
5405 va_start(ap, format)__builtin_va_start(ap, format);
5406 proto_tree_set_representation(pi, format, ap);
5407 va_end(ap)__builtin_va_end(ap);
5408 }
5409
5410 return pi;
5411}
5412
5413/* Set the FT_STRING value */
5414static void
5415proto_tree_set_string(field_info *fi, const char* value)
5416{
5417 if (value) {
5418 fvalue_set_string(fi->value, value);
5419 } else {
5420 /*
5421 * XXX - why is a null value for a string field
5422 * considered valid?
5423 */
5424 fvalue_set_string(fi->value, "[ Null ]");
5425 }
5426}
5427
5428/* Set the FT_AX25 value */
5429static void
5430proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5431{
5432 fvalue_set_ax25(fi->value, value);
5433}
5434
5435static void
5436proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5437{
5438 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5439}
5440
5441/* Set the FT_VINES value */
5442static void
5443proto_tree_set_vines(field_info *fi, const uint8_t* value)
5444{
5445 fvalue_set_vines(fi->value, value);
5446}
5447
5448static void
5449proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5450{
5451 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5452}
5453
5454/* Add a FT_ETHER to a proto_tree */
5455proto_item *
5456proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5457 int length, const uint8_t* value)
5458{
5459 proto_item *pi;
5460 header_field_info *hfinfo;
5461
5462 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5463
5464 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5464
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5464, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5464, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5464, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5465
5466 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_ETHER)((void) (((hfinfo)->type == FT_ETHER) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_ETHER", "epan/proto.c",
5466, ((hfinfo))->abbrev))))
;
5467
5468 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5469 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5470
5471 return pi;
5472}
5473
5474proto_item *
5475proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5476 int start, int length, const uint8_t* value,
5477 const char *format, ...)
5478{
5479 proto_item *pi;
5480 va_list ap;
5481
5482 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5483 if (pi != tree) {
5484 va_start(ap, format)__builtin_va_start(ap, format);
5485 proto_tree_set_representation_value(pi, format, ap);
5486 va_end(ap)__builtin_va_end(ap);
5487 }
5488
5489 return pi;
5490}
5491
5492proto_item *
5493proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5494 int start, int length, const uint8_t* value,
5495 const char *format, ...)
5496{
5497 proto_item *pi;
5498 va_list ap;
5499
5500 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5501 if (pi != tree) {
5502 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5502, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5503
5504 va_start(ap, format)__builtin_va_start(ap, format);
5505 proto_tree_set_representation(pi, format, ap);
5506 va_end(ap)__builtin_va_end(ap);
5507 }
5508
5509 return pi;
5510}
5511
5512/* Set the FT_ETHER value */
5513static void
5514proto_tree_set_ether(field_info *fi, const uint8_t* value)
5515{
5516 fvalue_set_ether(fi->value, value);
5517}
5518
5519static void
5520proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5521{
5522 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5523}
5524
5525/* Add a FT_BOOLEAN to a proto_tree */
5526proto_item *
5527proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5528 int length, uint64_t value)
5529{
5530 proto_item *pi;
5531 header_field_info *hfinfo;
5532
5533 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5534
5535 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5535
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5535, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5535, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5535, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5536
5537 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_BOOLEAN)((void) (((hfinfo)->type == FT_BOOLEAN) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_BOOLEAN", "epan/proto.c"
, 5537, ((hfinfo))->abbrev))))
;
5538
5539 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5540 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5541
5542 return pi;
5543}
5544
5545proto_item *
5546proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5547 tvbuff_t *tvb, int start, int length,
5548 uint64_t value, const char *format, ...)
5549{
5550 proto_item *pi;
5551 va_list ap;
5552
5553 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5554 if (pi != tree) {
5555 va_start(ap, format)__builtin_va_start(ap, format);
5556 proto_tree_set_representation_value(pi, format, ap);
5557 va_end(ap)__builtin_va_end(ap);
5558 }
5559
5560 return pi;
5561}
5562
5563proto_item *
5564proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5565 int start, int length, uint64_t value,
5566 const char *format, ...)
5567{
5568 proto_item *pi;
5569 va_list ap;
5570
5571 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5572 if (pi != tree) {
5573 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5573, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5574
5575 va_start(ap, format)__builtin_va_start(ap, format);
5576 proto_tree_set_representation(pi, format, ap);
5577 va_end(ap)__builtin_va_end(ap);
5578 }
5579
5580 return pi;
5581}
5582
5583/* Set the FT_BOOLEAN value */
5584static void
5585proto_tree_set_boolean(field_info *fi, uint64_t value)
5586{
5587 proto_tree_set_uint64(fi, value);
5588}
5589
5590/* Generate, into "buf", a string showing the bits of a bitfield.
5591 Return a pointer to the character after that string. */
5592static char *
5593other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5594{
5595 int i = 0;
5596 uint64_t bit;
5597 char *p;
5598
5599 p = buf;
5600
5601 /* This is a devel error. It is safer to stop here. */
5602 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5602, "width >= 1"
))))
;
5603
5604 bit = UINT64_C(1)1UL << (width - 1);
5605 for (;;) {
5606 if (mask & bit) {
5607 /* This bit is part of the field. Show its value. */
5608 if (val & bit)
5609 *p++ = '1';
5610 else
5611 *p++ = '0';
5612 } else {
5613 /* This bit is not part of the field. */
5614 *p++ = '.';
5615 }
5616 bit >>= 1;
5617 i++;
5618 if (i >= width)
5619 break;
5620 if (i % 4 == 0)
5621 *p++ = ' ';
5622 }
5623 *p = '\0';
5624 return p;
5625}
5626
5627static char *
5628decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5629{
5630 char *p;
5631
5632 p = other_decode_bitfield_value(buf, val, mask, width);
5633 p = g_stpcpy(p, " = ");
5634
5635 return p;
5636}
5637
5638static char *
5639other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5640{
5641 int i = 0;
5642 uint64_t bit;
5643 char *p;
5644
5645 p = buf;
5646
5647 /* This is a devel error. It is safer to stop here. */
5648 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5648, "width >= 1"
))))
;
5649
5650 bit = UINT64_C(1)1UL << (width - 1);
5651 for (;;) {
5652 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5653 (mask & bit)) {
5654 /* This bit is part of the field. Show its value. */
5655 if (val & bit)
5656 *p++ = '1';
5657 else
5658 *p++ = '0';
5659 } else {
5660 /* This bit is not part of the field. */
5661 *p++ = '.';
5662 }
5663 bit >>= 1;
5664 i++;
5665 if (i >= width)
5666 break;
5667 if (i % 4 == 0)
5668 *p++ = ' ';
5669 }
5670
5671 *p = '\0';
5672 return p;
5673}
5674
5675static char *
5676decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5677{
5678 char *p;
5679
5680 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5681 p = g_stpcpy(p, " = ");
5682
5683 return p;
5684}
5685
5686/* Add a FT_FLOAT to a proto_tree */
5687proto_item *
5688proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5689 int length, float value)
5690{
5691 proto_item *pi;
5692 header_field_info *hfinfo;
5693
5694 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5695
5696 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5696
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5696, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5696, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5696, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5697
5698 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_FLOAT)((void) (((hfinfo)->type == FT_FLOAT) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_FLOAT", "epan/proto.c",
5698, ((hfinfo))->abbrev))))
;
5699
5700 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5701 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5702
5703 return pi;
5704}
5705
5706proto_item *
5707proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5708 int start, int length, float value,
5709 const char *format, ...)
5710{
5711 proto_item *pi;
5712 va_list ap;
5713
5714 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5715 if (pi != tree) {
5716 va_start(ap, format)__builtin_va_start(ap, format);
5717 proto_tree_set_representation_value(pi, format, ap);
5718 va_end(ap)__builtin_va_end(ap);
5719 }
5720
5721 return pi;
5722}
5723
5724proto_item *
5725proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5726 int start, int length, float value,
5727 const char *format, ...)
5728{
5729 proto_item *pi;
5730 va_list ap;
5731
5732 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5733 if (pi != tree) {
5734 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5734, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5735
5736 va_start(ap, format)__builtin_va_start(ap, format);
5737 proto_tree_set_representation(pi, format, ap);
5738 va_end(ap)__builtin_va_end(ap);
5739 }
5740
5741 return pi;
5742}
5743
5744/* Set the FT_FLOAT value */
5745static void
5746proto_tree_set_float(field_info *fi, float value)
5747{
5748 fvalue_set_floating(fi->value, value);
5749}
5750
5751/* Add a FT_DOUBLE to a proto_tree */
5752proto_item *
5753proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5754 int length, double value)
5755{
5756 proto_item *pi;
5757 header_field_info *hfinfo;
5758
5759 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5760
5761 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5761
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5761, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5761, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5761, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5762
5763 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_DOUBLE)((void) (((hfinfo)->type == FT_DOUBLE) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_DOUBLE", "epan/proto.c"
, 5763, ((hfinfo))->abbrev))))
;
5764
5765 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5766 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5767
5768 return pi;
5769}
5770
5771proto_item *
5772proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5773 int start, int length, double value,
5774 const char *format, ...)
5775{
5776 proto_item *pi;
5777 va_list ap;
5778
5779 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5780 if (pi != tree) {
5781 va_start(ap, format)__builtin_va_start(ap, format);
5782 proto_tree_set_representation_value(pi, format, ap);
5783 va_end(ap)__builtin_va_end(ap);
5784 }
5785
5786 return pi;
5787}
5788
5789proto_item *
5790proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5791 int start, int length, double value,
5792 const char *format, ...)
5793{
5794 proto_item *pi;
5795 va_list ap;
5796
5797 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5798 if (pi != tree) {
5799 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5799, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5800
5801 va_start(ap, format)__builtin_va_start(ap, format);
5802 proto_tree_set_representation(pi, format, ap);
5803 va_end(ap)__builtin_va_end(ap);
5804 }
5805
5806 return pi;
5807}
5808
5809/* Set the FT_DOUBLE value */
5810static void
5811proto_tree_set_double(field_info *fi, double value)
5812{
5813 fvalue_set_floating(fi->value, value);
5814}
5815
5816/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5817proto_item *
5818proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5819 int length, uint32_t value)
5820{
5821 proto_item *pi = NULL((void*)0);
5822 header_field_info *hfinfo;
5823
5824 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5825
5826 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5826
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5826, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5826, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5826, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5827
5828 switch (hfinfo->type) {
5829 case FT_CHAR:
5830 case FT_UINT8:
5831 case FT_UINT16:
5832 case FT_UINT24:
5833 case FT_UINT32:
5834 case FT_FRAMENUM:
5835 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5836 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5837 break;
5838
5839 default:
5840 REPORT_DISSECTOR_BUG("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM",proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM"
, hfinfo->abbrev)
5841 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_CHAR, FT_UINT8, FT_UINT16, FT_UINT24, FT_UINT32, or FT_FRAMENUM"
, hfinfo->abbrev)
;
5842 }
5843
5844 return pi;
5845}
5846
5847proto_item *
5848proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5849 int start, int length, uint32_t value,
5850 const char *format, ...)
5851{
5852 proto_item *pi;
5853 va_list ap;
5854
5855 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5856 if (pi != tree) {
5857 va_start(ap, format)__builtin_va_start(ap, format);
5858 proto_tree_set_representation_value(pi, format, ap);
5859 va_end(ap)__builtin_va_end(ap);
5860 }
5861
5862 return pi;
5863}
5864
5865proto_item *
5866proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5867 int start, int length, uint32_t value,
5868 const char *format, ...)
5869{
5870 proto_item *pi;
5871 va_list ap;
5872
5873 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5874 if (pi != tree) {
5875 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5875, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5876
5877 va_start(ap, format)__builtin_va_start(ap, format);
5878 proto_tree_set_representation(pi, format, ap);
5879 va_end(ap)__builtin_va_end(ap);
5880 }
5881
5882 return pi;
5883}
5884
5885/* Set the FT_UINT{8,16,24,32} value */
5886static void
5887proto_tree_set_uint(field_info *fi, uint32_t value)
5888{
5889 const header_field_info *hfinfo;
5890 uint32_t integer;
5891
5892 hfinfo = fi->hfinfo;
5893 integer = value;
5894
5895 if (hfinfo->bitmask) {
5896 /* Mask out irrelevant portions */
5897 integer &= (uint32_t)(hfinfo->bitmask);
5898
5899 /* Shift bits */
5900 integer >>= hfinfo_bitshift(hfinfo);
5901
5902 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5903 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
5904 }
5905
5906 fvalue_set_uinteger(fi->value, integer);
5907}
5908
5909/* Add FT_UINT{40,48,56,64} to a proto_tree */
5910proto_item *
5911proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5912 int length, uint64_t value)
5913{
5914 proto_item *pi = NULL((void*)0);
5915 header_field_info *hfinfo;
5916
5917 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5918
5919 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5919
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5919, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5919, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5919, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
5920
5921 switch (hfinfo->type) {
5922 case FT_UINT40:
5923 case FT_UINT48:
5924 case FT_UINT56:
5925 case FT_UINT64:
5926 case FT_FRAMENUM:
5927 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5928 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5929 break;
5930
5931 default:
5932 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM",proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM"
, hfinfo->abbrev)
5933 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, FT_UINT64, or FT_FRAMENUM"
, hfinfo->abbrev)
;
5934 }
5935
5936 return pi;
5937}
5938
5939proto_item *
5940proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5941 int start, int length, uint64_t value,
5942 const char *format, ...)
5943{
5944 proto_item *pi;
5945 va_list ap;
5946
5947 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5948 if (pi != tree) {
5949 va_start(ap, format)__builtin_va_start(ap, format);
5950 proto_tree_set_representation_value(pi, format, ap);
5951 va_end(ap)__builtin_va_end(ap);
5952 }
5953
5954 return pi;
5955}
5956
5957proto_item *
5958proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5959 int start, int length, uint64_t value,
5960 const char *format, ...)
5961{
5962 proto_item *pi;
5963 va_list ap;
5964
5965 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5966 if (pi != tree) {
5967 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5967, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5968
5969 va_start(ap, format)__builtin_va_start(ap, format);
5970 proto_tree_set_representation(pi, format, ap);
5971 va_end(ap)__builtin_va_end(ap);
5972 }
5973
5974 return pi;
5975}
5976
5977/* Set the FT_UINT{40,48,56,64} value */
5978static void
5979proto_tree_set_uint64(field_info *fi, uint64_t value)
5980{
5981 const header_field_info *hfinfo;
5982 uint64_t integer;
5983
5984 hfinfo = fi->hfinfo;
5985 integer = value;
5986
5987 if (hfinfo->bitmask) {
5988 /* Mask out irrelevant portions */
5989 integer &= hfinfo->bitmask;
5990
5991 /* Shift bits */
5992 integer >>= hfinfo_bitshift(hfinfo);
5993
5994 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
5995 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
5996 }
5997
5998 fvalue_set_uinteger64(fi->value, integer);
5999}
6000
6001/* Add FT_INT{8,16,24,32} to a proto_tree */
6002proto_item *
6003proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6004 int length, int32_t value)
6005{
6006 proto_item *pi = NULL((void*)0);
6007 header_field_info *hfinfo;
6008
6009 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6010
6011 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6011
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6011, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6011, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6011, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
6012
6013 switch (hfinfo->type) {
6014 case FT_INT8:
6015 case FT_INT16:
6016 case FT_INT24:
6017 case FT_INT32:
6018 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6019 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6020 break;
6021
6022 default:
6023 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
6024 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6025 }
6026
6027 return pi;
6028}
6029
6030proto_item *
6031proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6032 int start, int length, int32_t value,
6033 const char *format, ...)
6034{
6035 proto_item *pi;
6036 va_list ap;
6037
6038 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6039 if (pi != tree) {
6040 va_start(ap, format)__builtin_va_start(ap, format);
6041 proto_tree_set_representation_value(pi, format, ap);
6042 va_end(ap)__builtin_va_end(ap);
6043 }
6044
6045 return pi;
6046}
6047
6048proto_item *
6049proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6050 int start, int length, int32_t value,
6051 const char *format, ...)
6052{
6053 proto_item *pi;
6054 va_list ap;
6055
6056 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6057 if (pi != tree) {
6058 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6058, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6059
6060 va_start(ap, format)__builtin_va_start(ap, format);
6061 proto_tree_set_representation(pi, format, ap);
6062 va_end(ap)__builtin_va_end(ap);
6063 }
6064
6065 return pi;
6066}
6067
6068/* Set the FT_INT{8,16,24,32} value */
6069static void
6070proto_tree_set_int(field_info *fi, int32_t value)
6071{
6072 const header_field_info *hfinfo;
6073 uint32_t integer;
6074 int no_of_bits;
6075
6076 hfinfo = fi->hfinfo;
6077 integer = (uint32_t) value;
6078
6079 if (hfinfo->bitmask) {
6080 /* Mask out irrelevant portions */
6081 integer &= (uint32_t)(hfinfo->bitmask);
6082
6083 /* Shift bits */
6084 integer >>= hfinfo_bitshift(hfinfo);
6085
6086 no_of_bits = ws_count_ones(hfinfo->bitmask);
6087 integer = ws_sign_ext32(integer, no_of_bits);
6088
6089 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6090 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
6091 }
6092
6093 fvalue_set_sinteger(fi->value, integer);
6094}
6095
6096/* Add FT_INT{40,48,56,64} to a proto_tree */
6097proto_item *
6098proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6099 int length, int64_t value)
6100{
6101 proto_item *pi = NULL((void*)0);
6102 header_field_info *hfinfo;
6103
6104 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6105
6106 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6106
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6106, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6106, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6106, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
6107
6108 switch (hfinfo->type) {
6109 case FT_INT40:
6110 case FT_INT48:
6111 case FT_INT56:
6112 case FT_INT64:
6113 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6114 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6115 break;
6116
6117 default:
6118 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
6119 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6120 }
6121
6122 return pi;
6123}
6124
6125proto_item *
6126proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6127 int start, int length, int64_t value,
6128 const char *format, ...)
6129{
6130 proto_item *pi;
6131 va_list ap;
6132
6133 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6134 if (pi != tree) {
6135 va_start(ap, format)__builtin_va_start(ap, format);
6136 proto_tree_set_representation_value(pi, format, ap);
6137 va_end(ap)__builtin_va_end(ap);
6138 }
6139
6140 return pi;
6141}
6142
6143/* Set the FT_INT{40,48,56,64} value */
6144static void
6145proto_tree_set_int64(field_info *fi, int64_t value)
6146{
6147 const header_field_info *hfinfo;
6148 uint64_t integer;
6149 int no_of_bits;
6150
6151 hfinfo = fi->hfinfo;
6152 integer = value;
6153
6154 if (hfinfo->bitmask) {
6155 /* Mask out irrelevant portions */
6156 integer &= hfinfo->bitmask;
6157
6158 /* Shift bits */
6159 integer >>= hfinfo_bitshift(hfinfo);
6160
6161 no_of_bits = ws_count_ones(hfinfo->bitmask);
6162 integer = ws_sign_ext64(integer, no_of_bits);
6163
6164 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 63) << 5)); } while(0)
;
6165 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 12)); } while(0)
;
6166 }
6167
6168 fvalue_set_sinteger64(fi->value, integer);
6169}
6170
6171proto_item *
6172proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6173 int start, int length, int64_t value,
6174 const char *format, ...)
6175{
6176 proto_item *pi;
6177 va_list ap;
6178
6179 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6180 if (pi != tree) {
6181 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6181, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6182
6183 va_start(ap, format)__builtin_va_start(ap, format);
6184 proto_tree_set_representation(pi, format, ap);
6185 va_end(ap)__builtin_va_end(ap);
6186 }
6187
6188 return pi;
6189}
6190
6191/* Add a FT_EUI64 to a proto_tree */
6192proto_item *
6193proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6194 int length, const uint64_t value)
6195{
6196 proto_item *pi;
6197 header_field_info *hfinfo;
6198
6199 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6200
6201 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6201
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6201, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6201, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6201, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
6202
6203 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_EUI64)((void) (((hfinfo)->type == FT_EUI64) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_EUI64", "epan/proto.c",
6203, ((hfinfo))->abbrev))))
;
6204
6205 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6206 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6207
6208 return pi;
6209}
6210
6211proto_item *
6212proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6213 int start, int length, const uint64_t value,
6214 const char *format, ...)
6215{
6216 proto_item *pi;
6217 va_list ap;
6218
6219 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6220 if (pi != tree) {
6221 va_start(ap, format)__builtin_va_start(ap, format);
6222 proto_tree_set_representation_value(pi, format, ap);
6223 va_end(ap)__builtin_va_end(ap);
6224 }
6225
6226 return pi;
6227}
6228
6229proto_item *
6230proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6231 int start, int length, const uint64_t value,
6232 const char *format, ...)
6233{
6234 proto_item *pi;
6235 va_list ap;
6236
6237 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6238 if (pi != tree) {
6239 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6239, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6240
6241 va_start(ap, format)__builtin_va_start(ap, format);
6242 proto_tree_set_representation(pi, format, ap);
6243 va_end(ap)__builtin_va_end(ap);
6244 }
6245
6246 return pi;
6247}
6248
6249/* Set the FT_EUI64 value */
6250static void
6251proto_tree_set_eui64(field_info *fi, const uint64_t value)
6252{
6253 uint8_t v[FT_EUI64_LEN8];
6254 phton64(v, value);
6255 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6256}
6257
6258static void
6259proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6260{
6261 if (encoding)
6262 {
6263 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6264 } else {
6265 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6266 }
6267}
6268
6269proto_item *
6270proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6271 const mac_hf_list_t *list_generic,
6272 int idx, tvbuff_t *tvb,
6273 proto_tree *tree, int offset)
6274{
6275 const uint8_t addr[6];
6276 const char *addr_name = NULL((void*)0);
6277 const char *oui_name = NULL((void*)0);
6278 proto_item *addr_item = NULL((void*)0);
6279 proto_tree *addr_tree = NULL((void*)0);
6280 proto_item *ret_val = NULL((void*)0);
6281
6282 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6283 return NULL((void*)0);
6284 }
6285
6286 /* Resolve what we can of the address */
6287 tvb_memcpy(tvb, (void *)addr, offset, 6);
6288 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6289 addr_name = get_ether_name(addr);
6290 }
6291 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6292 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6293 }
6294
6295 /* Add the item for the specific address type */
6296 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6297 if (idx >= 0) {
6298 addr_tree = proto_item_add_subtree(ret_val, idx);
6299 }
6300 else {
6301 addr_tree = tree;
6302 }
6303
6304 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6305 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6306 tvb, offset, 6, addr_name);
6307 proto_item_set_generated(addr_item);
6308 proto_item_set_hidden(addr_item);
6309 }
6310
6311 if (list_specific->hf_oui != NULL((void*)0)) {
6312 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6313 proto_item_set_generated(addr_item);
6314 proto_item_set_hidden(addr_item);
6315
6316 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6317 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6318 proto_item_set_generated(addr_item);
6319 proto_item_set_hidden(addr_item);
6320 }
6321 }
6322
6323 if (list_specific->hf_lg != NULL((void*)0)) {
6324 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6325 }
6326 if (list_specific->hf_ig != NULL((void*)0)) {
6327 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6328 }
6329
6330 /* Were we given a list for generic address fields? If not, stop here */
6331 if (list_generic == NULL((void*)0)) {
6332 return ret_val;
6333 }
6334
6335 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6336 proto_item_set_hidden(addr_item);
6337
6338 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6339 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6340 tvb, offset, 6, addr_name);
6341 proto_item_set_generated(addr_item);
6342 proto_item_set_hidden(addr_item);
6343 }
6344
6345 if (list_generic->hf_oui != NULL((void*)0)) {
6346 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6347 proto_item_set_generated(addr_item);
6348 proto_item_set_hidden(addr_item);
6349
6350 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6351 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6352 proto_item_set_generated(addr_item);
6353 proto_item_set_hidden(addr_item);
6354 }
6355 }
6356
6357 if (list_generic->hf_lg != NULL((void*)0)) {
6358 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6359 proto_item_set_hidden(addr_item);
6360 }
6361 if (list_generic->hf_ig != NULL((void*)0)) {
6362 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6363 proto_item_set_hidden(addr_item);
6364 }
6365 return ret_val;
6366}
6367
6368static proto_item *
6369proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6370{
6371 proto_node *pnode, *tnode, *sibling;
6372 field_info *tfi;
6373 unsigned depth = 1;
6374
6375 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6375, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6376
6377 /*
6378 * Restrict our depth. proto_tree_traverse_pre_order and
6379 * proto_tree_traverse_post_order (and possibly others) are recursive
6380 * so we need to be mindful of our stack size.
6381 */
6382 if (tree->first_child == NULL((void*)0)) {
6383 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6384 depth++;
6385 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6386 THROW_MESSAGE(DissectorError, wmem_strdup_printf(PNODE_POOL(tree),except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, hfinfo->name, hfinfo->abbrev
, ((const char*) (__func__)), 6389)))
6387 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, hfinfo->name, hfinfo->abbrev
, ((const char*) (__func__)), 6389)))
6388 prefs.gui_max_tree_depth,except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, hfinfo->name, hfinfo->abbrev
, ((const char*) (__func__)), 6389)))
6389 hfinfo->name, hfinfo->abbrev, G_STRFUNC, __LINE__))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, hfinfo->name, hfinfo->abbrev
, ((const char*) (__func__)), 6389)))
;
6390 }
6391 }
6392 }
6393
6394 /*
6395 * Make sure "tree" is ready to have subtrees under it, by
6396 * checking whether it's been given an ett_ value.
6397 *
6398 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6399 * node of the protocol tree. That node is not displayed,
6400 * so it doesn't need an ett_ value to remember whether it
6401 * was expanded.
6402 */
6403 tnode = tree;
6404 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6405 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6406 REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",proto_report_dissector_bug("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)"
, hfinfo->name, hfinfo->abbrev, tfi->tree_type, "epan/proto.c"
, 6407)
6407 hfinfo->name, hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__)proto_report_dissector_bug("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)"
, hfinfo->name, hfinfo->abbrev, tfi->tree_type, "epan/proto.c"
, 6407)
;
6408 /* XXX - is it safe to continue here? */
6409 }
6410
6411 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6412 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6413 pnode->parent = tnode;
6414 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6415 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6416 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6417
6418 if (tnode->last_child != NULL((void*)0)) {
6419 sibling = tnode->last_child;
6420 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6420, "sibling->next == ((void*)0)"
))))
;
6421 sibling->next = pnode;
6422 } else
6423 tnode->first_child = pnode;
6424 tnode->last_child = pnode;
6425
6426 /* We should not be adding a fake node for an interesting field */
6427 ws_assert(hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT)do { if ((1) && !(hfinfo->ref_type != HF_REF_TYPE_DIRECT
&& hfinfo->ref_type != HF_REF_TYPE_PRINT)) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6427, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6428
6429 /* XXX - Should the proto_item have a header_field_info member, at least
6430 * for faked items, to know what hfi was faked? (Some dissectors look at
6431 * the tree items directly.)
6432 */
6433 return (proto_item *)pnode;
6434}
6435
6436/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6437static proto_item *
6438proto_tree_add_node(proto_tree *tree, field_info *fi)
6439{
6440 proto_node *pnode, *tnode, *sibling;
6441 field_info *tfi;
6442 unsigned depth = 1;
6443
6444 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6444, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6445
6446 /*
6447 * Restrict our depth. proto_tree_traverse_pre_order and
6448 * proto_tree_traverse_post_order (and possibly others) are recursive
6449 * so we need to be mindful of our stack size.
6450 */
6451 if (tree->first_child == NULL((void*)0)) {
6452 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6453 depth++;
6454 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6455 fvalue_free(fi->value);
6456 fi->value = NULL((void*)0);
6457 THROW_MESSAGE(DissectorError, wmem_strdup_printf(PNODE_POOL(tree),except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, fi->hfinfo->name, fi->hfinfo
->abbrev, ((const char*) (__func__)), 6460)))
6458 "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, fi->hfinfo->name, fi->hfinfo
->abbrev, ((const char*) (__func__)), 6460)))
6459 prefs.gui_max_tree_depth,except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, fi->hfinfo->name, fi->hfinfo
->abbrev, ((const char*) (__func__)), 6460)))
6460 fi->hfinfo->name, fi->hfinfo->abbrev, G_STRFUNC, __LINE__))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data
->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)"
, prefs.gui_max_tree_depth, fi->hfinfo->name, fi->hfinfo
->abbrev, ((const char*) (__func__)), 6460)))
;
6461 }
6462 }
6463 }
6464
6465 /*
6466 * Make sure "tree" is ready to have subtrees under it, by
6467 * checking whether it's been given an ett_ value.
6468 *
6469 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6470 * node of the protocol tree. That node is not displayed,
6471 * so it doesn't need an ett_ value to remember whether it
6472 * was expanded.
6473 */
6474 tnode = tree;
6475 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6476 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6477 /* Since we are not adding fi to a node, its fvalue won't get
6478 * freed by proto_tree_free_node(), so free it now.
6479 */
6480 fvalue_free(fi->value);
6481 fi->value = NULL((void*)0);
6482 REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",proto_report_dissector_bug("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)"
, fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type
, "epan/proto.c", 6483)
6483 fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__)proto_report_dissector_bug("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)"
, fi->hfinfo->name, fi->hfinfo->abbrev, tfi->tree_type
, "epan/proto.c", 6483)
;
6484 /* XXX - is it safe to continue here? */
6485 }
6486
6487 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6488 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6489 pnode->parent = tnode;
6490 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6491 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6492 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6493
6494 if (tnode->last_child != NULL((void*)0)) {
6495 sibling = tnode->last_child;
6496 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6496, "sibling->next == ((void*)0)"
))))
;
6497 sibling->next = pnode;
6498 } else
6499 tnode->first_child = pnode;
6500 tnode->last_child = pnode;
6501
6502 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6503
6504 return (proto_item *)pnode;
6505}
6506
6507
6508/* Generic way to allocate field_info and add to proto_tree.
6509 * Sets *pfi to address of newly-allocated field_info struct */
6510static proto_item *
6511proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6512 int *length)
6513{
6514 proto_item *pi;
6515 field_info *fi;
6516 int item_length;
6517
6518 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6519 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6520 pi = proto_tree_add_node(tree, fi);
6521
6522 return pi;
6523}
6524
6525
6526static void
6527get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6528 int *item_length, const unsigned encoding)
6529{
6530 int length_remaining;
6531
6532 /*
6533 * We only allow a null tvbuff if the item has a zero length,
6534 * i.e. if there's no data backing it.
6535 */
6536 DISSECTOR_ASSERT(tvb != NULL || *length == 0)((void) ((tvb != ((void*)0) || *length == 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6536, "tvb != ((void*)0) || *length == 0"
))))
;
6537
6538 /*
6539 * XXX - in some protocols, there are 32-bit unsigned length
6540 * fields, so lengths in protocol tree and tvbuff routines
6541 * should really be unsigned. We should have, for those
6542 * field types for which "to the end of the tvbuff" makes sense,
6543 * additional routines that take no length argument and
6544 * add fields that run to the end of the tvbuff.
6545 */
6546 if (*length == -1) {
6547 /*
6548 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6549 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6550 * of -1 means "set the length to what remains in the
6551 * tvbuff".
6552 *
6553 * The assumption is either that
6554 *
6555 * 1) the length of the item can only be determined
6556 * by dissection (typically true of items with
6557 * subitems, which are probably FT_NONE or
6558 * FT_PROTOCOL)
6559 *
6560 * or
6561 *
6562 * 2) if the tvbuff is "short" (either due to a short
6563 * snapshot length or due to lack of reassembly of
6564 * fragments/segments/whatever), we want to display
6565 * what's available in the field (probably FT_BYTES
6566 * or FT_STRING) and then throw an exception later
6567 *
6568 * or
6569 *
6570 * 3) the field is defined to be "what's left in the
6571 * packet"
6572 *
6573 * so we set the length to what remains in the tvbuff so
6574 * that, if we throw an exception while dissecting, it
6575 * has what is probably the right value.
6576 *
6577 * For FT_STRINGZ, it means "the string is null-terminated,
6578 * not null-padded; set the length to the actual length
6579 * of the string", and if the tvbuff if short, we just
6580 * throw an exception.
6581 *
6582 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6583 * it means "find the end of the string",
6584 * and if the tvbuff if short, we just throw an exception.
6585 *
6586 * It's not valid for any other type of field. For those
6587 * fields, we treat -1 the same way we treat other
6588 * negative values - we assume the length is a Really
6589 * Big Positive Number, and throw a ReportedBoundsError
6590 * exception, under the assumption that the Really Big
6591 * Length would run past the end of the packet.
6592 */
6593 if ((FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
) || (FT_IS_UINT(hfinfo->type)(((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
) || ((hfinfo->type) == FT_UINT40 || (hfinfo->type) == FT_UINT48
|| (hfinfo->type) == FT_UINT56 || (hfinfo->type) == FT_UINT64
))
)) {
6594 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6595 /*
6596 * Leave the length as -1, so our caller knows
6597 * it was -1.
6598 */
6599 *item_length = *length;
6600 return;
6601 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6602 switch (tvb_get_uint8(tvb, start) >> 6)
6603 {
6604 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6605 *item_length = 1;
6606 break;
6607 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6608 *item_length = 2;
6609 break;
6610 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6611 *item_length = 4;
6612 break;
6613 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6614 *item_length = 8;
6615 break;
6616 }
6617 }
6618 }
6619
6620 switch (hfinfo->type) {
6621
6622 case FT_PROTOCOL:
6623 case FT_NONE:
6624 case FT_BYTES:
6625 case FT_STRING:
6626 case FT_STRINGZPAD:
6627 case FT_STRINGZTRUNC:
6628 /*
6629 * We allow FT_PROTOCOLs to be zero-length -
6630 * for example, an ONC RPC NULL procedure has
6631 * neither arguments nor reply, so the
6632 * payload for that protocol is empty.
6633 *
6634 * We also allow the others to be zero-length -
6635 * because that's the way the code has been for a
6636 * long, long time.
6637 *
6638 * However, we want to ensure that the start
6639 * offset is not *past* the byte past the end
6640 * of the tvbuff: we throw an exception in that
6641 * case.
6642 */
6643 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6644 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6644, "*length >= 0"
))))
;
6645 break;
6646
6647 case FT_STRINGZ:
6648 /*
6649 * Leave the length as -1, so our caller knows
6650 * it was -1.
6651 */
6652 break;
6653
6654 default:
6655 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6656 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6656))
;
6657 }
6658 *item_length = *length;
6659 } else {
6660 *item_length = *length;
6661 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6662 /*
6663 * These types are for interior nodes of the
6664 * tree, and don't have data associated with
6665 * them; if the length is negative (XXX - see
6666 * above) or goes past the end of the tvbuff,
6667 * cut it short at the end of the tvbuff.
6668 * That way, if this field is selected in
6669 * Wireshark, we don't highlight stuff past
6670 * the end of the data.
6671 */
6672 /* XXX - what to do, if we don't have a tvb? */
6673 if (tvb) {
6674 length_remaining = tvb_captured_length_remaining(tvb, start);
6675 if (*item_length < 0 ||
6676 (*item_length > 0 &&
6677 (length_remaining < *item_length)))
6678 *item_length = length_remaining;
6679 }
6680 }
6681 if (*item_length < 0) {
6682 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6683 }
6684 }
6685}
6686
6687static int
6688get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6689 int length, unsigned item_length, const int encoding)
6690{
6691 uint32_t n;
6692
6693 /*
6694 * We need to get the correct item length here.
6695 * That's normally done by proto_tree_new_item(),
6696 * but we won't be calling it.
6697 */
6698 switch (hfinfo->type) {
6699
6700 case FT_NONE:
6701 case FT_PROTOCOL:
6702 case FT_BYTES:
6703 /*
6704 * The length is the specified length.
6705 */
6706 break;
6707
6708 case FT_UINT_BYTES:
6709 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6710 item_length += n;
6711 if ((int)item_length < length) {
6712 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6713 }
6714 break;
6715
6716 /* XXX - make these just FT_UINT? */
6717 case FT_UINT8:
6718 case FT_UINT16:
6719 case FT_UINT24:
6720 case FT_UINT32:
6721 case FT_UINT40:
6722 case FT_UINT48:
6723 case FT_UINT56:
6724 case FT_UINT64:
6725 /* XXX - make these just FT_INT? */
6726 case FT_INT8:
6727 case FT_INT16:
6728 case FT_INT24:
6729 case FT_INT32:
6730 case FT_INT40:
6731 case FT_INT48:
6732 case FT_INT56:
6733 case FT_INT64:
6734 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6735 if (length < -1) {
6736 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6737 }
6738 if (length == -1) {
6739 uint64_t dummy;
6740 /* This can throw an exception */
6741 /* XXX - do this without fetching the varint? */
6742 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6743 if (length == 0) {
6744 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6745 }
6746 }
6747 item_length = length;
6748 break;
6749 }
6750
6751 /*
6752 * The length is the specified length.
6753 */
6754 break;
6755
6756 case FT_BOOLEAN:
6757 case FT_CHAR:
6758 case FT_IPv4:
6759 case FT_IPXNET:
6760 case FT_IPv6:
6761 case FT_FCWWN:
6762 case FT_AX25:
6763 case FT_VINES:
6764 case FT_ETHER:
6765 case FT_EUI64:
6766 case FT_GUID:
6767 case FT_OID:
6768 case FT_REL_OID:
6769 case FT_SYSTEM_ID:
6770 case FT_FLOAT:
6771 case FT_DOUBLE:
6772 case FT_STRING:
6773 /*
6774 * The length is the specified length.
6775 */
6776 break;
6777
6778 case FT_STRINGZ:
6779 if (length < -1) {
6780 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6781 }
6782 if (length == -1) {
6783 /* This can throw an exception */
6784 /* XXX - do this without fetching the string? */
6785 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6786 }
6787 item_length = length;
6788 break;
6789
6790 case FT_UINT_STRING:
6791 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6792 item_length += n;
6793 if ((int)item_length < length) {
6794 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6795 }
6796 break;
6797
6798 case FT_STRINGZPAD:
6799 case FT_STRINGZTRUNC:
6800 case FT_ABSOLUTE_TIME:
6801 case FT_RELATIVE_TIME:
6802 case FT_IEEE_11073_SFLOAT:
6803 case FT_IEEE_11073_FLOAT:
6804 /*
6805 * The length is the specified length.
6806 */
6807 break;
6808
6809 default:
6810 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in gset_full_length()",proto_report_dissector_bug("field %s has type %d (%s) not handled in gset_full_length()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
6811 hfinfo->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in gset_full_length()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
6812 hfinfo->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in gset_full_length()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
6813 ftype_name(hfinfo->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in gset_full_length()"
, hfinfo->abbrev, hfinfo->type, ftype_name(hfinfo->type
))
;
6814 break;
6815 }
6816 return item_length;
6817}
6818
6819// This was arbitrarily chosen, but if you're adding 50K items to the tree
6820// without advancing the offset you should probably take a long, hard look
6821// at what you're doing.
6822// We *could* make this a configurable option, but I (Gerald) would like to
6823// avoid adding yet another nerd knob.
6824# define PROTO_TREE_MAX_IDLE50000 50000
6825static field_info *
6826new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6827 const int start, const int item_length)
6828{
6829 field_info *fi;
6830
6831 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6832
6833 fi->hfinfo = hfinfo;
6834 fi->start = start;
6835 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6836 // If our start offset hasn't advanced after adding many items it probably
6837 // means we're in a large or infinite loop.
6838 if (fi->start > 0) {
6839 if (fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6840 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6841 DISSECTOR_ASSERT_HINT(PTREE_DATA(tree)->start_idle_count < PROTO_TREE_MAX_IDLE, fi->hfinfo->abbrev)((void) ((((tree)->tree_data)->start_idle_count < 50000
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6841, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6842 } else {
6843 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6844 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6845 }
6846 }
6847 fi->length = item_length;
6848 fi->tree_type = -1;
6849 fi->flags = 0;
6850 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6851 /* If the tree is not visible, set the item hidden, unless we
6852 * need the representation or length and can't fake them.
6853 */
6854 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6855 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6856 }
6857 }
6858 fi->value = fvalue_new(fi->hfinfo->type);
6859 fi->rep = NULL((void*)0);
6860
6861 /* add the data source tvbuff */
6862 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6863
6864 fi->appendix_start = 0;
6865 fi->appendix_length = 0;
6866
6867 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6868 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6869
6870 return fi;
6871}
6872
6873static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6874{
6875 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6876 return 0;
6877 }
6878
6879 /* Search for field name */
6880 char *ptr = strstr(representation, hfinfo->name);
6881 if (!ptr) {
6882 return 0;
6883 }
6884
6885 /* Check if field name ends with the ": " delimiter */
6886 ptr += strlen(hfinfo->name);
6887 if (strncmp(ptr, ": ", 2) == 0) {
6888 ptr += 2;
6889 }
6890
6891 /* Return offset to after field name */
6892 return ptr - representation;
6893}
6894
6895/* If the protocol tree is to be visible, set the representation of a
6896 proto_tree entry with the name of the field for the item and with
6897 the value formatted with the supplied printf-style format and
6898 argument list. */
6899static void
6900proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6901{
6902 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6902, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6903
6904 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6905 * items string representation */
6906 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6907 size_t name_pos, ret = 0;
6908 char *str;
6909 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6910 const header_field_info *hf;
6911
6912 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6912, "fi"))))
;
6913
6914 hf = fi->hfinfo;
6915
6916 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep)fi->rep = ((item_label_t*)wmem_alloc((((pi)->tree_data->
pinfo->pool)), sizeof(item_label_t))); fi->rep->value_pos
= 0; fi->rep->value_len = 0;
;
6917 if (hf->bitmask && (hf->type == FT_BOOLEAN || FT_IS_UINT(hf->type)(((hf->type) == FT_CHAR || (hf->type) == FT_UINT8 || (hf
->type) == FT_UINT16 || (hf->type) == FT_UINT24 || (hf->
type) == FT_UINT32 || (hf->type) == FT_FRAMENUM) || ((hf->
type) == FT_UINT40 || (hf->type) == FT_UINT48 || (hf->type
) == FT_UINT56 || (hf->type) == FT_UINT64))
)) {
6918 uint64_t val;
6919 char *p;
6920
6921 if (FT_IS_UINT32(hf->type)((hf->type) == FT_CHAR || (hf->type) == FT_UINT8 || (hf
->type) == FT_UINT16 || (hf->type) == FT_UINT24 || (hf->
type) == FT_UINT32 || (hf->type) == FT_FRAMENUM)
)
6922 val = fvalue_get_uinteger(fi->value);
6923 else
6924 val = fvalue_get_uinteger64(fi->value);
6925
6926 val <<= hfinfo_bitshift(hf);
6927
6928 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6929 ret = (p - fi->rep->representation);
6930 }
6931
6932 /* put in the hf name */
6933 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
6934
6935 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
6936 /* If possible, Put in the value of the string */
6937 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6938 WS_UTF_8_CHECK(str, -1)do { const char *__uni_endptr; if (1 && (str) != ((void
*)0) && !g_utf8_validate(str, -1, &__uni_endptr))
{ do { if (1) { ws_log_utf8_full("UTF-8", LOG_LEVEL_DEBUG, "epan/proto.c"
, 6938, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6939 fi->rep->value_pos = ret;
6940 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
6941 if (ret >= ITEM_LABEL_LENGTH240) {
6942 /* Uh oh, we don't have enough room. Tell the user
6943 * that the field is truncated.
6944 */
6945 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6946 }
6947 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6948 }
6949}
6950
6951/* If the protocol tree is to be visible, set the representation of a
6952 proto_tree entry with the representation formatted with the supplied
6953 printf-style format and argument list. */
6954static void
6955proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6956{
6957 size_t ret; /*tmp return value */
6958 char *str;
6959 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6960
6961 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6961, "fi"))))
;
6962
6963 if (!proto_item_is_hidden(pi)) {
6964 ITEM_LABEL_NEW(PNODE_POOL(pi), fi->rep)fi->rep = ((item_label_t*)wmem_alloc((((pi)->tree_data->
pinfo->pool)), sizeof(item_label_t))); fi->rep->value_pos
= 0; fi->rep->value_len = 0;
;
6965
6966 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6967 WS_UTF_8_CHECK(str, -1)do { const char *__uni_endptr; if (1 && (str) != ((void
*)0) && !g_utf8_validate(str, -1, &__uni_endptr))
{ do { if (1) { ws_log_utf8_full("UTF-8", LOG_LEVEL_DEBUG, "epan/proto.c"
, 6967, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6968 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
6969 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
6970 if (ret >= ITEM_LABEL_LENGTH240) {
6971 /* Uh oh, we don't have enough room. Tell the user
6972 * that the field is truncated.
6973 */
6974 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
6975 }
6976 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6977 }
6978}
6979
6980static int
6981proto_strlcpy(char *dest, const char *src, size_t dest_size)
6982{
6983 if (dest_size == 0) return 0;
6984
6985 size_t res = g_strlcpy(dest, src, dest_size);
6986
6987 /* At most dest_size - 1 characters will be copied
6988 * (unless dest_size is 0). */
6989 if (res >= dest_size)
6990 res = dest_size - 1;
6991 return (int) res;
6992}
6993
6994static header_field_info *
6995hfinfo_same_name_get_prev(const header_field_info *hfinfo)
6996{
6997 header_field_info *dup_hfinfo;
6998
6999 if (hfinfo->same_name_prev_id == -1)
7000 return NULL((void*)0);
7001 PROTO_REGISTRAR_GET_NTH(hfinfo->same_name_prev_id, dup_hfinfo)if((hfinfo->same_name_prev_id == 0 || (unsigned)hfinfo->
same_name_prev_id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7001
, __func__, "Unregistered hf! index=%d", hfinfo->same_name_prev_id
); ((void) ((hfinfo->same_name_prev_id > 0 && (
unsigned)hfinfo->same_name_prev_id < gpa_hfinfo.len) ? (
void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 7001, "hfinfo->same_name_prev_id > 0 && (unsigned)hfinfo->same_name_prev_id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
same_name_prev_id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7001,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7002 return dup_hfinfo;
7003}
7004
7005static void
7006hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7007{
7008 g_free(last_field_name);
7009 last_field_name = NULL((void*)0);
7010
7011 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7012 /* No hfinfo with the same name */
7013 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
7014 return;
7015 }
7016
7017 if (hfinfo->same_name_next) {
7018 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7019 }
7020
7021 if (hfinfo->same_name_prev_id != -1) {
7022 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7023 same_name_prev->same_name_next = hfinfo->same_name_next;
7024 if (!hfinfo->same_name_next) {
7025 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7026 g_hash_table_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7027 }
7028 }
7029}
7030
7031int
7032proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7033{
7034 const header_field_info *hfinfo = finfo->hfinfo;
7035 int label_len = 0;
7036 char *tmp_str;
7037 const char *str;
7038 const uint8_t *bytes;
7039 uint32_t number;
7040 uint64_t number64;
7041 const char *hf_str_val;
7042 char number_buf[NUMBER_LABEL_LENGTH80];
7043 const char *number_out;
7044 address addr;
7045 const ipv4_addr_and_mask *ipv4;
7046 const ipv6_addr_and_prefix *ipv6;
7047
7048 switch (hfinfo->type) {
7049
7050 case FT_NONE:
7051 case FT_PROTOCOL:
7052 return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7053
7054 case FT_UINT_BYTES:
7055 case FT_BYTES:
7056 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7057 hfinfo,
7058 fvalue_get_bytes_data(finfo->value),
7059 (unsigned)fvalue_length2(finfo->value),
7060 label_str_size);
7061 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7062 wmem_free(NULL((void*)0), tmp_str);
7063 break;
7064
7065 case FT_ABSOLUTE_TIME:
7066 {
7067 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7068 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7069 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7070 }
7071 tmp_str = abs_time_to_str_ex(NULL((void*)0), fvalue_get_time(finfo->value), hfinfo->display, flags);
7072 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7073 wmem_free(NULL((void*)0), tmp_str);
7074 break;
7075 }
7076
7077 case FT_RELATIVE_TIME:
7078 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7079 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7080 wmem_free(NULL((void*)0), tmp_str);
7081 break;
7082
7083 case FT_BOOLEAN:
7084 number64 = fvalue_get_uinteger64(finfo->value);
7085 label_len = proto_strlcpy(display_label_str,
7086 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7087 break;
7088
7089 case FT_CHAR:
7090 number = fvalue_get_uinteger(finfo->value);
7091
7092 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7093 char tmp[ITEM_LABEL_LENGTH240];
7094 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7095
7096 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7096, "fmtfunc"))))
;
7097 fmtfunc(tmp, number);
7098
7099 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7100
7101 } else if (hfinfo->strings) {
7102 number_out = hf_try_val_to_str(number, hfinfo);
7103
7104 if (!number_out) {
7105 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7106 }
7107
7108 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7109
7110 } else {
7111 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7112
7113 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7114 }
7115
7116 break;
7117
7118 /* XXX - make these just FT_NUMBER? */
7119 case FT_INT8:
7120 case FT_INT16:
7121 case FT_INT24:
7122 case FT_INT32:
7123 case FT_UINT8:
7124 case FT_UINT16:
7125 case FT_UINT24:
7126 case FT_UINT32:
7127 case FT_FRAMENUM:
7128 hf_str_val = NULL((void*)0);
7129 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
))
?
7130 (uint32_t) fvalue_get_sinteger(finfo->value) :
7131 fvalue_get_uinteger(finfo->value);
7132
7133 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7134 char tmp[ITEM_LABEL_LENGTH240];
7135 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7136
7137 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7137, "fmtfunc"))))
;
7138 fmtfunc(tmp, number);
7139
7140 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7141
7142 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7143 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7144 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7145 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7146 hf_str_val = hf_try_val_to_str(number, hfinfo);
7147 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7148 } else {
7149 number_out = hf_try_val_to_str(number, hfinfo);
7150
7151 if (!number_out) {
7152 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7153 }
7154
7155 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7156 }
7157 } else {
7158 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7159
7160 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7161 }
7162
7163 break;
7164
7165 case FT_INT40:
7166 case FT_INT48:
7167 case FT_INT56:
7168 case FT_INT64:
7169 case FT_UINT40:
7170 case FT_UINT48:
7171 case FT_UINT56:
7172 case FT_UINT64:
7173 hf_str_val = NULL((void*)0);
7174 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
))
?
7175 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7176 fvalue_get_uinteger64(finfo->value);
7177
7178 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7179 char tmp[ITEM_LABEL_LENGTH240];
7180 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7181
7182 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7182, "fmtfunc64"
))))
;
7183 fmtfunc64(tmp, number64);
7184
7185 label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7186 } else if (hfinfo->strings) {
7187 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7188 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7189 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7190 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7191 label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7192 } else {
7193 number_out = hf_try_val64_to_str(number64, hfinfo);
7194
7195 if (!number_out)
7196 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7197
7198 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7199 }
7200 } else {
7201 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7202
7203 label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7204 }
7205
7206 break;
7207
7208 case FT_EUI64:
7209 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7210 tmp_str = address_to_display(NULL((void*)0), &addr);
7211 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7212 wmem_free(NULL((void*)0), tmp_str);
7213 break;
7214
7215 case FT_IPv4:
7216 ipv4 = fvalue_get_ipv4(finfo->value);
7217 //XXX: Should we ignore the mask?
7218 set_address_ipv4(&addr, ipv4);
7219 tmp_str = address_to_display(NULL((void*)0), &addr);
7220 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7221 wmem_free(NULL((void*)0), tmp_str);
7222 free_address(&addr);
7223 break;
7224
7225 case FT_IPv6:
7226 ipv6 = fvalue_get_ipv6(finfo->value);
7227 set_address_ipv6(&addr, ipv6);
7228 tmp_str = address_to_display(NULL((void*)0), &addr);
7229 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7230 wmem_free(NULL((void*)0), tmp_str);
7231 free_address(&addr);
7232 break;
7233
7234 case FT_FCWWN:
7235 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7236 tmp_str = address_to_display(NULL((void*)0), &addr);
7237 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7238 wmem_free(NULL((void*)0), tmp_str);
7239 break;
7240
7241 case FT_ETHER:
7242 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7243 tmp_str = address_to_display(NULL((void*)0), &addr);
7244 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7245 wmem_free(NULL((void*)0), tmp_str);
7246 break;
7247
7248 case FT_GUID:
7249 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7250 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7251 wmem_free(NULL((void*)0), tmp_str);
7252 break;
7253
7254 case FT_REL_OID:
7255 bytes = fvalue_get_bytes_data(finfo->value);
7256 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
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_OID:
7262 bytes = fvalue_get_bytes_data(finfo->value);
7263 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
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_SYSTEM_ID:
7269 bytes = fvalue_get_bytes_data(finfo->value);
7270 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7271 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7272 wmem_free(NULL((void*)0), tmp_str);
7273 break;
7274
7275 case FT_FLOAT:
7276 case FT_DOUBLE:
7277 label_len = (int)fill_display_label_float(finfo, display_label_str);
7278 break;
7279
7280 case FT_IEEE_11073_SFLOAT:
7281 case FT_IEEE_11073_FLOAT:
7282 label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str);
7283 break;
7284
7285 case FT_STRING:
7286 case FT_STRINGZ:
7287 case FT_UINT_STRING:
7288 case FT_STRINGZPAD:
7289 case FT_STRINGZTRUNC:
7290 str = fvalue_get_string(finfo->value);
7291 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7292 if (label_len >= label_str_size) {
7293 /* Truncation occurred. Get the real length
7294 * copied (not including '\0') */
7295 label_len = label_str_size ? label_str_size - 1 : 0;
7296 }
7297 break;
7298
7299 default:
7300 /* First try ftype string representation */
7301 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7302 if (!tmp_str) {
7303 /* Default to show as bytes */
7304 bytes = fvalue_get_bytes_data(finfo->value);
7305 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7306 }
7307 label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7308 wmem_free(NULL((void*)0), tmp_str);
7309 break;
7310 }
7311 return label_len;
7312}
7313
7314const char *
7315proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7316 char *result, char *expr, const int size)
7317{
7318 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7319 GPtrArray *finfos;
7320 field_info *finfo = NULL((void*)0);
7321 header_field_info* hfinfo;
7322 const char *abbrev = NULL((void*)0);
7323
7324 char *str;
7325 col_custom_t *field_idx;
7326 int field_id;
7327 int ii = 0;
7328
7329 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7329, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7330 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7331 field_id = field_idx->field_id;
7332 if (field_id == 0) {
7333 GPtrArray *fvals = NULL((void*)0);
7334 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7335 if (fvals != NULL((void*)0)) {
7336
7337 // XXX - Handling occurrences is unusual when more
7338 // than one field is involved, e.g. there's four
7339 // results for tcp.port + tcp.port. We may really
7340 // want to apply it to the operands, not the output.
7341 // Note that occurrences are not quite the same as
7342 // the layer operator (should the grammar support
7343 // both?)
7344 /* Calculate single index or set outer boundaries */
7345 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7346 if (occurrence < 0) {
7347 i = occurrence + len;
7348 last = i;
7349 } else if (occurrence > 0) {
7350 i = occurrence - 1;
7351 last = i;
7352 } else {
7353 i = 0;
7354 last = len - 1;
7355 }
7356 if (i < 0 || i >= len) {
7357 g_ptr_array_unref(fvals);
7358 continue;
7359 }
7360 for (; i <= last; i++) {
7361 /* XXX - We could have a "resolved" result
7362 * for types where the value depends only
7363 * on the type, e.g. FT_IPv4, and not on
7364 * hfinfo->strings. Supporting the latter
7365 * requires knowing which hfinfo matched
7366 * if there are multiple with the same
7367 * abbreviation. In any case, we need to
7368 * know the expected return type of the
7369 * field expression.
7370 */
7371 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7372 if (offset_r && (offset_r < (size - 1)))
7373 result[offset_r++] = ',';
7374 if (offset_e && (offset_e < (size - 1)))
7375 expr[offset_e++] = ',';
7376 offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7377 // col_{add,append,set}_* calls ws_label_strcpy
7378 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7379
7380 g_free(str);
7381 }
7382 g_ptr_array_unref(fvals);
7383 } else if (passed) {
7384 // XXX - Occurrence doesn't make sense for a test
7385 // output, it should be applied to the operands.
7386 if (offset_r && (offset_r < (size - 1)))
7387 result[offset_r++] = ',';
7388 if (offset_e && (offset_e < (size - 1)))
7389 expr[offset_e++] = ',';
7390 /* Prevent multiple check marks */
7391 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7392 offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7393 } else {
7394 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7395 }
7396 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7397 offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7398 } else {
7399 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7400 }
7401 }
7402 continue;
7403 }
7404 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", 7404
, __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", 7404,
"(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", 7404,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7405
7406 /* do we need to rewind ? */
7407 if (!hfinfo)
7408 return "";
7409
7410 if (occurrence < 0) {
7411 /* Search other direction */
7412 while (hfinfo->same_name_prev_id != -1) {
7413 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", 7413
, __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", 7413, "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", 7413,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7414 }
7415 }
7416
7417 prev_len = 0; /* Reset handled occurrences */
7418
7419 while (hfinfo) {
7420 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7421
7422 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7423 if (occurrence < 0) {
7424 hfinfo = hfinfo->same_name_next;
7425 } else {
7426 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7427 }
7428 continue;
7429 }
7430
7431 /* Are there enough occurrences of the field? */
7432 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7433 if (occurrence < 0) {
7434 hfinfo = hfinfo->same_name_next;
7435 } else {
7436 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7437 }
7438 prev_len += len;
7439 continue;
7440 }
7441
7442 /* Calculate single index or set outer boundaries */
7443 if (occurrence < 0) {
7444 i = occurrence + len + prev_len;
7445 last = i;
7446 } else if (occurrence > 0) {
7447 i = occurrence - 1 - prev_len;
7448 last = i;
7449 } else {
7450 i = 0;
7451 last = len - 1;
7452 }
7453
7454 prev_len += len; /* Count handled occurrences */
7455
7456 while (i <= last) {
7457 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7458
7459 if (offset_r && (offset_r < (size - 1)))
7460 result[offset_r++] = ',';
7461
7462 if (display_details) {
7463 char representation[ITEM_LABEL_LENGTH240];
7464 size_t offset = 0;
7465
7466 if (finfo->rep && finfo->rep->value_len) {
7467 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7468 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7469 } else {
7470 proto_item_fill_label(finfo, representation, &offset);
7471 }
7472 offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7473 } else {
7474 switch (hfinfo->type) {
7475
7476 case FT_NONE:
7477 case FT_PROTOCOL:
7478 /* Prevent multiple check marks */
7479 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7480 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7481 } else {
7482 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7483 }
7484 break;
7485
7486 default:
7487 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7488 break;
7489 }
7490 }
7491
7492 if (offset_e && (offset_e < (size - 1)))
7493 expr[offset_e++] = ',';
7494
7495 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
))
)) {
7496 const char *hf_str_val;
7497 /* Integer types with BASE_NONE never get the numeric value. */
7498 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7499 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7500 } 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
)
) {
7501 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7502 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7503 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7504 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7505 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7506 }
7507 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7508 offset_e = (int)strlen(expr);
7509 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7510 /* Prevent multiple check marks */
7511 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7512 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7513 } else {
7514 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7515 }
7516 } else {
7517 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7518 // col_{add,append,set}_* calls ws_label_strcpy
7519 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7520 wmem_free(NULL((void*)0), str);
7521 }
7522 i++;
7523 }
7524
7525 /* XXX: Why is only the first abbreviation returned for a multifield
7526 * custom column? */
7527 if (!abbrev) {
7528 /* Store abbrev for return value */
7529 abbrev = hfinfo->abbrev;
7530 }
7531
7532 if (occurrence == 0) {
7533 /* Fetch next hfinfo with same name (abbrev) */
7534 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7535 } else {
7536 hfinfo = NULL((void*)0);
7537 }
7538 }
7539 }
7540
7541 if (offset_r >= (size - 1)) {
7542 mark_truncated(result, 0, size, NULL((void*)0));
7543 }
7544 if (offset_e >= (size - 1)) {
7545 mark_truncated(expr, 0, size, NULL((void*)0));
7546 }
7547 return abbrev ? abbrev : "";
7548}
7549
7550char *
7551proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7552{
7553 int len, prev_len, last, i;
7554 GPtrArray *finfos;
7555 field_info *finfo = NULL((void*)0);
7556 header_field_info* hfinfo;
7557
7558 char *filter = NULL((void*)0);
7559 GPtrArray *filter_array;
7560
7561 col_custom_t *col_custom;
7562 int field_id;
7563
7564 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7564, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7565 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7566 for (GSList *iter = field_ids; iter; iter = iter->next) {
7567 col_custom = (col_custom_t*)iter->data;
7568 field_id = col_custom->field_id;
7569 if (field_id == 0) {
7570 GPtrArray *fvals = NULL((void*)0);
7571 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7572 if (fvals != NULL((void*)0)) {
7573 // XXX - Handling occurrences is unusual when more
7574 // than one field is involved, e.g. there's four
7575 // results for tcp.port + tcp.port. We really
7576 // want to apply it to the operands, not the output.
7577 /* Calculate single index or set outer boundaries */
7578 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7579 if (occurrence < 0) {
7580 i = occurrence + len;
7581 last = i;
7582 } else if (occurrence > 0) {
7583 i = occurrence - 1;
7584 last = i;
7585 } else {
7586 i = 0;
7587 last = len - 1;
7588 }
7589 if (i < 0 || i >= len) {
7590 g_ptr_array_unref(fvals);
7591 continue;
7592 }
7593 for (; i <= last; i++) {
7594 /* XXX - Should multiple values for one
7595 * field use set membership to reduce
7596 * verbosity, here and below? */
7597 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7598 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7599 wmem_free(NULL((void*)0), str);
7600 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7601 g_ptr_array_add(filter_array, filter);
7602 }
7603 }
7604 g_ptr_array_unref(fvals);
7605 } else if (passed) {
7606 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7607 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7608 g_ptr_array_add(filter_array, filter);
7609 }
7610 } else {
7611 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7612 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7613 g_ptr_array_add(filter_array, filter);
7614 }
7615 }
7616 continue;
7617 }
7618
7619 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", 7619
, __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", 7619,
"(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", 7619,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7620
7621 /* do we need to rewind ? */
7622 if (!hfinfo)
7623 return NULL((void*)0);
7624
7625 if (occurrence < 0) {
7626 /* Search other direction */
7627 while (hfinfo->same_name_prev_id != -1) {
7628 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", 7628
, __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", 7628, "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", 7628,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7629 }
7630 }
7631
7632 prev_len = 0; /* Reset handled occurrences */
7633
7634 while (hfinfo) {
7635 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7636
7637 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7638 if (occurrence < 0) {
7639 hfinfo = hfinfo->same_name_next;
7640 } else {
7641 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7642 }
7643 continue;
7644 }
7645
7646 /* Are there enough occurrences of the field? */
7647 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7648 if (occurrence < 0) {
7649 hfinfo = hfinfo->same_name_next;
7650 } else {
7651 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7652 }
7653 prev_len += len;
7654 continue;
7655 }
7656
7657 /* Calculate single index or set outer boundaries */
7658 if (occurrence < 0) {
7659 i = occurrence + len + prev_len;
7660 last = i;
7661 } else if (occurrence > 0) {
7662 i = occurrence - 1 - prev_len;
7663 last = i;
7664 } else {
7665 i = 0;
7666 last = len - 1;
7667 }
7668
7669 prev_len += len; /* Count handled occurrences */
7670
7671 while (i <= last) {
7672 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7673
7674 filter = proto_construct_match_selected_string(finfo, edt);
7675 if (filter) {
7676 /* Only add the same expression once (especially for FT_PROTOCOL).
7677 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7678 */
7679 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7680 g_ptr_array_add(filter_array, filter);
7681 }
7682 }
7683 i++;
7684 }
7685
7686 if (occurrence == 0) {
7687 /* Fetch next hfinfo with same name (abbrev) */
7688 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7689 } else {
7690 hfinfo = NULL((void*)0);
7691 }
7692 }
7693 }
7694
7695 g_ptr_array_add(filter_array, NULL((void*)0));
7696
7697 /* XXX: Should this be || or && ? */
7698 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7699
7700 g_ptr_array_free(filter_array, true1);
7701
7702 return output;
7703}
7704
7705/* Set text of proto_item after having already been created. */
7706void
7707proto_item_set_text(proto_item *pi, const char *format, ...)
7708{
7709 field_info *fi = NULL((void*)0);
7710 va_list ap;
7711
7712 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7713
7714 fi = PITEM_FINFO(pi)((pi)->finfo);
7715 if (fi == NULL((void*)0))
7716 return;
7717
7718 if (fi->rep) {
7719 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7720 fi->rep = NULL((void*)0);
7721 }
7722
7723 va_start(ap, format)__builtin_va_start(ap, format);
7724 proto_tree_set_representation(pi, format, ap);
7725 va_end(ap)__builtin_va_end(ap);
7726}
7727
7728/* Append to text of proto_item after having already been created. */
7729void
7730proto_item_append_text(proto_item *pi, const char *format, ...)
7731{
7732 field_info *fi = NULL((void*)0);
7733 size_t curlen;
7734 char *str;
7735 va_list ap;
7736
7737 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7738
7739 fi = PITEM_FINFO(pi)((pi)->finfo);
7740 if (fi == NULL((void*)0)) {
7741 return;
7742 }
7743
7744 if (!proto_item_is_hidden(pi)) {
7745 /*
7746 * If we don't already have a representation,
7747 * generate the default representation.
7748 */
7749 if (fi->rep == NULL((void*)0)) {
7750 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;
;
7751 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7752 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7753 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7754 (strncmp(format, ": ", 2) == 0)) {
7755 fi->rep->value_pos += 2;
7756 }
7757 }
7758 if (fi->rep) {
7759 curlen = strlen(fi->rep->representation);
7760 /* curlen doesn't include the \0 byte.
7761 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7762 * the representation has already been truncated (of an up
7763 * to 4 byte UTF-8 character) or is just at the maximum length
7764 * unless we search for " [truncated]" (which may not be
7765 * at the start.)
7766 * It's safer to do nothing.
7767 */
7768 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7769 va_start(ap, format)__builtin_va_start(ap, format);
7770 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7771 va_end(ap)__builtin_va_end(ap);
7772 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"
, 7772, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7773 /* Keep fi->rep->value_pos */
7774 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7775 if (curlen >= ITEM_LABEL_LENGTH240) {
7776 /* Uh oh, we don't have enough room. Tell the user
7777 * that the field is truncated.
7778 */
7779 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7780 }
7781 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7782 }
7783 }
7784 }
7785}
7786
7787/* Prepend to text of proto_item after having already been created. */
7788void
7789proto_item_prepend_text(proto_item *pi, const char *format, ...)
7790{
7791 field_info *fi = NULL((void*)0);
7792 size_t pos;
7793 char representation[ITEM_LABEL_LENGTH240];
7794 char *str;
7795 va_list ap;
7796
7797 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7798
7799 fi = PITEM_FINFO(pi)((pi)->finfo);
7800 if (fi == NULL((void*)0)) {
7801 return;
7802 }
7803
7804 if (!proto_item_is_hidden(pi)) {
7805 /*
7806 * If we don't already have a representation,
7807 * generate the default representation.
7808 */
7809 if (fi->rep == NULL((void*)0)) {
7810 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;
;
7811 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7812 } else
7813 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7814
7815 va_start(ap, format)__builtin_va_start(ap, format);
7816 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7817 va_end(ap)__builtin_va_end(ap);
7818 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"
, 7818, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7819 fi->rep->value_pos += strlen(str);
7820 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7821 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7822 /* XXX: As above, if the old representation is close to the label
7823 * length, it might already be marked as truncated. */
7824 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7825 /* Uh oh, we don't have enough room. Tell the user
7826 * that the field is truncated.
7827 */
7828 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7829 }
7830 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7831 }
7832}
7833
7834static void
7835finfo_set_len(field_info *fi, const int length)
7836{
7837 int length_remaining;
7838
7839 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", 7839,
"length >= 0", fi->hfinfo->abbrev))))
;
7840 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7841 if (length > length_remaining)
7842 fi->length = length_remaining;
7843 else
7844 fi->length = length;
7845
7846 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7847 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7848 fvalue_set_protocol_length(fi->value, fi->length);
7849 }
7850
7851 /*
7852 * You cannot just make the "len" field of a GByteArray
7853 * larger, if there's no data to back that length;
7854 * you can only make it smaller.
7855 */
7856 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7857 GBytes *bytes = fvalue_get_bytes(fi->value);
7858 size_t size;
7859 const void *data = g_bytes_get_data(bytes, &size);
7860 if ((size_t)fi->length <= size) {
7861 fvalue_set_bytes_data(fi->value, data, fi->length);
7862 }
7863 g_bytes_unref(bytes);
7864 }
7865}
7866
7867void
7868proto_item_set_len(proto_item *pi, const int length)
7869{
7870 field_info *fi;
7871
7872 if (pi == NULL((void*)0))
7873 return;
7874
7875 fi = PITEM_FINFO(pi)((pi)->finfo);
7876 if (fi == NULL((void*)0))
7877 return;
7878
7879 finfo_set_len(fi, length);
7880}
7881
7882/*
7883 * Sets the length of the item based on its start and on the specified
7884 * offset, which is the offset past the end of the item; as the start
7885 * in the item is relative to the beginning of the data source tvbuff,
7886 * we need to pass in a tvbuff - the end offset is relative to the beginning
7887 * of that tvbuff.
7888 */
7889void
7890proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7891{
7892 field_info *fi;
7893 int length;
7894
7895 if (pi == NULL((void*)0))
7896 return;
7897
7898 fi = PITEM_FINFO(pi)((pi)->finfo);
7899 if (fi == NULL((void*)0))
7900 return;
7901
7902 end += tvb_raw_offset(tvb);
7903 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7903, "end >= fi->start"
))))
;
7904 length = end - fi->start;
7905
7906 finfo_set_len(fi, length);
7907}
7908
7909int
7910proto_item_get_len(const proto_item *pi)
7911{
7912 field_info *fi;
7913
7914 if (!pi)
7915 return -1;
7916 fi = PITEM_FINFO(pi)((pi)->finfo);
7917 return fi ? fi->length : -1;
7918}
7919
7920void
7921proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7922 if (!ti) {
7923 return;
7924 }
7925 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)
;
7926 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)
;
7927}
7928
7929char *
7930proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7931{
7932 field_info *fi;
7933
7934 if (!pi)
7935 return wmem_strdup(scope, "");
7936 fi = PITEM_FINFO(pi)((pi)->finfo);
7937 if (!fi)
7938 return wmem_strdup(scope, "");
7939 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7939, "fi->hfinfo != ((void*)0)"
))))
;
7940 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7941}
7942
7943proto_tree *
7944proto_tree_create_root(packet_info *pinfo)
7945{
7946 proto_node *pnode;
7947
7948 /* Initialize the proto_node */
7949 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
7950 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
7951 pnode->parent = NULL((void*)0);
7952 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
7953 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
7954
7955 /* Make sure we can access pinfo everywhere */
7956 pnode->tree_data->pinfo = pinfo;
7957
7958 /* Don't initialize the tree_data_t. Wait until we know we need it */
7959 pnode->tree_data->interesting_hfids = NULL((void*)0);
7960
7961 /* Set the default to false so it's easier to
7962 * find errors; if we expect to see the protocol tree
7963 * but for some reason the default 'visible' is not
7964 * changed, then we'll find out very quickly. */
7965 pnode->tree_data->visible = false0;
7966
7967 /* Make sure that we fake protocols (if possible) */
7968 pnode->tree_data->fake_protocols = true1;
7969
7970 /* Keep track of the number of children */
7971 pnode->tree_data->count = 0;
7972
7973 /* Initialize our loop checks */
7974 pnode->tree_data->max_start = 0;
7975 pnode->tree_data->start_idle_count = 0;
7976
7977 return (proto_tree *)pnode;
7978}
7979
7980
7981/* "prime" a proto_tree with a single hfid that a dfilter
7982 * is interested in. */
7983void
7984proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
7985{
7986 header_field_info *hfinfo;
7987
7988 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", 7988, __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", 7988, "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", 7988, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
7989 /* this field is referenced by a filter so increase the refcount.
7990 also increase the refcount for the parent, i.e the protocol.
7991 Don't increase the refcount if we're already printing the
7992 type, as that is a superset of direct reference.
7993 */
7994 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
7995 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
7996 }
7997 /* only increase the refcount if there is a parent.
7998 if this is a protocol and not a field then parent will be -1
7999 and there is no parent to add any refcounting for.
8000 */
8001 if (hfinfo->parent != -1) {
8002 header_field_info *parent_hfinfo;
8003 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", 8003
, __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", 8003,
"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", 8003,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8004
8005 /* Mark parent as indirectly referenced unless it is already directly
8006 * referenced, i.e. the user has specified the parent in a filter.
8007 */
8008 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8009 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8010 }
8011}
8012
8013/* "prime" a proto_tree with a single hfid that a dfilter
8014 * is interested in. */
8015void
8016proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8017{
8018 header_field_info *hfinfo;
8019
8020 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", 8020, __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", 8020, "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", 8020, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8021 /* this field is referenced by an (output) filter so increase the refcount.
8022 also increase the refcount for the parent, i.e the protocol.
8023 */
8024 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8025 /* only increase the refcount if there is a parent.
8026 if this is a protocol and not a field then parent will be -1
8027 and there is no parent to add any refcounting for.
8028 */
8029 if (hfinfo->parent != -1) {
8030 header_field_info *parent_hfinfo;
8031 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", 8031
, __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", 8031,
"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", 8031,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8032
8033 /* Mark parent as indirectly referenced unless it is already directly
8034 * referenced, i.e. the user has specified the parent in a filter.
8035 */
8036 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8037 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8038 }
8039}
8040
8041proto_tree *
8042proto_item_add_subtree(proto_item *pi, const int idx) {
8043 field_info *fi;
8044
8045 if (!pi)
8046 return NULL((void*)0);
8047
8048 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", 8048, "idx >= 0 && idx < num_tree_types"
))))
;
8049
8050 fi = PITEM_FINFO(pi)((pi)->finfo);
8051 if (!fi)
8052 return (proto_tree *)pi;
8053
8054 fi->tree_type = idx;
8055
8056 return (proto_tree *)pi;
8057}
8058
8059proto_tree *
8060proto_item_get_subtree(proto_item *pi) {
8061 field_info *fi;
8062
8063 if (!pi)
8064 return NULL((void*)0);
8065 fi = PITEM_FINFO(pi)((pi)->finfo);
8066 if ( (fi) && (fi->tree_type == -1) )
8067 return NULL((void*)0);
8068 return (proto_tree *)pi;
8069}
8070
8071proto_item *
8072proto_item_get_parent(const proto_item *ti) {
8073 if (!ti)
8074 return NULL((void*)0);
8075 return ti->parent;
8076}
8077
8078proto_item *
8079proto_item_get_parent_nth(proto_item *ti, int gen) {
8080 if (!ti)
8081 return NULL((void*)0);
8082 while (gen--) {
8083 ti = ti->parent;
8084 if (!ti)
8085 return NULL((void*)0);
8086 }
8087 return ti;
8088}
8089
8090
8091proto_item *
8092proto_tree_get_parent(proto_tree *tree) {
8093 if (!tree)
8094 return NULL((void*)0);
8095 return (proto_item *)tree;
8096}
8097
8098proto_tree *
8099proto_tree_get_parent_tree(proto_tree *tree) {
8100 if (!tree)
8101 return NULL((void*)0);
8102
8103 /* we're the root tree, there's no parent
8104 return ourselves so the caller has at least a tree to attach to */
8105 if (!tree->parent)
8106 return tree;
8107
8108 return (proto_tree *)tree->parent;
8109}
8110
8111proto_tree *
8112proto_tree_get_root(proto_tree *tree) {
8113 if (!tree)
8114 return NULL((void*)0);
8115 while (tree->parent) {
8116 tree = tree->parent;
8117 }
8118 return tree;
8119}
8120
8121void
8122proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8123 proto_item *item_to_move)
8124{
8125 /* This function doesn't generate any values. It only reorganizes the prococol tree
8126 * so we can bail out immediately if it isn't visible. */
8127 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8128 return;
8129
8130 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", 8130, "item_to_move->parent == tree"
))))
;
8131 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", 8131, "fixed_item->parent == tree"
))))
;
8132
8133 /*** cut item_to_move out ***/
8134
8135 /* is item_to_move the first? */
8136 if (tree->first_child == item_to_move) {
8137 /* simply change first child to next */
8138 tree->first_child = item_to_move->next;
8139
8140 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", 8140, "tree->last_child != item_to_move"
))))
;
8141 } else {
8142 proto_item *curr_item;
8143 /* find previous and change it's next */
8144 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8145 if (curr_item->next == item_to_move) {
8146 break;
8147 }
8148 }
8149
8150 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8150, "curr_item"
))))
;
8151
8152 curr_item->next = item_to_move->next;
8153
8154 /* fix last_child if required */
8155 if (tree->last_child == item_to_move) {
8156 tree->last_child = curr_item;
8157 }
8158 }
8159
8160 /*** insert to_move after fixed ***/
8161 item_to_move->next = fixed_item->next;
8162 fixed_item->next = item_to_move;
8163 if (tree->last_child == fixed_item) {
8164 tree->last_child = item_to_move;
8165 }
8166}
8167
8168void
8169proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8170 const int length)
8171{
8172 field_info *fi;
8173
8174 if (tree == NULL((void*)0))
8175 return;
8176
8177 fi = PTREE_FINFO(tree)((tree)->finfo);
8178 if (fi == NULL((void*)0))
8179 return;
8180
8181 start += tvb_raw_offset(tvb);
8182 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8182, "start >= 0"
))))
;
8183 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8183, "length >= 0"
))))
;
8184
8185 fi->appendix_start = start;
8186 fi->appendix_length = length;
8187}
8188
8189static void
8190check_protocol_filter_name_or_fail(const char *filter_name)
8191{
8192 /* Require at least two characters. */
8193 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8194 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)
;
8195 }
8196
8197 if (proto_check_field_name(filter_name) != '\0') {
8198 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)
8199 " 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)
8200 " 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)
;
8201 }
8202
8203 /* Check that it doesn't match some very common numeric forms. */
8204 if (filter_name[0] == '0' &&
8205 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8206 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8207 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])
8208 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])
;
8209 }
8210
8211 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8212
8213 /* Check that it contains at least one letter. */
8214 bool_Bool have_letter = false0;
8215 for (const char *s = filter_name; *s != '\0'; s++) {
8216 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8217 have_letter = true1;
8218 break;
8219 }
8220 }
8221 if (!have_letter) {
8222 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)
8223 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8224 }
8225
8226 /* Check for reserved keywords. */
8227 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8228 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)
8229 " 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)
;
8230 }
8231}
8232
8233int
8234proto_register_protocol(const char *name, const char *short_name,
8235 const char *filter_name)
8236{
8237 protocol_t *protocol;
8238 header_field_info *hfinfo;
8239
8240 /*
8241 * Make sure there's not already a protocol with any of those
8242 * names. Crash if there is, as that's an error in the code
8243 * or an inappropriate plugin.
8244 * This situation has to be fixed to not register more than one
8245 * protocol with the same name.
8246 */
8247
8248 if (g_hash_table_lookup(proto_names, name)) {
8249 /* ws_error will terminate the program */
8250 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)
8251 " 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)
;
8252 }
8253
8254 if (g_hash_table_lookup(proto_short_names, short_name)) {
8255 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)
8256 " 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)
;
8257 }
8258
8259 check_protocol_filter_name_or_fail(filter_name);
8260
8261 if (g_hash_table_lookup(proto_filter_names, filter_name)) {
8262 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)
8263 " 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)
;
8264 }
8265
8266 /*
8267 * Add this protocol to the list of known protocols;
8268 * the list is sorted by protocol short name.
8269 */
8270 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8271 protocol->name = name;
8272 protocol->short_name = short_name;
8273 protocol->filter_name = filter_name;
8274 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8275 protocol->is_enabled = true1; /* protocol is enabled by default */
8276 protocol->enabled_by_default = true1; /* see previous comment */
8277 protocol->can_toggle = true1;
8278 protocol->parent_proto_id = -1;
8279 protocol->heur_list = NULL((void*)0);
8280
8281 /* List will be sorted later by name, when all protocols completed registering */
8282 protocols = g_list_prepend(protocols, protocol);
8283 g_hash_table_insert(proto_names, (void *)name, protocol);
8284 g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol);
8285 g_hash_table_insert(proto_short_names, (void *)short_name, protocol);
8286
8287 /* Here we allocate a new header_field_info struct */
8288 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8289 hfinfo->name = name;
8290 hfinfo->abbrev = filter_name;
8291 hfinfo->type = FT_PROTOCOL;
8292 hfinfo->display = BASE_NONE;
8293 hfinfo->strings = protocol;
8294 hfinfo->bitmask = 0;
8295 hfinfo->ref_type = HF_REF_TYPE_NONE;
8296 hfinfo->blurb = NULL((void*)0);
8297 hfinfo->parent = -1; /* This field differentiates protos and fields */
8298
8299 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8300 return protocol->proto_id;
8301}
8302
8303int
8304proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8305{
8306 protocol_t *protocol;
8307 header_field_info *hfinfo;
8308
8309 /*
8310 * Helper protocols don't need the strict rules as a "regular" protocol
8311 * Just register it in a list and make a hf_ field from it
8312 */
8313 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8314 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)
;
8315 }
8316
8317 if (parent_proto <= 0) {
8318 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)
8319 " 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)
;
8320 }
8321
8322 check_protocol_filter_name_or_fail(filter_name);
8323
8324 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8325 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8326 protocol->name = name;
8327 protocol->short_name = short_name;
8328 protocol->filter_name = filter_name;
8329 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8330
8331 /* Enabling and toggling is really determined by parent protocol,
8332 but provide default values here */
8333 protocol->is_enabled = true1;
8334 protocol->enabled_by_default = true1;
8335 protocol->can_toggle = true1;
8336
8337 protocol->parent_proto_id = parent_proto;
8338 protocol->heur_list = NULL((void*)0);
8339
8340 /* List will be sorted later by name, when all protocols completed registering */
8341 protocols = g_list_prepend(protocols, protocol);
8342
8343 /* Here we allocate a new header_field_info struct */
8344 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8345 hfinfo->name = name;
8346 hfinfo->abbrev = filter_name;
8347 hfinfo->type = field_type;
8348 hfinfo->display = BASE_NONE;
8349 if (field_type == FT_BYTES) {
8350 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8351 }
8352 hfinfo->strings = protocol;
8353 hfinfo->bitmask = 0;
8354 hfinfo->ref_type = HF_REF_TYPE_NONE;
8355 hfinfo->blurb = NULL((void*)0);
8356 hfinfo->parent = -1; /* This field differentiates protos and fields */
8357
8358 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8359 return protocol->proto_id;
8360}
8361
8362bool_Bool
8363proto_deregister_protocol(const char *short_name)
8364{
8365 protocol_t *protocol;
8366 header_field_info *hfinfo;
8367 int proto_id;
8368 unsigned i;
8369
8370 proto_id = proto_get_id_by_short_name(short_name);
8371 protocol = find_protocol_by_id(proto_id);
8372 if (protocol == NULL((void*)0))
8373 return false0;
8374
8375 g_hash_table_remove(proto_names, protocol->name);
8376 g_hash_table_remove(proto_short_names, (void *)short_name);
8377 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8378
8379 if (protocol->fields) {
8380 for (i = 0; i < protocol->fields->len; i++) {
8381 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8382 hfinfo_remove_from_gpa_name_map(hfinfo);
8383 expert_deregister_expertinfo(hfinfo->abbrev);
8384 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8385 }
8386 g_ptr_array_free(protocol->fields, true1);
8387 protocol->fields = NULL((void*)0);
8388 }
8389
8390 g_list_free(protocol->heur_list);
8391
8392 /* Remove this protocol from the list of known protocols */
8393 protocols = g_list_remove(protocols, protocol);
8394
8395 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8396 g_hash_table_steal(gpa_name_map, protocol->filter_name);
8397
8398 g_free(last_field_name);
8399 last_field_name = NULL((void*)0);
8400
8401 return true1;
8402}
8403
8404void
8405proto_register_alias(const int proto_id, const char *alias_name)
8406{
8407 protocol_t *protocol;
8408
8409 protocol = find_protocol_by_id(proto_id);
8410 if (alias_name && protocol) {
8411 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8412 }
8413}
8414
8415/*
8416 * Routines to use to iterate over the protocols.
8417 * The argument passed to the iterator routines is an opaque cookie to
8418 * their callers; it's the GList pointer for the current element in
8419 * the list.
8420 * The ID of the protocol is returned, or -1 if there is no protocol.
8421 */
8422int
8423proto_get_first_protocol(void **cookie)
8424{
8425 protocol_t *protocol;
8426
8427 if (protocols == NULL((void*)0))
8428 return -1;
8429 *cookie = protocols;
8430 protocol = (protocol_t *)protocols->data;
8431 return protocol->proto_id;
8432}
8433
8434int
8435proto_get_data_protocol(void *cookie)
8436{
8437 GList *list_item = (GList *)cookie;
8438
8439 protocol_t *protocol = (protocol_t *)list_item->data;
8440 return protocol->proto_id;
8441}
8442
8443int
8444proto_get_next_protocol(void **cookie)
8445{
8446 GList *list_item = (GList *)*cookie;
8447 protocol_t *protocol;
8448
8449 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8450 if (list_item == NULL((void*)0))
8451 return -1;
8452 *cookie = list_item;
8453 protocol = (protocol_t *)list_item->data;
8454 return protocol->proto_id;
8455}
8456
8457header_field_info *
8458proto_get_first_protocol_field(const int proto_id, void **cookie)
8459{
8460 protocol_t *protocol = find_protocol_by_id(proto_id);
8461
8462 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8463 return NULL((void*)0);
8464
8465 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8466 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8467}
8468
8469header_field_info *
8470proto_get_next_protocol_field(const int proto_id, void **cookie)
8471{
8472 protocol_t *protocol = find_protocol_by_id(proto_id);
8473 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8474
8475 i++;
8476
8477 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8478 return NULL((void*)0);
8479
8480 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8481 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8482}
8483
8484protocol_t *
8485find_protocol_by_id(const int proto_id)
8486{
8487 header_field_info *hfinfo;
8488
8489 if (proto_id <= 0)
8490 return NULL((void*)0);
8491
8492 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", 8492, __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", 8492,
"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", 8492, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8493 if (hfinfo->type != FT_PROTOCOL) {
8494 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", 8494, "hfinfo->display & 0x00004000"
))))
;
8495 }
8496 return (protocol_t *)hfinfo->strings;
8497}
8498
8499int
8500proto_get_id(const protocol_t *protocol)
8501{
8502 return protocol->proto_id;
8503}
8504
8505bool_Bool
8506proto_name_already_registered(const char *name)
8507{
8508 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8508, "name", "No name present"))))
;
8509
8510 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8511 return true1;
8512 return false0;
8513}
8514
8515int
8516proto_get_id_by_filter_name(const char *filter_name)
8517{
8518 const protocol_t *protocol = NULL((void*)0);
8519
8520 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", 8520,
"filter_name", "No filter name present"))))
;
8521
8522 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8523
8524 if (protocol == NULL((void*)0))
8525 return -1;
8526 return protocol->proto_id;
8527}
8528
8529int
8530proto_get_id_by_short_name(const char *short_name)
8531{
8532 const protocol_t *protocol = NULL((void*)0);
8533
8534 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", 8534,
"short_name", "No short name present"))))
;
8535
8536 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8537
8538 if (protocol == NULL((void*)0))
8539 return -1;
8540 return protocol->proto_id;
8541}
8542
8543const char *
8544proto_get_protocol_name(const int proto_id)
8545{
8546 protocol_t *protocol;
8547
8548 protocol = find_protocol_by_id(proto_id);
8549
8550 if (protocol == NULL((void*)0))
8551 return NULL((void*)0);
8552 return protocol->name;
8553}
8554
8555const char *
8556proto_get_protocol_short_name(const protocol_t *protocol)
8557{
8558 if (protocol == NULL((void*)0))
8559 return "(none)";
8560 return protocol->short_name;
8561}
8562
8563const char *
8564proto_get_protocol_long_name(const protocol_t *protocol)
8565{
8566 if (protocol == NULL((void*)0))
8567 return "(none)";
8568 return protocol->name;
8569}
8570
8571const char *
8572proto_get_protocol_filter_name(const int proto_id)
8573{
8574 protocol_t *protocol;
8575
8576 protocol = find_protocol_by_id(proto_id);
8577 if (protocol == NULL((void*)0))
8578 return "(none)";
8579 return protocol->filter_name;
8580}
8581
8582void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8583{
8584 heur_dtbl_entry_t* heuristic_dissector;
8585
8586 if (protocol == NULL((void*)0))
8587 return;
8588
8589 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8590 if (heuristic_dissector != NULL((void*)0))
8591 {
8592 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8593 }
8594}
8595
8596void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8597{
8598 if (protocol == NULL((void*)0))
8599 return;
8600
8601 g_list_foreach(protocol->heur_list, func, user_data);
8602}
8603
8604void
8605proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8606 bool_Bool *is_tcp, bool_Bool *is_udp,
8607 bool_Bool *is_sctp, bool_Bool *is_tls,
8608 bool_Bool *is_rtp,
8609 bool_Bool *is_lte_rlc)
8610{
8611 wmem_list_frame_t *protos = wmem_list_head(layers);
8612 int proto_id;
8613 const char *proto_name;
8614
8615 /* Walk the list of a available protocols in the packet and
8616 attempt to find "major" ones. */
8617 /* It might make more sense to assemble and return a bitfield. */
8618 while (protos != NULL((void*)0))
8619 {
8620 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8621 proto_name = proto_get_protocol_filter_name(proto_id);
8622
8623 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8624 (!strcmp(proto_name, "ipv6")))) {
8625 *is_ip = true1;
8626 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8627 *is_tcp = true1;
8628 } else if (is_udp && !strcmp(proto_name, "udp")) {
8629 *is_udp = true1;
8630 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8631 *is_sctp = true1;
8632 } else if (is_tls && !strcmp(proto_name, "tls")) {
8633 *is_tls = true1;
8634 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8635 *is_rtp = true1;
8636 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8637 *is_lte_rlc = true1;
8638 }
8639
8640 protos = wmem_list_frame_next(protos);
8641 }
8642}
8643
8644bool_Bool
8645proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8646{
8647 wmem_list_frame_t *protos = wmem_list_head(layers);
8648 int proto_id;
8649 const char *name;
8650
8651 /* Walk the list of a available protocols in the packet and
8652 attempt to find the specified protocol. */
8653 while (protos != NULL((void*)0))
8654 {
8655 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8656 name = proto_get_protocol_filter_name(proto_id);
8657
8658 if (!strcmp(name, proto_name))
8659 {
8660 return true1;
8661 }
8662
8663 protos = wmem_list_frame_next(protos);
8664 }
8665
8666 return false0;
8667}
8668
8669char *
8670proto_list_layers(const packet_info *pinfo)
8671{
8672 wmem_strbuf_t *buf;
8673 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8674
8675 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8676
8677 /* Walk the list of layers in the packet and
8678 return a string of all entries. */
8679 while (layers != NULL((void*)0))
8680 {
8681 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8682
8683 layers = wmem_list_frame_next(layers);
8684 if (layers != NULL((void*)0)) {
8685 wmem_strbuf_append_c(buf, ':');
8686 }
8687 }
8688
8689 return wmem_strbuf_finalize(buf);
8690}
8691
8692uint8_t
8693proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8694{
8695 int *proto_layer_num_ptr;
8696
8697 proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8698 if (proto_layer_num_ptr == NULL((void*)0)) {
8699 return 0;
8700 }
8701
8702 return (uint8_t)*proto_layer_num_ptr;
8703}
8704
8705bool_Bool
8706proto_is_pino(const protocol_t *protocol)
8707{
8708 return (protocol->parent_proto_id != -1);
8709}
8710
8711bool_Bool
8712// NOLINTNEXTLINE(misc-no-recursion)
8713proto_is_protocol_enabled(const protocol_t *protocol)
8714{
8715 if (protocol == NULL((void*)0))
8716 return false0;
8717
8718 //parent protocol determines enable/disable for helper dissectors
8719 if (proto_is_pino(protocol))
8720 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8721
8722 return protocol->is_enabled;
8723}
8724
8725bool_Bool
8726// NOLINTNEXTLINE(misc-no-recursion)
8727proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8728{
8729 //parent protocol determines enable/disable for helper dissectors
8730 if (proto_is_pino(protocol))
8731 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8732
8733 return protocol->enabled_by_default;
8734}
8735
8736bool_Bool
8737// NOLINTNEXTLINE(misc-no-recursion)
8738proto_can_toggle_protocol(const int proto_id)
8739{
8740 protocol_t *protocol;
8741
8742 protocol = find_protocol_by_id(proto_id);
8743 //parent protocol determines toggling for helper dissectors
8744 if (proto_is_pino(protocol))
8745 return proto_can_toggle_protocol(protocol->parent_proto_id);
8746
8747 return protocol->can_toggle;
8748}
8749
8750void
8751proto_disable_by_default(const int proto_id)
8752{
8753 protocol_t *protocol;
8754
8755 protocol = find_protocol_by_id(proto_id);
8756 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8756, "protocol->can_toggle"
))))
;
8757 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", 8757, "proto_is_pino(protocol) == 0"
))))
;
8758 protocol->is_enabled = false0;
8759 protocol->enabled_by_default = false0;
8760}
8761
8762void
8763proto_set_decoding(const int proto_id, const bool_Bool enabled)
8764{
8765 protocol_t *protocol;
8766
8767 protocol = find_protocol_by_id(proto_id);
8768 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8768, "protocol->can_toggle"
))))
;
8769 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", 8769, "proto_is_pino(protocol) == 0"
))))
;
8770 protocol->is_enabled = enabled;
8771}
8772
8773void
8774proto_disable_all(void)
8775{
8776 /* This doesn't explicitly disable heuristic protocols,
8777 * but the heuristic doesn't get called if the parent
8778 * protocol isn't enabled.
8779 */
8780 protocol_t *protocol;
8781 GList *list_item = protocols;
8782
8783 if (protocols == NULL((void*)0))
8784 return;
8785
8786 while (list_item) {
8787 protocol = (protocol_t *)list_item->data;
8788 if (protocol->can_toggle) {
8789 protocol->is_enabled = false0;
8790 }
8791 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8792 }
8793}
8794
8795static void
8796heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8797{
8798 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8799
8800 heur->enabled = heur->enabled_by_default;
8801}
8802
8803void
8804proto_reenable_all(void)
8805{
8806 protocol_t *protocol;
8807 GList *list_item = protocols;
8808
8809 if (protocols == NULL((void*)0))
8810 return;
8811
8812 while (list_item) {
8813 protocol = (protocol_t *)list_item->data;
8814 if (protocol->can_toggle)
8815 protocol->is_enabled = protocol->enabled_by_default;
8816 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8817 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8818 }
8819}
8820
8821void
8822proto_set_cant_toggle(const int proto_id)
8823{
8824 protocol_t *protocol;
8825
8826 protocol = find_protocol_by_id(proto_id);
8827 protocol->can_toggle = false0;
8828}
8829
8830static int
8831proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8832{
8833 if (proto != NULL((void*)0)) {
8834 g_ptr_array_add(proto->fields, hfi);
8835 }
8836
8837 return proto_register_field_init(hfi, parent);
8838}
8839
8840/* for use with static arrays only, since we don't allocate our own copies
8841of the header_field_info struct contained within the hf_register_info struct */
8842void
8843proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8844{
8845 hf_register_info *ptr = hf;
8846 protocol_t *proto;
8847 int i;
8848
8849 proto = find_protocol_by_id(parent);
8850
8851 if (proto->fields == NULL((void*)0)) {
8852 proto->fields = g_ptr_array_sized_new(num_records);
8853 }
8854
8855 for (i = 0; i < num_records; i++, ptr++) {
8856 /*
8857 * Make sure we haven't registered this yet.
8858 * Most fields have variables associated with them
8859 * that are initialized to -1; some have array elements,
8860 * or possibly uninitialized variables, so we also allow
8861 * 0 (which is unlikely to be the field ID we get back
8862 * from "proto_register_field_init()").
8863 */
8864 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8865 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8866 "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)
8867 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8868 return;
8869 }
8870
8871 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8872 }
8873}
8874
8875/* deregister already registered fields */
8876void
8877proto_deregister_field (const int parent, int hf_id)
8878{
8879 header_field_info *hfi;
8880 protocol_t *proto;
8881 unsigned i;
8882
8883 g_free(last_field_name);
8884 last_field_name = NULL((void*)0);
8885
8886 if (hf_id == -1 || hf_id == 0)
8887 return;
8888
8889 proto = find_protocol_by_id (parent);
8890 if (!proto || proto->fields == NULL((void*)0)) {
8891 return;
8892 }
8893
8894 for (i = 0; i < proto->fields->len; i++) {
8895 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8896 if (hfi->id == hf_id) {
8897 /* Found the hf_id in this protocol */
8898 g_hash_table_steal(gpa_name_map, hfi->abbrev);
8899 g_ptr_array_remove_index_fast(proto->fields, i);
8900 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8901 return;
8902 }
8903 }
8904}
8905
8906/* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8907void
8908proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8909{
8910 header_field_info *hfinfo;
8911 protocol_t *proto;
8912
8913 g_free(last_field_name);
8914 last_field_name = NULL((void*)0);
8915
8916 proto = find_protocol_by_id(parent);
8917 if (proto && proto->fields && proto->fields->len > 0) {
8918 guint i = proto->fields->len;
8919 do {
8920 i--;
8921
8922 hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8923 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) )
) {
8924 hfinfo_remove_from_gpa_name_map(hfinfo);
8925 expert_deregister_expertinfo(hfinfo->abbrev);
8926 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8927 g_ptr_array_remove_index_fast(proto->fields, i);
8928 }
8929 } while (i > 0);
8930 }
8931}
8932
8933void
8934proto_add_deregistered_data (void *data)
8935{
8936 g_ptr_array_add(deregistered_data, data);
8937}
8938
8939void
8940proto_add_deregistered_slice (size_t block_size, void *mem_block)
8941{
8942 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
)))
;
8943
8944 slice_data->block_size = block_size;
8945 slice_data->mem_block = mem_block;
8946
8947 g_ptr_array_add(deregistered_slice, slice_data);
8948}
8949
8950void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8951{
8952 if (field_strings == NULL((void*)0)) {
8953 return;
8954 }
8955
8956 switch (field_type) {
8957 case FT_FRAMENUM:
8958 /* This is just an integer represented as a pointer */
8959 break;
8960 case FT_PROTOCOL: {
8961 protocol_t *protocol = (protocol_t *)field_strings;
8962 g_free((char *)protocol->short_name);
8963 break;
8964 }
8965 case FT_BOOLEAN: {
8966 true_false_string *tf = (true_false_string *)field_strings;
8967 g_free((char *)tf->true_string);
8968 g_free((char *)tf->false_string);
8969 break;
8970 }
8971 case FT_UINT40:
8972 case FT_INT40:
8973 case FT_UINT48:
8974 case FT_INT48:
8975 case FT_UINT56:
8976 case FT_INT56:
8977 case FT_UINT64:
8978 case FT_INT64: {
8979 if (field_display & BASE_UNIT_STRING0x00001000) {
8980 unit_name_string *unit = (unit_name_string *)field_strings;
8981 g_free((char *)unit->singular);
8982 g_free((char *)unit->plural);
8983 } else if (field_display & BASE_RANGE_STRING0x00000100) {
8984 range_string *rs = (range_string *)field_strings;
8985 while (rs->strptr) {
8986 g_free((char *)rs->strptr);
8987 rs++;
8988 }
8989 } else if (field_display & BASE_EXT_STRING0x00000200) {
8990 val64_string_ext *vse = (val64_string_ext *)field_strings;
8991 val64_string *vs = (val64_string *)vse->_vs_p;
8992 while (vs->strptr) {
8993 g_free((char *)vs->strptr);
8994 vs++;
8995 }
8996 val64_string_ext_free(vse);
8997 field_strings = NULL((void*)0);
8998 } else if (field_display == BASE_CUSTOM) {
8999 /* this will be a pointer to a function, don't free that */
9000 field_strings = NULL((void*)0);
9001 } else {
9002 val64_string *vs64 = (val64_string *)field_strings;
9003 while (vs64->strptr) {
9004 g_free((char *)vs64->strptr);
9005 vs64++;
9006 }
9007 }
9008 break;
9009 }
9010 case FT_CHAR:
9011 case FT_UINT8:
9012 case FT_INT8:
9013 case FT_UINT16:
9014 case FT_INT16:
9015 case FT_UINT24:
9016 case FT_INT24:
9017 case FT_UINT32:
9018 case FT_INT32:
9019 case FT_FLOAT:
9020 case FT_DOUBLE: {
9021 if (field_display & BASE_UNIT_STRING0x00001000) {
9022 unit_name_string *unit = (unit_name_string *)field_strings;
9023 g_free((char *)unit->singular);
9024 g_free((char *)unit->plural);
9025 } else if (field_display & BASE_RANGE_STRING0x00000100) {
9026 range_string *rs = (range_string *)field_strings;
9027 while (rs->strptr) {
9028 g_free((char *)rs->strptr);
9029 rs++;
9030 }
9031 } else if (field_display & BASE_EXT_STRING0x00000200) {
9032 value_string_ext *vse = (value_string_ext *)field_strings;
9033 value_string *vs = (value_string *)vse->_vs_p;
9034 while (vs->strptr) {
9035 g_free((char *)vs->strptr);
9036 vs++;
9037 }
9038 value_string_ext_free(vse);
9039 field_strings = NULL((void*)0);
9040 } else if (field_display == BASE_CUSTOM) {
9041 /* this will be a pointer to a function, don't free that */
9042 field_strings = NULL((void*)0);
9043 } else {
9044 value_string *vs = (value_string *)field_strings;
9045 while (vs->strptr) {
9046 g_free((char *)vs->strptr);
9047 vs++;
9048 }
9049 }
9050 break;
9051 default:
9052 break;
9053 }
9054 }
9055
9056 if (field_type != FT_FRAMENUM) {
9057 g_free((void *)field_strings);
9058 }
9059}
9060
9061static void
9062free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9063{
9064 header_field_info *hfi = (header_field_info *) data;
9065 int hf_id = hfi->id;
9066
9067 g_free((char *)hfi->name);
9068 g_free((char *)hfi->abbrev);
9069 g_free((char *)hfi->blurb);
9070
9071 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9072
9073 if (hfi->parent == -1)
9074 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)
;
9075
9076 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9077}
9078
9079static void
9080free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9081{
9082 g_free (data);
9083}
9084
9085static void
9086free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9087{
9088 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9089
9090 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9091 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)
;
9092}
9093
9094/* free deregistered fields and data */
9095void
9096proto_free_deregistered_fields (void)
9097{
9098 expert_free_deregistered_expertinfos();
9099
9100 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9101 g_ptr_array_free(deregistered_fields, true1);
9102 deregistered_fields = g_ptr_array_new();
9103
9104 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9105 g_ptr_array_free(deregistered_data, true1);
9106 deregistered_data = g_ptr_array_new();
9107
9108 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9109 g_ptr_array_free(deregistered_slice, true1);
9110 deregistered_slice = g_ptr_array_new();
9111}
9112
9113static const value_string hf_display[] = {
9114 { BASE_NONE, "BASE_NONE" },
9115 { BASE_DEC, "BASE_DEC" },
9116 { BASE_HEX, "BASE_HEX" },
9117 { BASE_OCT, "BASE_OCT" },
9118 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9119 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9120 { BASE_CUSTOM, "BASE_CUSTOM" },
9121 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9122 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9123 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9124 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9125 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9126 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9127 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9128 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9129 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9130 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9131 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9132 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9133 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9134 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9135 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9136 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9137 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9138 { BASE_PT_UDP, "BASE_PT_UDP" },
9139 { BASE_PT_TCP, "BASE_PT_TCP" },
9140 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9141 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9142 { BASE_OUI, "BASE_OUI" },
9143 { 0, NULL((void*)0) } };
9144
9145const char* proto_field_display_to_string(int field_display)
9146{
9147 return val_to_str_const(field_display, hf_display, "Unknown");
9148}
9149
9150static inline port_type
9151display_to_port_type(field_display_e e)
9152{
9153 switch (e) {
9154 case BASE_PT_UDP:
9155 return PT_UDP;
9156 case BASE_PT_TCP:
9157 return PT_TCP;
9158 case BASE_PT_DCCP:
9159 return PT_DCCP;
9160 case BASE_PT_SCTP:
9161 return PT_SCTP;
9162 default:
9163 break;
9164 }
9165 return PT_NONE;
9166}
9167
9168/* temporary function containing assert part for easier profiling */
9169static void
9170tmp_fld_check_assert(header_field_info *hfinfo)
9171{
9172 char* tmp_str;
9173
9174 /* The field must have a name (with length > 0) */
9175 if (!hfinfo->name || !hfinfo->name[0]) {
9176 if (hfinfo->abbrev)
9177 /* Try to identify the field */
9178 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)
9179 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9180 else
9181 /* Hum, no luck */
9182 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)"
)
;
9183 }
9184
9185 /* fields with an empty string for an abbreviation aren't filterable */
9186 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9187 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)
;
9188
9189 /* These types of fields are allowed to have value_strings,
9190 * true_false_strings or a protocol_t struct
9191 */
9192 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9193 switch (hfinfo->type) {
9194
9195 /*
9196 * These types are allowed to support display value_strings,
9197 * value64_strings, the extended versions of the previous
9198 * two, range strings, or unit strings.
9199 */
9200 case FT_CHAR:
9201 case FT_UINT8:
9202 case FT_UINT16:
9203 case FT_UINT24:
9204 case FT_UINT32:
9205 case FT_UINT40:
9206 case FT_UINT48:
9207 case FT_UINT56:
9208 case FT_UINT64:
9209 case FT_INT8:
9210 case FT_INT16:
9211 case FT_INT24:
9212 case FT_INT32:
9213 case FT_INT40:
9214 case FT_INT48:
9215 case FT_INT56:
9216 case FT_INT64:
9217 case FT_BOOLEAN:
9218 case FT_PROTOCOL:
9219 break;
9220
9221 /*
9222 * This is allowed to have a value of type
9223 * enum ft_framenum_type to indicate what relationship
9224 * the frame in question has to the frame in which
9225 * the field is put.
9226 */
9227 case FT_FRAMENUM:
9228 break;
9229
9230 /*
9231 * These types are allowed to support only unit strings.
9232 */
9233 case FT_FLOAT:
9234 case FT_DOUBLE:
9235 case FT_IEEE_11073_SFLOAT:
9236 case FT_IEEE_11073_FLOAT:
9237 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9238 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))
9239 " (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))
9240 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))
;
9241 }
9242 break;
9243
9244 /*
9245 * These types are allowed to support display
9246 * time_value_strings.
9247 */
9248 case FT_ABSOLUTE_TIME:
9249 if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9250 hfinfo->display & BASE_EXT_STRING0x00000200 ||
9251 hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9252 hfinfo->display & BASE_UNIT_STRING0x00001000) {
9253 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))
9254 " (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))
9255 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))
;
9256 }
9257 break;
9258
9259 /*
9260 * This type is only allowed to support a string if it's
9261 * a protocol (for pinos).
9262 */
9263 case FT_BYTES:
9264 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9265 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))
9266 " (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))
9267 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))
;
9268 }
9269 break;
9270
9271 default:
9272 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))
9273 " (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))
9274 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))
;
9275 }
9276 }
9277
9278 /* TODO: This check may slow down startup, and output quite a few warnings.
9279 It would be good to be able to enable this (and possibly other checks?)
9280 in non-release builds. */
9281#ifdef ENABLE_CHECK_FILTER
9282 /* Check for duplicate value_string values.
9283 There are lots that have the same value *and* string, so for now only
9284 report those that have same value but different string. */
9285 if ((hfinfo->strings != NULL((void*)0)) &&
9286 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9287 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9288 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9289 (
9290 (hfinfo->type == FT_CHAR) ||
9291 (hfinfo->type == FT_UINT8) ||
9292 (hfinfo->type == FT_UINT16) ||
9293 (hfinfo->type == FT_UINT24) ||
9294 (hfinfo->type == FT_UINT32) ||
9295 (hfinfo->type == FT_INT8) ||
9296 (hfinfo->type == FT_INT16) ||
9297 (hfinfo->type == FT_INT24) ||
9298 (hfinfo->type == FT_INT32) )) {
9299
9300 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9301 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9302 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9303 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9304 } else {
9305 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9306 CHECK_HF_VALUE(value_string, "u", start_values);
9307 }
9308 } else {
9309 const value_string *start_values = (const value_string*)hfinfo->strings;
9310 CHECK_HF_VALUE(value_string, "u", start_values);
9311 }
9312 }
9313
9314 if (hfinfo->type == FT_BOOLEAN) {
9315 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9316 if (tfs) {
9317 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9318 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"
, 9320, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9319 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9320, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9320 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9320, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9321 }
9322 }
9323 }
9324
9325 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9326 const range_string *rs = (const range_string*)(hfinfo->strings);
9327 if (rs) {
9328 const range_string *this_it = rs;
9329
9330 do {
9331 if (this_it->value_max < this_it->value_min) {
9332 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"
, 9336, __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)
9333 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9336, __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)
9334 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9336, __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)
9335 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9336, __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)
9336 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9336, __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)
;
9337 ++this_it;
9338 continue;
9339 }
9340
9341 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9342 /* Not OK if this one is completely hidden by an earlier one! */
9343 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9344 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"
, 9350, __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)
9345 "(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"
, 9350, __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)
9346 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9350, __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)
9347 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9350, __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)
9348 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9350, __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)
9349 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9350, __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)
9350 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9350, __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)
;
9351 }
9352 }
9353 ++this_it;
9354 } while (this_it->strptr);
9355 }
9356 }
9357#endif
9358
9359 switch (hfinfo->type) {
9360
9361 case FT_CHAR:
9362 /* Require the char type to have BASE_HEX, BASE_OCT,
9363 * BASE_CUSTOM, or BASE_NONE as its base.
9364 *
9365 * If the display value is BASE_NONE and there is a
9366 * strings conversion then the dissector writer is
9367 * telling us that the field's numerical value is
9368 * meaningless; we'll avoid showing the value to the
9369 * user.
9370 */
9371 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9372 case BASE_HEX:
9373 case BASE_OCT:
9374 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9375 break;
9376 case BASE_NONE:
9377 if (hfinfo->strings == NULL((void*)0))
9378 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
))
9379 " 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
))
9380 " 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
))
9381 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
))
9382 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
))
;
9383 break;
9384 default:
9385 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9386 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)
9387 " 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)
9388 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)
9389 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)
;
9390 //wmem_free(NULL, tmp_str);
9391 }
9392 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9393 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
))
9394 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
))
9395 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
))
;
9396 }
9397 break;
9398 case FT_INT8:
9399 case FT_INT16:
9400 case FT_INT24:
9401 case FT_INT32:
9402 case FT_INT40:
9403 case FT_INT48:
9404 case FT_INT56:
9405 case FT_INT64:
9406 /* Hexadecimal and octal are, in printf() and everywhere
9407 * else, unsigned so don't allow dissectors to register a
9408 * signed field to be displayed unsigned. (Else how would
9409 * we display negative values?)
9410 */
9411 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9412 case BASE_HEX:
9413 case BASE_OCT:
9414 case BASE_DEC_HEX:
9415 case BASE_HEX_DEC:
9416 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9417 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)
9418 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)
9419 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)
;
9420 //wmem_free(NULL, tmp_str);
9421 }
9422 /* FALL THROUGH */
9423 case FT_UINT8:
9424 case FT_UINT16:
9425 case FT_UINT24:
9426 case FT_UINT32:
9427 case FT_UINT40:
9428 case FT_UINT48:
9429 case FT_UINT56:
9430 case FT_UINT64:
9431 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
))
) {
9432 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9433 if (hfinfo->type != FT_UINT16) {
9434 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))
9435 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))
9436 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))
;
9437 }
9438 if (hfinfo->strings != NULL((void*)0)) {
9439 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)
9440 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)
9441 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)
;
9442 }
9443 if (hfinfo->bitmask != 0) {
9444 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)
9445 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)
9446 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)
;
9447 }
9448 wmem_free(NULL((void*)0), tmp_str);
9449 break;
9450 }
9451
9452 if (hfinfo->display == BASE_OUI) {
9453 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9454 if (hfinfo->type != FT_UINT24) {
9455 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))
9456 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))
9457 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))
;
9458 }
9459 if (hfinfo->strings != NULL((void*)0)) {
9460 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)
9461 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)
9462 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)
;
9463 }
9464 if (hfinfo->bitmask != 0) {
9465 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)
9466 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)
9467 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)
;
9468 }
9469 wmem_free(NULL((void*)0), tmp_str);
9470 break;
9471 }
9472
9473 /* Require integral types (other than frame number,
9474 * which is always displayed in decimal) to have a
9475 * number base.
9476 *
9477 * If the display value is BASE_NONE and there is a
9478 * strings conversion then the dissector writer is
9479 * telling us that the field's numerical value is
9480 * meaningless; we'll avoid showing the value to the
9481 * user.
9482 */
9483 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9484 case BASE_DEC:
9485 case BASE_HEX:
9486 case BASE_OCT:
9487 case BASE_DEC_HEX:
9488 case BASE_HEX_DEC:
9489 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9490 break;
9491 case BASE_NONE:
9492 if (hfinfo->strings == NULL((void*)0)) {
9493 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
))
9494 " 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
))
9495 " 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
))
9496 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
))
9497 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
))
;
9498 }
9499 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9500 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
))
9501 " 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
))
9502 " 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
))
9503 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
))
9504 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
))
;
9505 }
9506 break;
9507
9508 default:
9509 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9510 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)
9511 " 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)
9512 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)
9513 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)
;
9514 //wmem_free(NULL, tmp_str);
9515 }
9516 break;
9517 case FT_BYTES:
9518 case FT_UINT_BYTES:
9519 /* Require bytes to have a "display type" that could
9520 * add a character between displayed bytes.
9521 */
9522 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9523 case BASE_NONE:
9524 case SEP_DOT:
9525 case SEP_DASH:
9526 case SEP_COLON:
9527 case SEP_SPACE:
9528 break;
9529 default:
9530 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9531 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)
9532 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)
;
9533 //wmem_free(NULL, tmp_str);
9534 }
9535 if (hfinfo->bitmask != 0)
9536 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
))
9537 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
))
9538 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
))
;
9539 //allowed to support string if its a protocol (for pinos)
9540 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9541 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
))
9542 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
))
9543 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
))
;
9544 break;
9545
9546 case FT_PROTOCOL:
9547 case FT_FRAMENUM:
9548 if (hfinfo->display != BASE_NONE) {
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 %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)
9551 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)
9552 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)
;
9553 //wmem_free(NULL, tmp_str);
9554 }
9555 if (hfinfo->bitmask != 0)
9556 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
))
9557 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
))
9558 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
))
;
9559 break;
9560
9561 case FT_BOOLEAN:
9562 break;
9563
9564 case FT_ABSOLUTE_TIME:
9565 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9566 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9567 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)
9568 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)
;
9569 //wmem_free(NULL, tmp_str);
9570 }
9571 if (hfinfo->bitmask != 0)
9572 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
))
9573 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
))
9574 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
))
;
9575 break;
9576
9577 case FT_STRING:
9578 case FT_STRINGZ:
9579 case FT_UINT_STRING:
9580 case FT_STRINGZPAD:
9581 case FT_STRINGZTRUNC:
9582 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9583 case BASE_NONE:
9584 case BASE_STR_WSP:
9585 break;
9586
9587 default:
9588 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9589 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)
9590 " 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)
9591 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)
9592 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)
;
9593 //wmem_free(NULL, tmp_str);
9594 }
9595
9596 if (hfinfo->bitmask != 0)
9597 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
))
9598 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
))
9599 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
))
;
9600 if (hfinfo->strings != NULL((void*)0))
9601 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
))
9602 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
))
9603 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
))
;
9604 break;
9605
9606 case FT_IPv4:
9607 switch (hfinfo->display) {
9608 case BASE_NONE:
9609 case BASE_NETMASK:
9610 break;
9611
9612 default:
9613 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9614 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)
9615 " 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)
9616 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)
9617 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)
;
9618 //wmem_free(NULL, tmp_str);
9619 break;
9620 }
9621 break;
9622 case FT_FLOAT:
9623 case FT_DOUBLE:
9624 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9625 case BASE_NONE:
9626 case BASE_DEC:
9627 case BASE_HEX:
9628 case BASE_EXP:
9629 case BASE_CUSTOM:
9630 break;
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 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)
9634 " 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)
9635 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)
9636 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)
;
9637 //wmem_free(NULL, tmp_str);
9638 }
9639 if (hfinfo->bitmask != 0)
9640 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
))
9641 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
))
9642 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
))
;
9643 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9644 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
))
9645 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
))
9646 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
))
;
9647 break;
9648 case FT_IEEE_11073_SFLOAT:
9649 case FT_IEEE_11073_FLOAT:
9650 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9651 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9652 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)
9653 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)
9654 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)
9655 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)
;
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 ((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 default:
9668 if (hfinfo->display != BASE_NONE) {
9669 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9670 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)
9671 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)
9672 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)
9673 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)
;
9674 //wmem_free(NULL, tmp_str);
9675 }
9676 if (hfinfo->bitmask != 0)
9677 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
))
9678 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
))
9679 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
))
;
9680 if (hfinfo->strings != NULL((void*)0))
9681 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
))
9682 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
))
9683 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
))
;
9684 break;
9685 }
9686}
9687
9688static void
9689register_type_length_mismatch(void)
9690{
9691 static ei_register_info ei[] = {
9692 { &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)}}
}},
9693 { &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)}}
}},
9694 };
9695
9696 expert_module_t* expert_type_length_mismatch;
9697
9698 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9699
9700 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9701 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9702
9703 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9704 disabling them makes no sense. */
9705 proto_set_cant_toggle(proto_type_length_mismatch);
9706}
9707
9708static void
9709register_byte_array_string_decodinws_error(void)
9710{
9711 static ei_register_info ei[] = {
9712 { &ei_byte_array_string_decoding_failed_error,
9713 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9714 "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)}}
9715 }
9716 },
9717 };
9718
9719 expert_module_t* expert_byte_array_string_decoding_error;
9720
9721 proto_byte_array_string_decoding_error =
9722 proto_register_protocol("Byte Array-String Decoding Error",
9723 "Byte Array-string decoding error",
9724 "_ws.byte_array_string.decoding_error");
9725
9726 expert_byte_array_string_decoding_error =
9727 expert_register_protocol(proto_byte_array_string_decoding_error);
9728 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9729
9730 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9731 disabling them makes no sense. */
9732 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9733}
9734
9735static void
9736register_date_time_string_decodinws_error(void)
9737{
9738 static ei_register_info ei[] = {
9739 { &ei_date_time_string_decoding_failed_error,
9740 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9741 "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)}}
9742 }
9743 },
9744 };
9745
9746 expert_module_t* expert_date_time_string_decoding_error;
9747
9748 proto_date_time_string_decoding_error =
9749 proto_register_protocol("Date and Time-String Decoding Error",
9750 "Date and Time-string decoding error",
9751 "_ws.date_time_string.decoding_error");
9752
9753 expert_date_time_string_decoding_error =
9754 expert_register_protocol(proto_date_time_string_decoding_error);
9755 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9756
9757 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9758 disabling them makes no sense. */
9759 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9760}
9761
9762static void
9763register_string_errors(void)
9764{
9765 static ei_register_info ei[] = {
9766 { &ei_string_trailing_characters,
9767 { "_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)}}
}
9768 },
9769 };
9770
9771 expert_module_t* expert_string_errors;
9772
9773 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9774
9775 expert_string_errors = expert_register_protocol(proto_string_errors);
9776 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9777
9778 /* "String Errors" isn't really a protocol, it's an error indication;
9779 disabling them makes no sense. */
9780 proto_set_cant_toggle(proto_string_errors);
9781}
9782
9783#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
9784static int
9785proto_register_field_init(header_field_info *hfinfo, const int parent)
9786{
9787
9788 tmp_fld_check_assert(hfinfo);
9789
9790 hfinfo->parent = parent;
9791 hfinfo->same_name_next = NULL((void*)0);
9792 hfinfo->same_name_prev_id = -1;
9793
9794 /* if we always add and never delete, then id == len - 1 is correct */
9795 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9796 if (!gpa_hfinfo.hfi) {
9797 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9798 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9799 /* The entry with index 0 is not used. */
9800 gpa_hfinfo.hfi[0] = NULL((void*)0);
9801 gpa_hfinfo.len = 1;
9802 } else {
9803 gpa_hfinfo.allocated_len += 1000;
9804 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9805 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9806 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9807 }
9808 }
9809 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9810 gpa_hfinfo.len++;
9811 hfinfo->id = gpa_hfinfo.len - 1;
9812
9813 /* if we have real names, enter this field in the name tree */
9814 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
9815
9816 header_field_info *same_name_next_hfinfo;
9817 unsigned char c;
9818
9819 /* Check that the filter name (abbreviation) is legal;
9820 * it must contain only alphanumerics, '-', "_", and ".". */
9821 c = proto_check_field_name(hfinfo->abbrev);
9822 if (c) {
9823 if (c == '.') {
9824 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)
;
9825 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9826 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)
;
9827 } else {
9828 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)
;
9829 }
9830 }
9831
9832 /* We allow multiple hfinfo's to be registered under the same
9833 * abbreviation. This was done for X.25, as, depending
9834 * on whether it's modulo-8 or modulo-128 operation,
9835 * some bitfield fields may be in different bits of
9836 * a byte, and we want to be able to refer to that field
9837 * with one name regardless of whether the packets
9838 * are modulo-8 or modulo-128 packets. */
9839
9840 same_name_hfinfo = NULL((void*)0);
9841
9842 g_hash_table_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9843 /* GLIB 2.x - if it is already present
9844 * the previous hfinfo with the same name is saved
9845 * to same_name_hfinfo by value destroy callback */
9846 if (same_name_hfinfo) {
9847 /* There's already a field with this name.
9848 * Put the current field *before* that field
9849 * in the list of fields with this name, Thus,
9850 * we end up with an effectively
9851 * doubly-linked-list of same-named hfinfo's,
9852 * with the head of the list (stored in the
9853 * hash) being the last seen hfinfo.
9854 */
9855 same_name_next_hfinfo =
9856 same_name_hfinfo->same_name_next;
9857
9858 hfinfo->same_name_next = same_name_next_hfinfo;
9859 if (same_name_next_hfinfo)
9860 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9861
9862 same_name_hfinfo->same_name_next = hfinfo;
9863 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9864#ifdef ENABLE_CHECK_FILTER
9865 while (same_name_hfinfo) {
9866 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9867 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"
, 9867, __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)
;
9868 same_name_hfinfo = same_name_hfinfo->same_name_next;
9869 }
9870#endif
9871 }
9872 }
9873
9874 return hfinfo->id;
9875}
9876
9877void
9878proto_register_subtree_array(int * const *indices, const int num_indices)
9879{
9880 int i;
9881 int *const *ptr = indices;
9882
9883 /*
9884 * If we've already allocated the array of tree types, expand
9885 * it; this lets plugins such as mate add tree types after
9886 * the initial startup. (If we haven't already allocated it,
9887 * we don't allocate it; on the first pass, we just assign
9888 * ett values and keep track of how many we've assigned, and
9889 * when we're finished registering all dissectors we allocate
9890 * the array, so that we do only one allocation rather than
9891 * wasting CPU time and memory by growing the array for each
9892 * dissector that registers ett values.)
9893 */
9894 if (tree_is_expanded != NULL((void*)0)) {
9895 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9896
9897 /* set new items to 0 */
9898 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9899 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9900 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9901 }
9902
9903 /*
9904 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9905 * returning the indices through the pointers in the array whose
9906 * first element is pointed to by "indices", and update
9907 * "num_tree_types" appropriately.
9908 */
9909 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9910 if (**ptr != -1 && **ptr != 0) {
9911 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.")
9912 " 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.")
9913 " 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.")
9914 " 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.")
;
9915 }
9916 **ptr = num_tree_types;
9917 }
9918}
9919
9920static void
9921mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
9922{
9923 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "]";
9924 const size_t trunc_len = sizeof(trunc_str)-1;
9925 char *last_char;
9926
9927 /* ..... field_name: dataaaaaaaaaaaaa
9928 * |
9929 * ^^^^^ name_pos
9930 *
9931 * ..... field_name […]: dataaaaaaaaaaaaa
9932 *
9933 * name_pos==0 means that we have only data or only a field_name
9934 */
9935
9936 if (name_pos < size - trunc_len) {
9937 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
9938 memcpy(label_str + name_pos, trunc_str, trunc_len);
9939
9940 /* in general, label_str is UTF-8
9941 we can truncate it only at the beginning of a new character
9942 we go backwards from the byte right after our buffer and
9943 find the next starting byte of a UTF-8 character, this is
9944 where we cut
9945 there's no need to use g_utf8_find_prev_char(), the search
9946 will always succeed since we copied trunc_str into the
9947 buffer */
9948 /* g_utf8_prev_char does not deference the memory address
9949 * passed in (until after decrementing it, so it is perfectly
9950 * legal to pass in a pointer one past the last element.
9951 */
9952 last_char = g_utf8_prev_char(label_str + size);
9953 *last_char = '\0';
9954
9955 if (value_pos && *value_pos > 0) {
9956 if (name_pos == 0) {
9957 *value_pos += trunc_len;
9958 } else {
9959 /* Move one back to include trunc_str in the value. */
9960 *value_pos -= 1;
9961 }
9962 }
9963 } else if (name_pos < size)
9964 (void) g_strlcpy(label_str + name_pos, trunc_str, size - name_pos);
9965}
9966
9967static void
9968label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
9969{
9970 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
9971}
9972
9973static size_t
9974label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
9975{
9976 size_t name_pos;
9977
9978 /* "%s: %s", hfinfo->name, text */
9979 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
9980 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
9981 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
9982 if (value_pos) {
9983 *value_pos = pos;
9984 }
9985 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
9986 }
9987
9988 if (pos >= ITEM_LABEL_LENGTH240) {
9989 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9990 label_mark_truncated(label_str, name_pos, value_pos);
9991 }
9992
9993 return pos;
9994}
9995
9996static size_t
9997label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
9998{
9999 size_t name_pos;
10000
10001 /* "%s: %s (%s)", hfinfo->name, text, descr */
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 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10009 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10010 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10011 } else {
10012 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
10013 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10014 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
10015 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10016 }
10017 }
10018
10019 if (pos >= ITEM_LABEL_LENGTH240) {
10020 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10021 label_mark_truncated(label_str, name_pos, value_pos);
10022 }
10023
10024 return pos;
10025}
10026
10027void
10028proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10029{
10030 const header_field_info *hfinfo;
10031 const char *str;
10032 const uint8_t *bytes;
10033 uint32_t integer;
10034 const ipv4_addr_and_mask *ipv4;
10035 const ipv6_addr_and_prefix *ipv6;
10036 const e_guid_t *guid;
10037 char *name;
10038 address addr;
10039 char *addr_str;
10040 char *tmp;
10041
10042 if (!label_str) {
10043 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10043, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
10044 return;
10045 }
10046
10047 label_str[0]= '\0';
10048
10049 if (!fi) {
10050 return;
10051 }
10052
10053 hfinfo = fi->hfinfo;
10054
10055 switch (hfinfo->type) {
10056 case FT_NONE:
10057 case FT_PROTOCOL:
10058 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10059 if (value_pos) {
10060 *value_pos = strlen(hfinfo->name);
10061 }
10062 break;
10063
10064 case FT_BOOLEAN:
10065 fill_label_boolean(fi, label_str, value_pos);
10066 break;
10067
10068 case FT_BYTES:
10069 case FT_UINT_BYTES:
10070 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10071 fvalue_get_bytes_data(fi->value),
10072 (unsigned)fvalue_length2(fi->value));
10073 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10074 wmem_free(NULL((void*)0), tmp);
10075 break;
10076
10077 case FT_CHAR:
10078 if (hfinfo->bitmask) {
10079 fill_label_bitfield_char(fi, label_str, value_pos);
10080 } else {
10081 fill_label_char(fi, label_str, value_pos);
10082 }
10083 break;
10084
10085 /* Four types of integers to take care of:
10086 * Bitfield, with val_string
10087 * Bitfield, w/o val_string
10088 * Non-bitfield, with val_string
10089 * Non-bitfield, w/o val_string
10090 */
10091 case FT_UINT8:
10092 case FT_UINT16:
10093 case FT_UINT24:
10094 case FT_UINT32:
10095 if (hfinfo->bitmask) {
10096 fill_label_bitfield(fi, label_str, value_pos, false0);
10097 } else {
10098 fill_label_number(fi, label_str, value_pos, false0);
10099 }
10100 break;
10101
10102 case FT_FRAMENUM:
10103 fill_label_number(fi, label_str, value_pos, false0);
10104 break;
10105
10106 case FT_UINT40:
10107 case FT_UINT48:
10108 case FT_UINT56:
10109 case FT_UINT64:
10110 if (hfinfo->bitmask) {
10111 fill_label_bitfield64(fi, label_str, value_pos, false0);
10112 } else {
10113 fill_label_number64(fi, label_str, value_pos, false0);
10114 }
10115 break;
10116
10117 case FT_INT8:
10118 case FT_INT16:
10119 case FT_INT24:
10120 case FT_INT32:
10121 if (hfinfo->bitmask) {
10122 fill_label_bitfield(fi, label_str, value_pos, true1);
10123 } else {
10124 fill_label_number(fi, label_str, value_pos, true1);
10125 }
10126 break;
10127
10128 case FT_INT40:
10129 case FT_INT48:
10130 case FT_INT56:
10131 case FT_INT64:
10132 if (hfinfo->bitmask) {
10133 fill_label_bitfield64(fi, label_str, value_pos, true1);
10134 } else {
10135 fill_label_number64(fi, label_str, value_pos, true1);
10136 }
10137 break;
10138
10139 case FT_FLOAT:
10140 case FT_DOUBLE:
10141 fill_label_float(fi, label_str, value_pos);
10142 break;
10143
10144 case FT_ABSOLUTE_TIME:
10145 {
10146 const nstime_t *value = fvalue_get_time(fi->value);
10147 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10148 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10149 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10150 }
10151 if (hfinfo->strings) {
10152 /*
10153 * Table of time valus to be displayed
10154 * specially.
10155 */
10156 const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10157 if (time_string != NULL((void*)0)) {
10158 label_fill(label_str, 0, hfinfo, time_string, value_pos);
10159 break;
10160 }
10161 }
10162 tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10163 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10164 wmem_free(NULL((void*)0), tmp);
10165 break;
10166 }
10167 case FT_RELATIVE_TIME:
10168 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10169 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10170 wmem_free(NULL((void*)0), tmp);
10171 break;
10172
10173 case FT_IPXNET:
10174 integer = fvalue_get_uinteger(fi->value);
10175 tmp = get_ipxnet_name(NULL((void*)0), integer);
10176 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10177 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10178 wmem_free(NULL((void*)0), tmp);
10179 wmem_free(NULL((void*)0), addr_str);
10180 break;
10181
10182 case FT_VINES:
10183 addr.type = AT_VINES;
10184 addr.len = VINES_ADDR_LEN6;
10185 addr.data = fvalue_get_bytes_data(fi->value);
10186
10187 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10188 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10189 wmem_free(NULL((void*)0), addr_str);
10190 break;
10191
10192 case FT_ETHER:
10193 bytes = fvalue_get_bytes_data(fi->value);
10194
10195 addr.type = AT_ETHER;
10196 addr.len = 6;
10197 addr.data = bytes;
10198
10199 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10200 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10201 wmem_free(NULL((void*)0), addr_str);
10202 break;
10203
10204 case FT_IPv4:
10205 ipv4 = fvalue_get_ipv4(fi->value);
10206 set_address_ipv4(&addr, ipv4);
10207
10208 if (hfinfo->display == BASE_NETMASK) {
10209 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10210 } else {
10211 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10212 }
10213 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10214 wmem_free(NULL((void*)0), addr_str);
10215 free_address(&addr);
10216 break;
10217
10218 case FT_IPv6:
10219 ipv6 = fvalue_get_ipv6(fi->value);
10220 set_address_ipv6(&addr, ipv6);
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 free_address(&addr);
10226 break;
10227
10228 case FT_FCWWN:
10229 bytes = fvalue_get_bytes_data(fi->value);
10230 addr.type = AT_FCWWN;
10231 addr.len = FCWWN_ADDR_LEN8;
10232 addr.data = bytes;
10233
10234 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10235 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10236 wmem_free(NULL((void*)0), addr_str);
10237 break;
10238
10239 case FT_GUID:
10240 guid = fvalue_get_guid(fi->value);
10241 tmp = guid_to_str(NULL((void*)0), guid);
10242 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10243 wmem_free(NULL((void*)0), tmp);
10244 break;
10245
10246 case FT_OID:
10247 bytes = fvalue_get_bytes_data(fi->value);
10248 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10249 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10250 if (name) {
10251 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10252 wmem_free(NULL((void*)0), name);
10253 } else {
10254 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10255 }
10256 wmem_free(NULL((void*)0), tmp);
10257 break;
10258
10259 case FT_REL_OID:
10260 bytes = fvalue_get_bytes_data(fi->value);
10261 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10262 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10263 if (name) {
10264 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10265 wmem_free(NULL((void*)0), name);
10266 } else {
10267 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10268 }
10269 wmem_free(NULL((void*)0), tmp);
10270 break;
10271
10272 case FT_SYSTEM_ID:
10273 bytes = fvalue_get_bytes_data(fi->value);
10274 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10275 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10276 wmem_free(NULL((void*)0), tmp);
10277 break;
10278
10279 case FT_EUI64:
10280 bytes = fvalue_get_bytes_data(fi->value);
10281 addr.type = AT_EUI64;
10282 addr.len = EUI64_ADDR_LEN8;
10283 addr.data = bytes;
10284
10285 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10286 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10287 wmem_free(NULL((void*)0), addr_str);
10288 break;
10289 case FT_STRING:
10290 case FT_STRINGZ:
10291 case FT_UINT_STRING:
10292 case FT_STRINGZPAD:
10293 case FT_STRINGZTRUNC:
10294 case FT_AX25:
10295 str = fvalue_get_string(fi->value);
10296 label_fill(label_str, 0, hfinfo, str, value_pos);
10297 break;
10298
10299 case FT_IEEE_11073_SFLOAT:
10300 case FT_IEEE_11073_FLOAT:
10301 fill_label_ieee_11073_float(fi, label_str, value_pos);
10302 break;
10303
10304 default:
10305 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
))
10306 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
))
10307 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
))
10308 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
))
;
10309 break;
10310 }
10311}
10312
10313static void
10314fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10315{
10316 char *p;
10317 int bitfield_byte_length = 0, bitwidth;
10318 uint64_t unshifted_value;
10319 uint64_t value;
10320
10321 const header_field_info *hfinfo = fi->hfinfo;
10322
10323 value = fvalue_get_uinteger64(fi->value);
10324 if (hfinfo->bitmask) {
10325 /* Figure out the bit width */
10326 bitwidth = hfinfo_container_bitwidth(hfinfo);
10327
10328 /* Un-shift bits */
10329 unshifted_value = value;
10330 unshifted_value <<= hfinfo_bitshift(hfinfo);
10331
10332 /* Create the bitfield first */
10333 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10334 bitfield_byte_length = (int) (p - label_str);
10335 }
10336
10337 /* Fill in the textual info */
10338 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10339}
10340
10341static const char *
10342hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10343{
10344 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10345 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10346
10347 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10348 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10349 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10350 else
10351 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10352 }
10353
10354 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10355 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10356
10357 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10358 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10359
10360 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10361}
10362
10363static const char *
10364hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10365{
10366 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10367 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10368 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10369 else
10370 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10371 }
10372
10373 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10374 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10375
10376 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10377 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10378
10379 /* If this is reached somebody registered a 64-bit field with a 32-bit
10380 * value-string, which isn't right. */
10381 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)
10382 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10383
10384 /* This is necessary to squelch MSVC errors; is there
10385 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10386 never returns? */
10387 return NULL((void*)0);
10388}
10389
10390static const char *
10391hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10392{
10393 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10394 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10395
10396 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)
;
10397
10398 /* This is necessary to squelch MSVC errors; is there
10399 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10400 never returns? */
10401 return NULL((void*)0);
10402}
10403
10404static const char *
10405hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10406{
10407 const char *str = hf_try_val_to_str(value, hfinfo);
10408
10409 return (str) ? str : unknown_str;
10410}
10411
10412static const char *
10413hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10414{
10415 const char *str = hf_try_val64_to_str(value, hfinfo);
10416
10417 return (str) ? str : unknown_str;
10418}
10419
10420/* Fills data for bitfield chars with val_strings */
10421static void
10422fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10423{
10424 char *p;
10425 int bitfield_byte_length, bitwidth;
10426 uint32_t unshifted_value;
10427 uint32_t value;
10428
10429 char buf[32];
10430 const char *out;
10431
10432 const header_field_info *hfinfo = fi->hfinfo;
10433
10434 /* Figure out the bit width */
10435 bitwidth = hfinfo_container_bitwidth(hfinfo);
10436
10437 /* Un-shift bits */
10438 value = fvalue_get_uinteger(fi->value);
10439
10440 unshifted_value = value;
10441 if (hfinfo->bitmask) {
10442 unshifted_value <<= hfinfo_bitshift(hfinfo);
10443 }
10444
10445 /* Create the bitfield first */
10446 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10447 bitfield_byte_length = (int) (p - label_str);
10448
10449 /* Fill in the textual info using stored (shifted) value */
10450 if (hfinfo->display == BASE_CUSTOM) {
10451 char tmp[ITEM_LABEL_LENGTH240];
10452 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10453
10454 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10454, "fmtfunc"))))
;
10455 fmtfunc(tmp, value);
10456 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10457 }
10458 else if (hfinfo->strings) {
10459 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10460
10461 out = hfinfo_char_vals_format(hfinfo, buf, value);
10462 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10463 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10464 else
10465 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10466 }
10467 else {
10468 out = hfinfo_char_value_format(hfinfo, buf, value);
10469
10470 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10471 }
10472}
10473
10474/* Fills data for bitfield ints with val_strings */
10475static void
10476fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10477{
10478 char *p;
10479 int bitfield_byte_length, bitwidth;
10480 uint32_t value, unshifted_value;
10481 char buf[NUMBER_LABEL_LENGTH80];
10482 const char *out;
10483
10484 const header_field_info *hfinfo = fi->hfinfo;
10485
10486 /* Figure out the bit width */
10487 if (fi->flags & FI_VARINT0x00040000)
10488 bitwidth = fi->length*8;
10489 else
10490 bitwidth = hfinfo_container_bitwidth(hfinfo);
10491
10492 /* Un-shift bits */
10493 if (is_signed)
10494 value = fvalue_get_sinteger(fi->value);
10495 else
10496 value = fvalue_get_uinteger(fi->value);
10497
10498 unshifted_value = value;
10499 if (hfinfo->bitmask) {
10500 unshifted_value <<= hfinfo_bitshift(hfinfo);
10501 }
10502
10503 /* Create the bitfield first */
10504 if (fi->flags & FI_VARINT0x00040000)
10505 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10506 else
10507 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10508 bitfield_byte_length = (int) (p - label_str);
10509
10510 /* Fill in the textual info using stored (shifted) value */
10511 if (hfinfo->display == BASE_CUSTOM) {
10512 char tmp[ITEM_LABEL_LENGTH240];
10513 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10514
10515 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10515, "fmtfunc"))))
;
10516 fmtfunc(tmp, value);
10517 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10518 }
10519 else if (hfinfo->strings) {
10520 const char *val_str = hf_try_val_to_str(value, hfinfo);
10521
10522 out = hfinfo_number_vals_format(hfinfo, buf, value);
10523 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10524 /*
10525 * Unique values only display value_string string
10526 * if there is a match. Otherwise it's just a number
10527 */
10528 if (val_str) {
10529 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10530 } else {
10531 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10532 }
10533 } else {
10534 if (val_str == NULL((void*)0))
10535 val_str = "Unknown";
10536
10537 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10538 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10539 else
10540 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10541 }
10542 }
10543 else {
10544 out = hfinfo_number_value_format(hfinfo, buf, value);
10545
10546 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10547 }
10548}
10549
10550static void
10551fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10552{
10553 char *p;
10554 int bitfield_byte_length, bitwidth;
10555 uint64_t value, unshifted_value;
10556 char buf[NUMBER_LABEL_LENGTH80];
10557 const char *out;
10558
10559 const header_field_info *hfinfo = fi->hfinfo;
10560
10561 /* Figure out the bit width */
10562 if (fi->flags & FI_VARINT0x00040000)
10563 bitwidth = fi->length*8;
10564 else
10565 bitwidth = hfinfo_container_bitwidth(hfinfo);
10566
10567 /* Un-shift bits */
10568 if (is_signed)
10569 value = fvalue_get_sinteger64(fi->value);
10570 else
10571 value = fvalue_get_uinteger64(fi->value);
10572
10573 unshifted_value = value;
10574 if (hfinfo->bitmask) {
10575 unshifted_value <<= hfinfo_bitshift(hfinfo);
10576 }
10577
10578 /* Create the bitfield first */
10579 if (fi->flags & FI_VARINT0x00040000)
10580 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10581 else
10582 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10583 bitfield_byte_length = (int) (p - label_str);
10584
10585 /* Fill in the textual info using stored (shifted) value */
10586 if (hfinfo->display == BASE_CUSTOM) {
10587 char tmp[ITEM_LABEL_LENGTH240];
10588 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10589
10590 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10590, "fmtfunc64"
))))
;
10591 fmtfunc64(tmp, value);
10592 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10593 }
10594 else if (hfinfo->strings) {
10595 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10596
10597 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10598 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10599 /*
10600 * Unique values only display value_string string
10601 * if there is a match. Otherwise it's just a number
10602 */
10603 if (val_str) {
10604 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10605 } else {
10606 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10607 }
10608 } else {
10609 if (val_str == NULL((void*)0))
10610 val_str = "Unknown";
10611
10612 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10613 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10614 else
10615 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10616 }
10617 }
10618 else {
10619 out = hfinfo_number_value_format64(hfinfo, buf, value);
10620
10621 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10622 }
10623}
10624
10625static void
10626fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10627{
10628 const header_field_info *hfinfo = fi->hfinfo;
10629 uint32_t value;
10630
10631 char buf[32];
10632 const char *out;
10633
10634 value = fvalue_get_uinteger(fi->value);
10635
10636 /* Fill in the textual info */
10637 if (hfinfo->display == BASE_CUSTOM) {
10638 char tmp[ITEM_LABEL_LENGTH240];
10639 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10640
10641 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10641, "fmtfunc"))))
;
10642 fmtfunc(tmp, value);
10643 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10644 }
10645 else if (hfinfo->strings) {
10646 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10647
10648 out = hfinfo_char_vals_format(hfinfo, buf, value);
10649 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10650 }
10651 else {
10652 out = hfinfo_char_value_format(hfinfo, buf, value);
10653
10654 label_fill(label_str, 0, hfinfo, out, value_pos);
10655 }
10656}
10657
10658static void
10659fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10660{
10661 const header_field_info *hfinfo = fi->hfinfo;
10662 uint32_t value;
10663
10664 char buf[NUMBER_LABEL_LENGTH80];
10665 const char *out;
10666
10667 if (is_signed)
10668 value = fvalue_get_sinteger(fi->value);
10669 else
10670 value = fvalue_get_uinteger(fi->value);
10671
10672 /* Fill in the textual info */
10673 if (hfinfo->display == BASE_CUSTOM) {
10674 char tmp[ITEM_LABEL_LENGTH240];
10675 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10676
10677 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10677, "fmtfunc"))))
;
10678 fmtfunc(tmp, value);
10679 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10680 }
10681 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10682 /*
10683 * It makes no sense to have a value-string table for a
10684 * frame-number field - they're just integers giving
10685 * the ordinal frame number.
10686 */
10687 const char *val_str = hf_try_val_to_str(value, hfinfo);
10688
10689 out = hfinfo_number_vals_format(hfinfo, buf, value);
10690 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10691 /*
10692 * Unique values only display value_string string
10693 * if there is a match. Otherwise it's just a number
10694 */
10695 if (val_str) {
10696 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10697 } else {
10698 label_fill(label_str, 0, hfinfo, out, value_pos);
10699 }
10700 } else {
10701 if (val_str == NULL((void*)0))
10702 val_str = "Unknown";
10703
10704 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10705 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10706 else
10707 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10708 }
10709 }
10710 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
))
) {
10711 char tmp[ITEM_LABEL_LENGTH240];
10712
10713 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10714 display_to_port_type((field_display_e)hfinfo->display), value);
10715 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10716 }
10717 else {
10718 out = hfinfo_number_value_format(hfinfo, buf, value);
10719
10720 label_fill(label_str, 0, hfinfo, out, value_pos);
10721 }
10722}
10723
10724static void
10725fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10726{
10727 const header_field_info *hfinfo = fi->hfinfo;
10728 uint64_t value;
10729
10730 char buf[NUMBER_LABEL_LENGTH80];
10731 const char *out;
10732
10733 if (is_signed)
10734 value = fvalue_get_sinteger64(fi->value);
10735 else
10736 value = fvalue_get_uinteger64(fi->value);
10737
10738 /* Fill in the textual info */
10739 if (hfinfo->display == BASE_CUSTOM) {
10740 char tmp[ITEM_LABEL_LENGTH240];
10741 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10742
10743 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10743, "fmtfunc64"
))))
;
10744 fmtfunc64(tmp, value);
10745 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10746 }
10747 else if (hfinfo->strings) {
10748 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10749
10750 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10751 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10752 /*
10753 * Unique values only display value_string string
10754 * if there is a match. Otherwise it's just a number
10755 */
10756 if (val_str) {
10757 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10758 } else {
10759 label_fill(label_str, 0, hfinfo, out, value_pos);
10760 }
10761 } else {
10762 if (val_str == NULL((void*)0))
10763 val_str = "Unknown";
10764
10765 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10766 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10767 else
10768 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10769 }
10770 }
10771 else {
10772 out = hfinfo_number_value_format64(hfinfo, buf, value);
10773
10774 label_fill(label_str, 0, hfinfo, out, value_pos);
10775 }
10776}
10777
10778static size_t
10779fill_display_label_float(const field_info *fi, char *label_str)
10780{
10781 int display;
10782 int n;
10783 double value;
10784
10785 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10786 value = fvalue_get_floating(fi->value);
10787
10788 if (display == BASE_CUSTOM) {
10789 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10790 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10790, "fmtfunc"))))
;
10791 fmtfunc(label_str, value);
10792 return strlen(label_str);
10793 }
10794
10795 switch (display) {
10796 case BASE_NONE:
10797 if (fi->hfinfo->type == FT_FLOAT) {
10798 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%.*g", FLT_DIG6, value);
10799 } else {
10800 n = (int)strlen(dtoa_g_fmt(label_str, value));
10801 }
10802 break;
10803 case BASE_DEC:
10804 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%f", value);
10805 break;
10806 case BASE_HEX:
10807 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%a", value);
10808 break;
10809 case BASE_EXP:
10810 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%e", value);
10811 break;
10812 default:
10813 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10813
, __func__, "assertion \"not reached\" failed")
;
10814 }
10815 if (n < 0) {
10816 return 0; /* error */
10817 }
10818 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10819 const char *hf_str_val;
10820 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10821 n += proto_strlcpy(label_str + n, hf_str_val, ITEM_LABEL_LENGTH240 - n);
10822 }
10823 if (n > ITEM_LABEL_LENGTH240) {
10824 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10824, __func__, "label length too small"); } } while (0)
;
10825 return strlen(label_str);
10826 }
10827
10828 return n;
10829}
10830
10831void
10832fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10833{
10834 char tmp[ITEM_LABEL_LENGTH240];
10835
10836 fill_display_label_float(fi, tmp);
10837 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10838}
10839
10840static size_t
10841fill_display_label_ieee_11073_float(const field_info *fi, char *label_str)
10842{
10843 int display;
10844 size_t pos = 0;
10845 double value;
10846 char* tmp_str;
10847
10848 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10849 tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10850 pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10851 wmem_free(NULL((void*)0), tmp_str);
10852
10853 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10854 const char *hf_str_val;
10855 fvalue_to_double(fi->value, &value);
10856 hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10857 pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10858 }
10859 if (pos > ITEM_LABEL_LENGTH240) {
10860 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10860, __func__, "label length too small"); } } while (0)
;
10861 return strlen(label_str);
10862 }
10863
10864 return pos;
10865}
10866
10867void
10868fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10869{
10870 char tmp[ITEM_LABEL_LENGTH240];
10871
10872 fill_display_label_ieee_11073_float(fi, tmp);
10873 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10874}
10875
10876int
10877hfinfo_bitshift(const header_field_info *hfinfo)
10878{
10879 return ws_ctz(hfinfo->bitmask);
10880}
10881
10882
10883static int
10884hfinfo_bitoffset(const header_field_info *hfinfo)
10885{
10886 if (!hfinfo->bitmask) {
10887 return 0;
10888 }
10889
10890 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10891 * as the first bit */
10892 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10893}
10894
10895static int
10896hfinfo_mask_bitwidth(const header_field_info *hfinfo)
10897{
10898 if (!hfinfo->bitmask) {
10899 return 0;
10900 }
10901
10902 /* ilog2 = first set bit, ctz = last set bit */
10903 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
10904}
10905
10906static int
10907hfinfo_type_bitwidth(enum ftenum type)
10908{
10909 int bitwidth = 0;
10910
10911 switch (type) {
10912 case FT_CHAR:
10913 case FT_UINT8:
10914 case FT_INT8:
10915 bitwidth = 8;
10916 break;
10917 case FT_UINT16:
10918 case FT_INT16:
10919 bitwidth = 16;
10920 break;
10921 case FT_UINT24:
10922 case FT_INT24:
10923 bitwidth = 24;
10924 break;
10925 case FT_UINT32:
10926 case FT_INT32:
10927 bitwidth = 32;
10928 break;
10929 case FT_UINT40:
10930 case FT_INT40:
10931 bitwidth = 40;
10932 break;
10933 case FT_UINT48:
10934 case FT_INT48:
10935 bitwidth = 48;
10936 break;
10937 case FT_UINT56:
10938 case FT_INT56:
10939 bitwidth = 56;
10940 break;
10941 case FT_UINT64:
10942 case FT_INT64:
10943 bitwidth = 64;
10944 break;
10945 default:
10946 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 10946))
;
10947 ;
10948 }
10949 return bitwidth;
10950}
10951
10952
10953static int
10954hfinfo_container_bitwidth(const header_field_info *hfinfo)
10955{
10956 if (!hfinfo->bitmask) {
10957 return 0;
10958 }
10959
10960 if (hfinfo->type == FT_BOOLEAN) {
10961 return hfinfo->display; /* hacky? :) */
10962 }
10963
10964 return hfinfo_type_bitwidth(hfinfo->type);
10965}
10966
10967static int
10968hfinfo_hex_digits(const header_field_info *hfinfo)
10969{
10970 int bitwidth;
10971
10972 /* If we have a bitmask, hfinfo->type is the width of the container, so not
10973 * appropriate to determine the number of hex digits for the field.
10974 * So instead, we compute it from the bitmask.
10975 */
10976 if (hfinfo->bitmask != 0) {
10977 bitwidth = hfinfo_mask_bitwidth(hfinfo);
10978 } else {
10979 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
10980 }
10981
10982 /* Divide by 4, rounding up, to get number of hex digits. */
10983 return (bitwidth + 3) / 4;
10984}
10985
10986const char *
10987hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
10988{
10989 char *ptr = &buf[6];
10990 static const char hex_digits[16] =
10991 { '0', '1', '2', '3', '4', '5', '6', '7',
10992 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
10993
10994 *ptr = '\0';
10995 *(--ptr) = '\'';
10996 /* Properly format value */
10997 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
10998 /*
10999 * Printable, so just show the character, and, if it needs
11000 * to be escaped, escape it.
11001 */
11002 *(--ptr) = value;
11003 if (value == '\\' || value == '\'')
11004 *(--ptr) = '\\';
11005 } else {
11006 /*
11007 * Non-printable; show it as an escape sequence.
11008 */
11009 switch (value) {
11010
11011 case '\0':
11012 /*
11013 * Show a NUL with only one digit.
11014 */
11015 *(--ptr) = '0';
11016 break;
11017
11018 case '\a':
11019 case '\b':
11020 case '\f':
11021 case '\n':
11022 case '\r':
11023 case '\t':
11024 case '\v':
11025 *(--ptr) = value - '\a' + 'a';
11026 break;
11027
11028 default:
11029 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11030
11031 case BASE_OCT:
11032 *(--ptr) = (value & 0x7) + '0';
11033 value >>= 3;
11034 *(--ptr) = (value & 0x7) + '0';
11035 value >>= 3;
11036 *(--ptr) = (value & 0x7) + '0';
11037 break;
11038
11039 case BASE_HEX:
11040 *(--ptr) = hex_digits[value & 0x0F];
11041 value >>= 4;
11042 *(--ptr) = hex_digits[value & 0x0F];
11043 *(--ptr) = 'x';
11044 break;
11045
11046 default:
11047 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11048 }
11049 }
11050 *(--ptr) = '\\';
11051 }
11052 *(--ptr) = '\'';
11053 return ptr;
11054}
11055
11056static const char *
11057hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11058{
11059 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11060 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
))
;
11061
11062 *ptr = '\0';
11063 /* Properly format value */
11064 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11065 case BASE_DEC:
11066 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11067
11068 case BASE_DEC_HEX:
11069 *(--ptr) = ')';
11070 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11071 *(--ptr) = '(';
11072 *(--ptr) = ' ';
11073 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11074 return ptr;
11075
11076 case BASE_OCT:
11077 return oct_to_str_back(ptr, value);
11078
11079 case BASE_HEX:
11080 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11081
11082 case BASE_HEX_DEC:
11083 *(--ptr) = ')';
11084 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11085 *(--ptr) = '(';
11086 *(--ptr) = ' ';
11087 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11088 return ptr;
11089
11090 case BASE_PT_UDP:
11091 case BASE_PT_TCP:
11092 case BASE_PT_DCCP:
11093 case BASE_PT_SCTP:
11094 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11095 display_to_port_type((field_display_e)display), value);
11096 return buf;
11097 case BASE_OUI:
11098 {
11099 uint8_t p_oui[3];
11100 const char *manuf_name;
11101
11102 p_oui[0] = value >> 16 & 0xFF;
11103 p_oui[1] = value >> 8 & 0xFF;
11104 p_oui[2] = value & 0xFF;
11105
11106 /* Attempt an OUI lookup. */
11107 manuf_name = uint_get_manuf_name_if_known(value);
11108 if (manuf_name == NULL((void*)0)) {
11109 /* Could not find an OUI. */
11110 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11111 }
11112 else {
11113 /* Found an address string. */
11114 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11115 }
11116 return buf;
11117 }
11118
11119 default:
11120 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11121 }
11122 return ptr;
11123}
11124
11125static const char *
11126hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11127{
11128 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11129 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
))
;
11130
11131 *ptr = '\0';
11132 /* Properly format value */
11133 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11134 case BASE_DEC:
11135 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11136
11137 case BASE_DEC_HEX:
11138 *(--ptr) = ')';
11139 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11140 *(--ptr) = '(';
11141 *(--ptr) = ' ';
11142 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11143 return ptr;
11144
11145 case BASE_OCT:
11146 return oct64_to_str_back(ptr, value);
11147
11148 case BASE_HEX:
11149 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11150
11151 case BASE_HEX_DEC:
11152 *(--ptr) = ')';
11153 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11154 *(--ptr) = '(';
11155 *(--ptr) = ' ';
11156 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11157 return ptr;
11158
11159 default:
11160 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11161 }
11162
11163 return ptr;
11164}
11165
11166static const char *
11167hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11168{
11169 int display = hfinfo->display;
11170
11171 if (hfinfo->type == FT_FRAMENUM) {
11172 /*
11173 * Frame numbers are always displayed in decimal.
11174 */
11175 display = BASE_DEC;
11176 }
11177
11178 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11179}
11180
11181static const char *
11182hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11183{
11184 int display = hfinfo->display;
11185
11186 if (hfinfo->type == FT_FRAMENUM) {
11187 /*
11188 * Frame numbers are always displayed in decimal.
11189 */
11190 display = BASE_DEC;
11191 }
11192
11193 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11194}
11195
11196static const char *
11197hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11198{
11199 /* Get the underlying BASE_ value */
11200 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11201
11202 return hfinfo_char_value_format_display(display, buf, value);
11203}
11204
11205static const char *
11206hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11207{
11208 /* Get the underlying BASE_ value */
11209 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11210
11211 if (hfinfo->type == FT_FRAMENUM) {
11212 /*
11213 * Frame numbers are always displayed in decimal.
11214 */
11215 display = BASE_DEC;
11216 }
11217
11218 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11219 display = BASE_DEC;
11220 } else if (display == BASE_OUI) {
11221 display = BASE_HEX;
11222 }
11223
11224 switch (display) {
11225 case BASE_NONE:
11226 /* case BASE_DEC: */
11227 case BASE_DEC_HEX:
11228 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11229 case BASE_CUSTOM:
11230 display = BASE_DEC;
11231 break;
11232
11233 /* case BASE_HEX: */
11234 case BASE_HEX_DEC:
11235 display = BASE_HEX;
11236 break;
11237 }
11238
11239 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11240}
11241
11242static const char *
11243hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11244{
11245 /* Get the underlying BASE_ value */
11246 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11247
11248 if (hfinfo->type == FT_FRAMENUM) {
11249 /*
11250 * Frame numbers are always displayed in decimal.
11251 */
11252 display = BASE_DEC;
11253 }
11254
11255 switch (display) {
11256 case BASE_NONE:
11257 /* case BASE_DEC: */
11258 case BASE_DEC_HEX:
11259 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11260 case BASE_CUSTOM:
11261 display = BASE_DEC;
11262 break;
11263
11264 /* case BASE_HEX: */
11265 case BASE_HEX_DEC:
11266 display = BASE_HEX;
11267 break;
11268 }
11269
11270 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11271}
11272
11273static const char *
11274hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11275{
11276 /* Get the underlying BASE_ value */
11277 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11278
11279 return hfinfo_char_value_format_display(display, buf, value);
11280}
11281
11282static const char *
11283hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11284{
11285 /* Get the underlying BASE_ value */
11286 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11287
11288 if (display == BASE_NONE)
11289 return NULL((void*)0);
11290
11291 if (display == BASE_DEC_HEX)
11292 display = BASE_DEC;
11293 if (display == BASE_HEX_DEC)
11294 display = BASE_HEX;
11295
11296 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11297}
11298
11299static const char *
11300hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11301{
11302 /* Get the underlying BASE_ value */
11303 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11304
11305 if (display == BASE_NONE)
11306 return NULL((void*)0);
11307
11308 if (display == BASE_DEC_HEX)
11309 display = BASE_DEC;
11310 if (display == BASE_HEX_DEC)
11311 display = BASE_HEX;
11312
11313 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11314}
11315
11316const char *
11317proto_registrar_get_name(const int n)
11318{
11319 header_field_info *hfinfo;
11320
11321 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", 11321
, __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", 11321
, "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", 11321, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11322 return hfinfo->name;
11323}
11324
11325const char *
11326proto_registrar_get_abbrev(const int n)
11327{
11328 header_field_info *hfinfo;
11329
11330 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", 11330
, __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", 11330
, "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", 11330, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11331 return hfinfo->abbrev;
11332}
11333
11334enum ftenum
11335proto_registrar_get_ftype(const int n)
11336{
11337 header_field_info *hfinfo;
11338
11339 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11339
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11339
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11339, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11340 return hfinfo->type;
11341}
11342
11343int
11344proto_registrar_get_parent(const int n)
11345{
11346 header_field_info *hfinfo;
11347
11348 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11348
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11348
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11348, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11349 return hfinfo->parent;
11350}
11351
11352bool_Bool
11353proto_registrar_is_protocol(const int n)
11354{
11355 header_field_info *hfinfo;
11356
11357 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11357
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11357
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11357, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11358 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11359}
11360
11361/* Returns length of field in packet (not necessarily the length
11362 * in our internal representation, as in the case of IPv4).
11363 * 0 means undeterminable at time of registration
11364 * -1 means the field is not registered. */
11365int
11366proto_registrar_get_length(const int n)
11367{
11368 header_field_info *hfinfo;
11369
11370 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", 11370
, __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", 11370
, "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", 11370, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11371 return ftype_wire_size(hfinfo->type);
11372}
11373
11374/* Looks for a protocol or a field in a proto_tree. Returns true if
11375 * it exists anywhere, or false if it exists nowhere. */
11376bool_Bool
11377proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11378{
11379 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11380
11381 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11382 return true1;
11383 }
11384 else {
11385 return false0;
11386 }
11387}
11388
11389/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11390 * This only works if the hfindex was "primed" before the dissection
11391 * took place, as we just pass back the already-created GPtrArray*.
11392 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11393 * handles that. */
11394GPtrArray *
11395proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11396{
11397 if (!tree)
11398 return NULL((void*)0);
11399
11400 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11401 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11402 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11403 else
11404 return NULL((void*)0);
11405}
11406
11407bool_Bool
11408proto_tracking_interesting_fields(const proto_tree *tree)
11409{
11410 GHashTable *interesting_hfids;
11411
11412 if (!tree)
11413 return false0;
11414
11415 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11416
11417 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11418}
11419
11420/* Helper struct for proto_find_info() and proto_all_finfos() */
11421typedef struct {
11422 GPtrArray *array;
11423 int id;
11424} ffdata_t;
11425
11426/* Helper function for proto_find_info() */
11427static bool_Bool
11428find_finfo(proto_node *node, void * data)
11429{
11430 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11431 if (fi && fi->hfinfo) {
11432 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11433 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11434 }
11435 }
11436
11437 /* Don't stop traversing. */
11438 return false0;
11439}
11440
11441/* Helper function for proto_find_first_info() */
11442static bool_Bool
11443find_first_finfo(proto_node *node, void *data)
11444{
11445 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11446 if (fi && fi->hfinfo) {
11447 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11448 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11449
11450 /* Stop traversing. */
11451 return true1;
11452 }
11453 }
11454
11455 /* Continue traversing. */
11456 return false0;
11457}
11458
11459/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11460* This works on any proto_tree, primed or unprimed, but actually searches
11461* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11462* The caller does need to free the returned GPtrArray with
11463* g_ptr_array_free(<array>, true).
11464*/
11465GPtrArray *
11466proto_find_finfo(proto_tree *tree, const int id)
11467{
11468 ffdata_t ffdata;
11469
11470 ffdata.array = g_ptr_array_new();
11471 ffdata.id = id;
11472
11473 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11474
11475 return ffdata.array;
11476}
11477
11478/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11479* This works on any proto_tree, primed or unprimed, but actually searches
11480* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11481* The caller does need to free the returned GPtrArray with
11482* g_ptr_array_free(<array>, true).
11483*/
11484GPtrArray *
11485proto_find_first_finfo(proto_tree *tree, const int id)
11486{
11487 ffdata_t ffdata;
11488
11489 ffdata.array = g_ptr_array_new();
11490 ffdata.id = id;
11491
11492 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11493
11494 return ffdata.array;
11495}
11496
11497/* Helper function for proto_all_finfos() */
11498static bool_Bool
11499every_finfo(proto_node *node, void * data)
11500{
11501 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11502 if (fi && fi->hfinfo) {
11503 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11504 }
11505
11506 /* Don't stop traversing. */
11507 return false0;
11508}
11509
11510/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11511 * The caller does need to free the returned GPtrArray with
11512 * g_ptr_array_free(<array>, true).
11513 */
11514GPtrArray *
11515proto_all_finfos(proto_tree *tree)
11516{
11517 ffdata_t ffdata;
11518
11519 /* Pre allocate enough space to hold all fields in most cases */
11520 ffdata.array = g_ptr_array_sized_new(512);
11521 ffdata.id = 0;
11522
11523 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11524
11525 return ffdata.array;
11526}
11527
11528
11529typedef struct {
11530 unsigned offset;
11531 field_info *finfo;
11532 tvbuff_t *tvb;
11533} offset_search_t;
11534
11535static bool_Bool
11536check_for_offset(proto_node *node, void * data)
11537{
11538 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11539 offset_search_t *offsearch = (offset_search_t *)data;
11540
11541 /* !fi == the top most container node which holds nothing */
11542 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11543 if (offsearch->offset >= (unsigned) fi->start &&
11544 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11545
11546 offsearch->finfo = fi;
11547 return false0; /* keep traversing */
11548 }
11549 }
11550 return false0; /* keep traversing */
11551}
11552
11553/* Search a proto_tree backwards (from leaves to root) looking for the field
11554 * whose start/length occupies 'offset' */
11555/* XXX - I couldn't find an easy way to search backwards, so I search
11556 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11557 * the one I want to return to the user. This algorithm is inefficient
11558 * and could be re-done, but I'd have to handle all the children and
11559 * siblings of each node myself. When I have more time I'll do that.
11560 * (yeah right) */
11561field_info *
11562proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11563{
11564 offset_search_t offsearch;
11565
11566 offsearch.offset = offset;
11567 offsearch.finfo = NULL((void*)0);
11568 offsearch.tvb = tvb;
11569
11570 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11571
11572 return offsearch.finfo;
11573}
11574
11575typedef struct {
11576 int length;
11577 char *buf;
11578} decoded_data_t;
11579
11580static bool_Bool
11581check_for_undecoded(proto_node *node, void * data)
11582{
11583 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11584 decoded_data_t* decoded = (decoded_data_t*)data;
11585 int i;
11586 unsigned byte;
11587 unsigned bit;
11588
11589 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11590 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11591 byte = i / 8;
11592 bit = i % 8;
11593 decoded->buf[byte] |= (1 << bit);
11594 }
11595 }
11596
11597 return false0;
11598}
11599
11600char*
11601proto_find_undecoded_data(proto_tree *tree, unsigned length)
11602{
11603 decoded_data_t decoded;
11604 decoded.length = length;
11605 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11606
11607 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11608 return decoded.buf;
11609}
11610
11611/* Dumps the protocols in the registration database to stdout. An independent
11612 * program can take this output and format it into nice tables or HTML or
11613 * whatever.
11614 *
11615 * There is one record per line. The fields are tab-delimited.
11616 *
11617 * Field 1 = protocol name
11618 * Field 2 = protocol short name
11619 * Field 3 = protocol filter name
11620 * Field 4 = protocol enabled
11621 * Field 5 = protocol enabled by default
11622 * Field 6 = protocol can toggle
11623 */
11624void
11625proto_registrar_dump_protocols(void)
11626{
11627 protocol_t *protocol;
11628 int i;
11629 void *cookie = NULL((void*)0);
11630
11631
11632 i = proto_get_first_protocol(&cookie);
11633 while (i != -1) {
11634 protocol = find_protocol_by_id(i);
11635 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11636 protocol->name,
11637 protocol->short_name,
11638 protocol->filter_name,
11639 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11640 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11641 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11642 i = proto_get_next_protocol(&cookie);
11643 }
11644}
11645
11646/* Dumps the value_strings, extended value string headers, range_strings
11647 * or true/false strings for fields that have them.
11648 * There is one record per line. Fields are tab-delimited.
11649 * There are four types of records: Value String, Extended Value String Header,
11650 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11651 * the type of record.
11652 *
11653 * Note that a record will be generated only if the value_string,... is referenced
11654 * in a registered hfinfo entry.
11655 *
11656 *
11657 * Value Strings
11658 * -------------
11659 * Field 1 = 'V'
11660 * Field 2 = Field abbreviation to which this value string corresponds
11661 * Field 3 = Integer value
11662 * Field 4 = String
11663 *
11664 * Extended Value String Headers
11665 * -----------------------------
11666 * Field 1 = 'E'
11667 * Field 2 = Field abbreviation to which this extended value string header corresponds
11668 * Field 3 = Extended Value String "Name"
11669 * Field 4 = Number of entries in the associated value_string array
11670 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11671 *
11672 * Range Strings
11673 * -------------
11674 * Field 1 = 'R'
11675 * Field 2 = Field abbreviation to which this range string corresponds
11676 * Field 3 = Integer value: lower bound
11677 * Field 4 = Integer value: upper bound
11678 * Field 5 = String
11679 *
11680 * True/False Strings
11681 * ------------------
11682 * Field 1 = 'T'
11683 * Field 2 = Field abbreviation to which this true/false string corresponds
11684 * Field 3 = True String
11685 * Field 4 = False String
11686 */
11687void
11688proto_registrar_dump_values(void)
11689{
11690 header_field_info *hfinfo;
11691 int i, len, vi;
11692 const value_string *vals;
11693 const val64_string *vals64;
11694 const range_string *range;
11695 const true_false_string *tfs;
11696 const unit_name_string *units;
11697
11698 len = gpa_hfinfo.len;
11699 for (i = 0; i < len ; i++) {
11700 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11701 continue; /* This is a deregistered protocol or field */
11702
11703 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", 11703
, __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", 11703
, "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", 11703, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11704
11705 if (hfinfo->id == hf_text_only) {
11706 continue;
11707 }
11708
11709 /* ignore protocols */
11710 if (proto_registrar_is_protocol(i)) {
11711 continue;
11712 }
11713 /* process header fields */
11714#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11715 /*
11716 * If this field isn't at the head of the list of
11717 * fields with this name, skip this field - all
11718 * fields with the same name are really just versions
11719 * of the same field stored in different bits, and
11720 * should have the same type/radix/value list, and
11721 * just differ in their bit masks. (If a field isn't
11722 * a bitfield, but can be, say, 1 or 2 bytes long,
11723 * it can just be made FT_UINT16, meaning the
11724 * *maximum* length is 2 bytes, and be used
11725 * for all lengths.)
11726 */
11727 if (hfinfo->same_name_prev_id != -1)
11728 continue;
11729#endif
11730 vals = NULL((void*)0);
11731 vals64 = NULL((void*)0);
11732 range = NULL((void*)0);
11733 tfs = NULL((void*)0);
11734 units = NULL((void*)0);
11735
11736 if (hfinfo->strings != NULL((void*)0)) {
11737 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11738 (hfinfo->type == FT_CHAR ||
11739 hfinfo->type == FT_UINT8 ||
11740 hfinfo->type == FT_UINT16 ||
11741 hfinfo->type == FT_UINT24 ||
11742 hfinfo->type == FT_UINT32 ||
11743 hfinfo->type == FT_UINT40 ||
11744 hfinfo->type == FT_UINT48 ||
11745 hfinfo->type == FT_UINT56 ||
11746 hfinfo->type == FT_UINT64 ||
11747 hfinfo->type == FT_INT8 ||
11748 hfinfo->type == FT_INT16 ||
11749 hfinfo->type == FT_INT24 ||
11750 hfinfo->type == FT_INT32 ||
11751 hfinfo->type == FT_INT40 ||
11752 hfinfo->type == FT_INT48 ||
11753 hfinfo->type == FT_INT56 ||
11754 hfinfo->type == FT_INT64 ||
11755 hfinfo->type == FT_FLOAT ||
11756 hfinfo->type == FT_DOUBLE)) {
11757
11758 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11759 range = (const range_string *)hfinfo->strings;
11760 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11761 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11762 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11763 } else {
11764 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11765 }
11766 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11767 vals64 = (const val64_string *)hfinfo->strings;
11768 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11769 units = (const unit_name_string *)hfinfo->strings;
11770 } else {
11771 vals = (const value_string *)hfinfo->strings;
11772 }
11773 }
11774 else if (hfinfo->type == FT_BOOLEAN) {
11775 tfs = (const struct true_false_string *)hfinfo->strings;
11776 }
11777 }
11778
11779 /* Print value strings? */
11780 if (vals) {
11781 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11782 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11783 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11784 if (!val64_string_ext_validate(vse_p)) {
11785 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11785, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11786 continue;
11787 }
11788 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11789 printf("E\t%s\t%u\t%s\t%s\n",
11790 hfinfo->abbrev,
11791 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11792 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11793 val64_string_ext_match_type_str(vse_p));
11794 } else {
11795 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11796 if (!value_string_ext_validate(vse_p)) {
11797 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11797, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11798 continue;
11799 }
11800 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11801 printf("E\t%s\t%u\t%s\t%s\n",
11802 hfinfo->abbrev,
11803 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11804 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11805 value_string_ext_match_type_str(vse_p));
11806 }
11807 }
11808 vi = 0;
11809 while (vals[vi].strptr) {
11810 /* Print in the proper base */
11811 if (hfinfo->type == FT_CHAR) {
11812 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11813 printf("V\t%s\t'%c'\t%s\n",
11814 hfinfo->abbrev,
11815 vals[vi].value,
11816 vals[vi].strptr);
11817 } else {
11818 if (hfinfo->display == BASE_HEX) {
11819 printf("V\t%s\t'\\x%02x'\t%s\n",
11820 hfinfo->abbrev,
11821 vals[vi].value,
11822 vals[vi].strptr);
11823 }
11824 else {
11825 printf("V\t%s\t'\\%03o'\t%s\n",
11826 hfinfo->abbrev,
11827 vals[vi].value,
11828 vals[vi].strptr);
11829 }
11830 }
11831 } else {
11832 if (hfinfo->display == BASE_HEX) {
11833 printf("V\t%s\t0x%x\t%s\n",
11834 hfinfo->abbrev,
11835 vals[vi].value,
11836 vals[vi].strptr);
11837 }
11838 else {
11839 printf("V\t%s\t%u\t%s\n",
11840 hfinfo->abbrev,
11841 vals[vi].value,
11842 vals[vi].strptr);
11843 }
11844 }
11845 vi++;
11846 }
11847 }
11848 else if (vals64) {
11849 vi = 0;
11850 while (vals64[vi].strptr) {
11851 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11852 hfinfo->abbrev,
11853 vals64[vi].value,
11854 vals64[vi].strptr);
11855 vi++;
11856 }
11857 }
11858
11859 /* print range strings? */
11860 else if (range) {
11861 vi = 0;
11862 while (range[vi].strptr) {
11863 /* Print in the proper base */
11864 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11865 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11866 hfinfo->abbrev,
11867 range[vi].value_min,
11868 range[vi].value_max,
11869 range[vi].strptr);
11870 }
11871 else {
11872 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11873 hfinfo->abbrev,
11874 range[vi].value_min,
11875 range[vi].value_max,
11876 range[vi].strptr);
11877 }
11878 vi++;
11879 }
11880 }
11881
11882 /* Print true/false strings? */
11883 else if (tfs) {
11884 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11885 tfs->true_string, tfs->false_string);
11886 }
11887 /* Print unit strings? */
11888 else if (units) {
11889 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11890 units->singular, units->plural ? units->plural : "(no plural)");
11891 }
11892 }
11893}
11894
11895/* Prints the number of registered fields.
11896 * Useful for determining an appropriate value for
11897 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
11898 *
11899 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
11900 * the number of fields, true otherwise.
11901 */
11902bool_Bool
11903proto_registrar_dump_fieldcount(void)
11904{
11905 uint32_t i;
11906 header_field_info *hfinfo;
11907 uint32_t deregistered_count = 0;
11908 uint32_t same_name_count = 0;
11909 uint32_t protocol_count = 0;
11910
11911 for (i = 0; i < gpa_hfinfo.len; i++) {
11912 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
11913 deregistered_count++;
11914 continue; /* This is a deregistered protocol or header field */
11915 }
11916
11917 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", 11917
, __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", 11917
, "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", 11917, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11918
11919 if (proto_registrar_is_protocol(i))
11920 protocol_count++;
11921
11922 if (hfinfo->same_name_prev_id != -1)
11923 same_name_count++;
11924 }
11925
11926 printf("There are %u header fields registered, of which:\n"
11927 "\t%u are deregistered\n"
11928 "\t%u are protocols\n"
11929 "\t%u have the same name as another field\n\n",
11930 gpa_hfinfo.len, deregistered_count, protocol_count,
11931 same_name_count);
11932
11933 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
11934 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
11935 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
11936 "\n");
11937
11938 printf("The header field table consumes %u KiB of memory.\n",
11939 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
11940 printf("The fields themselves consume %u KiB of memory.\n",
11941 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
11942
11943 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
11944}
11945
11946static void
11947elastic_add_base_mapping(json_dumper *dumper)
11948{
11949 json_dumper_set_member_name(dumper, "index_patterns");
11950 json_dumper_begin_array(dumper);
11951 // The index names from write_json_index() in print.c
11952 json_dumper_value_string(dumper, "packets-*");
11953 json_dumper_end_array(dumper);
11954
11955 json_dumper_set_member_name(dumper, "settings");
11956 json_dumper_begin_object(dumper);
11957 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
11958 json_dumper_value_anyf(dumper, "%d", 1000000);
11959 json_dumper_end_object(dumper);
11960}
11961
11962static char*
11963ws_type_to_elastic(unsigned type)
11964{
11965 switch(type) {
11966 case FT_INT8:
11967 return "byte";
11968 case FT_UINT8:
11969 case FT_INT16:
11970 return "short";
11971 case FT_UINT16:
11972 case FT_INT32:
11973 case FT_UINT24:
11974 case FT_INT24:
11975 return "integer";
11976 case FT_FRAMENUM:
11977 case FT_UINT32:
11978 case FT_UINT40:
11979 case FT_UINT48:
11980 case FT_UINT56:
11981 case FT_INT40:
11982 case FT_INT48:
11983 case FT_INT56:
11984 case FT_INT64:
11985 return "long";
11986 case FT_UINT64:
11987 return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
11988 case FT_FLOAT:
11989 return "float";
11990 case FT_DOUBLE:
11991 case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
11992 return "double";
11993 case FT_IPv6:
11994 case FT_IPv4:
11995 return "ip";
11996 case FT_ABSOLUTE_TIME:
11997 return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
11998 case FT_BOOLEAN:
11999 return "boolean";
12000 default:
12001 return NULL((void*)0);
12002 }
12003}
12004
12005static char*
12006dot_to_underscore(char* str)
12007{
12008 unsigned i;
12009 for (i = 0; i < strlen(str); i++) {
12010 if (str[i] == '.')
12011 str[i] = '_';
12012 }
12013 return str;
12014}
12015
12016/* Dumps a mapping file for ElasticSearch
12017 * This is the v1 (legacy) _template API.
12018 * At some point it may need to be updated with the composable templates
12019 * introduced in Elasticsearch 7.8 (_index_template)
12020 */
12021void
12022proto_registrar_dump_elastic(const char* filter)
12023{
12024 header_field_info *hfinfo;
12025 header_field_info *parent_hfinfo;
12026 unsigned i;
12027 bool_Bool open_object = true1;
12028 const char* prev_proto = NULL((void*)0);
12029 char* str;
12030 char** protos = NULL((void*)0);
12031 char* proto;
12032 bool_Bool found;
12033 unsigned j;
12034 char* type;
12035 char* prev_item = NULL((void*)0);
12036
12037 /* We have filtering protocols. Extract them. */
12038 if (filter) {
12039 protos = g_strsplit(filter, ",", -1);
12040 }
12041
12042 /*
12043 * To help tracking down the json tree, objects have been appended with a comment:
12044 * n.label -> where n is the indentation level and label the name of the object
12045 */
12046
12047 json_dumper dumper = {
12048 .output_file = stdoutstdout,
12049 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12050 };
12051 json_dumper_begin_object(&dumper); // 1.root
12052 elastic_add_base_mapping(&dumper);
12053
12054 json_dumper_set_member_name(&dumper, "mappings");
12055 json_dumper_begin_object(&dumper); // 2.mappings
12056
12057 json_dumper_set_member_name(&dumper, "properties");
12058 json_dumper_begin_object(&dumper); // 3.properties
12059 json_dumper_set_member_name(&dumper, "timestamp");
12060 json_dumper_begin_object(&dumper); // 4.timestamp
12061 json_dumper_set_member_name(&dumper, "type");
12062 json_dumper_value_string(&dumper, "date");
12063 json_dumper_end_object(&dumper); // 4.timestamp
12064
12065 json_dumper_set_member_name(&dumper, "layers");
12066 json_dumper_begin_object(&dumper); // 4.layers
12067 json_dumper_set_member_name(&dumper, "properties");
12068 json_dumper_begin_object(&dumper); // 5.properties
12069
12070 for (i = 0; i < gpa_hfinfo.len; i++) {
12071 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12072 continue; /* This is a deregistered protocol or header field */
12073
12074 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", 12074
, __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", 12074
, "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", 12074, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12075
12076 /*
12077 * Skip the pseudo-field for "proto_tree_add_text()" since
12078 * we don't want it in the list of filterable protocols.
12079 */
12080 if (hfinfo->id == hf_text_only)
12081 continue;
12082
12083 if (!proto_registrar_is_protocol(i)) {
12084 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", 12084
, __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", 12084
, "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", 12084
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12085
12086 /*
12087 * Skip the field if filter protocols have been set and this one's
12088 * parent is not listed.
12089 */
12090 if (protos) {
12091 found = false0;
12092 j = 0;
12093 proto = protos[0];
12094 while(proto) {
12095 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12096 found = true1;
12097 break;
12098 }
12099 j++;
12100 proto = protos[j];
12101 }
12102 if (!found)
12103 continue;
12104 }
12105
12106 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12107 json_dumper_end_object(&dumper); // 7.properties
12108 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12109 open_object = true1;
12110 }
12111
12112 prev_proto = parent_hfinfo->abbrev;
12113
12114 if (open_object) {
12115 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12116 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12117 json_dumper_set_member_name(&dumper, "properties");
12118 json_dumper_begin_object(&dumper); // 7.properties
12119 open_object = false0;
12120 }
12121 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12122 type = ws_type_to_elastic(hfinfo->type);
12123 /* when type is NULL, we have the default mapping: string */
12124 if (type) {
12125 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12126 dot_to_underscore(str);
12127 if (g_strcmp0(prev_item, str)) {
12128 json_dumper_set_member_name(&dumper, str);
12129 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12130 json_dumper_set_member_name(&dumper, "type");
12131 json_dumper_value_string(&dumper, type);
12132 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12133 }
12134 g_free(prev_item);
12135 prev_item = str;
12136 }
12137 }
12138 }
12139 g_free(prev_item);
12140
12141 if (prev_proto) {
12142 json_dumper_end_object(&dumper); // 7.properties
12143 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12144 }
12145
12146 json_dumper_end_object(&dumper); // 5.properties
12147 json_dumper_end_object(&dumper); // 4.layers
12148 json_dumper_end_object(&dumper); // 3.properties
12149 json_dumper_end_object(&dumper); // 2.mappings
12150 json_dumper_end_object(&dumper); // 1.root
12151 bool_Bool ret = json_dumper_finish(&dumper);
12152 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12152, "ret"))))
;
12153
12154 g_strfreev(protos);
12155}
12156
12157/* Dumps the contents of the registration database to stdout. An independent
12158 * program can take this output and format it into nice tables or HTML or
12159 * whatever.
12160 *
12161 * There is one record per line. Each record is either a protocol or a header
12162 * field, differentiated by the first field. The fields are tab-delimited.
12163 *
12164 * Protocols
12165 * ---------
12166 * Field 1 = 'P'
12167 * Field 2 = descriptive protocol name
12168 * Field 3 = protocol abbreviation
12169 *
12170 * Header Fields
12171 * -------------
12172 * Field 1 = 'F'
12173 * Field 2 = descriptive field name
12174 * Field 3 = field abbreviation
12175 * Field 4 = type ( textual representation of the ftenum type )
12176 * Field 5 = parent protocol abbreviation
12177 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12178 * Field 7 = bitmask: format: hex: 0x....
12179 * Field 8 = blurb describing field
12180 */
12181void
12182proto_registrar_dump_fields(void)
12183{
12184 header_field_info *hfinfo, *parent_hfinfo;
12185 int i, len;
12186 const char *enum_name;
12187 const char *base_name;
12188 const char *blurb;
12189 char width[5];
12190
12191 len = gpa_hfinfo.len;
12192 for (i = 0; i < len ; i++) {
12193 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12194 continue; /* This is a deregistered protocol or header field */
12195
12196 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", 12196
, __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", 12196
, "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", 12196, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12197
12198 /*
12199 * Skip the pseudo-field for "proto_tree_add_text()" since
12200 * we don't want it in the list of filterable fields.
12201 */
12202 if (hfinfo->id == hf_text_only)
12203 continue;
12204
12205 /* format for protocols */
12206 if (proto_registrar_is_protocol(i)) {
12207 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12208 }
12209 /* format for header fields */
12210 else {
12211 /*
12212 * If this field isn't at the head of the list of
12213 * fields with this name, skip this field - all
12214 * fields with the same name are really just versions
12215 * of the same field stored in different bits, and
12216 * should have the same type/radix/value list, and
12217 * just differ in their bit masks. (If a field isn't
12218 * a bitfield, but can be, say, 1 or 2 bytes long,
12219 * it can just be made FT_UINT16, meaning the
12220 * *maximum* length is 2 bytes, and be used
12221 * for all lengths.)
12222 */
12223 if (hfinfo->same_name_prev_id != -1)
12224 continue;
12225
12226 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", 12226
, __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", 12226
, "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", 12226
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12227
12228 enum_name = ftype_name(hfinfo->type);
12229 base_name = "";
12230
12231 if (hfinfo->type == FT_CHAR ||
12232 hfinfo->type == FT_UINT8 ||
12233 hfinfo->type == FT_UINT16 ||
12234 hfinfo->type == FT_UINT24 ||
12235 hfinfo->type == FT_UINT32 ||
12236 hfinfo->type == FT_UINT40 ||
12237 hfinfo->type == FT_UINT48 ||
12238 hfinfo->type == FT_UINT56 ||
12239 hfinfo->type == FT_UINT64 ||
12240 hfinfo->type == FT_INT8 ||
12241 hfinfo->type == FT_INT16 ||
12242 hfinfo->type == FT_INT24 ||
12243 hfinfo->type == FT_INT32 ||
12244 hfinfo->type == FT_INT40 ||
12245 hfinfo->type == FT_INT48 ||
12246 hfinfo->type == FT_INT56 ||
12247 hfinfo->type == FT_INT64) {
12248
12249 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12250 case BASE_NONE:
12251 case BASE_DEC:
12252 case BASE_HEX:
12253 case BASE_OCT:
12254 case BASE_DEC_HEX:
12255 case BASE_HEX_DEC:
12256 case BASE_CUSTOM:
12257 case BASE_PT_UDP:
12258 case BASE_PT_TCP:
12259 case BASE_PT_DCCP:
12260 case BASE_PT_SCTP:
12261 case BASE_OUI:
12262 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12263 break;
12264 default:
12265 base_name = "????";
12266 break;
12267 }
12268 } else if (hfinfo->type == FT_BOOLEAN) {
12269 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12270 snprintf(width, sizeof(width), "%d", hfinfo->display);
12271 base_name = width;
12272 }
12273
12274 blurb = hfinfo->blurb;
12275 if (blurb == NULL((void*)0))
12276 blurb = "";
12277 else if (strlen(blurb) == 0)
12278 blurb = "\"\"";
12279
12280 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12281 hfinfo->name, hfinfo->abbrev, enum_name,
12282 parent_hfinfo->abbrev, base_name,
12283 hfinfo->bitmask, blurb);
12284 }
12285 }
12286}
12287
12288/* Dumps all abbreviated field and protocol completions of the given string to
12289 * stdout. An independent program may use this for command-line tab completion
12290 * of fields.
12291 */
12292bool_Bool
12293proto_registrar_dump_field_completions(const char *prefix)
12294{
12295 header_field_info *hfinfo;
12296 int i, len;
12297 size_t prefix_len;
12298 bool_Bool matched = false0;
12299
12300 prefix_len = strlen(prefix);
12301 len = gpa_hfinfo.len;
12302 for (i = 0; i < len ; i++) {
12303 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12304 continue; /* This is a deregistered protocol or header field */
12305
12306 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", 12306
, __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", 12306
, "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", 12306, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12307
12308 /*
12309 * Skip the pseudo-field for "proto_tree_add_text()" since
12310 * we don't want it in the list of filterable fields.
12311 */
12312 if (hfinfo->id == hf_text_only)
12313 continue;
12314
12315 /* format for protocols */
12316 if (proto_registrar_is_protocol(i)) {
12317 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12318 matched = true1;
12319 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12320 }
12321 }
12322 /* format for header fields */
12323 else {
12324 /*
12325 * If this field isn't at the head of the list of
12326 * fields with this name, skip this field - all
12327 * fields with the same name are really just versions
12328 * of the same field stored in different bits, and
12329 * should have the same type/radix/value list, and
12330 * just differ in their bit masks. (If a field isn't
12331 * a bitfield, but can be, say, 1 or 2 bytes long,
12332 * it can just be made FT_UINT16, meaning the
12333 * *maximum* length is 2 bytes, and be used
12334 * for all lengths.)
12335 */
12336 if (hfinfo->same_name_prev_id != -1)
12337 continue;
12338
12339 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12340 matched = true1;
12341 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12342 }
12343 }
12344 }
12345 return matched;
12346}
12347
12348/* Dumps field types and descriptive names to stdout. An independent
12349 * program can take this output and format it into nice tables or HTML or
12350 * whatever.
12351 *
12352 * There is one record per line. The fields are tab-delimited.
12353 *
12354 * Field 1 = field type name, e.g. FT_UINT8
12355 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12356 */
12357void
12358proto_registrar_dump_ftypes(void)
12359{
12360 int fte;
12361
12362 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12363 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12364 }
12365}
12366
12367/* This function indicates whether it's possible to construct a
12368 * "match selected" display filter string for the specified field,
12369 * returns an indication of whether it's possible, and, if it's
12370 * possible and "filter" is non-null, constructs the filter and
12371 * sets "*filter" to point to it.
12372 * You do not need to [g_]free() this string since it will be automatically
12373 * freed once the next packet is dissected.
12374 */
12375static bool_Bool
12376construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12377 char **filter)
12378{
12379 const header_field_info *hfinfo;
12380 char *ptr;
12381 int buf_len;
12382 int i;
12383 int start, length, length_remaining;
12384 uint8_t c;
12385
12386 if (!finfo)
12387 return false0;
12388
12389 hfinfo = finfo->hfinfo;
12390 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12390, "hfinfo"))))
;
12391
12392 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12393 * then "the numeric value ... is not used when preparing
12394 * filters for the field in question." If it's any other
12395 * base, we'll generate the filter normally (which will
12396 * be numeric, even though the human-readable string does
12397 * work for filtering.)
12398 *
12399 * XXX - It might be nice to use fvalue_to_string_repr() in
12400 * "proto_item_fill_label()" as well, although, there, you'd
12401 * have to deal with the base *and* with resolved values for
12402 * addresses.
12403 *
12404 * Perhaps in addition to taking the repr type (DISPLAY
12405 * or DFILTER) and the display (base), fvalue_to_string_repr()
12406 * should have the the "strings" values in the header_field_info
12407 * structure for the field as a parameter, so it can have
12408 * if the field is Boolean or an enumerated integer type,
12409 * the tables used to generate human-readable values.
12410 */
12411 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12412 const char *str = NULL((void*)0);
12413
12414 switch (hfinfo->type) {
12415
12416 case FT_INT8:
12417 case FT_INT16:
12418 case FT_INT24:
12419 case FT_INT32:
12420 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12421 break;
12422
12423 case FT_CHAR:
12424 case FT_UINT8:
12425 case FT_UINT16:
12426 case FT_UINT24:
12427 case FT_UINT32:
12428 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12429 break;
12430
12431 default:
12432 break;
12433 }
12434
12435 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12436 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12437 return true1;
12438 }
12439 }
12440
12441 switch (hfinfo->type) {
12442
12443 case FT_PROTOCOL:
12444 if (filter != NULL((void*)0))
12445 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12446 break;
12447
12448 case FT_NONE:
12449 /*
12450 * If the length is 0, just match the name of the
12451 * field.
12452 *
12453 * (Also check for negative values, just in case,
12454 * as we'll cast it to an unsigned value later.)
12455 */
12456 length = finfo->length;
12457 if (length == 0) {
12458 if (filter != NULL((void*)0))
12459 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12460 break;
12461 }
12462 if (length < 0)
12463 return false0;
12464
12465 /*
12466 * This doesn't have a value, so we'd match
12467 * on the raw bytes at this address.
12468 *
12469 * Should we be allowed to access to the raw bytes?
12470 * If "edt" is NULL, the answer is "no".
12471 */
12472 if (edt == NULL((void*)0))
12473 return false0;
12474
12475 /*
12476 * Is this field part of the raw frame tvbuff?
12477 * If not, we can't use "frame[N:M]" to match
12478 * it.
12479 *
12480 * XXX - should this be frame-relative, or
12481 * protocol-relative?
12482 *
12483 * XXX - does this fallback for non-registered
12484 * fields even make sense?
12485 */
12486 if (finfo->ds_tvb != edt->tvb)
12487 return false0; /* you lose */
12488
12489 /*
12490 * Don't go past the end of that tvbuff.
12491 */
12492 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12493 if (length > length_remaining)
12494 length = length_remaining;
12495 if (length <= 0)
12496 return false0;
12497
12498 if (filter != NULL((void*)0)) {
12499 start = finfo->start;
12500 buf_len = 32 + length * 3;
12501 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12502 ptr = *filter;
12503
12504 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12505 "frame[%d:%d] == ", finfo->start, length);
12506 for (i=0; i<length; i++) {
12507 c = tvb_get_uint8(finfo->ds_tvb, start);
12508 start++;
12509 if (i == 0 ) {
12510 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12511 }
12512 else {
12513 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12514 }
12515 }
12516 }
12517 break;
12518
12519 /* By default, use the fvalue's "to_string_repr" method. */
12520 default:
12521 if (filter != NULL((void*)0)) {
12522 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12523 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12524 wmem_free(NULL((void*)0), str);
12525 }
12526 break;
12527 }
12528
12529 return true1;
12530}
12531
12532/*
12533 * Returns true if we can do a "match selected" on the field, false
12534 * otherwise.
12535 */
12536bool_Bool
12537proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12538{
12539 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12540}
12541
12542/* This function attempts to construct a "match selected" display filter
12543 * string for the specified field; if it can do so, it returns a pointer
12544 * to the string, otherwise it returns NULL.
12545 *
12546 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12547 */
12548char *
12549proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12550{
12551 char *filter = NULL((void*)0);
12552
12553 if (!construct_match_selected_string(finfo, edt, &filter))
12554 {
12555 wmem_free(NULL((void*)0), filter);
12556 return NULL((void*)0);
12557 }
12558 return filter;
12559}
12560
12561/* This function is common code for all proto_tree_add_bitmask... functions.
12562 */
12563
12564static bool_Bool
12565proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12566 const int len, const int ett, int * const *fields,
12567 const int flags, bool_Bool first,
12568 bool_Bool use_parent_tree,
12569 proto_tree* tree, uint64_t value)
12570{
12571 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12572 uint64_t bitmask = 0;
12573 uint64_t tmpval;
12574 header_field_info *hf;
12575 uint32_t integer32;
12576 int bit_offset;
12577 int no_of_bits;
12578
12579 if (!*fields)
12580 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"
)
;
12581
12582 if (len < 0 || len > 8)
12583 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12584 /**
12585 * packet-frame.c uses len=0 since the value is taken from the packet
12586 * metadata, not the packet bytes. In that case, assume that all bits
12587 * in the provided value are valid.
12588 */
12589 if (len > 0) {
12590 available_bits >>= (8 - (unsigned)len)*8;
12591 }
12592
12593 if (use_parent_tree == false0)
12594 tree = proto_item_add_subtree(item, ett);
12595
12596 while (*fields) {
12597 uint64_t present_bits;
12598 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", 12598, __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", 12598
, "**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", 12598, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12599 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", 12599
, "hf->bitmask != 0", hf->abbrev))))
;
12600
12601 bitmask |= hf->bitmask;
12602
12603 /* Skip fields that aren't fully present */
12604 present_bits = available_bits & hf->bitmask;
12605 if (present_bits != hf->bitmask) {
12606 fields++;
12607 continue;
12608 }
12609
12610 switch (hf->type) {
12611 case FT_CHAR:
12612 case FT_UINT8:
12613 case FT_UINT16:
12614 case FT_UINT24:
12615 case FT_UINT32:
12616 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12617 break;
12618
12619 case FT_INT8:
12620 case FT_INT16:
12621 case FT_INT24:
12622 case FT_INT32:
12623 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12624 break;
12625
12626 case FT_UINT40:
12627 case FT_UINT48:
12628 case FT_UINT56:
12629 case FT_UINT64:
12630 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12631 break;
12632
12633 case FT_INT40:
12634 case FT_INT48:
12635 case FT_INT56:
12636 case FT_INT64:
12637 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12638 break;
12639
12640 case FT_BOOLEAN:
12641 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12642 break;
12643
12644 default:
12645 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))
12646 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))
12647 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))
12648 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))
;
12649 break;
12650 }
12651 if (flags & BMT_NO_APPEND0x01) {
12652 fields++;
12653 continue;
12654 }
12655 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12656
12657 /* XXX: README.developer and the comments have always defined
12658 * BMT_NO_INT as "only boolean flags are added to the title /
12659 * don't add non-boolean (integral) fields", but the
12660 * implementation has always added BASE_CUSTOM and fields with
12661 * value_strings, though not fields with unit_strings.
12662 * Possibly this is because some dissectors use a FT_UINT8
12663 * with a value_string for fields that should be a FT_BOOLEAN.
12664 */
12665 switch (hf->type) {
12666 case FT_CHAR:
12667 if (hf->display == BASE_CUSTOM) {
12668 char lbl[ITEM_LABEL_LENGTH240];
12669 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12670
12671 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12671, "fmtfunc"))))
;
12672 fmtfunc(lbl, (uint32_t) tmpval);
12673 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12674 hf->name, lbl);
12675 first = false0;
12676 }
12677 else if (hf->strings) {
12678 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12679 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12680 first = false0;
12681 }
12682 else if (!(flags & BMT_NO_INT0x02)) {
12683 char buf[32];
12684 const char *out;
12685
12686 if (!first) {
12687 proto_item_append_text(item, ", ");
12688 }
12689
12690 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12691 proto_item_append_text(item, "%s: %s", hf->name, out);
12692 first = false0;
12693 }
12694
12695 break;
12696
12697 case FT_UINT8:
12698 case FT_UINT16:
12699 case FT_UINT24:
12700 case FT_UINT32:
12701 if (hf->display == BASE_CUSTOM) {
12702 char lbl[ITEM_LABEL_LENGTH240];
12703 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12704
12705 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12705, "fmtfunc"))))
;
12706 fmtfunc(lbl, (uint32_t) tmpval);
12707 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12708 hf->name, lbl);
12709 first = false0;
12710 }
12711 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12712 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12713 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12714 first = false0;
12715 }
12716 else if (!(flags & BMT_NO_INT0x02)) {
12717 char buf[NUMBER_LABEL_LENGTH80];
12718 const char *out = NULL((void*)0);
12719
12720 if (!first) {
12721 proto_item_append_text(item, ", ");
12722 }
12723
12724 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12725 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12726 }
12727 if (out == NULL((void*)0)) {
12728 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12729 }
12730 proto_item_append_text(item, "%s: %s", hf->name, out);
12731 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12732 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12733 }
12734 first = false0;
12735 }
12736
12737 break;
12738
12739 case FT_INT8:
12740 case FT_INT16:
12741 case FT_INT24:
12742 case FT_INT32:
12743 integer32 = (uint32_t) tmpval;
12744 if (hf->bitmask) {
12745 no_of_bits = ws_count_ones(hf->bitmask);
12746 integer32 = ws_sign_ext32(integer32, no_of_bits);
12747 }
12748 if (hf->display == BASE_CUSTOM) {
12749 char lbl[ITEM_LABEL_LENGTH240];
12750 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12751
12752 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12752, "fmtfunc"))))
;
12753 fmtfunc(lbl, (int32_t) integer32);
12754 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12755 hf->name, lbl);
12756 first = false0;
12757 }
12758 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12759 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12760 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12761 first = false0;
12762 }
12763 else if (!(flags & BMT_NO_INT0x02)) {
12764 char buf[NUMBER_LABEL_LENGTH80];
12765 const char *out = NULL((void*)0);
12766
12767 if (!first) {
12768 proto_item_append_text(item, ", ");
12769 }
12770
12771 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12772 out = hf_try_val_to_str((int32_t) integer32, hf);
12773 }
12774 if (out == NULL((void*)0)) {
12775 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12776 }
12777 proto_item_append_text(item, "%s: %s", hf->name, out);
12778 if (hf->display & BASE_UNIT_STRING0x00001000) {
12779 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12780 }
12781 first = false0;
12782 }
12783
12784 break;
12785
12786 case FT_UINT40:
12787 case FT_UINT48:
12788 case FT_UINT56:
12789 case FT_UINT64:
12790 if (hf->display == BASE_CUSTOM) {
12791 char lbl[ITEM_LABEL_LENGTH240];
12792 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12793
12794 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12794, "fmtfunc"))))
;
12795 fmtfunc(lbl, tmpval);
12796 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12797 hf->name, lbl);
12798 first = false0;
12799 }
12800 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12801 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12802 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12803 first = false0;
12804 }
12805 else if (!(flags & BMT_NO_INT0x02)) {
12806 char buf[NUMBER_LABEL_LENGTH80];
12807 const char *out = NULL((void*)0);
12808
12809 if (!first) {
12810 proto_item_append_text(item, ", ");
12811 }
12812
12813 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12814 out = hf_try_val64_to_str(tmpval, hf);
12815 }
12816 if (out == NULL((void*)0)) {
12817 out = hfinfo_number_value_format64(hf, buf, tmpval);
12818 }
12819 proto_item_append_text(item, "%s: %s", hf->name, out);
12820 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12821 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12822 }
12823 first = false0;
12824 }
12825
12826 break;
12827
12828 case FT_INT40:
12829 case FT_INT48:
12830 case FT_INT56:
12831 case FT_INT64:
12832 if (hf->bitmask) {
12833 no_of_bits = ws_count_ones(hf->bitmask);
12834 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12835 }
12836 if (hf->display == BASE_CUSTOM) {
12837 char lbl[ITEM_LABEL_LENGTH240];
12838 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12839
12840 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12840, "fmtfunc"))))
;
12841 fmtfunc(lbl, (int64_t) tmpval);
12842 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12843 hf->name, lbl);
12844 first = false0;
12845 }
12846 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12847 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12848 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12849 first = false0;
12850 }
12851 else if (!(flags & BMT_NO_INT0x02)) {
12852 char buf[NUMBER_LABEL_LENGTH80];
12853 const char *out = NULL((void*)0);
12854
12855 if (!first) {
12856 proto_item_append_text(item, ", ");
12857 }
12858
12859 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12860 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12861 }
12862 if (out == NULL((void*)0)) {
12863 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12864 }
12865 proto_item_append_text(item, "%s: %s", hf->name, out);
12866 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12867 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12868 }
12869 first = false0;
12870 }
12871
12872 break;
12873
12874 case FT_BOOLEAN:
12875 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12876 /* If we have true/false strings, emit full - otherwise messages
12877 might look weird */
12878 const struct true_false_string *tfs =
12879 (const struct true_false_string *)hf->strings;
12880
12881 if (tmpval) {
12882 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12883 hf->name, tfs->true_string);
12884 first = false0;
12885 } else if (!(flags & BMT_NO_FALSE0x04)) {
12886 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12887 hf->name, tfs->false_string);
12888 first = false0;
12889 }
12890 } else if (hf->bitmask & value) {
12891 /* If the flag is set, show the name */
12892 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12893 first = false0;
12894 }
12895 break;
12896 default:
12897 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))
12898 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))
12899 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))
12900 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))
;
12901 break;
12902 }
12903
12904 fields++;
12905 }
12906
12907 /* XXX: We don't pass the hfi into this function. Perhaps we should,
12908 * but then again most dissectors don't set the bitmask field for
12909 * the higher level bitmask hfi, so calculate the bitmask from the
12910 * fields present. */
12911 if (item) {
12912 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
12913 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
12914 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)
;
12915 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)
;
12916 }
12917 return first;
12918}
12919
12920/* This function will dissect a sequence of bytes that describe a
12921 * bitmask and supply the value of that sequence through a pointer.
12922 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12923 * to be dissected.
12924 * This field will form an expansion under which the individual fields of the
12925 * bitmask is dissected and displayed.
12926 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12927 *
12928 * fields is an array of pointers to int that lists all the fields of the
12929 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12930 * or another integer of the same type/size as hf_hdr with a mask specified.
12931 * This array is terminated by a NULL entry.
12932 *
12933 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12934 * FT_integer fields that have a value_string attached will have the
12935 * matched string displayed on the expansion line.
12936 */
12937proto_item *
12938proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
12939 const unsigned offset, const int hf_hdr,
12940 const int ett, int * const *fields,
12941 const unsigned encoding, uint64_t *retval)
12942{
12943 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);
12944}
12945
12946/* This function will dissect a sequence of bytes that describe a
12947 * bitmask.
12948 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12949 * to be dissected.
12950 * This field will form an expansion under which the individual fields of the
12951 * bitmask is dissected and displayed.
12952 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12953 *
12954 * fields is an array of pointers to int that lists all the fields of the
12955 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12956 * or another integer of the same type/size as hf_hdr with a mask specified.
12957 * This array is terminated by a NULL entry.
12958 *
12959 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12960 * FT_integer fields that have a value_string attached will have the
12961 * matched string displayed on the expansion line.
12962 */
12963proto_item *
12964proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
12965 const unsigned offset, const int hf_hdr,
12966 const int ett, int * const *fields,
12967 const unsigned encoding)
12968{
12969 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
12970}
12971
12972/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12973 * what data is appended to the header.
12974 */
12975proto_item *
12976proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12977 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
12978 uint64_t *retval)
12979{
12980 proto_item *item = NULL((void*)0);
12981 header_field_info *hf;
12982 int len;
12983 uint64_t value;
12984
12985 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", 12985, __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", 12985
, "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", 12985, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12986 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", 12986, (hf)->abbrev)))
;
12987 len = ftype_wire_size(hf->type);
12988 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12989
12990 if (parent_tree) {
12991 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12992 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12993 flags, false0, false0, NULL((void*)0), value);
12994 }
12995
12996 *retval = value;
12997 if (hf->bitmask) {
12998 /* Mask out irrelevant portions */
12999 *retval &= hf->bitmask;
13000 /* Shift bits */
13001 *retval >>= hfinfo_bitshift(hf);
13002 }
13003
13004 return item;
13005}
13006
13007/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13008 * what data is appended to the header.
13009 */
13010proto_item *
13011proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13012 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13013{
13014 proto_item *item = NULL((void*)0);
13015 header_field_info *hf;
13016 int len;
13017 uint64_t value;
13018
13019 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", 13019, __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", 13019
, "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", 13019, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13020 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", 13020, (hf)->abbrev)))
;
13021
13022 if (parent_tree) {
13023 len = ftype_wire_size(hf->type);
13024 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13025 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13026 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13027 flags, false0, false0, NULL((void*)0), value);
13028 }
13029
13030 return item;
13031}
13032
13033/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13034 can't be retrieved directly from tvb) */
13035proto_item *
13036proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13037 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13038{
13039 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13040 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13041}
13042
13043/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13044WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13045proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13046 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13047{
13048 proto_item *item = NULL((void*)0);
13049 header_field_info *hf;
13050 int len;
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 /* the proto_tree_add_uint/_uint64() calls below
13055 will fail if tvb==NULL and len!=0 */
13056 len = tvb ? ftype_wire_size(hf->type) : 0;
13057
13058 if (parent_tree) {
13059 if (len <= 4)
13060 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13061 else
13062 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13063
13064 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13065 flags, false0, false0, NULL((void*)0), value);
13066 }
13067
13068 return item;
13069}
13070
13071/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13072void
13073proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13074 const int len, int * const *fields, const unsigned encoding)
13075{
13076 uint64_t value;
13077
13078 if (tree) {
13079 value = get_uint64_value(tree, tvb, offset, len, encoding);
13080 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13081 BMT_NO_APPEND0x01, false0, true1, tree, value);
13082 }
13083}
13084
13085WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13086proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13087 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13088{
13089 uint64_t value;
13090
13091 value = get_uint64_value(tree, tvb, offset, len, encoding);
13092 if (tree) {
13093 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13094 BMT_NO_APPEND0x01, false0, true1, tree, value);
13095 }
13096 if (retval) {
13097 *retval = value;
13098 }
13099}
13100
13101WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13102proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13103 const int len, int * const *fields, const uint64_t value)
13104{
13105 if (tree) {
13106 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13107 BMT_NO_APPEND0x01, false0, true1, tree, value);
13108 }
13109}
13110
13111
13112/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13113 * This is intended to support bitmask fields whose lengths can vary, perhaps
13114 * as the underlying standard evolves over time.
13115 * With this API there is the possibility of being called to display more or
13116 * less data than the dissector was coded to support.
13117 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13118 * Thus when presented with "too much" or "too little" data, MSbits will be
13119 * ignored or MSfields sacrificed.
13120 *
13121 * Only fields for which all defined bits are available are displayed.
13122 */
13123proto_item *
13124proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13125 const unsigned offset, const unsigned len, const int hf_hdr,
13126 const int ett, int * const *fields, struct expert_field* exp,
13127 const unsigned encoding)
13128{
13129 proto_item *item = NULL((void*)0);
13130 header_field_info *hf;
13131 unsigned decodable_len;
13132 unsigned decodable_offset;
13133 uint32_t decodable_value;
13134 uint64_t value;
13135
13136 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", 13136, __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", 13136
, "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", 13136, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13137 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", 13137, (hf)->abbrev)))
;
13138
13139 decodable_offset = offset;
13140 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13141
13142 /* If we are ftype_wire_size-limited,
13143 * make sure we decode as many LSBs as possible.
13144 */
13145 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13146 decodable_offset += (len - decodable_len);
13147 }
13148
13149 if (parent_tree) {
13150 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13151 decodable_len, encoding);
13152
13153 /* The root item covers all the bytes even if we can't decode them all */
13154 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13155 decodable_value);
13156 }
13157
13158 if (decodable_len < len) {
13159 /* Dissector likely requires updating for new protocol revision */
13160 expert_add_info_format(NULL((void*)0), item, exp,
13161 "Only least-significant %d of %d bytes decoded",
13162 decodable_len, len);
13163 }
13164
13165 if (item) {
13166 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13167 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13168 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13169 }
13170
13171 return item;
13172}
13173
13174/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13175proto_item *
13176proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13177 const unsigned offset, const unsigned len,
13178 const char *name, const char *fallback,
13179 const int ett, int * const *fields,
13180 const unsigned encoding, const int flags)
13181{
13182 proto_item *item = NULL((void*)0);
13183 uint64_t value;
13184
13185 if (parent_tree) {
13186 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13187 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13188 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13189 flags, true1, false0, NULL((void*)0), value) && fallback) {
13190 /* Still at first item - append 'fallback' text if any */
13191 proto_item_append_text(item, "%s", fallback);
13192 }
13193 }
13194
13195 return item;
13196}
13197
13198proto_item *
13199proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13200 const unsigned bit_offset, const int no_of_bits,
13201 const unsigned encoding)
13202{
13203 header_field_info *hfinfo;
13204 int octet_length;
13205 int octet_offset;
13206
13207 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", 13207, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13207
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13207, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13208
13209 if (no_of_bits < 0) {
13210 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13211 }
13212 octet_length = (no_of_bits + 7) >> 3;
13213 octet_offset = bit_offset >> 3;
13214 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13215
13216 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13217 * but only after doing a bunch more work (which we can, in the common
13218 * case, shortcut here).
13219 */
13220 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13221 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", 13221
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13221, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13221, "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", 13221, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13222
13223 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13224}
13225
13226/*
13227 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13228 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13229 * Offset should be given in bits from the start of the tvb.
13230 */
13231
13232static proto_item *
13233_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13234 const unsigned bit_offset, const int no_of_bits,
13235 uint64_t *return_value, const unsigned encoding)
13236{
13237 int offset;
13238 unsigned length;
13239 uint8_t tot_no_bits;
13240 char *bf_str;
13241 char lbl_str[ITEM_LABEL_LENGTH240];
13242 uint64_t value = 0;
13243 uint8_t *bytes = NULL((void*)0);
13244 size_t bytes_length = 0;
13245
13246 proto_item *pi;
13247 header_field_info *hf_field;
13248
13249 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13250 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", 13250, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13250
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13250, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13251
13252 if (hf_field->bitmask != 0) {
13253 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)
13254 " 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)
13255 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)
;
13256 }
13257
13258 if (no_of_bits < 0) {
13259 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13260 } else if (no_of_bits == 0) {
13261 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)
13262 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)
;
13263 }
13264
13265 /* Byte align offset */
13266 offset = bit_offset>>3;
13267
13268 /*
13269 * Calculate the number of octets used to hold the bits
13270 */
13271 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13272 length = (tot_no_bits + 7) >> 3;
13273
13274 if (no_of_bits < 65) {
13275 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13276 } else if (hf_field->type != FT_BYTES) {
13277 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)
13278 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)
;
13279 return NULL((void*)0);
13280 }
13281
13282 /* Sign extend for signed types */
13283 switch (hf_field->type) {
13284 case FT_INT8:
13285 case FT_INT16:
13286 case FT_INT24:
13287 case FT_INT32:
13288 case FT_INT40:
13289 case FT_INT48:
13290 case FT_INT56:
13291 case FT_INT64:
13292 value = ws_sign_ext64(value, no_of_bits);
13293 break;
13294
13295 default:
13296 break;
13297 }
13298
13299 if (return_value) {
13300 *return_value = value;
13301 }
13302
13303 /* Coast clear. Try and fake it */
13304 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13305 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", 13305
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13305, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13305, "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", 13305, __func__, "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); } } }
;
13306
13307 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13308
13309 switch (hf_field->type) {
13310 case FT_BOOLEAN:
13311 /* Boolean field */
13312 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13313 "%s = %s: %s",
13314 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13315 break;
13316
13317 case FT_CHAR:
13318 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13319 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13320 break;
13321
13322 case FT_UINT8:
13323 case FT_UINT16:
13324 case FT_UINT24:
13325 case FT_UINT32:
13326 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13327 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13328 break;
13329
13330 case FT_INT8:
13331 case FT_INT16:
13332 case FT_INT24:
13333 case FT_INT32:
13334 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13335 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13336 break;
13337
13338 case FT_UINT40:
13339 case FT_UINT48:
13340 case FT_UINT56:
13341 case FT_UINT64:
13342 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13343 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13344 break;
13345
13346 case FT_INT40:
13347 case FT_INT48:
13348 case FT_INT56:
13349 case FT_INT64:
13350 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13351 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13352 break;
13353
13354 case FT_BYTES:
13355 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13356 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13357 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13358 proto_item_set_text(pi, "%s", lbl_str);
13359 return pi;
13360
13361 /* TODO: should handle FT_UINT_BYTES ? */
13362
13363 default:
13364 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))
13365 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))
13366 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))
13367 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))
;
13368 return NULL((void*)0);
13369 }
13370
13371 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13372 return pi;
13373}
13374
13375proto_item *
13376proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13377 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13378 uint64_t *return_value)
13379{
13380 proto_item *pi;
13381 int no_of_bits;
13382 int octet_offset;
13383 unsigned mask_initial_bit_offset;
13384 unsigned mask_greatest_bit_offset;
13385 unsigned octet_length;
13386 uint8_t i;
13387 char bf_str[256];
13388 char lbl_str[ITEM_LABEL_LENGTH240];
13389 uint64_t value;
13390 uint64_t composite_bitmask;
13391 uint64_t composite_bitmap;
13392
13393 header_field_info *hf_field;
13394
13395 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13396 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", 13396, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13396
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13396, "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
13397
13398 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13399 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)
13400 " 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)
13401 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)
;
13402 }
13403
13404 mask_initial_bit_offset = bit_offset % 8;
13405
13406 no_of_bits = 0;
13407 value = 0;
13408 i = 0;
13409 mask_greatest_bit_offset = 0;
13410 composite_bitmask = 0;
13411 composite_bitmap = 0;
13412
13413 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
13414 uint64_t crumb_mask, crumb_value;
13415 uint8_t crumb_end_bit_offset;
13416
13417 crumb_value = tvb_get_bits64(tvb,
13418 bit_offset + crumb_spec[i].crumb_bit_offset,
13419 crumb_spec[i].crumb_bit_length,
13420 ENC_BIG_ENDIAN0x00000000);
13421 value += crumb_value;
13422 no_of_bits += crumb_spec[i].crumb_bit_length;
13423 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", 13423
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13424
13425 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13426 octet containing the initial offset.
13427 If the mask is beyond 32 bits, then give up on bit map display.
13428 This could be improved in future, probably showing a table
13429 of 32 or 64 bits per row */
13430 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13431 crumb_end_bit_offset = mask_initial_bit_offset
13432 + crumb_spec[i].crumb_bit_offset
13433 + crumb_spec[i].crumb_bit_length;
13434 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'
13435
13436 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13437 mask_greatest_bit_offset = crumb_end_bit_offset;
13438 }
13439 /* Currently the bitmap of the crumbs are only shown if
13440 * smaller than 32 bits. Do not bother calculating the
13441 * mask if it is larger than that. */
13442 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13443 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'
13444 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13445 }
13446 }
13447 /* Shift left for the next segment */
13448 value <<= crumb_spec[++i].crumb_bit_length;
13449 }
13450
13451 /* Sign extend for signed types */
13452 switch (hf_field->type) {
13453 case FT_INT8:
13454 case FT_INT16:
13455 case FT_INT24:
13456 case FT_INT32:
13457 case FT_INT40:
13458 case FT_INT48:
13459 case FT_INT56:
13460 case FT_INT64:
13461 value = ws_sign_ext64(value, no_of_bits);
13462 break;
13463 default:
13464 break;
13465 }
13466
13467 if (return_value) {
13468 *return_value = value;
13469 }
13470
13471 /* Coast clear. Try and fake it */
13472 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13473 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", 13473
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13473, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13473, "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", 13473, __func__, "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); } } }
;
13474
13475 /* initialise the format string */
13476 bf_str[0] = '\0';
13477
13478 octet_offset = bit_offset >> 3;
13479
13480 /* Round up mask length to nearest octet */
13481 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13482 mask_greatest_bit_offset = octet_length << 3;
13483
13484 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13485 It would be a useful enhancement to eliminate this restriction. */
13486 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13487 other_decode_bitfield_value(bf_str,
13488 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13489 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13490 mask_greatest_bit_offset);
13491 } else {
13492 /* If the bitmask is too large, try to describe its contents. */
13493 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13494 }
13495
13496 switch (hf_field->type) {
13497 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13498 /* Boolean field */
13499 return proto_tree_add_boolean_format(tree, hfindex,
13500 tvb, octet_offset, octet_length, value,
13501 "%s = %s: %s",
13502 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13503 break;
13504
13505 case FT_CHAR:
13506 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13507 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13508 break;
13509
13510 case FT_UINT8:
13511 case FT_UINT16:
13512 case FT_UINT24:
13513 case FT_UINT32:
13514 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13515 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13516 break;
13517
13518 case FT_INT8:
13519 case FT_INT16:
13520 case FT_INT24:
13521 case FT_INT32:
13522 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13523 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13524 break;
13525
13526 case FT_UINT40:
13527 case FT_UINT48:
13528 case FT_UINT56:
13529 case FT_UINT64:
13530 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13531 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13532 break;
13533
13534 case FT_INT40:
13535 case FT_INT48:
13536 case FT_INT56:
13537 case FT_INT64:
13538 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13539 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13540 break;
13541
13542 default:
13543 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))
13544 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))
13545 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))
13546 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))
;
13547 return NULL((void*)0);
13548 }
13549 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13550 return pi;
13551}
13552
13553void
13554proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13555 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13556{
13557 header_field_info *hfinfo;
13558 int start = bit_offset >> 3;
13559 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13560
13561 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13562 * so that we can use the tree's memory scope in calculating the string */
13563 if (length == -1) {
13564 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13565 } else {
13566 tvb_ensure_bytes_exist(tvb, start, length);
13567 }
13568 if (!tree) return;
13569
13570 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", 13570, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13570
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13570, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13571 proto_tree_add_text_internal(tree, tvb, start, length,
13572 "%s crumb %d of %s (decoded above)",
13573 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13574 tvb_get_bits32(tvb,
13575 bit_offset,
13576 crumb_spec[crumb_index].crumb_bit_length,
13577 ENC_BIG_ENDIAN0x00000000),
13578 ENC_BIG_ENDIAN0x00000000),
13579 crumb_index,
13580 hfinfo->name);
13581}
13582
13583proto_item *
13584proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13585 const unsigned bit_offset, const int no_of_bits,
13586 uint64_t *return_value, const unsigned encoding)
13587{
13588 proto_item *item;
13589
13590 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13591 bit_offset, no_of_bits,
13592 return_value, encoding))) {
13593 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)
;
13594 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)
;
13595 }
13596 return item;
13597}
13598
13599static proto_item *
13600_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13601 tvbuff_t *tvb, const unsigned bit_offset,
13602 const int no_of_bits, void *value_ptr,
13603 const unsigned encoding, char *value_str)
13604{
13605 int offset;
13606 unsigned length;
13607 uint8_t tot_no_bits;
13608 char *str;
13609 uint64_t value = 0;
13610 header_field_info *hf_field;
13611
13612 /* We do not have to return a value, try to fake it as soon as possible */
13613 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13614 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", 13614
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13614, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13614, "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", 13614, __func__, "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); } } }
;
13615
13616 if (hf_field->bitmask != 0) {
13617 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)
13618 " 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)
13619 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)
;
13620 }
13621
13622 if (no_of_bits < 0) {
13623 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13624 } else if (no_of_bits == 0) {
13625 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)
13626 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)
;
13627 }
13628
13629 /* Byte align offset */
13630 offset = bit_offset>>3;
13631
13632 /*
13633 * Calculate the number of octets used to hold the bits
13634 */
13635 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13636 length = tot_no_bits>>3;
13637 /* If we are using part of the next octet, increase length by 1 */
13638 if (tot_no_bits & 0x07)
13639 length++;
13640
13641 if (no_of_bits < 65) {
13642 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13643 } else {
13644 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)
13645 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)
;
13646 return NULL((void*)0);
13647 }
13648
13649 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13650
13651 (void) g_strlcat(str, " = ", 256+64);
13652 (void) g_strlcat(str, hf_field->name, 256+64);
13653
13654 /*
13655 * This function does not receive an actual value but a dimensionless pointer to that value.
13656 * For this reason, the type of the header field is examined in order to determine
13657 * what kind of value we should read from this address.
13658 * The caller of this function must make sure that for the specific header field type the address of
13659 * a compatible value is provided.
13660 */
13661 switch (hf_field->type) {
13662 case FT_BOOLEAN:
13663 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13664 "%s: %s", str, value_str);
13665 break;
13666
13667 case FT_CHAR:
13668 case FT_UINT8:
13669 case FT_UINT16:
13670 case FT_UINT24:
13671 case FT_UINT32:
13672 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13673 "%s: %s", str, value_str);
13674 break;
13675
13676 case FT_UINT40:
13677 case FT_UINT48:
13678 case FT_UINT56:
13679 case FT_UINT64:
13680 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13681 "%s: %s", str, value_str);
13682 break;
13683
13684 case FT_INT8:
13685 case FT_INT16:
13686 case FT_INT24:
13687 case FT_INT32:
13688 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13689 "%s: %s", str, value_str);
13690 break;
13691
13692 case FT_INT40:
13693 case FT_INT48:
13694 case FT_INT56:
13695 case FT_INT64:
13696 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13697 "%s: %s", str, value_str);
13698 break;
13699
13700 case FT_FLOAT:
13701 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13702 "%s: %s", str, value_str);
13703 break;
13704
13705 default:
13706 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))
13707 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))
13708 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))
13709 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))
;
13710 return NULL((void*)0);
13711 }
13712}
13713
13714static proto_item *
13715proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13716 tvbuff_t *tvb, const unsigned bit_offset,
13717 const int no_of_bits, void *value_ptr,
13718 const unsigned encoding, char *value_str)
13719{
13720 proto_item *item;
13721
13722 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13723 tvb, bit_offset, no_of_bits,
13724 value_ptr, encoding, value_str))) {
13725 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)
;
13726 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)
;
13727 }
13728 return item;
13729}
13730
13731#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);
\
13732 va_start(ap, format)__builtin_va_start(ap, format); \
13733 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13734 va_end(ap)__builtin_va_end(ap);
13735
13736proto_item *
13737proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13738 tvbuff_t *tvb, const unsigned bit_offset,
13739 const int no_of_bits, uint32_t value,
13740 const unsigned encoding,
13741 const char *format, ...)
13742{
13743 va_list ap;
13744 char *dst;
13745 header_field_info *hf_field;
13746
13747 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13748
13749 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", 13749
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13749, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13749, "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", 13749, __func__, "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); } } }
;
13750
13751 switch (hf_field->type) {
13752 case FT_UINT8:
13753 case FT_UINT16:
13754 case FT_UINT24:
13755 case FT_UINT32:
13756 break;
13757
13758 default:
13759 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)
13760 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)
;
13761 return NULL((void*)0);
13762 }
13763
13764 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
13766 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13767}
13768
13769proto_item *
13770proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13771 tvbuff_t *tvb, const unsigned bit_offset,
13772 const int no_of_bits, uint64_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_UINT40:
13786 case FT_UINT48:
13787 case FT_UINT56:
13788 case FT_UINT64:
13789 break;
13790
13791 default:
13792 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)
13793 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)
;
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_float_bits_format_value(proto_tree *tree, const int hfindex,
13804 tvbuff_t *tvb, const unsigned bit_offset,
13805 const int no_of_bits, float 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 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",
13817, ((hf_field))->abbrev))))
;
13818
13819 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);
;
13820
13821 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13822}
13823
13824proto_item *
13825proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13826 tvbuff_t *tvb, const unsigned bit_offset,
13827 const int no_of_bits, int32_t value,
13828 const unsigned encoding,
13829 const char *format, ...)
13830{
13831 va_list ap;
13832 char *dst;
13833 header_field_info *hf_field;
13834
13835 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13836
13837 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", 13837
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13837, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13837, "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", 13837, __func__, "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); } } }
;
13838
13839 switch (hf_field->type) {
13840 case FT_INT8:
13841 case FT_INT16:
13842 case FT_INT24:
13843 case FT_INT32:
13844 break;
13845
13846 default:
13847 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)
13848 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)
;
13849 return NULL((void*)0);
13850 }
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_int64_bits_format_value(proto_tree *tree, const int hfindex,
13859 tvbuff_t *tvb, const unsigned bit_offset,
13860 const int no_of_bits, int64_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_INT40:
13874 case FT_INT48:
13875 case FT_INT56:
13876 case FT_INT64:
13877 break;
13878
13879 default:
13880 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)
13881 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)
;
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_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13892 tvbuff_t *tvb, const unsigned bit_offset,
13893 const int no_of_bits, uint64_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 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"
, 13905, ((hf_field))->abbrev))))
;
13906
13907 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);
;
13908
13909 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13910}
13911
13912proto_item *
13913proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13914 const unsigned bit_offset, const int no_of_chars)
13915{
13916 proto_item *pi;
13917 header_field_info *hfinfo;
13918 int byte_length;
13919 int byte_offset;
13920 char *string;
13921
13922 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13923
13924 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", 13924
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13924, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13924, "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", 13924, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13925
13926 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"
, 13926, ((hfinfo))->abbrev))))
;
13927
13928 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13929 byte_offset = bit_offset >> 3;
13930
13931 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13932
13933 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13934 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13934, "byte_length >= 0"
))))
;
13935 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13936
13937 return pi;
13938}
13939
13940proto_item *
13941proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13942 const unsigned bit_offset, const int no_of_chars)
13943{
13944 proto_item *pi;
13945 header_field_info *hfinfo;
13946 int byte_length;
13947 int byte_offset;
13948 char *string;
13949
13950 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13951
13952 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", 13952
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13952, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13952, "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", 13952, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13953
13954 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"
, 13954, ((hfinfo))->abbrev))))
;
13955
13956 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13957 byte_offset = bit_offset >> 3;
13958
13959 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13960
13961 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13962 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13962, "byte_length >= 0"
))))
;
13963 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13964
13965 return pi;
13966}
13967
13968const value_string proto_checksum_vals[] = {
13969 { PROTO_CHECKSUM_E_BAD, "Bad" },
13970 { PROTO_CHECKSUM_E_GOOD, "Good" },
13971 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
13972 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
13973 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
13974
13975 { 0, NULL((void*)0) }
13976};
13977
13978proto_item *
13979proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13980 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
13981 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
13982{
13983 header_field_info *hfinfo;
13984 uint32_t checksum;
13985 uint32_t len;
13986 proto_item* ti = NULL((void*)0);
13987 proto_item* ti2;
13988 bool_Bool incorrect_checksum = true1;
13989
13990 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", 13990, __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", 13990
, "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", 13990, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
13991
13992 switch (hfinfo->type) {
13993 case FT_UINT8:
13994 len = 1;
13995 break;
13996 case FT_UINT16:
13997 len = 2;
13998 break;
13999 case FT_UINT24:
14000 len = 3;
14001 break;
14002 case FT_UINT32:
14003 len = 4;
14004 break;
14005 default:
14006 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)
14007 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
14008 }
14009
14010 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14011 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14012 proto_item_set_generated(ti);
14013 if (hf_checksum_status != -1) {
14014 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14015 proto_item_set_generated(ti2);
14016 }
14017 return ti;
14018 }
14019
14020 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14021 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14022 proto_item_set_generated(ti);
14023 } else {
14024 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14025 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14026 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14027 if (computed_checksum == 0) {
14028 proto_item_append_text(ti, " [correct]");
14029 if (hf_checksum_status != -1) {
14030 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14031 proto_item_set_generated(ti2);
14032 }
14033 incorrect_checksum = false0;
14034 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14035 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14036 /* XXX - This can't distinguish between "shouldbe"
14037 * 0x0000 and 0xFFFF unless we know whether there
14038 * were any nonzero bits (other than the checksum).
14039 * Protocols should not use this path if they might
14040 * have an all zero packet.
14041 * Some implementations put the wrong zero; maybe
14042 * we should have a special expert info for that?
14043 */
14044 }
14045 } else {
14046 if (checksum == computed_checksum) {
14047 proto_item_append_text(ti, " [correct]");
14048 if (hf_checksum_status != -1) {
14049 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14050 proto_item_set_generated(ti2);
14051 }
14052 incorrect_checksum = false0;
14053 }
14054 }
14055
14056 if (incorrect_checksum) {
14057 if (hf_checksum_status != -1) {
14058 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14059 proto_item_set_generated(ti2);
14060 }
14061 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14062 proto_item_append_text(ti, " [incorrect]");
14063 if (bad_checksum_expert != NULL((void*)0))
14064 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14065 } else {
14066 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14067 if (bad_checksum_expert != NULL((void*)0))
14068 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);
14069 }
14070 }
14071 } else {
14072 if (hf_checksum_status != -1) {
14073 proto_item_append_text(ti, " [unverified]");
14074 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14075 proto_item_set_generated(ti2);
14076 }
14077 }
14078 }
14079
14080 return ti;
14081}
14082
14083proto_item *
14084proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14085 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14086 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14087{
14088 header_field_info *hfinfo;
14089 uint8_t *checksum = NULL((void*)0);
14090 proto_item* ti = NULL((void*)0);
14091 proto_item* ti2;
14092 bool_Bool incorrect_checksum = true1;
14093
14094 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", 14094, __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", 14094
, "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", 14094, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
14095
14096 if (hfinfo->type != FT_BYTES) {
14097 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)
14098 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
14099 }
14100
14101 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14102 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14103 proto_item_set_generated(ti);
14104 if (hf_checksum_status != -1) {
14105 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14106 proto_item_set_generated(ti2);
14107 }
14108 return ti;
14109 }
14110
14111 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14112 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14113 proto_item_set_generated(ti);
14114 } else {
14115 checksum = (uint8_t*)wmem_alloc0_array(wmem_packet_scope(), uint8_t, checksum_len)((uint8_t*)wmem_alloc0((wmem_packet_scope()), (((((checksum_len
)) <= 0) || ((size_t)sizeof(uint8_t) > (9223372036854775807L
/ (size_t)((checksum_len))))) ? 0 : (sizeof(uint8_t) * ((checksum_len
))))))
;
14116 tvb_memcpy(tvb, checksum, offset, checksum_len);
14117 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14118 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14119 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14120 if (computed_checksum == 0) {
14121 proto_item_append_text(ti, " [correct]");
14122 if (hf_checksum_status != -1) {
14123 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14124 proto_item_set_generated(ti2);
14125 }
14126 incorrect_checksum = false0;
14127 }
14128 } else {
14129 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14130 proto_item_append_text(ti, " [correct]");
14131 if (hf_checksum_status != -1) {
14132 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14133 proto_item_set_generated(ti2);
14134 }
14135 incorrect_checksum = false0;
14136 }
14137 }
14138
14139 if (incorrect_checksum) {
14140 if (hf_checksum_status != -1) {
14141 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14142 proto_item_set_generated(ti2);
14143 }
14144 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14145 proto_item_append_text(ti, " [incorrect]");
14146 if (bad_checksum_expert != NULL((void*)0))
14147 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14148 } else {
14149 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14150 char *computed_checksum_str = (char*)wmem_alloc0_array(wmem_packet_scope(), char, computed_checksum_str_len)((char*)wmem_alloc0((wmem_packet_scope()), (((((computed_checksum_str_len
)) <= 0) || ((size_t)sizeof(char) > (9223372036854775807L
/ (size_t)((computed_checksum_str_len))))) ? 0 : (sizeof(char
) * ((computed_checksum_str_len))))))
;
14151 for (size_t counter = 0; counter < checksum_len; ++counter) {
14152 snprintf(
14153 /* On ecah iteration inserts two characters */
14154 (char*)&computed_checksum_str[counter << 1],
14155 computed_checksum_str_len - (counter << 1),
14156 "%02x",
14157 computed_checksum[counter]);
14158 }
14159 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14160 if (bad_checksum_expert != NULL((void*)0))
14161 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14162 }
14163 }
14164 } else {
14165 if (hf_checksum_status != -1) {
14166 proto_item_append_text(ti, " [unverified]");
14167 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14168 proto_item_set_generated(ti2);
14169 }
14170 }
14171 }
14172
14173 return ti;
14174}
14175
14176unsigned char
14177proto_check_field_name(const char *field_name)
14178{
14179 return module_check_valid_name(field_name, false0);
14180}
14181
14182unsigned char
14183proto_check_field_name_lower(const char *field_name)
14184{
14185 return module_check_valid_name(field_name, true1);
14186}
14187
14188bool_Bool
14189tree_expanded(int tree_type)
14190{
14191 if (tree_type <= 0) {
14192 return false0;
14193 }
14194 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", 14194, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14195 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14196}
14197
14198void
14199tree_expanded_set(int tree_type, bool_Bool value)
14200{
14201 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", 14201, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14202
14203 if (value)
14204 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14205 else
14206 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14207}
14208
14209/*
14210 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14211 *
14212 * Local variables:
14213 * c-basic-offset: 8
14214 * tab-width: 8
14215 * indent-tabs-mode: t
14216 * End:
14217 *
14218 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14219 * :indentSize=8:tabSize=8:noTabs=false:
14220 */