Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13327, 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/2024-11-30-100238-3913-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2024-11-30-100238-3913-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <[email protected]>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13
14#include <stdio.h>
15#include <string.h>
16#include <glib.h>
17#include <float.h>
18#include <inttypes.h>
19#include <errno(*__errno_location ()).h>
20
21#include <epan/tfs.h>
22#include <epan/unit_strings.h>
23
24#include <wsutil/array.h>
25#include <wsutil/bits_ctz.h>
26#include <wsutil/bits_count_ones.h>
27#include <wsutil/sign_ext.h>
28#include <wsutil/utf8_entities.h>
29#include <wsutil/json_dumper.h>
30#include <wsutil/wslog.h>
31#include <wsutil/ws_assert.h>
32#include <wsutil/unicode-utils.h>
33
34#include <ftypes/ftypes.h>
35
36#include "packet.h"
37#include "exceptions.h"
38#include "ptvcursor.h"
39#include "strutil.h"
40#include "addr_resolv.h"
41#include "address_types.h"
42#include "oids.h"
43#include "proto.h"
44#include "epan_dissect.h"
45#include "dfilter/dfilter.h"
46#include "tvbuff.h"
47#include <epan/wmem_scopes.h>
48#include "charsets.h"
49#include "column-info.h"
50#include "to_str.h"
51#include "osi-utils.h"
52#include "expert.h"
53#include "show_exception.h"
54#include "in_cksum.h"
55#include "register-int.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 int cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 int offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @param free_block a code block to call to free resources if this returns
95 @return NULL if 'tree' is null */
96#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
97 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
98
99/** See inlined comments.
100 @param length the length of this item
101 @param cleanup_block a code block to call to free resources if this returns
102 @return NULL if 'length' is lower -1 or equal 0 */
103#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
104 if (length < -1 || length == 0 ) { \
105 cleanup_block; \
106 return NULL((void*)0); \
107 }
108
109/** See inlined comments.
110 @param length the length of this item
111 @return NULL if 'length' is lower -1 or equal 0 */
112#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
113 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
114
115/** See inlined comments.
116 @param tree the tree to append this item to
117 @param hfindex field index
118 @param hfinfo header_field
119 @param free_block a code block to call to free resources if this returns
120 @return the header field matching 'hfinfo' */
121#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", 121
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 121, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 121, "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", 121, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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
); } } }
\
122 /* If the tree is not visible and this item is not referenced \
123 we don't have to do much work at all but we should still \
124 return a node so that referenced field items below this node \
125 (think proto_item_add_subtree()) will still have somewhere \
126 to attach to or else filtering will not work (they would be \
127 ignored since tree would be NULL). \
128 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
129 because that means we can change its length or repr, and we \
130 don't want to do so with calls intended for this faked new \
131 item, so this item needs a new (hidden) child node. \
132 We fake FT_PROTOCOL unless some clients have requested us \
133 not to do so. \
134 */ \
135 PTREE_DATA(tree)((tree)->tree_data)->count++; \
136 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", 136, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 136, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 136, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
137 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
138 free_block; \
139 if (wireshark_abort_on_too_many_items) \
140 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", 141
, __func__, "Adding %s would put more than %d 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 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 141
, __func__, "Adding %s would put more than %d 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 /* Let the exception handler add items to the tree */ \
143 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
144 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)))
145 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)))
146 "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)))
147 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)))
; \
148 } \
149 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
150 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
151 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
152 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
153 && (hfinfo->type != FT_PROTOCOL || \
154 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
155 free_block; \
156 /* return fake node with no field info */\
157 return proto_tree_add_fake_node(tree, hfinfo); \
158 } \
159 } \
160 }
161
162/** See inlined comments.
163 @param tree the tree to append this item to
164 @param hfindex field index
165 @param hfinfo header_field
166 @return the header field matching 'hfinfo' */
167#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", 167
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
\
168 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", 168
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 168, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 168, "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", 168, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
169
170
171/** See inlined comments.
172 @param pi the created protocol item we're about to return */
173#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 173, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
174 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 174, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
175 if (!PITEM_FINFO(pi)((pi)->finfo)) \
176 return pi; \
177 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
178 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
179 /* If the tree (GUI) or item isn't visible it's pointless for \
180 * us to generate the protocol item's string representation */ \
181 return pi; \
182 }
183/* Same as above but returning void */
184#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
185 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
186 return; \
187 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
188 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
189 /* If the tree (GUI) or item isn't visible it's pointless for \
190 * us to generate the protocol item's string representation */ \
191 return; \
192 }
193/* Similar to above, but allows a NULL tree */
194#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; }
\
195 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
196 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
197 /* If the tree (GUI) or item isn't visible it's pointless for \
198 * us to generate the protocol item's string representation */ \
199 return pi; \
200 }
201
202#ifdef ENABLE_CHECK_FILTER
203#define CHECK_HF_VALUE(type, spec, start_values) \
204{ \
205 const type *current; \
206 int n, m; \
207 current = start_values; \
208 for (n=0; current; n++, current++) { \
209 /* Drop out if we reached the end. */ \
210 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
211 break; \
212 } \
213 /* Check value against all previous */ \
214 for (m=0; m < n; m++) { \
215 /* There are lots of duplicates with the same string, \
216 so only report if different... */ \
217 if ((start_values[m].value == current->value) && \
218 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
219 ws_warning("Field '%s' (%s) has a conflicting entry in its" \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 222, __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)
220 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 222, __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)
221 hfinfo->name, hfinfo->abbrev, \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 222, __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)
222 current->value, m, start_values[m].strptr, n, current->strptr)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 222, __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)
; \
223 } \
224 } \
225 } \
226}
227#endif
228
229/* The longest NUMBER-like field label we have is for BASE_OUI, which
230 * can have up to 64 bytes for the manufacturer name if resolved plus
231 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
232 */
233#define NUMBER_LABEL_LENGTH80 80
234
235static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
236static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
237static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
238static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
239static int hfinfo_bitoffset(const header_field_info *hfinfo);
240static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
241static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
242
243#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
244 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
245
246static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
247static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
248#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)
249
250static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
251static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
252static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
253static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
255static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
256static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
257
258static size_t fill_display_label_float(const field_info *fi, char *label_str);
259static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
260
261static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
265static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
266static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
267static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
268static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
269static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
270static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
271
272static void proto_cleanup_base(void);
273
274static proto_item *
275proto_tree_add_node(proto_tree *tree, field_info *fi);
276
277static proto_item *
278proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
279
280static void
281get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
282 int *item_length, const unsigned encoding);
283
284static int
285get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
286 int length, unsigned item_length, const int encoding);
287
288static field_info *
289new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
290 const int start, const int item_length);
291
292static proto_item *
293proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
294 int start, int *length);
295
296static void
297proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
298static void
299proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
300
301static void
302proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
303static void
304proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
305static void
306proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
307static void
308proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
309static void
310proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
311static void
312proto_tree_set_string(field_info *fi, const char* value);
313static void
314proto_tree_set_ax25(field_info *fi, const uint8_t* value);
315static void
316proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
317static void
318proto_tree_set_vines(field_info *fi, const uint8_t* value);
319static void
320proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
321static void
322proto_tree_set_ether(field_info *fi, const uint8_t* value);
323static void
324proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
325static void
326proto_tree_set_ipxnet(field_info *fi, uint32_t value);
327static void
328proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
329static void
330proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
331static void
332proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
333static void
334proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
335static void
336proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
337static void
338proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
339static void
340proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
341static void
342proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
343static void
344proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
345static void
346proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
347static void
348proto_tree_set_boolean(field_info *fi, uint64_t value);
349static void
350proto_tree_set_float(field_info *fi, float value);
351static void
352proto_tree_set_double(field_info *fi, double value);
353static void
354proto_tree_set_uint(field_info *fi, uint32_t value);
355static void
356proto_tree_set_int(field_info *fi, int32_t value);
357static void
358proto_tree_set_uint64(field_info *fi, uint64_t value);
359static void
360proto_tree_set_int64(field_info *fi, int64_t value);
361static void
362proto_tree_set_eui64(field_info *fi, const uint64_t value);
363static void
364proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
365
366/* Handle type length mismatch (now filterable) expert info */
367static int proto_type_length_mismatch;
368static expert_field ei_type_length_mismatch_error;
369static expert_field ei_type_length_mismatch_warn;
370static void register_type_length_mismatch(void);
371
372/* Handle byte array string decoding errors with expert info */
373static int proto_byte_array_string_decoding_error;
374static expert_field ei_byte_array_string_decoding_failed_error;
375static void register_byte_array_string_decodinws_error(void);
376
377/* Handle date and time string decoding errors with expert info */
378static int proto_date_time_string_decoding_error;
379static expert_field ei_date_time_string_decoding_failed_error;
380static void register_date_time_string_decodinws_error(void);
381
382/* Handle string errors expert info */
383static int proto_string_errors;
384static expert_field ei_string_trailing_characters;
385static void register_string_errors(void);
386
387static int proto_register_field_init(header_field_info *hfinfo, const int parent);
388
389/* special-case header field used within proto.c */
390static header_field_info hfi_text_only =
391 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
392int hf_text_only;
393
394/* Structure for information about a protocol */
395struct _protocol {
396 const char *name; /* long description */
397 const char *short_name; /* short description */
398 const char *filter_name; /* name of this protocol in filters */
399 GPtrArray *fields; /* fields for this protocol */
400 int proto_id; /* field ID for this protocol */
401 bool_Bool is_enabled; /* true if protocol is enabled */
402 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
403 bool_Bool can_toggle; /* true if is_enabled can be changed */
404 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
405 For dissectors that need a protocol name so they
406 can be added to a dissector table, but use the
407 parent_proto_id for things like enable/disable */
408 GList *heur_list; /* Heuristic dissectors associated with this protocol */
409};
410
411/* List of all protocols */
412static GList *protocols;
413
414/* Structure stored for deregistered g_slice */
415struct g_slice_data {
416 size_t block_size;
417 void *mem_block;
418};
419
420/* Deregistered fields */
421static GPtrArray *deregistered_fields;
422static GPtrArray *deregistered_data;
423static GPtrArray *deregistered_slice;
424
425/* indexed by prefix, contains initializers */
426static GHashTable* prefixes;
427
428/* Contains information about a field when a dissector calls
429 * proto_tree_add_item. */
430#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)))
431#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
432
433/* Contains the space for proto_nodes. */
434#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
435 node->first_child = NULL((void*)0); \
436 node->last_child = NULL((void*)0); \
437 node->next = NULL((void*)0);
438
439#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
440 wmem_free(pool, node)
441
442/* String space for protocol and field items for the GUI */
443#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;
\
444 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
445 il->value_pos = 0; \
446 il->value_len = 0;
447#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
448 wmem_free(pool, il);
449
450#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", 450, __func__, "Unregistered hf! index=%d",
hfindex); ((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!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 450, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
451 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
452 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 452
, __func__, "Unregistered hf! index=%d", hfindex)
; \
453 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", 453, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
454 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", 454, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
455 hfinfo = gpa_hfinfo.hfi[hfindex];
456
457/* List which stores protocols and fields that have been registered */
458typedef struct _gpa_hfinfo_t {
459 uint32_t len;
460 uint32_t allocated_len;
461 header_field_info **hfi;
462} gpa_hfinfo_t;
463
464static gpa_hfinfo_t gpa_hfinfo;
465
466/* Hash table of abbreviations and IDs */
467static GHashTable *gpa_name_map;
468static header_field_info *same_name_hfinfo;
469
470/* Hash table protocol aliases. const char * -> const char * */
471static GHashTable *gpa_protocol_aliases;
472
473/*
474 * We're called repeatedly with the same field name when sorting a column.
475 * Cache our last gpa_name_map hit for faster lookups.
476 */
477static char *last_field_name;
478static header_field_info *last_hfinfo;
479
480static void save_same_name_hfinfo(void *data)
481{
482 same_name_hfinfo = (header_field_info*)data;
483}
484
485/* Points to the first element of an array of bits, indexed by
486 a subtree item type; that array element is true if subtrees of
487 an item of that type are to be expanded. */
488static uint32_t *tree_is_expanded;
489
490/* Number of elements in that array. The entry with index 0 is not used. */
491int num_tree_types = 1;
492
493/* Name hashtables for fast detection of duplicate names */
494static GHashTable* proto_names;
495static GHashTable* proto_short_names;
496static GHashTable* proto_filter_names;
497
498static const char *reserved_filter_names[] = {
499 /* Display filter keywords. */
500 "eq",
501 "ne",
502 "all_eq",
503 "any_eq",
504 "all_ne",
505 "any_ne",
506 "gt",
507 "ge",
508 "lt",
509 "le",
510 "bitand",
511 "bitwise_and",
512 "contains",
513 "matches",
514 "not",
515 "and",
516 "or",
517 "xor",
518 "in",
519 "any",
520 "all",
521 "true",
522 "false",
523 "nan",
524 "inf",
525 "infinity",
526 NULL((void*)0)
527};
528
529static GHashTable *proto_reserved_filter_names;
530
531static int
532proto_compare_name(const void *p1_arg, const void *p2_arg)
533{
534 const protocol_t *p1 = (const protocol_t *)p1_arg;
535 const protocol_t *p2 = (const protocol_t *)p2_arg;
536
537 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
538}
539
540static GSList *dissector_plugins;
541
542#ifdef HAVE_PLUGINS1
543void
544proto_register_plugin(const proto_plugin *plug)
545{
546 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
547}
548#else /* HAVE_PLUGINS */
549void
550proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
551{
552 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 552, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
553}
554#endif /* HAVE_PLUGINS */
555
556static void
557call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
558{
559 proto_plugin *plug = (proto_plugin *)data;
560
561 if (plug->register_protoinfo) {
562 plug->register_protoinfo();
563 }
564}
565
566static void
567call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
568{
569 proto_plugin *plug = (proto_plugin *)data;
570
571 if (plug->register_handoff) {
572 plug->register_handoff();
573 }
574}
575
576/* initialize data structures and register protocols and fields */
577void
578proto_init(GSList *register_all_plugin_protocols_list,
579 GSList *register_all_plugin_handoffs_list,
580 register_cb cb,
581 void *client_data)
582{
583 proto_cleanup_base();
584
585 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
586 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
587 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
588
589 proto_reserved_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
590 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
591 /* GHashTable has no key destructor so the cast is safe. */
592 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
593 }
594
595 gpa_hfinfo.len = 0;
596 gpa_hfinfo.allocated_len = 0;
597 gpa_hfinfo.hfi = NULL((void*)0);
598 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL((void*)0), save_same_name_hfinfo);
599 gpa_protocol_aliases = g_hash_table_new(g_str_hash, g_str_equal);
600 deregistered_fields = g_ptr_array_new();
601 deregistered_data = g_ptr_array_new();
602 deregistered_slice = g_ptr_array_new();
603
604 /* Initialize the ftype subsystem */
605 ftypes_initialize();
606
607 /* Initialize the address type subsystem */
608 address_types_initialize();
609
610 /* Register one special-case FT_TEXT_ONLY field for use when
611 converting wireshark to new-style proto_tree. These fields
612 are merely strings on the GUI tree; they are not filterable */
613 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
614
615 /* Register the pseudo-protocols used for exceptions. */
616 register_show_exception();
617 register_type_length_mismatch();
618 register_byte_array_string_decodinws_error();
619 register_date_time_string_decodinws_error();
620 register_string_errors();
621 ftypes_register_pseudofields();
622 col_register_protocol();
623
624 /* Have each built-in dissector register its protocols, fields,
625 dissector tables, and dissectors to be called through a
626 handle, and do whatever one-time initialization it needs to
627 do. */
628 register_all_protocols(cb, client_data);
629
630 /* Now call the registration routines for all epan plugins. */
631 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
632 ((void (*)(register_cb, void *))l->data)(cb, client_data);
633 }
634
635 /* Now call the registration routines for all dissector plugins. */
636 if (cb)
637 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
638 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
639
640 /* Now call the "handoff registration" routines of all built-in
641 dissectors; those routines register the dissector in other
642 dissectors' handoff tables, and fetch any dissector handles
643 they need. */
644 register_all_protocol_handoffs(cb, client_data);
645
646 /* Now do the same with epan plugins. */
647 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
648 ((void (*)(register_cb, void *))l->data)(cb, client_data);
649 }
650
651 /* Now do the same with dissector plugins. */
652 if (cb)
653 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
654 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
655
656 /* sort the protocols by protocol name */
657 protocols = g_list_sort(protocols, proto_compare_name);
658
659 /* sort the dissector handles in dissector tables (for -G reports
660 * and -d error messages. The GUI sorts the handles itself.) */
661 packet_all_tables_sort_handles();
662
663 /* We've assigned all the subtree type values; allocate the array
664 for them, and zero it out. */
665 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
)))
;
666}
667
668static void
669proto_cleanup_base(void)
670{
671 protocol_t *protocol;
672 header_field_info *hfinfo;
673
674 /* Free the abbrev/ID hash table */
675 if (gpa_name_map) {
676 g_hash_table_destroy(gpa_name_map);
677 gpa_name_map = NULL((void*)0);
678 }
679 if (gpa_protocol_aliases) {
680 g_hash_table_destroy(gpa_protocol_aliases);
681 gpa_protocol_aliases = NULL((void*)0);
682 }
683 g_free(last_field_name);
684 last_field_name = NULL((void*)0);
685
686 while (protocols) {
687 protocol = (protocol_t *)protocols->data;
688 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", 688
, __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", 688, "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", 688, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
689 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", 689, "protocol->proto_id == hfinfo->id"
))))
;
690
691 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)
;
692 if (protocol->parent_proto_id != -1) {
693 // pino protocol
694 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 694, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
695 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"
, 695, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
696 } else {
697 if (protocol->fields) {
698 g_ptr_array_free(protocol->fields, true1);
699 }
700 g_list_free(protocol->heur_list);
701 }
702 protocols = g_list_remove(protocols, protocol);
703 g_free(protocol);
704 }
705
706 if (proto_names) {
707 g_hash_table_destroy(proto_names);
708 proto_names = NULL((void*)0);
709 }
710
711 if (proto_short_names) {
712 g_hash_table_destroy(proto_short_names);
713 proto_short_names = NULL((void*)0);
714 }
715
716 if (proto_filter_names) {
717 g_hash_table_destroy(proto_filter_names);
718 proto_filter_names = NULL((void*)0);
719 }
720
721 if (proto_reserved_filter_names) {
722 g_hash_table_destroy(proto_reserved_filter_names);
723 proto_reserved_filter_names = NULL((void*)0);
724 }
725
726 if (gpa_hfinfo.allocated_len) {
727 gpa_hfinfo.len = 0;
728 gpa_hfinfo.allocated_len = 0;
729 g_free(gpa_hfinfo.hfi);
730 gpa_hfinfo.hfi = NULL((void*)0);
731 }
732
733 if (deregistered_fields) {
734 g_ptr_array_free(deregistered_fields, true1);
735 deregistered_fields = NULL((void*)0);
736 }
737
738 if (deregistered_data) {
739 g_ptr_array_free(deregistered_data, true1);
740 deregistered_data = NULL((void*)0);
741 }
742
743 if (deregistered_slice) {
744 g_ptr_array_free(deregistered_slice, true1);
745 deregistered_slice = NULL((void*)0);
746 }
747
748 g_free(tree_is_expanded);
749 tree_is_expanded = NULL((void*)0);
750
751 if (prefixes)
752 g_hash_table_destroy(prefixes);
753}
754
755void
756proto_cleanup(void)
757{
758 proto_free_deregistered_fields();
759 proto_cleanup_base();
760
761 g_slist_free(dissector_plugins);
762 dissector_plugins = NULL((void*)0);
763}
764
765static bool_Bool
766// NOLINTNEXTLINE(misc-no-recursion)
767proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
768 void *data)
769{
770 proto_node *pnode = tree;
771 proto_node *child;
772 proto_node *current;
773
774 if (func(pnode, data))
775 return true1;
776
777 child = pnode->first_child;
778 while (child != NULL((void*)0)) {
779 /*
780 * The routine we call might modify the child, e.g. by
781 * freeing it, so we get the child's successor before
782 * calling that routine.
783 */
784 current = child;
785 child = current->next;
786 // We recurse here, but we're limited by prefs.gui_max_tree_depth
787 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
788 return true1;
789 }
790
791 return false0;
792}
793
794void
795proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
796 void *data)
797{
798 proto_node *node = tree;
799 proto_node *current;
800
801 if (!node)
802 return;
803
804 node = node->first_child;
805 while (node != NULL((void*)0)) {
806 current = node;
807 node = current->next;
808 func((proto_tree *)current, data);
809 }
810}
811
812static void
813free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
814{
815 GPtrArray *ptrs = (GPtrArray *)value;
816 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
817 header_field_info *hfinfo;
818
819 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", 819, __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", 819, "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", 819, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
820 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
821 /* when a field is referenced by a filter this also
822 affects the refcount for the parent protocol so we need
823 to adjust the refcount for the parent as well
824 */
825 if (hfinfo->parent != -1) {
826 header_field_info *parent_hfinfo;
827 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", 827
, __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", 827, "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", 827, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
828 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
829 }
830 hfinfo->ref_type = HF_REF_TYPE_NONE;
831 }
832
833 g_ptr_array_free(ptrs, true1);
834}
835
836static void
837proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
838{
839 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
840
841 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
842
843 if (finfo) {
844 fvalue_free(finfo->value);
845 finfo->value = NULL((void*)0);
846 }
847}
848
849void
850proto_tree_reset(proto_tree *tree)
851{
852 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
853
854 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
855
856 /* free tree data */
857 if (tree_data->interesting_hfids) {
858 /* Free all the GPtrArray's in the interesting_hfids hash. */
859 g_hash_table_foreach(tree_data->interesting_hfids,
860 free_GPtrArray_value, NULL((void*)0));
861
862 /* And then remove all values. */
863 g_hash_table_remove_all(tree_data->interesting_hfids);
864 }
865
866 /* Reset track of the number of children */
867 tree_data->count = 0;
868
869 /* Reset our loop checks */
870 tree_data->max_start = 0;
871 tree_data->start_idle_count = 0;
872
873 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
874}
875
876/* frees the resources that the dissection a proto_tree uses */
877void
878proto_tree_free(proto_tree *tree)
879{
880 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
881
882 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
883
884 /* free tree data */
885 if (tree_data->interesting_hfids) {
886 /* Free all the GPtrArray's in the interesting_hfids hash. */
887 g_hash_table_foreach(tree_data->interesting_hfids,
888 free_GPtrArray_value, NULL((void*)0));
889
890 /* And then destroy the hash. */
891 g_hash_table_destroy(tree_data->interesting_hfids);
892 }
893
894 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)
;
895
896 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
897}
898
899/* Is the parsing being done for a visible proto_tree or an invisible one?
900 * By setting this correctly, the proto_tree creation is sped up by not
901 * having to call vsnprintf and copy strings around.
902 */
903bool_Bool
904proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
905{
906 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
907
908 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
909
910 return old_visible;
911}
912
913void
914proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
915{
916 if (tree)
917 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
918}
919
920/* Assume dissector set only its protocol fields.
921 This function is called by dissectors and allows the speeding up of filtering
922 in wireshark; if this function returns false it is safe to reset tree to NULL
923 and thus skip calling most of the expensive proto_tree_add_...()
924 functions.
925 If the tree is visible we implicitly assume the field is referenced.
926*/
927bool_Bool
928proto_field_is_referenced(proto_tree *tree, int proto_id)
929{
930 register header_field_info *hfinfo;
931
932
933 if (!tree)
934 return false0;
935
936 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
937 return true1;
938
939 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", 939, __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", 939, "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", 939, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
940 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
941 return true1;
942
943 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
944 return true1;
945
946 return false0;
947}
948
949
950/* Finds a record in the hfinfo array by id. */
951header_field_info *
952proto_registrar_get_nth(unsigned hfindex)
953{
954 register header_field_info *hfinfo;
955
956 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", 956, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 956, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 956, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
957 return hfinfo;
958}
959
960
961/* Prefix initialization
962 * this allows for a dissector to register a display filter name prefix
963 * so that it can delay the initialization of the hf array as long as
964 * possible.
965 */
966
967/* compute a hash for the part before the dot of a display filter */
968static unsigned
969prefix_hash (const void *key) {
970 /* end the string at the dot and compute its hash */
971 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
972 char* c = copy;
973 unsigned tmp;
974
975 for (; *c; c++) {
976 if (*c == '.') {
977 *c = 0;
978 break;
979 }
980 }
981
982 tmp = g_str_hash(copy);
983 g_free(copy);
984 return tmp;
985}
986
987/* are both strings equal up to the end or the dot? */
988static gboolean
989prefix_equal (const void *ap, const void *bp) {
990 const char* a = (const char *)ap;
991 const char* b = (const char *)bp;
992
993 do {
994 char ac = *a++;
995 char bc = *b++;
996
997 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
998
999 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1000 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1001
1002 if (ac != bc) return FALSE(0);
1003 } while (1);
1004
1005 return FALSE(0);
1006}
1007
1008/* Register a new prefix for "delayed" initialization of field arrays */
1009void
1010proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1011 if (! prefixes ) {
1012 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1013 }
1014
1015 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1016}
1017
1018/* helper to call all prefix initializers */
1019static gboolean
1020initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1021 ((prefix_initializer_t)v)((const char *)k);
1022 return TRUE(!(0));
1023}
1024
1025/** Initialize every remaining uninitialized prefix. */
1026void
1027proto_initialize_all_prefixes(void) {
1028 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1029}
1030
1031/* Finds a record in the hfinfo array by name.
1032 * If it fails to find it in the already registered fields,
1033 * it tries to find and call an initializer in the prefixes
1034 * table and if so it looks again.
1035 */
1036
1037header_field_info *
1038proto_registrar_get_byname(const char *field_name)
1039{
1040 header_field_info *hfinfo;
1041 prefix_initializer_t pi;
1042
1043 if (!field_name)
1044 return NULL((void*)0);
1045
1046 if (g_strcmp0(field_name, last_field_name) == 0) {
1047 return last_hfinfo;
1048 }
1049
1050 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1051
1052 if (hfinfo) {
1053 g_free(last_field_name);
1054 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1055 last_hfinfo = hfinfo;
1056 return hfinfo;
1057 }
1058
1059 if (!prefixes)
1060 return NULL((void*)0);
1061
1062 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1063 pi(field_name);
1064 g_hash_table_remove(prefixes, field_name);
1065 } else {
1066 return NULL((void*)0);
1067 }
1068
1069 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1070
1071 if (hfinfo) {
1072 g_free(last_field_name);
1073 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1074 last_hfinfo = hfinfo;
1075 }
1076 return hfinfo;
1077}
1078
1079header_field_info*
1080proto_registrar_get_byalias(const char *alias_name)
1081{
1082 if (!alias_name) {
1083 return NULL((void*)0);
1084 }
1085
1086 /* Find our aliased protocol. */
1087 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1088 char *dot = strchr(an_copy, '.');
1089 if (dot) {
1090 *dot = '\0';
1091 }
1092 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1093 if (!proto_pfx) {
1094 g_free(an_copy);
1095 return NULL((void*)0);
1096 }
1097
1098 /* Construct our aliased field and look it up. */
1099 GString *filter_name = g_string_new(proto_pfx);
1100 if (dot) {
1101 g_string_append_printf(filter_name, ".%s", dot+1);
1102 }
1103 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1104 g_free(an_copy);
1105 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)))))
;
1106
1107 return hfinfo;
1108}
1109
1110int
1111proto_registrar_get_id_byname(const char *field_name)
1112{
1113 header_field_info *hfinfo;
1114
1115 hfinfo = proto_registrar_get_byname(field_name);
1116
1117 if (!hfinfo)
1118 return -1;
1119
1120 return hfinfo->id;
1121}
1122
1123static int
1124label_strcat_flags(const header_field_info *hfinfo)
1125{
1126 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1127 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1128
1129 return 0;
1130}
1131
1132static char *
1133format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1134 const uint8_t *bytes, unsigned length, size_t max_str_len)
1135{
1136 char *str = NULL((void*)0);
1137 const uint8_t *p;
1138 bool_Bool is_printable;
1139
1140 if (bytes) {
1141 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1142 /*
1143 * If all bytes are valid and printable UTF-8, show the
1144 * bytes as a string - in quotes to indicate that it's
1145 * a string.
1146 */
1147 if (isprint_utf8_string(bytes, length)) {
1148 str = wmem_strdup_printf(scope, "\"%.*s\"",
1149 (int)length, bytes);
1150 return str;
1151 }
1152 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1153 /*
1154 * Check whether all bytes are printable.
1155 */
1156 is_printable = true1;
1157 for (p = bytes; p < bytes+length; p++) {
1158 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1159 /* Not printable. */
1160 is_printable = false0;
1161 break;
1162 }
1163 }
1164
1165 /*
1166 * If all bytes are printable ASCII, show the bytes
1167 * as a string - in quotes to indicate that it's
1168 * a string.
1169 */
1170 if (is_printable) {
1171 str = wmem_strdup_printf(scope, "\"%.*s\"",
1172 (int)length, bytes);
1173 return str;
1174 }
1175 }
1176
1177 /*
1178 * Either it's not printable ASCII, or we don't care whether
1179 * it's printable ASCII; show it as hex bytes.
1180 */
1181 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1182 case SEP_DOT:
1183 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1184 break;
1185 case SEP_DASH:
1186 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1187 break;
1188 case SEP_COLON:
1189 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1190 break;
1191 case SEP_SPACE:
1192 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1193 break;
1194 case BASE_NONE:
1195 default:
1196 if (prefs.display_byte_fields_with_spaces) {
1197 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1198 } else {
1199 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1200 }
1201 break;
1202 }
1203 }
1204 else {
1205 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1206 str = wmem_strdup(scope, "<none>");
1207 } else {
1208 str = wmem_strdup(scope, "<MISSING>");
1209 }
1210 }
1211 return str;
1212}
1213
1214static char *
1215format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1216 const uint8_t *bytes, unsigned length)
1217{
1218 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1219}
1220
1221static void
1222ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1223{
1224 subtree_lvl *pushed_tree;
1225
1226 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"
, 1226, "ptvc->pushed_tree_max <= 256-8"))))
;
1227 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1228
1229 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1230 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1230, "pushed_tree != ((void*)0)"
))))
;
1231 ptvc->pushed_tree = pushed_tree;
1232}
1233
1234static void
1235ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1236{
1237 ptvc->pushed_tree = NULL((void*)0);
1238 ptvc->pushed_tree_max = 0;
1239 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", 1239, "ptvc->pushed_tree_index == 0"
))))
;
1240 ptvc->pushed_tree_index = 0;
1241}
1242
1243/* Allocates an initializes a ptvcursor_t with 3 variables:
1244 * proto_tree, tvbuff, and offset. */
1245ptvcursor_t *
1246ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1247{
1248 ptvcursor_t *ptvc;
1249
1250 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1251 ptvc->scope = scope;
1252 ptvc->tree = tree;
1253 ptvc->tvb = tvb;
1254 ptvc->offset = offset;
1255 ptvc->pushed_tree = NULL((void*)0);
1256 ptvc->pushed_tree_max = 0;
1257 ptvc->pushed_tree_index = 0;
1258 return ptvc;
1259}
1260
1261
1262/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1263void
1264ptvcursor_free(ptvcursor_t *ptvc)
1265{
1266 ptvcursor_free_subtree_levels(ptvc);
1267 /*g_free(ptvc);*/
1268}
1269
1270/* Returns tvbuff. */
1271tvbuff_t *
1272ptvcursor_tvbuff(ptvcursor_t *ptvc)
1273{
1274 return ptvc->tvb;
1275}
1276
1277/* Returns current offset. */
1278int
1279ptvcursor_current_offset(ptvcursor_t *ptvc)
1280{
1281 return ptvc->offset;
1282}
1283
1284proto_tree *
1285ptvcursor_tree(ptvcursor_t *ptvc)
1286{
1287 if (!ptvc)
1288 return NULL((void*)0);
1289
1290 return ptvc->tree;
1291}
1292
1293void
1294ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1295{
1296 ptvc->tree = tree;
1297}
1298
1299/* creates a subtree, sets it as the working tree and pushes the old working tree */
1300proto_tree *
1301ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1302{
1303 subtree_lvl *subtree;
1304 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1305 ptvcursor_new_subtree_levels(ptvc);
1306
1307 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1308 subtree->tree = ptvc->tree;
1309 subtree->it= NULL((void*)0);
1310 ptvc->pushed_tree_index++;
1311 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1312}
1313
1314/* pops a subtree */
1315void
1316ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1317{
1318 subtree_lvl *subtree;
1319
1320 if (ptvc->pushed_tree_index <= 0)
1321 return;
1322
1323 ptvc->pushed_tree_index--;
1324 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1325 if (subtree->it != NULL((void*)0))
1326 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1327
1328 ptvc->tree = subtree->tree;
1329}
1330
1331/* saves the current tvb offset and the item in the current subtree level */
1332static void
1333ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1334{
1335 subtree_lvl *subtree;
1336
1337 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", 1337, "ptvc->pushed_tree_index > 0"
))))
;
1338
1339 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1340 subtree->it = it;
1341 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1342}
1343
1344/* Creates a subtree and adds it to the cursor as the working tree but does not
1345 * save the old working tree */
1346proto_tree *
1347ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1348{
1349 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1350 return ptvc->tree;
1351}
1352
1353static proto_tree *
1354ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1355{
1356 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1357 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1358 ptvcursor_subtree_set_item(ptvc, it);
1359 return ptvcursor_tree(ptvc);
1360}
1361
1362/* Add an item to the tree and create a subtree
1363 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1364 * In this case, when the subtree will be closed, the parent item length will
1365 * be equal to the advancement of the cursor since the creation of the subtree.
1366 */
1367proto_tree *
1368ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1369 const unsigned encoding, int ett_subtree)
1370{
1371 proto_item *it;
1372
1373 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1374 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1375}
1376
1377static proto_item *
1378proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1379
1380/* Add a text node to the tree and create a subtree
1381 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1382 * In this case, when the subtree will be closed, the item length will be equal
1383 * to the advancement of the cursor since the creation of the subtree.
1384 */
1385proto_tree *
1386ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1387 int ett_subtree, const char *format, ...)
1388{
1389 proto_item *pi;
1390 va_list ap;
1391 header_field_info *hfinfo;
1392 proto_tree *tree;
1393
1394 tree = ptvcursor_tree(ptvc);
1395
1396 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1397
1398 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", 1398
, __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", 1398, "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", 1398, "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", 1398, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1399
1400 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1401 ptvcursor_current_offset(ptvc), length);
1402
1403 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1403, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1404
1405 va_start(ap, format)__builtin_va_start(ap, format);
1406 proto_tree_set_representation(pi, format, ap);
1407 va_end(ap)__builtin_va_end(ap);
1408
1409 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1410}
1411
1412/* Add a text-only node, leaving it to our caller to fill the text in */
1413static proto_item *
1414proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1415{
1416 proto_item *pi;
1417
1418 if (tree == NULL((void*)0))
1419 return NULL((void*)0);
1420
1421 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1422
1423 return pi;
1424}
1425
1426/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1427proto_item *
1428proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1429 const char *format, ...)
1430{
1431 proto_item *pi;
1432 va_list ap;
1433 header_field_info *hfinfo;
1434
1435 if (length == -1) {
1436 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1437 } else {
1438 tvb_ensure_bytes_exist(tvb, start, length);
1439 }
1440
1441 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1442
1443 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", 1443
, __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", 1443, "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", 1443, "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", 1443, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1444
1445 pi = proto_tree_add_text_node(tree, tvb, start, length);
1446
1447 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1447, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1448
1449 va_start(ap, format)__builtin_va_start(ap, format);
1450 proto_tree_set_representation(pi, format, ap);
1451 va_end(ap)__builtin_va_end(ap);
1452
1453 return pi;
1454}
1455
1456/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1457proto_item *
1458proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1459 int length, const char *format, va_list ap)
1460{
1461 proto_item *pi;
1462 header_field_info *hfinfo;
1463
1464 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1465 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1466 * the length to be what's in the tvbuff if length is -1, and the
1467 * minimum of length and what's in the tvbuff if not.
1468 */
1469
1470 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1471
1472 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", 1472
, __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", 1472, "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", 1472, "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", 1472, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1473
1474 pi = proto_tree_add_text_node(tree, tvb, start, length);
1475
1476 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1476, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1477
1478 proto_tree_set_representation(pi, format, ap);
1479
1480 return pi;
1481}
1482
1483/* Add a text-only node that creates a subtree underneath.
1484 */
1485proto_tree *
1486proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1487{
1488 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1489}
1490
1491/* Add a text-only node that creates a subtree underneath.
1492 */
1493proto_tree *
1494proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1495{
1496 proto_tree *pt;
1497 proto_item *pi;
1498 va_list ap;
1499
1500 va_start(ap, format)__builtin_va_start(ap, format);
1501 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1502 va_end(ap)__builtin_va_end(ap);
1503
1504 if (tree_item != NULL((void*)0))
1505 *tree_item = pi;
1506
1507 pt = proto_item_add_subtree(pi, idx);
1508
1509 return pt;
1510}
1511
1512/* Add a text-only node for debugging purposes. The caller doesn't need
1513 * to worry about tvbuff, start, or length. Debug message gets sent to
1514 * STDOUT, too */
1515proto_item *
1516proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1517{
1518 proto_item *pi;
1519 va_list ap;
1520
1521 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1522
1523 if (pi) {
1524 va_start(ap, format)__builtin_va_start(ap, format);
1525 proto_tree_set_representation(pi, format, ap);
1526 va_end(ap)__builtin_va_end(ap);
1527 }
1528 va_start(ap, format)__builtin_va_start(ap, format);
1529 vprintf(format, ap);
1530 va_end(ap)__builtin_va_end(ap);
1531 printf("\n");
1532
1533 return pi;
1534}
1535
1536proto_item *
1537proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1538{
1539 proto_item *pi;
1540 header_field_info *hfinfo;
1541
1542 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1543
1544 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", 1544
, __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", 1544, "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", 1544, "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", 1544, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1545
1546 pi = proto_tree_add_text_node(tree, tvb, start, length);
1547
1548 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1548, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1549
1550 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1551
1552 return pi;
1553}
1554
1555proto_item *
1556proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1557{
1558 proto_item *pi;
1559 header_field_info *hfinfo;
1560 char *str;
1561
1562 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1563
1564 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", 1564
, __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", 1564, "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", 1564, "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", 1564, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1565
1566 pi = proto_tree_add_text_node(tree, tvb, start, length);
1567
1568 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1568, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1569
1570 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1571 proto_item_set_text(pi, "%s", str);
1572 wmem_free(NULL((void*)0), str);
1573
1574 return pi;
1575}
1576
1577void proto_report_dissector_bug(const char *format, ...)
1578{
1579 va_list args;
1580
1581 if (wireshark_abort_on_dissector_bug) {
1582 /*
1583 * Try to have the error message show up in the crash
1584 * information.
1585 */
1586 va_start(args, format)__builtin_va_start(args, format);
1587 ws_vadd_crash_info(format, args);
1588 va_end(args)__builtin_va_end(args);
1589
1590 /*
1591 * Print the error message.
1592 */
1593 va_start(args, format)__builtin_va_start(args, format);
1594 vfprintf(stderrstderr, format, args);
1595 va_end(args)__builtin_va_end(args);
1596 putc('\n', stderrstderr);
1597
1598 /*
1599 * And crash.
1600 */
1601 abort();
1602 } else {
1603 va_start(args, format)__builtin_va_start(args, format);
1604 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1605 va_end(args)__builtin_va_end(args);
1606 }
1607}
1608
1609/* We could probably get away with changing is_error to a minimum length value. */
1610static void
1611report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1612{
1613 if (is_error) {
1614 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1615 } else {
1616 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1617 }
1618
1619 if (is_error) {
1620 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1621 }
1622}
1623
1624static uint32_t
1625get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1626{
1627 uint32_t value;
1628 bool_Bool length_error;
1629
1630 switch (length) {
1631
1632 case 1:
1633 value = tvb_get_uint8(tvb, offset);
1634 if (encoding & ENC_ZIGBEE0x40000000) {
1635 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1636 value = 0;
1637 }
1638 }
1639 break;
1640
1641 case 2:
1642 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1643 : tvb_get_ntohs(tvb, offset);
1644 if (encoding & ENC_ZIGBEE0x40000000) {
1645 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1646 value = 0;
1647 }
1648 }
1649 break;
1650
1651 case 3:
1652 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1653 : tvb_get_ntoh24(tvb, offset);
1654 break;
1655
1656 case 4:
1657 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1658 : tvb_get_ntohl(tvb, offset);
1659 break;
1660
1661 default:
1662 if (length < 1) {
1663 length_error = true1;
1664 value = 0;
1665 } else {
1666 length_error = false0;
1667 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1668 : tvb_get_ntohl(tvb, offset);
1669 }
1670 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1671 break;
1672 }
1673 return value;
1674}
1675
1676static inline uint64_t
1677get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1678{
1679 uint64_t value;
1680
1681 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1682
1683 if (length < 1 || length > 8) {
1684 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1685 }
1686
1687 return value;
1688}
1689
1690static int32_t
1691get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1692{
1693 int32_t value;
1694 bool_Bool length_error;
1695
1696 switch (length) {
1697
1698 case 1:
1699 value = tvb_get_int8(tvb, offset);
1700 break;
1701
1702 case 2:
1703 value = encoding ? tvb_get_letohis(tvb, offset)
1704 : tvb_get_ntohis(tvb, offset);
1705 break;
1706
1707 case 3:
1708 value = encoding ? tvb_get_letohi24(tvb, offset)
1709 : tvb_get_ntohi24(tvb, offset);
1710 break;
1711
1712 case 4:
1713 value = encoding ? tvb_get_letohil(tvb, offset)
1714 : tvb_get_ntohil(tvb, offset);
1715 break;
1716
1717 default:
1718 if (length < 1) {
1719 length_error = true1;
1720 value = 0;
1721 } else {
1722 length_error = false0;
1723 value = encoding ? tvb_get_letohil(tvb, offset)
1724 : tvb_get_ntohil(tvb, offset);
1725 }
1726 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1727 break;
1728 }
1729 return value;
1730}
1731
1732/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1733 * be cast-able as a int64_t. This is weird, but what the code has always done.
1734 */
1735static inline uint64_t
1736get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1737{
1738 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1739
1740 switch (length) {
1741 case 7:
1742 value = ws_sign_ext64(value, 56);
1743 break;
1744 case 6:
1745 value = ws_sign_ext64(value, 48);
1746 break;
1747 case 5:
1748 value = ws_sign_ext64(value, 40);
1749 break;
1750 case 4:
1751 value = ws_sign_ext64(value, 32);
1752 break;
1753 case 3:
1754 value = ws_sign_ext64(value, 24);
1755 break;
1756 case 2:
1757 value = ws_sign_ext64(value, 16);
1758 break;
1759 case 1:
1760 value = ws_sign_ext64(value, 8);
1761 break;
1762 }
1763
1764 return value;
1765}
1766
1767/* For FT_STRING */
1768static inline const uint8_t *
1769get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1770 int length, int *ret_length, const unsigned encoding)
1771{
1772 if (length == -1) {
1773 length = tvb_ensure_captured_length_remaining(tvb, start);
1774 }
1775 *ret_length = length;
1776 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1777}
1778
1779/* For FT_STRINGZ */
1780static inline const uint8_t *
1781get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1782 int start, int length, int *ret_length, const unsigned encoding)
1783{
1784 const uint8_t *value;
1785
1786 if (length < -1) {
1787 report_type_length_mismatch(tree, "a string", length, true1);
1788 }
1789 if (length == -1) {
1790 /* This can throw an exception */
1791 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1792 } else {
1793 /* In this case, length signifies the length of the string.
1794 *
1795 * This could either be a null-padded string, which doesn't
1796 * necessarily have a '\0' at the end, or a null-terminated
1797 * string, with a trailing '\0'. (Yes, there are cases
1798 * where you have a string that's both counted and null-
1799 * terminated.)
1800 *
1801 * In the first case, we must allocate a buffer of length
1802 * "length+1", to make room for a trailing '\0'.
1803 *
1804 * In the second case, we don't assume that there is a
1805 * trailing '\0' there, as the packet might be malformed.
1806 * (XXX - should we throw an exception if there's no
1807 * trailing '\0'?) Therefore, we allocate a buffer of
1808 * length "length+1", and put in a trailing '\0', just to
1809 * be safe.
1810 *
1811 * (XXX - this would change if we made string values counted
1812 * rather than null-terminated.)
1813 */
1814 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1815 }
1816 *ret_length = length;
1817 return value;
1818}
1819
1820/* For FT_UINT_STRING */
1821static inline const uint8_t *
1822get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1823 tvbuff_t *tvb, int start, int length, int *ret_length,
1824 const unsigned encoding)
1825{
1826 uint32_t n;
1827 const uint8_t *value;
1828
1829 /* I believe it's ok if this is called with a NULL tree */
1830 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1831 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1832 length += n;
1833 *ret_length = length;
1834 return value;
1835}
1836
1837/* For FT_STRINGZPAD */
1838static inline const uint8_t *
1839get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1840 int length, int *ret_length, const unsigned encoding)
1841{
1842 /*
1843 * XXX - currently, string values are null-
1844 * terminated, so a "zero-padded" string
1845 * isn't special. If we represent string
1846 * values as something that includes a counted
1847 * array of bytes, we'll need to strip the
1848 * trailing NULs.
1849 */
1850 if (length == -1) {
1851 length = tvb_ensure_captured_length_remaining(tvb, start);
1852 }
1853 *ret_length = length;
1854 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1855}
1856
1857/* For FT_STRINGZTRUNC */
1858static inline const uint8_t *
1859get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1860 int length, int *ret_length, const unsigned encoding)
1861{
1862 /*
1863 * XXX - currently, string values are null-
1864 * terminated, so a "zero-truncated" string
1865 * isn't special. If we represent string
1866 * values as something that includes a counted
1867 * array of bytes, we'll need to strip everything
1868 * starting with the terminating NUL.
1869 */
1870 if (length == -1) {
1871 length = tvb_ensure_captured_length_remaining(tvb, start);
1872 }
1873 *ret_length = length;
1874 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1875}
1876
1877/*
1878 * Deltas between the epochs for various non-UN*X time stamp formats and
1879 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1880 * stamp format.
1881 */
1882
1883/*
1884 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1885 * XXX - if it's OK if this is unsigned, can we just use
1886 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1887 */
1888#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1889
1890/*
1891 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1892 */
1893#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1894
1895/* this can be called when there is no tree, so tree may be null */
1896static void
1897get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1898 const int length, const unsigned encoding, nstime_t *time_stamp,
1899 const bool_Bool is_relative)
1900{
1901 uint32_t tmpsecs;
1902 uint64_t tmp64secs;
1903 uint64_t todusecs;
1904
1905 switch (encoding) {
1906
1907 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1908 /*
1909 * If the length is 16, 8-byte seconds, followed
1910 * by 8-byte fractional time in nanoseconds,
1911 * both big-endian.
1912 *
1913 * If the length is 12, 8-byte seconds, followed
1914 * by 4-byte fractional time in nanoseconds,
1915 * both big-endian.
1916 *
1917 * If the length is 8, 4-byte seconds, followed
1918 * by 4-byte fractional time in nanoseconds,
1919 * both big-endian.
1920 *
1921 * For absolute times, the seconds are seconds
1922 * since the UN*X epoch.
1923 */
1924 if (length == 16) {
1925 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1926 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1927 } else if (length == 12) {
1928 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1929 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1930 } else if (length == 8) {
1931 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1932 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1933 } else if (length == 4) {
1934 /*
1935 * Backwards compatibility.
1936 * ENC_TIME_SECS_NSECS is 0; using
1937 * ENC_BIG_ENDIAN by itself with a 4-byte
1938 * time-in-seconds value was done in the
1939 * past.
1940 */
1941 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1942 time_stamp->nsecs = 0;
1943 } else {
1944 time_stamp->secs = 0;
1945 time_stamp->nsecs = 0;
1946 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1947 }
1948 break;
1949
1950 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
1951 /*
1952 * If the length is 16, 8-byte seconds, followed
1953 * by 8-byte fractional time in nanoseconds,
1954 * both little-endian.
1955 *
1956 * If the length is 12, 8-byte seconds, followed
1957 * by 4-byte fractional time in nanoseconds,
1958 * both little-endian.
1959 *
1960 * If the length is 8, 4-byte seconds, followed
1961 * by 4-byte fractional time in nanoseconds,
1962 * both little-endian.
1963 *
1964 * For absolute times, the seconds are seconds
1965 * since the UN*X epoch.
1966 */
1967 if (length == 16) {
1968 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1969 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
1970 } else if (length == 12) {
1971 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1972 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1973 } else if (length == 8) {
1974 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1975 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1976 } else if (length == 4) {
1977 /*
1978 * Backwards compatibility.
1979 * ENC_TIME_SECS_NSECS is 0; using
1980 * ENC_LITTLE_ENDIAN by itself with a 4-byte
1981 * time-in-seconds value was done in the
1982 * past.
1983 */
1984 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1985 time_stamp->nsecs = 0;
1986 } else {
1987 time_stamp->secs = 0;
1988 time_stamp->nsecs = 0;
1989 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1990 }
1991 break;
1992
1993 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
1994 /*
1995 * NTP time stamp, big-endian.
1996 * Only supported for absolute times.
1997 */
1998 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1998, "!is_relative"
))))
;
1999
2000 /* We need a temporary variable here so the unsigned math
2001 * works correctly (for years > 2036 according to RFC 2030
2002 * chapter 3).
2003 *
2004 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2005 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2006 * If bit 0 is not set, the time is in the range 2036-2104 and
2007 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2008 */
2009 tmpsecs = tvb_get_ntohl(tvb, start);
2010 if ((tmpsecs & 0x80000000) != 0)
2011 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2012 else
2013 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2014
2015 if (length == 8) {
2016 tmp64secs = tvb_get_ntoh64(tvb, start);
2017 if (tmp64secs == 0) {
2018 //This is "NULL" time
2019 time_stamp->secs = 0;
2020 time_stamp->nsecs = 0;
2021 } else {
2022 /*
2023 * Convert 1/2^32s of a second to
2024 * nanoseconds.
2025 */
2026 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2027 }
2028 } else if (length == 4) {
2029 /*
2030 * Backwards compatibility.
2031 */
2032 if (tmpsecs == 0) {
2033 //This is "NULL" time
2034 time_stamp->secs = 0;
2035 }
2036 time_stamp->nsecs = 0;
2037 } else {
2038 time_stamp->secs = 0;
2039 time_stamp->nsecs = 0;
2040 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2041 }
2042 break;
2043
2044 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2045 /*
2046 * NTP time stamp, little-endian.
2047 * Only supported for absolute times.
2048 *
2049 * NTP doesn't use this, because it's an Internet format
2050 * and hence big-endian. Any implementation must decide
2051 * whether the NTP timestamp is a 64-bit unsigned fixed
2052 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2053 * with a 32-bit unsigned seconds field followed by a
2054 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2055 * the previous two).
2056 *
2057 * XXX: We do the latter, but no dissector uses this format.
2058 * OTOH, ERF timestamps do the former, so perhaps we
2059 * should switch the interpretation so that packet-erf.c
2060 * could use this directly?
2061 */
2062 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2062, "!is_relative"
))))
;
2063
2064 /* We need a temporary variable here so the unsigned math
2065 * works correctly (for years > 2036 according to RFC 2030
2066 * chapter 3).
2067 *
2068 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2069 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2070 * If bit 0 is not set, the time is in the range 2036-2104 and
2071 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2072 */
2073 tmpsecs = tvb_get_letohl(tvb, start);
2074 if ((tmpsecs & 0x80000000) != 0)
2075 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2076 else
2077 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2078
2079 if (length == 8) {
2080 tmp64secs = tvb_get_letoh64(tvb, start);
2081 if (tmp64secs == 0) {
2082 //This is "NULL" time
2083 time_stamp->secs = 0;
2084 time_stamp->nsecs = 0;
2085 } else {
2086 /*
2087 * Convert 1/2^32s of a second to
2088 * nanoseconds.
2089 */
2090 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2091 }
2092 } else if (length == 4) {
2093 /*
2094 * Backwards compatibility.
2095 */
2096 if (tmpsecs == 0) {
2097 //This is "NULL" time
2098 time_stamp->secs = 0;
2099 }
2100 time_stamp->nsecs = 0;
2101 } else {
2102 time_stamp->secs = 0;
2103 time_stamp->nsecs = 0;
2104 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2105 }
2106 break;
2107
2108 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2109 /*
2110 * S/3x0 and z/Architecture TOD clock time stamp,
2111 * big-endian. The epoch is January 1, 1900,
2112 * 00:00:00 (proleptic?) UTC.
2113 *
2114 * Only supported for absolute times.
2115 */
2116 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2116, "!is_relative"
))))
;
2117 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2117, "length == 8"
))))
;
2118
2119 if (length == 8) {
2120 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2121 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2122 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2123 } else {
2124 time_stamp->secs = 0;
2125 time_stamp->nsecs = 0;
2126 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2127 }
2128 break;
2129
2130 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2131 /*
2132 * S/3x0 and z/Architecture TOD clock time stamp,
2133 * little-endian. The epoch is January 1, 1900,
2134 * 00:00:00 (proleptic?) UTC.
2135 *
2136 * Only supported for absolute times.
2137 */
2138 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2138, "!is_relative"
))))
;
2139
2140 if (length == 8) {
2141 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2142 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2143 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2144 } else {
2145 time_stamp->secs = 0;
2146 time_stamp->nsecs = 0;
2147 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2148 }
2149 break;
2150
2151 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2152 /*
2153 * Time stamp using the same seconds/fraction format
2154 * as NTP, but with the origin of the time stamp being
2155 * the UNIX epoch rather than the NTP epoch; big-
2156 * endian.
2157 *
2158 * Only supported for absolute times.
2159 */
2160 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2160, "!is_relative"
))))
;
2161
2162 if (length == 8) {
2163 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2164 /*
2165 * Convert 1/2^32s of a second to nanoseconds.
2166 */
2167 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2168 } else {
2169 time_stamp->secs = 0;
2170 time_stamp->nsecs = 0;
2171 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2172 }
2173 break;
2174
2175 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2176 /*
2177 * Time stamp using the same seconds/fraction format
2178 * as NTP, but with the origin of the time stamp being
2179 * the UNIX epoch rather than the NTP epoch; little-
2180 * endian.
2181 *
2182 * Only supported for absolute times.
2183 *
2184 * The RTPS specification explicitly supports Little
2185 * Endian encoding. In one place, it states that its
2186 * Time_t representation "is the one defined by ...
2187 * RFC 1305", but in another explicitly defines it as
2188 * a struct consisting of an 32 bit unsigned seconds
2189 * field and a 32 bit unsigned fraction field, not a 64
2190 * bit fixed point, so we do that here.
2191 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2192 */
2193 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2193, "!is_relative"
))))
;
2194
2195 if (length == 8) {
2196 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2197 /*
2198 * Convert 1/2^32s of a second to nanoseconds.
2199 */
2200 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2201 } else {
2202 time_stamp->secs = 0;
2203 time_stamp->nsecs = 0;
2204 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2205 }
2206 break;
2207
2208 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2209 /*
2210 * MIP6 time stamp, big-endian.
2211 * A 64-bit unsigned integer field containing a timestamp. The
2212 * value indicates the number of seconds since January 1, 1970,
2213 * 00:00 UTC, by using a fixed point format. In this format, the
2214 * integer number of seconds is contained in the first 48 bits of
2215 * the field, and the remaining 16 bits indicate the number of
2216 * 1/65536 fractions of a second.
2217
2218 * Only supported for absolute times.
2219 */
2220 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2220, "!is_relative"
))))
;
2221
2222 if (length == 8) {
2223 /* We need a temporary variable here so the casting and fractions
2224 * of a second work correctly.
2225 */
2226 tmp64secs = tvb_get_ntoh48(tvb, start);
2227 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2228 tmpsecs <<= 16;
2229
2230 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2231 //This is "NULL" time
2232 time_stamp->secs = 0;
2233 time_stamp->nsecs = 0;
2234 } else {
2235 time_stamp->secs = (time_t)tmp64secs;
2236 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2237 }
2238 } else {
2239 time_stamp->secs = 0;
2240 time_stamp->nsecs = 0;
2241 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2242 }
2243 break;
2244
2245 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2246 /*
2247 * If the length is 16, 8-byte seconds, followed
2248 * by 8-byte fractional time in microseconds,
2249 * both big-endian.
2250 *
2251 * If the length is 12, 8-byte seconds, followed
2252 * by 4-byte fractional time in microseconds,
2253 * both big-endian.
2254 *
2255 * If the length is 8, 4-byte seconds, followed
2256 * by 4-byte fractional time in microseconds,
2257 * both big-endian.
2258 *
2259 * For absolute times, the seconds are seconds
2260 * since the UN*X epoch.
2261 */
2262 if (length == 16) {
2263 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2264 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2265 } else if (length == 12) {
2266 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2267 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2268 } else if (length == 8) {
2269 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2270 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2271 } else {
2272 time_stamp->secs = 0;
2273 time_stamp->nsecs = 0;
2274 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2275 }
2276 break;
2277
2278 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2279 /*
2280 * If the length is 16, 8-byte seconds, followed
2281 * by 8-byte fractional time in microseconds,
2282 * both little-endian.
2283 *
2284 * If the length is 12, 8-byte seconds, followed
2285 * by 4-byte fractional time in microseconds,
2286 * both little-endian.
2287 *
2288 * If the length is 8, 4-byte seconds, followed
2289 * by 4-byte fractional time in microseconds,
2290 * both little-endian.
2291 *
2292 * For absolute times, the seconds are seconds
2293 * since the UN*X epoch.
2294 */
2295 if (length == 16) {
2296 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2297 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2298 } else if (length == 12) {
2299 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2300 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2301 } else if (length == 8) {
2302 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2303 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2304 } else {
2305 time_stamp->secs = 0;
2306 time_stamp->nsecs = 0;
2307 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2308 }
2309 break;
2310
2311 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2312 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2313 /*
2314 * Seconds, 1 to 8 bytes.
2315 * For absolute times, it's seconds since the
2316 * UN*X epoch.
2317 */
2318 if (length >= 1 && length <= 8) {
2319 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2320 time_stamp->nsecs = 0;
2321 } else {
2322 time_stamp->secs = 0;
2323 time_stamp->nsecs = 0;
2324 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2325 }
2326 break;
2327
2328 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2329 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2330 /*
2331 * Milliseconds, 1 to 8 bytes.
2332 * For absolute times, it's milliseconds since the
2333 * UN*X epoch.
2334 */
2335 if (length >= 1 && length <= 8) {
2336 uint64_t msecs;
2337
2338 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2339 time_stamp->secs = (time_t)(msecs / 1000);
2340 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2341 } else {
2342 time_stamp->secs = 0;
2343 time_stamp->nsecs = 0;
2344 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2345 }
2346 break;
2347
2348 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2349 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2350 /*
2351 * Microseconds, 1 to 8 bytes.
2352 * For absolute times, it's microseconds since the
2353 * UN*X epoch.
2354 */
2355 if (length >= 1 && length <= 8) {
2356 uint64_t usecs;
2357
2358 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2359 time_stamp->secs = (time_t)(usecs / 1000000);
2360 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2361 } else {
2362 time_stamp->secs = 0;
2363 time_stamp->nsecs = 0;
2364 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2365 }
2366 break;
2367
2368 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2369 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2370 /*
2371 * nanoseconds, 1 to 8 bytes.
2372 * For absolute times, it's nanoseconds since the
2373 * UN*X epoch.
2374 */
2375
2376 if (length >= 1 && length <= 8) {
2377 uint64_t nsecs;
2378
2379 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2380 time_stamp->secs = (time_t)(nsecs / 1000000000);
2381 time_stamp->nsecs = (int)(nsecs % 1000000000);
2382 } else {
2383 time_stamp->secs = 0;
2384 time_stamp->nsecs = 0;
2385 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2386 }
2387 break;
2388
2389 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2390 /*
2391 * 1/64ths of a second since the UN*X epoch,
2392 * big-endian.
2393 *
2394 * Only supported for absolute times.
2395 */
2396 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2396, "!is_relative"
))))
;
2397
2398 if (length == 8) {
2399 /*
2400 * The upper 48 bits are seconds since the
2401 * UN*X epoch.
2402 */
2403 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2404 /*
2405 * The lower 16 bits are 1/2^16s of a second;
2406 * convert them to nanoseconds.
2407 *
2408 * XXX - this may give the impression of higher
2409 * precision than you actually get.
2410 */
2411 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2412 } else {
2413 time_stamp->secs = 0;
2414 time_stamp->nsecs = 0;
2415 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2416 }
2417 break;
2418
2419 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2420 /*
2421 * 1/64ths of a second since the UN*X epoch,
2422 * little-endian.
2423 *
2424 * Only supported for absolute times.
2425 */
2426 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2426, "!is_relative"
))))
;
2427
2428 if (length == 8) {
2429 /*
2430 * XXX - this is assuming that, if anybody
2431 * were ever to use this format - RFC 3971
2432 * doesn't, because that's an Internet
2433 * protocol, and those use network byte
2434 * order, i.e. big-endian - they'd treat it
2435 * as a 64-bit count of 1/2^16s of a second,
2436 * putting the upper 48 bits at the end.
2437 *
2438 * The lower 48 bits are seconds since the
2439 * UN*X epoch.
2440 */
2441 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2442 /*
2443 * The upper 16 bits are 1/2^16s of a second;
2444 * convert them to nanoseconds.
2445 *
2446 * XXX - this may give the impression of higher
2447 * precision than you actually get.
2448 */
2449 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2450 } else {
2451 time_stamp->secs = 0;
2452 time_stamp->nsecs = 0;
2453 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2454 }
2455 break;
2456
2457 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2458 /*
2459 * NTP time stamp, with 1-second resolution (i.e.,
2460 * seconds since the NTP epoch), big-endian.
2461 * Only supported for absolute times.
2462 */
2463 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2463, "!is_relative"
))))
;
2464
2465 if (length == 4) {
2466 /*
2467 * We need a temporary variable here so the unsigned math
2468 * works correctly (for years > 2036 according to RFC 2030
2469 * chapter 3).
2470 *
2471 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2472 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2473 * If bit 0 is not set, the time is in the range 2036-2104 and
2474 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2475 */
2476 tmpsecs = tvb_get_ntohl(tvb, start);
2477 if ((tmpsecs & 0x80000000) != 0)
2478 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2479 else
2480 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2481 time_stamp->nsecs = 0;
2482 } else {
2483 time_stamp->secs = 0;
2484 time_stamp->nsecs = 0;
2485 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2486 }
2487 break;
2488
2489 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2490 /*
2491 * NTP time stamp, with 1-second resolution (i.e.,
2492 * seconds since the NTP epoch), little-endian.
2493 * Only supported for absolute times.
2494 */
2495 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2495, "!is_relative"
))))
;
2496
2497 /*
2498 * We need a temporary variable here so the unsigned math
2499 * works correctly (for years > 2036 according to RFC 2030
2500 * chapter 3).
2501 *
2502 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2503 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2504 * If bit 0 is not set, the time is in the range 2036-2104 and
2505 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2506 */
2507 if (length == 4) {
2508 tmpsecs = tvb_get_letohl(tvb, start);
2509 if ((tmpsecs & 0x80000000) != 0)
2510 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2511 else
2512 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2513 time_stamp->nsecs = 0;
2514 } else {
2515 time_stamp->secs = 0;
2516 time_stamp->nsecs = 0;
2517 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2518 }
2519 break;
2520
2521 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2522 /*
2523 * Milliseconds, 6 to 8 bytes.
2524 * For absolute times, it's milliseconds since the
2525 * NTP epoch.
2526 *
2527 * ETSI TS 129.274 8.119 defines this as:
2528 * "a 48 bit unsigned integer in network order format
2529 * ...encoded as the number of milliseconds since
2530 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2531 * rounded value of 1000 x the value of the 64-bit
2532 * timestamp (Seconds + (Fraction / (1<<32))) defined
2533 * in clause 6 of IETF RFC 5905."
2534 *
2535 * Taken literally, the part after "i.e." would
2536 * mean that the value rolls over before reaching
2537 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2538 * when the 64 bit timestamp rolls over, and we have
2539 * to pick an NTP Era equivalence class to support
2540 * (such as 1968-01-20 to 2104-02-06).
2541 *
2542 * OTOH, the extra room might be used to store Era
2543 * information instead, in which case times until
2544 * 10819-08-03 can be represented with 6 bytes without
2545 * ambiguity. We handle both implementations, and assume
2546 * that times before 1968-01-20 are not represented.
2547 *
2548 * Only 6 bytes or more makes sense as an absolute
2549 * time. 5 bytes or fewer could express a span of
2550 * less than 35 years, either 1900-1934 or 2036-2070.
2551 */
2552 if (length >= 6 && length <= 8) {
2553 uint64_t msecs;
2554
2555 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2556 tmp64secs = (msecs / 1000);
2557 /*
2558 * Assume that times in the first half of NTP
2559 * Era 0 really represent times in the NTP
2560 * Era 1.
2561 */
2562 if (tmp64secs >= 0x80000000)
2563 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2564 else
2565 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2566 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2567 }
2568 else {
2569 time_stamp->secs = 0;
2570 time_stamp->nsecs = 0;
2571 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2572 }
2573 break;
2574
2575 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2576 /*
2577 * MP4 file time stamps, big-endian.
2578 * Only supported for absolute times.
2579 */
2580 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2580, "!is_relative"
))))
;
2581
2582 if (length == 8) {
2583 tmp64secs = tvb_get_ntoh64(tvb, start);
2584 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2585 time_stamp->nsecs = 0;
2586 } else if (length == 4) {
2587 tmpsecs = tvb_get_ntohl(tvb, start);
2588 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2589 time_stamp->nsecs = 0;
2590 } else {
2591 time_stamp->secs = 0;
2592 time_stamp->nsecs = 0;
2593 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2594 }
2595 break;
2596
2597 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2598 /*
2599 * Zigbee ZCL time stamps, big-endian.
2600 * Only supported for absolute times.
2601 */
2602 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2602, "!is_relative"
))))
;
2603
2604 if (length == 8) {
2605 tmp64secs = tvb_get_ntoh64(tvb, start);
2606 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_2000_01_01_00_00_00_UTC((unsigned)(((3*365 + 366)*7 + 2*365)*24*3600)));
2607 time_stamp->nsecs = 0;
2608 } else if (length == 4) {
2609 tmpsecs = tvb_get_ntohl(tvb, start);
2610 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_2000_01_01_00_00_00_UTC((unsigned)(((3*365 + 366)*7 + 2*365)*24*3600)));
2611 time_stamp->nsecs = 0;
2612 } else {
2613 time_stamp->secs = 0;
2614 time_stamp->nsecs = 0;
2615 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2616 }
2617 break;
2618
2619 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2620 /*
2621 * Zigbee ZCL time stamps, little-endian.
2622 * Only supported for absolute times.
2623 */
2624 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2624, "!is_relative"
))))
;
2625
2626 if (length == 8) {
2627 tmp64secs = tvb_get_letoh64(tvb, start);
2628 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_2000_01_01_00_00_00_UTC((unsigned)(((3*365 + 366)*7 + 2*365)*24*3600)));
2629 time_stamp->nsecs = 0;
2630 } else if (length == 4) {
2631 tmpsecs = tvb_get_letohl(tvb, start);
2632 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_2000_01_01_00_00_00_UTC((unsigned)(((3*365 + 366)*7 + 2*365)*24*3600)));
2633 time_stamp->nsecs = 0;
2634 } else {
2635 time_stamp->secs = 0;
2636 time_stamp->nsecs = 0;
2637 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2638 }
2639 break;
2640
2641 default:
2642 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2642))
;
2643 break;
2644 }
2645}
2646
2647static void
2648tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2649{
2650 const header_field_info *hfinfo = fi->hfinfo;
2651
2652 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2653 GPtrArray *ptrs = NULL((void*)0);
2654
2655 if (tree_data->interesting_hfids == NULL((void*)0)) {
2656 /* Initialize the hash because we now know that it is needed */
2657 tree_data->interesting_hfids =
2658 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2659 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2660 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2661 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2662 }
2663
2664 if (!ptrs) {
2665 /* First element triggers the creation of pointer array */
2666 ptrs = g_ptr_array_new();
2667 g_hash_table_insert(tree_data->interesting_hfids,
2668 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2669 }
2670
2671 g_ptr_array_add(ptrs, fi);
2672 }
2673}
2674
2675
2676/*
2677 * Validates that field length bytes are available starting from
2678 * start (pos/neg). Throws an exception if they aren't.
2679 */
2680static void
2681test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2682 int start, int length, const unsigned encoding)
2683{
2684 int size = length;
2685
2686 if (!tvb)
2687 return;
2688
2689 if ((hfinfo->type == FT_STRINGZ) ||
2690 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2691 (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
))
))) {
2692 /* If we're fetching until the end of the TVB, only validate
2693 * that the offset is within range.
2694 */
2695 if (length == -1)
2696 size = 0;
2697 }
2698
2699 tvb_ensure_bytes_exist(tvb, start, size);
2700}
2701
2702static void
2703detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2704{
2705 bool_Bool found_stray_character = false0;
2706
2707 if (!string)
2708 return;
2709
2710 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2711 case ENC_ASCII0x00000000:
2712 case ENC_UTF_80x00000002:
2713 for (int i = (int)strlen(string); i < length; i++) {
2714 if (string[i] != '\0') {
2715 found_stray_character = true1;
2716 break;
2717 }
2718 }
2719 break;
2720
2721 default:
2722 break;
2723 }
2724
2725 if (found_stray_character) {
2726 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2727 }
2728}
2729
2730static void
2731free_fvalue_cb(void *data)
2732{
2733 fvalue_t *fv = (fvalue_t*)data;
2734 fvalue_free(fv);
2735}
2736
2737/* Add an item to a proto_tree, using the text label registered to that item;
2738 the item is extracted from the tvbuff handed to it. */
2739static proto_item *
2740proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2741 tvbuff_t *tvb, int start, int length,
2742 unsigned encoding)
2743{
2744 proto_item *pi;
2745 uint32_t value, n;
2746 uint64_t value64;
2747 ws_in4_addr ipv4_value;
2748 float floatval;
2749 double doubleval;
2750 const char *stringval = NULL((void*)0);
2751 nstime_t time_stamp;
2752 bool_Bool length_error;
2753
2754 /* Ensure that the newly created fvalue_t is freed if we throw an
2755 * exception before adding it to the tree. (gcc creates clobbering
2756 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2757 * XXX: Move the new_field_info() call inside here?
2758 */
2759 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))
;
2760
2761 switch (new_fi->hfinfo->type) {
2762 case FT_NONE:
2763 /* no value to set for FT_NONE */
2764 break;
2765
2766 case FT_PROTOCOL:
2767 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2768 break;
2769
2770 case FT_BYTES:
2771 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2772 break;
2773
2774 case FT_UINT_BYTES:
2775 n = get_uint_value(tree, tvb, start, length, encoding);
2776 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2777
2778 /* Instead of calling proto_item_set_len(), since we don't yet
2779 * have a proto_item, we set the field_info's length ourselves. */
2780 new_fi->length = n + length;
2781 break;
2782
2783 case FT_BOOLEAN:
2784 /*
2785 * Map all non-zero values to little-endian for
2786 * backwards compatibility.
2787 */
2788 if (encoding)
2789 encoding = ENC_LITTLE_ENDIAN0x80000000;
2790 proto_tree_set_boolean(new_fi,
2791 get_uint64_value(tree, tvb, start, length, encoding));
2792 break;
2793
2794 case FT_CHAR:
2795 /* XXX - make these just FT_UINT? */
2796 case FT_UINT8:
2797 case FT_UINT16:
2798 case FT_UINT24:
2799 case FT_UINT32:
2800 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2801 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2802 value = (uint32_t)value64;
2803 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2804 new_fi->flags |= FI_VARINT0x00004000;
2805 }
2806 }
2807 else {
2808 /*
2809 * Map all non-zero values to little-endian for
2810 * backwards compatibility.
2811 */
2812 if (encoding)
2813 encoding = ENC_LITTLE_ENDIAN0x80000000;
2814
2815 value = get_uint_value(tree, tvb, start, length, encoding);
2816 }
2817 proto_tree_set_uint(new_fi, value);
2818 break;
2819
2820 case FT_UINT40:
2821 case FT_UINT48:
2822 case FT_UINT56:
2823 case FT_UINT64:
2824 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2825 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2826 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2827 new_fi->flags |= FI_VARINT0x00004000;
2828 }
2829 }
2830 else {
2831 /*
2832 * Map all other non-zero values to little-endian for
2833 * backwards compatibility.
2834 */
2835 if (encoding)
2836 encoding = ENC_LITTLE_ENDIAN0x80000000;
2837
2838 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2839 }
2840 proto_tree_set_uint64(new_fi, value64);
2841 break;
2842
2843 /* XXX - make these just FT_INT? */
2844 case FT_INT8:
2845 case FT_INT16:
2846 case FT_INT24:
2847 case FT_INT32:
2848 /*
2849 * Map all non-zero values to little-endian for
2850 * backwards compatibility.
2851 */
2852 if (encoding)
2853 encoding = ENC_LITTLE_ENDIAN0x80000000;
2854 proto_tree_set_int(new_fi,
2855 get_int_value(tree, tvb, start, length, encoding));
2856 break;
2857
2858 case FT_INT40:
2859 case FT_INT48:
2860 case FT_INT56:
2861 case FT_INT64:
2862 /*
2863 * Map all non-zero values to little-endian for
2864 * backwards compatibility.
2865 */
2866 if (encoding)
2867 encoding = ENC_LITTLE_ENDIAN0x80000000;
2868 proto_tree_set_int64(new_fi,
2869 get_int64_value(tree, tvb, start, length, encoding));
2870 break;
2871
2872 case FT_IPv4:
2873 /*
2874 * Map all non-zero values to little-endian for
2875 * backwards compatibility.
2876 */
2877 if (encoding)
2878 encoding = ENC_LITTLE_ENDIAN0x80000000;
2879 if (length != FT_IPv4_LEN4) {
2880 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2881 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2882 }
2883 ipv4_value = tvb_get_ipv4(tvb, start);
2884 /*
2885 * NOTE: to support code written when
2886 * proto_tree_add_item() took a bool as its
2887 * last argument, with false meaning "big-endian"
2888 * and true meaning "little-endian", we treat any
2889 * non-zero value of "encoding" as meaning
2890 * "little-endian".
2891 */
2892 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);
2893 break;
2894
2895 case FT_IPXNET:
2896 if (length != FT_IPXNET_LEN4) {
2897 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2898 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2899 }
2900 proto_tree_set_ipxnet(new_fi,
2901 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2902 break;
2903
2904 case FT_IPv6:
2905 if (length != FT_IPv6_LEN16) {
2906 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2907 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2908 }
2909 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2910 break;
2911
2912 case FT_FCWWN:
2913 if (length != FT_FCWWN_LEN8) {
2914 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2915 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2916 }
2917 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2918 break;
2919
2920 case FT_AX25:
2921 if (length != 7) {
2922 length_error = length < 7 ? true1 : false0;
2923 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2924 }
2925 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2926 break;
2927
2928 case FT_VINES:
2929 if (length != VINES_ADDR_LEN6) {
2930 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2931 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2932 }
2933 proto_tree_set_vines_tvb(new_fi, tvb, start);
2934 break;
2935
2936 case FT_ETHER:
2937 if (length != FT_ETHER_LEN6) {
2938 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2939 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2940 }
2941 proto_tree_set_ether_tvb(new_fi, tvb, start);
2942 break;
2943
2944 case FT_EUI64:
2945 /*
2946 * Map all non-zero values to little-endian for
2947 * backwards compatibility.
2948 */
2949 if (encoding)
2950 encoding = ENC_LITTLE_ENDIAN0x80000000;
2951 if (length != FT_EUI64_LEN8) {
2952 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
2953 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2954 }
2955 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2956 break;
2957 case FT_GUID:
2958 /*
2959 * Map all non-zero values to little-endian for
2960 * backwards compatibility.
2961 */
2962 if (encoding)
2963 encoding = ENC_LITTLE_ENDIAN0x80000000;
2964 if (length != FT_GUID_LEN16) {
2965 length_error = length < FT_GUID_LEN16 ? true1 : false0;
2966 report_type_length_mismatch(tree, "a GUID", length, length_error);
2967 }
2968 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2969 break;
2970
2971 case FT_OID:
2972 case FT_REL_OID:
2973 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2974 break;
2975
2976 case FT_SYSTEM_ID:
2977 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2978 break;
2979
2980 case FT_FLOAT:
2981 /*
2982 * NOTE: to support code written when
2983 * proto_tree_add_item() took a bool as its
2984 * last argument, with false meaning "big-endian"
2985 * and true meaning "little-endian", we treat any
2986 * non-zero value of "encoding" as meaning
2987 * "little-endian".
2988 *
2989 * At some point in the future, we might
2990 * support non-IEEE-binary floating-point
2991 * formats in the encoding as well
2992 * (IEEE decimal, System/3x0, VAX).
2993 */
2994 if (encoding)
2995 encoding = ENC_LITTLE_ENDIAN0x80000000;
2996 if (length != 4) {
2997 length_error = length < 4 ? true1 : false0;
2998 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2999 }
3000 if (encoding)
3001 floatval = tvb_get_letohieee_float(tvb, start);
3002 else
3003 floatval = tvb_get_ntohieee_float(tvb, start);
3004 proto_tree_set_float(new_fi, floatval);
3005 break;
3006
3007 case FT_DOUBLE:
3008 /*
3009 * NOTE: to support code written when
3010 * proto_tree_add_item() took a bool as its
3011 * last argument, with false meaning "big-endian"
3012 * and true meaning "little-endian", we treat any
3013 * non-zero value of "encoding" as meaning
3014 * "little-endian".
3015 *
3016 * At some point in the future, we might
3017 * support non-IEEE-binary floating-point
3018 * formats in the encoding as well
3019 * (IEEE decimal, System/3x0, VAX).
3020 */
3021 if (encoding == true1)
3022 encoding = ENC_LITTLE_ENDIAN0x80000000;
3023 if (length != 8) {
3024 length_error = length < 8 ? true1 : false0;
3025 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3026 }
3027 if (encoding)
3028 doubleval = tvb_get_letohieee_double(tvb, start);
3029 else
3030 doubleval = tvb_get_ntohieee_double(tvb, start);
3031 proto_tree_set_double(new_fi, doubleval);
3032 break;
3033
3034 case FT_STRING:
3035 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3036 tvb, start, length, &length, encoding);
3037 proto_tree_set_string(new_fi, stringval);
3038
3039 /* Instead of calling proto_item_set_len(), since we
3040 * don't yet have a proto_item, we set the
3041 * field_info's length ourselves.
3042 *
3043 * XXX - our caller can't use that length to
3044 * advance an offset unless they arrange that
3045 * there always be a protocol tree into which
3046 * we're putting this item.
3047 */
3048 new_fi->length = length;
3049 break;
3050
3051 case FT_STRINGZ:
3052 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3053 tree, tvb, start, length, &length, encoding);
3054 proto_tree_set_string(new_fi, stringval);
3055
3056 /* Instead of calling proto_item_set_len(),
3057 * since we don't yet have a proto_item, we
3058 * set the field_info's length ourselves.
3059 *
3060 * XXX - our caller can't use that length to
3061 * advance an offset unless they arrange that
3062 * there always be a protocol tree into which
3063 * we're putting this item.
3064 */
3065 new_fi->length = length;
3066 break;
3067
3068 case FT_UINT_STRING:
3069 /*
3070 * NOTE: to support code written when
3071 * proto_tree_add_item() took a bool as its
3072 * last argument, with false meaning "big-endian"
3073 * and true meaning "little-endian", if the
3074 * encoding value is true, treat that as
3075 * ASCII with a little-endian length.
3076 *
3077 * This won't work for code that passes
3078 * arbitrary non-zero values; that code
3079 * will need to be fixed.
3080 */
3081 if (encoding == true1)
3082 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3083 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3084 tree, tvb, start, length, &length, encoding);
3085 proto_tree_set_string(new_fi, stringval);
3086
3087 /* Instead of calling proto_item_set_len(), since we
3088 * don't yet have a proto_item, we set the
3089 * field_info's length ourselves.
3090 *
3091 * XXX - our caller can't use that length to
3092 * advance an offset unless they arrange that
3093 * there always be a protocol tree into which
3094 * we're putting this item.
3095 */
3096 new_fi->length = length;
3097 break;
3098
3099 case FT_STRINGZPAD:
3100 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3101 tvb, start, length, &length, encoding);
3102 proto_tree_set_string(new_fi, stringval);
3103
3104 /* Instead of calling proto_item_set_len(), since we
3105 * don't yet have a proto_item, we set the
3106 * field_info's length ourselves.
3107 *
3108 * XXX - our caller can't use that length to
3109 * advance an offset unless they arrange that
3110 * there always be a protocol tree into which
3111 * we're putting this item.
3112 */
3113 new_fi->length = length;
3114 break;
3115
3116 case FT_STRINGZTRUNC:
3117 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3118 tvb, start, length, &length, encoding);
3119 proto_tree_set_string(new_fi, stringval);
3120
3121 /* Instead of calling proto_item_set_len(), since we
3122 * don't yet have a proto_item, we set the
3123 * field_info's length ourselves.
3124 *
3125 * XXX - our caller can't use that length to
3126 * advance an offset unless they arrange that
3127 * there always be a protocol tree into which
3128 * we're putting this item.
3129 */
3130 new_fi->length = length;
3131 break;
3132
3133 case FT_ABSOLUTE_TIME:
3134 /*
3135 * Absolute times can be in any of a number of
3136 * formats, and they can be big-endian or
3137 * little-endian.
3138 *
3139 * Historically FT_TIMEs were only timespecs;
3140 * the only question was whether they were stored
3141 * in big- or little-endian format.
3142 *
3143 * For backwards compatibility, we interpret an
3144 * encoding of 1 as meaning "little-endian timespec",
3145 * so that passing true is interpreted as that.
3146 */
3147 if (encoding == true1)
3148 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3149
3150 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3151
3152 proto_tree_set_time(new_fi, &time_stamp);
3153 break;
3154
3155 case FT_RELATIVE_TIME:
3156 /*
3157 * Relative times can be in any of a number of
3158 * formats, and they can be big-endian or
3159 * little-endian.
3160 *
3161 * Historically FT_TIMEs were only timespecs;
3162 * the only question was whether they were stored
3163 * in big- or little-endian format.
3164 *
3165 * For backwards compatibility, we interpret an
3166 * encoding of 1 as meaning "little-endian timespec",
3167 * so that passing true is interpreted as that.
3168 */
3169 if (encoding == true1)
3170 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3171
3172 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3173
3174 proto_tree_set_time(new_fi, &time_stamp);
3175 break;
3176 case FT_IEEE_11073_SFLOAT:
3177 if (encoding)
3178 encoding = ENC_LITTLE_ENDIAN0x80000000;
3179 if (length != 2) {
3180 length_error = length < 2 ? true1 : false0;
3181 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3182 }
3183
3184 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3185
3186 break;
3187 case FT_IEEE_11073_FLOAT:
3188 if (encoding)
3189 encoding = ENC_LITTLE_ENDIAN0x80000000;
3190 if (length != 4) {
3191 length_error = length < 4 ? true1 : false0;
3192 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3193 }
3194
3195 break;
3196 default:
3197 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))
3198 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))
3199 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))
3200 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))
;
3201 break;
3202 }
3203 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)
;
3204
3205 /* Don't add new node to proto_tree until now so that any exceptions
3206 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3207 /* XXX. wouldn't be better to add this item to tree, with some special
3208 * flag (FI_EXCEPTION?) to know which item caused exception? For
3209 * strings and bytes, we would have to set new_fi->value to something
3210 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3211 * could handle NULL values. */
3212 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3213 pi = proto_tree_add_node(tree, new_fi);
3214
3215 switch (new_fi->hfinfo->type) {
3216
3217 case FT_STRING:
3218 /* XXX: trailing stray character detection should be done
3219 * _before_ conversion to UTF-8, because conversion can change
3220 * the length, or else get_string_length should return a value
3221 * for the "length in bytes of the string after conversion
3222 * including internal nulls." (Noting that we do, for other
3223 * reasons, still need the "length in bytes in the field",
3224 * especially for FT_STRINGZ.)
3225 *
3226 * This is true even for ASCII and UTF-8, because
3227 * substituting REPLACEMENT CHARACTERS for illegal characters
3228 * can also do so (and for UTF-8 possibly even make the
3229 * string _shorter_).
3230 */
3231 detect_trailing_stray_characters(encoding, stringval, length, pi);
3232 break;
3233
3234 default:
3235 break;
3236 }
3237
3238 return pi;
3239}
3240
3241proto_item *
3242proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3243 const int start, int length,
3244 const unsigned encoding, int32_t *retval)
3245{
3246 header_field_info *hfinfo;
3247 field_info *new_fi;
3248 int32_t value;
3249
3250 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", 3250, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3250,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3250, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3251
3252 switch (hfinfo->type) {
3253 case FT_INT8:
3254 case FT_INT16:
3255 case FT_INT24:
3256 case FT_INT32:
3257 break;
3258 case FT_INT64:
3259 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)
3260 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3261 default:
3262 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)
3263 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3264 }
3265
3266 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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 if(retval)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 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3271 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3272 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3273
3274 if (encoding & ENC_STRING0x03000000) {
3275 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3276 }
3277 /* I believe it's ok if this is called with a NULL tree */
3278 value = get_int_value(tree, tvb, start, length, encoding);
3279
3280 if (retval) {
3281 int no_of_bits;
3282 *retval = value;
3283 if (hfinfo->bitmask) {
3284 /* Mask out irrelevant portions */
3285 *retval &= (uint32_t)(hfinfo->bitmask);
3286 /* Shift bits */
3287 *retval >>= hfinfo_bitshift(hfinfo);
3288 }
3289 no_of_bits = ws_count_ones(hfinfo->bitmask);
3290 *retval = ws_sign_ext32(*retval, no_of_bits);
3291 }
3292
3293 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3294
3295 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", 3295
, __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", 3295, "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", 3295, "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", 3295, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3296
3297 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3298
3299 proto_tree_set_int(new_fi, value);
3300
3301 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3302
3303 return proto_tree_add_node(tree, new_fi);
3304}
3305
3306proto_item *
3307proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3308 const int start, int length,
3309 const unsigned encoding, uint32_t *retval)
3310{
3311 header_field_info *hfinfo;
3312 field_info *new_fi;
3313 uint32_t value;
3314
3315 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", 3315, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3315,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3315, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3316
3317 switch (hfinfo->type) {
3318 case FT_CHAR:
3319 case FT_UINT8:
3320 case FT_UINT16:
3321 case FT_UINT24:
3322 case FT_UINT32:
3323 break;
3324 default:
3325 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)
3326 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)
;
3327 }
3328
3329 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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 if(retval)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 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3334 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3335 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3336
3337 if (encoding & ENC_STRING0x03000000) {
3338 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3339 }
3340 /* I believe it's ok if this is called with a NULL tree */
3341 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3342 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3343 uint64_t temp64;
3344 tvb_get_varint(tvb, start, length, &temp64, encoding);
3345 value = (uint32_t)temp64;
3346 } else {
3347 value = get_uint_value(tree, tvb, start, length, encoding);
3348 }
3349
3350 if (retval) {
3351 *retval = value;
3352 if (hfinfo->bitmask) {
3353 /* Mask out irrelevant portions */
3354 *retval &= (uint32_t)(hfinfo->bitmask);
3355 /* Shift bits */
3356 *retval >>= hfinfo_bitshift(hfinfo);
3357 }
3358 }
3359
3360 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3361
3362 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", 3362
, __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", 3362, "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", 3362, "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", 3362, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3363
3364 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3365
3366 proto_tree_set_uint(new_fi, value);
3367
3368 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3369 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3370 new_fi->flags |= FI_VARINT0x00004000;
3371 }
3372 return proto_tree_add_node(tree, new_fi);
3373}
3374
3375/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3376 * and returns proto_item* and uint value retreived*/
3377proto_item *
3378ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3379 const unsigned encoding, uint32_t *retval)
3380{
3381 field_info *new_fi;
3382 header_field_info *hfinfo;
3383 int item_length;
3384 int offset;
3385 uint32_t value;
3386
3387 offset = ptvc->offset;
3388 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", 3388, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3388,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3388, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3389
3390 switch (hfinfo->type) {
3391 case FT_CHAR:
3392 case FT_UINT8:
3393 case FT_UINT16:
3394 case FT_UINT24:
3395 case FT_UINT32:
3396 break;
3397 default:
3398 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)
3399 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)
;
3400 }
3401
3402 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3403 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3404
3405 /* I believe it's ok if this is called with a NULL tree */
3406 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3407 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3408
3409 if (retval) {
3410 *retval = value;
3411 if (hfinfo->bitmask) {
3412 /* Mask out irrelevant portions */
3413 *retval &= (uint32_t)(hfinfo->bitmask);
3414 /* Shift bits */
3415 *retval >>= hfinfo_bitshift(hfinfo);
3416 }
3417 }
3418
3419 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3420 item_length, encoding);
3421
3422 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3423
3424 /* Coast clear. Try and fake it */
3425 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", 3425
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3425, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3425, "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", 3425, __func__, "Adding %s would put more than %d 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); } } }
;
3426
3427 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3428
3429 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3430 offset, length, encoding);
3431}
3432
3433/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3434 * and returns proto_item* and int value retreived*/
3435proto_item *
3436ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3437 const unsigned encoding, int32_t *retval)
3438{
3439 field_info *new_fi;
3440 header_field_info *hfinfo;
3441 int item_length;
3442 int offset;
3443 uint32_t value;
3444
3445 offset = ptvc->offset;
3446 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", 3446, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3446,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3446, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3447
3448 switch (hfinfo->type) {
3449 case FT_INT8:
3450 case FT_INT16:
3451 case FT_INT24:
3452 case FT_INT32:
3453 break;
3454 default:
3455 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)
3456 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3457 }
3458
3459 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3460 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3461
3462 /* I believe it's ok if this is called with a NULL tree */
3463 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3464 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3465
3466 if (retval) {
3467 int no_of_bits;
3468 *retval = value;
3469 if (hfinfo->bitmask) {
3470 /* Mask out irrelevant portions */
3471 *retval &= (uint32_t)(hfinfo->bitmask);
3472 /* Shift bits */
3473 *retval >>= hfinfo_bitshift(hfinfo);
3474 }
3475 no_of_bits = ws_count_ones(hfinfo->bitmask);
3476 *retval = ws_sign_ext32(*retval, no_of_bits);
3477 }
3478
3479 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3480 item_length, encoding);
3481
3482 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3483
3484 /* Coast clear. Try and fake it */
3485 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", 3485
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3485, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3485, "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", 3485, __func__, "Adding %s would put more than %d 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); } } }
;
3486
3487 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3488
3489 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3490 offset, length, encoding);
3491}
3492
3493/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3494 * and returns proto_item* and string value retreived */
3495proto_item*
3496ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3497{
3498 header_field_info *hfinfo;
3499 field_info *new_fi;
3500 const uint8_t *value;
3501 int item_length;
3502 int offset;
3503
3504 offset = ptvc->offset;
3505
3506 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", 3506
, __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", 3506, "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", 3506, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3507
3508 switch (hfinfo->type) {
3509 case FT_STRING:
3510 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3511 break;
3512 case FT_STRINGZ:
3513 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3514 break;
3515 case FT_UINT_STRING:
3516 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3517 break;
3518 case FT_STRINGZPAD:
3519 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3520 break;
3521 case FT_STRINGZTRUNC:
3522 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3523 break;
3524 default:
3525 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)
3526 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)
;
3527 }
3528
3529 if (retval)
3530 *retval = value;
3531
3532 ptvc->offset += item_length;
3533
3534 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3535
3536 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", 3536, __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", 3536,
"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", 3536, "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", 3536
, __func__, "Adding %s would put more than %d 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); } } }
;
3537
3538 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3539
3540 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3541 offset, length, encoding);
3542}
3543
3544/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3545 * and returns proto_item* and boolean value retreived */
3546proto_item*
3547ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3548{
3549 header_field_info *hfinfo;
3550 field_info *new_fi;
3551 int item_length;
3552 int offset;
3553 uint64_t value, bitval;
3554
3555 offset = ptvc->offset;
3556 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", 3556, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3556,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3556, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3557
3558 if (hfinfo->type != FT_BOOLEAN) {
3559 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)
3560 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3561 }
3562
3563 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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 if(retval)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 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3568 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3569 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3570
3571 if (encoding & ENC_STRING0x03000000) {
3572 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3573 }
3574
3575 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3576 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3577
3578 /* I believe it's ok if this is called with a NULL tree */
3579 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3580
3581 if (retval) {
3582 bitval = value;
3583 if (hfinfo->bitmask) {
3584 /* Mask out irrelevant portions */
3585 bitval &= hfinfo->bitmask;
3586 }
3587 *retval = (bitval != 0);
3588 }
3589
3590 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3591 item_length, encoding);
3592
3593 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3594
3595 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", 3595, __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", 3595,
"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", 3595, "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", 3595
, __func__, "Adding %s would put more than %d 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); } } }
;
3596
3597 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3598
3599 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3600 offset, length, encoding);
3601}
3602
3603proto_item *
3604proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3605 const int start, int length, const unsigned encoding, uint64_t *retval)
3606{
3607 header_field_info *hfinfo;
3608 field_info *new_fi;
3609 uint64_t value;
3610
3611 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", 3611, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3611,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3611, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3612
3613 switch (hfinfo->type) {
3614 case FT_UINT40:
3615 case FT_UINT48:
3616 case FT_UINT56:
3617 case FT_UINT64:
3618 break;
3619 default:
3620 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)
3621 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3622 }
3623
3624 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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 if(retval)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 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3629 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3630 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3631
3632 if (encoding & ENC_STRING0x03000000) {
3633 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3634 }
3635 /* I believe it's ok if this is called with a NULL tree */
3636 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3637 tvb_get_varint(tvb, start, length, &value, encoding);
3638 } else {
3639 value = get_uint64_value(tree, tvb, start, length, encoding);
3640 }
3641
3642 if (retval) {
3643 *retval = value;
3644 if (hfinfo->bitmask) {
3645 /* Mask out irrelevant portions */
3646 *retval &= hfinfo->bitmask;
3647 /* Shift bits */
3648 *retval >>= hfinfo_bitshift(hfinfo);
3649 }
3650 }
3651
3652 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3653
3654 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", 3654
, __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", 3654, "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", 3654, "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", 3654, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3655
3656 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3657
3658 proto_tree_set_uint64(new_fi, value);
3659
3660 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3661 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3662 new_fi->flags |= FI_VARINT0x00004000;
3663 }
3664
3665 return proto_tree_add_node(tree, new_fi);
3666}
3667
3668proto_item *
3669proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3670 const int start, int length, const unsigned encoding, int64_t *retval)
3671{
3672 header_field_info *hfinfo;
3673 field_info *new_fi;
3674 int64_t value;
3675
3676 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", 3676, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3676,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3676, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3677
3678 switch (hfinfo->type) {
3679 case FT_INT40:
3680 case FT_INT48:
3681 case FT_INT56:
3682 case FT_INT64:
3683 break;
3684 default:
3685 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)
3686 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3687 }
3688
3689 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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 if(retval)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 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3694 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3695 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3696
3697 if (encoding & ENC_STRING0x03000000) {
3698 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3699 }
3700 /* I believe it's ok if this is called with a NULL tree */
3701 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3702 tvb_get_varint(tvb, start, length, &value, encoding);
3703 }
3704 else {
3705 value = get_int64_value(tree, tvb, start, length, encoding);
3706 }
3707
3708 if (retval) {
3709 *retval = value;
3710 }
3711
3712 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3713
3714 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", 3714
, __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", 3714, "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", 3714, "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", 3714, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3715
3716 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3717
3718 proto_tree_set_int64(new_fi, value);
3719
3720 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3721 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3722 new_fi->flags |= FI_VARINT0x00004000;
3723 }
3724
3725 return proto_tree_add_node(tree, new_fi);
3726}
3727
3728proto_item *
3729proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3730 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3731{
3732 header_field_info *hfinfo;
3733 field_info *new_fi;
3734 uint64_t value;
3735
3736 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", 3736, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3736,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3736, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3737
3738 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
))
)) {
3739 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)
3740 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3741 }
3742
3743 /* length validation for native number encoding caught by get_uint64_value() */
3744 /* length has to be -1 or > 0 regardless of encoding */
3745 if (length == 0)
3746 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)
3747 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3748
3749 if (encoding & ENC_STRING0x03000000) {
3750 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3751 }
3752
3753 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3754
3755 if (retval) {
3756 *retval = value;
3757 if (hfinfo->bitmask) {
3758 /* Mask out irrelevant portions */
3759 *retval &= hfinfo->bitmask;
3760 /* Shift bits */
3761 *retval >>= hfinfo_bitshift(hfinfo);
3762 }
3763 }
3764
3765 if (lenretval) {
3766 *lenretval = length;
3767 }
3768
3769 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3770
3771 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", 3771
, __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", 3771, "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", 3771, "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", 3771, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3772
3773 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3774
3775 proto_tree_set_uint64(new_fi, value);
3776
3777 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3778 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3779 new_fi->flags |= FI_VARINT0x00004000;
3780 }
3781
3782 return proto_tree_add_node(tree, new_fi);
3783
3784}
3785
3786proto_item *
3787proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3788 const int start, int length,
3789 const unsigned encoding, bool_Bool *retval)
3790{
3791 header_field_info *hfinfo;
3792 field_info *new_fi;
3793 uint64_t value, bitval;
3794
3795 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", 3795, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3795,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3795, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3796
3797 if (hfinfo->type != FT_BOOLEAN) {
3798 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)
3799 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3800 }
3801
3802 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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 if(retval)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 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3807 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3808 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3809
3810 if (encoding & ENC_STRING0x03000000) {
3811 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3812 }
3813 /* I believe it's ok if this is called with a NULL tree */
3814 value = get_uint64_value(tree, tvb, start, length, encoding);
3815
3816 if (retval) {
3817 bitval = value;
3818 if (hfinfo->bitmask) {
3819 /* Mask out irrelevant portions */
3820 bitval &= hfinfo->bitmask;
3821 }
3822 *retval = (bitval != 0);
3823 }
3824
3825 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3826
3827 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", 3827
, __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", 3827, "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", 3827, "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", 3827, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3828
3829 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3830
3831 proto_tree_set_boolean(new_fi, value);
3832
3833 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3834
3835 return proto_tree_add_node(tree, new_fi);
3836}
3837
3838proto_item *
3839proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3840 const int start, int length,
3841 const unsigned encoding, float *retval)
3842{
3843 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3844 field_info *new_fi;
3845 float value;
3846
3847 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", 3847,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3848
3849 if (hfinfo->type != FT_FLOAT) {
3850 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)
;
3851 }
3852
3853 if (length != 4) {
3854 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3855 }
3856
3857 /* treat any nonzero encoding as little endian for backwards compatibility */
3858 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3859 if (retval) {
3860 *retval = value;
3861 }
3862
3863 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3864
3865 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", 3865
, __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", 3865, "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", 3865, "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", 3865, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3866
3867 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3868 if (encoding) {
3869 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3870 }
3871
3872 proto_tree_set_float(new_fi, value);
3873
3874 return proto_tree_add_node(tree, new_fi);
3875}
3876
3877proto_item *
3878proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3879 const int start, int length,
3880 const unsigned encoding, double *retval)
3881{
3882 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3883 field_info *new_fi;
3884 double value;
3885
3886 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", 3886,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3887
3888 if (hfinfo->type != FT_DOUBLE) {
3889 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)
;
3890 }
3891
3892 if (length != 8) {
3893 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3894 }
3895
3896 /* treat any nonzero encoding as little endian for backwards compatibility */
3897 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3898 if (retval) {
3899 *retval = value;
3900 }
3901
3902 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3903
3904 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", 3904
, __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", 3904, "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", 3904, "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", 3904, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3905
3906 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3907 if (encoding) {
3908 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3909 }
3910
3911 proto_tree_set_double(new_fi, value);
3912
3913 return proto_tree_add_node(tree, new_fi);
3914}
3915
3916proto_item *
3917proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3918 const int start, int length,
3919 const unsigned encoding, ws_in4_addr *retval)
3920{
3921 header_field_info *hfinfo;
3922 field_info *new_fi;
3923 ws_in4_addr value;
3924
3925 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", 3925, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3925,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3925, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3926
3927 switch (hfinfo->type) {
3928 case FT_IPv4:
3929 break;
3930 default:
3931 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)
3932 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3933 }
3934
3935 if (length != FT_IPv4_LEN4)
3936 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)
3937 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3938
3939 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3940 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3941 }
3942
3943 /*
3944 * NOTE: to support code written when proto_tree_add_item() took
3945 * a bool as its last argument, with false meaning "big-endian"
3946 * and true meaning "little-endian", we treat any non-zero value
3947 * of "encoding" as meaning "little-endian".
3948 */
3949 value = tvb_get_ipv4(tvb, start);
3950 if (encoding)
3951 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))))
;
3952
3953 if (retval) {
3954 *retval = value;
3955 }
3956
3957 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3958
3959 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", 3959
, __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", 3959, "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", 3959, "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", 3959, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3960
3961 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3962
3963 proto_tree_set_ipv4(new_fi, value);
3964
3965 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3966 return proto_tree_add_node(tree, new_fi);
3967}
3968
3969proto_item *
3970proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3971 const int start, int length,
3972 const unsigned encoding, ws_in6_addr *addr)
3973{
3974 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3975 field_info *new_fi;
3976
3977 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", 3977,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3978
3979 switch (hfinfo->type) {
3980 case FT_IPv6:
3981 break;
3982 default:
3983 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)
3984 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
3985 }
3986
3987 if (length != FT_IPv6_LEN16)
3988 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)
3989 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
3990
3991 if (encoding) {
3992 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"
)
;
3993 }
3994
3995 tvb_get_ipv6(tvb, start, addr);
3996
3997 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3998
3999 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", 3999
, __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", 3999, "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", 3999, "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", 3999, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4000
4001 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4002
4003 proto_tree_set_ipv6(new_fi, addr);
4004
4005 return proto_tree_add_node(tree, new_fi);
4006}
4007
4008proto_item *
4009proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4010 const int start, int length, const unsigned encoding, uint8_t *retval) {
4011
4012 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4013 field_info *new_fi;
4014
4015 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", 4015,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4016
4017 switch (hfinfo->type) {
4018 case FT_ETHER:
4019 break;
4020 default:
4021 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)
4022 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4023 }
4024
4025 if (length != FT_ETHER_LEN6)
4026 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)
4027 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4028
4029 if (encoding) {
4030 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"
)
;
4031 }
4032
4033 tvb_memcpy(tvb, retval, start, length);
4034
4035 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4036
4037 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", 4037
, __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", 4037, "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", 4037, "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", 4037, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4038
4039 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4040
4041 proto_tree_set_ether(new_fi, retval);
4042
4043 return proto_tree_add_node(tree, new_fi);
4044}
4045
4046
4047proto_item *
4048proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4049 tvbuff_t *tvb,
4050 const int start, int length,
4051 const unsigned encoding,
4052 wmem_allocator_t *scope,
4053 const uint8_t **retval,
4054 int *lenretval)
4055{
4056 proto_item *pi;
4057 header_field_info *hfinfo;
4058 field_info *new_fi;
4059 const uint8_t *value;
4060
4061 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", 4061, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4061,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4061, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4062
4063 switch (hfinfo->type) {
4064 case FT_STRING:
4065 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4066 break;
4067 case FT_STRINGZ:
4068 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4069 break;
4070 case FT_UINT_STRING:
4071 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4072 break;
4073 case FT_STRINGZPAD:
4074 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4075 break;
4076 case FT_STRINGZTRUNC:
4077 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4078 break;
4079 default:
4080 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)
4081 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)
;
4082 }
4083
4084 if (retval)
4085 *retval = value;
4086
4087 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4088
4089 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", 4089
, __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", 4089, "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", 4089, "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", 4089, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4090
4091 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4092
4093 proto_tree_set_string(new_fi, value);
4094
4095 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4096
4097 pi = proto_tree_add_node(tree, new_fi);
4098
4099 switch (hfinfo->type) {
4100
4101 case FT_STRINGZ:
4102 case FT_STRINGZPAD:
4103 case FT_STRINGZTRUNC:
4104 case FT_UINT_STRING:
4105 break;
4106
4107 case FT_STRING:
4108 detect_trailing_stray_characters(encoding, value, length, pi);
4109 break;
4110
4111 default:
4112 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4112
, __func__, "assertion \"not reached\" failed")
;
4113 }
4114
4115 return pi;
4116}
4117
4118proto_item *
4119proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4120 const int start, int length,
4121 const unsigned encoding, wmem_allocator_t *scope,
4122 const uint8_t **retval)
4123{
4124 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4125 tvb, start, length, encoding, scope, retval, &length);
4126}
4127
4128proto_item *
4129proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4130 tvbuff_t *tvb,
4131 const int start, int length,
4132 const unsigned encoding,
4133 wmem_allocator_t *scope,
4134 char **retval,
4135 int *lenretval)
4136{
4137 proto_item *pi;
4138 header_field_info *hfinfo;
4139 field_info *new_fi;
4140 const uint8_t *value;
4141 uint32_t n = 0;
4142
4143 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", 4143, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4143,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4143, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4144
4145 switch (hfinfo->type) {
4146 case FT_STRING:
4147 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4148 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4149 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4150 break;
4151 case FT_STRINGZ:
4152 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4153 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4154 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4155 break;
4156 case FT_UINT_STRING:
4157 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4158 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4159 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4160 break;
4161 case FT_STRINGZPAD:
4162 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4163 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4164 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4165 break;
4166 case FT_STRINGZTRUNC:
4167 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4168 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4169 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4170 break;
4171 case FT_BYTES:
4172 tvb_ensure_bytes_exist(tvb, start, length);
4173 value = tvb_get_ptr(tvb, start, length);
4174 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4175 *lenretval = length;
4176 break;
4177 case FT_UINT_BYTES:
4178 n = get_uint_value(tree, tvb, start, length, encoding);
4179 tvb_ensure_bytes_exist(tvb, start + length, n);
4180 value = tvb_get_ptr(tvb, start + length, n);
4181 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4182 *lenretval = length + n;
4183 break;
4184 default:
4185 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)
4186 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)
;
4187 }
4188
4189 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4190
4191 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", 4191
, __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", 4191, "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", 4191, "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", 4191, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4192
4193 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4194
4195 switch (hfinfo->type) {
4196
4197 case FT_STRING:
4198 case FT_STRINGZ:
4199 case FT_UINT_STRING:
4200 case FT_STRINGZPAD:
4201 case FT_STRINGZTRUNC:
4202 proto_tree_set_string(new_fi, value);
4203 break;
4204
4205 case FT_BYTES:
4206 proto_tree_set_bytes(new_fi, value, length);
4207 break;
4208
4209 case FT_UINT_BYTES:
4210 proto_tree_set_bytes(new_fi, value, n);
4211 break;
4212
4213 default:
4214 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4214
, __func__, "assertion \"not reached\" failed")
;
4215 }
4216
4217 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4218
4219 pi = proto_tree_add_node(tree, new_fi);
4220
4221 switch (hfinfo->type) {
4222
4223 case FT_STRINGZ:
4224 case FT_STRINGZPAD:
4225 case FT_STRINGZTRUNC:
4226 case FT_UINT_STRING:
4227 break;
4228
4229 case FT_STRING:
4230 detect_trailing_stray_characters(encoding, value, length, pi);
4231 break;
4232
4233 case FT_BYTES:
4234 case FT_UINT_BYTES:
4235 break;
4236
4237 default:
4238 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4238
, __func__, "assertion \"not reached\" failed")
;
4239 }
4240
4241 return pi;
4242}
4243
4244proto_item *
4245proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4246 tvbuff_t *tvb,
4247 const int start, int length,
4248 const unsigned encoding,
4249 wmem_allocator_t *scope,
4250 char **retval)
4251{
4252 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4253 tvb, start, length, encoding, scope, retval, &length);
4254}
4255
4256proto_item *
4257proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4258 tvbuff_t *tvb,
4259 const int start, int length, const unsigned encoding,
4260 wmem_allocator_t *scope, char **retval)
4261{
4262 header_field_info *hfinfo;
4263 field_info *new_fi;
4264 nstime_t time_stamp;
4265 int flags;
4266
4267 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", 4267, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4267,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4267, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4268
4269 switch (hfinfo->type) {
4270 case FT_ABSOLUTE_TIME:
4271 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4272 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4273 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4274 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4275 }
4276 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4277 break;
4278 case FT_RELATIVE_TIME:
4279 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4280 *retval = rel_time_to_secs_str(scope, &time_stamp);
4281 break;
4282 default:
4283 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)
4284 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4285 }
4286
4287 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4288
4289 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", 4289
, __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", 4289, "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", 4289, "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", 4289, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4290
4291 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4292
4293 switch (hfinfo->type) {
4294
4295 case FT_ABSOLUTE_TIME:
4296 case FT_RELATIVE_TIME:
4297 proto_tree_set_time(new_fi, &time_stamp);
4298 break;
4299 default:
4300 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4300
, __func__, "assertion \"not reached\" failed")
;
4301 }
4302
4303 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4304
4305 return proto_tree_add_node(tree, new_fi);
4306}
4307
4308/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4309 and returns proto_item* */
4310proto_item *
4311ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4312 const unsigned encoding)
4313{
4314 field_info *new_fi;
4315 header_field_info *hfinfo;
4316 int item_length;
4317 int offset;
4318
4319 offset = ptvc->offset;
4320 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", 4320, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4320,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4320, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4321 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4322 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4323
4324 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
4325 item_length, encoding);
4326
4327 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4328
4329 /* Coast clear. Try and fake it */
4330 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", 4330
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4330, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4330, "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", 4330, __func__, "Adding %s would put more than %d 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); } } }
;
4331
4332 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4333
4334 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4335 offset, length, encoding);
4336}
4337
4338/* Add an item to a proto_tree, using the text label registered to that item;
4339 the item is extracted from the tvbuff handed to it. */
4340proto_item *
4341proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4342 const int start, int length, const unsigned encoding)
4343{
4344 field_info *new_fi;
4345 int item_length;
4346
4347 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", 4347,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4348
4349 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4350 test_length(hfinfo, tvb, start, item_length, encoding);
4351
4352 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4353
4354 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", 4354
, __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", 4354, "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", 4354, "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", 4354, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4355
4356 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4357
4358 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4359}
4360
4361proto_item *
4362proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4363 const int start, int length, const unsigned encoding)
4364{
4365 register header_field_info *hfinfo;
4366
4367 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", 4367, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4367,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4367, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4368 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4369}
4370
4371/* Add an item to a proto_tree, using the text label registered to that item;
4372 the item is extracted from the tvbuff handed to it.
4373
4374 Return the length of the item through the pointer. */
4375proto_item *
4376proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4377 tvbuff_t *tvb, const int start,
4378 int length, const unsigned encoding,
4379 int *lenretval)
4380{
4381 field_info *new_fi;
4382 int item_length;
4383 proto_item *item;
4384
4385 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", 4385,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4386
4387 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4388 test_length(hfinfo, tvb, start, item_length, encoding);
4389
4390 if (!tree) {
4391 /*
4392 * We need to get the correct item length here.
4393 * That's normally done by proto_tree_new_item(),
4394 * but we won't be calling it.
4395 */
4396 *lenretval = get_full_length(hfinfo, tvb, start, length,
4397 item_length, encoding);
4398 return NULL((void*)0);
4399 }
4400
4401 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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 /*((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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 * 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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 * 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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 */((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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 *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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4408 })((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", 4408
, __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", 4408, "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", 4408, "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", 4408
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4409
4410 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4411
4412 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4413 *lenretval = new_fi->length;
4414 return item;
4415}
4416
4417proto_item *
4418proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4419 const int start, int length,
4420 const unsigned encoding, int *lenretval)
4421{
4422 register header_field_info *hfinfo;
4423
4424 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", 4424, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4424,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4424, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4425 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4426}
4427
4428/* which FT_ types can use proto_tree_add_bytes_item() */
4429static inline bool_Bool
4430validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4431{
4432 return (type == FT_BYTES ||
4433 type == FT_UINT_BYTES ||
4434 type == FT_OID ||
4435 type == FT_REL_OID ||
4436 type == FT_SYSTEM_ID );
4437}
4438
4439/* Note: this does no validation that the byte array of an FT_OID or
4440 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4441 so I think it's ok to continue not validating it?
4442 */
4443proto_item *
4444proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4445 const int start, int length, const unsigned encoding,
4446 GByteArray *retval, int *endoff, int *err)
4447{
4448 field_info *new_fi;
4449 GByteArray *bytes = retval;
4450 GByteArray *created_bytes = NULL((void*)0);
4451 bool_Bool failed = false0;
4452 uint32_t n = 0;
4453 header_field_info *hfinfo;
4454 bool_Bool generate = (bytes || tree) ? true1 : false0;
4455
4456 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", 4456, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4456,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4456, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4457
4458 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", 4458,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4459
4460 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", 4461, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4461 "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", 4461, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4462
4463 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4464
4465 if (encoding & ENC_STR_NUM0x01000000) {
4466 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"
)
;
4467 }
4468
4469 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4470 if (hfinfo->type == FT_UINT_BYTES) {
4471 /* can't decode FT_UINT_BYTES from strings */
4472 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")
4473 "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")
;
4474 }
4475
4476 unsigned hex_encoding = encoding;
4477 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4478 /* If none of the separator values are used,
4479 * assume no separator (the common case). */
4480 hex_encoding |= ENC_SEP_NONE0x00010000;
4481#if 0
4482 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")
4483 "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")
;
4484#endif
4485 }
4486
4487 if (!bytes) {
4488 /* caller doesn't care about return value, but we need it to
4489 call tvb_get_string_bytes() and set the tree later */
4490 bytes = created_bytes = g_byte_array_new();
4491 }
4492
4493 /*
4494 * bytes might be NULL after this, but can't add expert
4495 * error until later; if it's NULL, just note that
4496 * it failed.
4497 */
4498 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4499 if (bytes == NULL((void*)0))
4500 failed = true1;
4501 }
4502 else if (generate) {
4503 tvb_ensure_bytes_exist(tvb, start, length);
4504
4505 if (hfinfo->type == FT_UINT_BYTES) {
4506 n = length; /* n is now the "header" length */
4507 length = get_uint_value(tree, tvb, start, n, encoding);
4508 /* length is now the value's length; only store the value in the array */
4509 tvb_ensure_bytes_exist(tvb, start + n, length);
4510 if (!bytes) {
4511 /* caller doesn't care about return value, but
4512 * we may need it to set the tree later */
4513 bytes = created_bytes = g_byte_array_new();
4514 }
4515 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4516 }
4517 else if (length > 0) {
4518 if (!bytes) {
4519 /* caller doesn't care about return value, but
4520 * we may need it to set the tree later */
4521 bytes = created_bytes = g_byte_array_new();
4522 }
4523 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4524 }
4525
4526 if (endoff)
4527 *endoff = start + n + length;
4528 }
4529
4530 if (err)
4531 *err = failed ? EINVAL22 : 0;
4532
4533 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); }
4534 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4535 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); }
4536 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); }
4537 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); }
4538 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4539 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4540
4541 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 {((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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4547 } )((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", 4547
, __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", 4547, "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", 4547, "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", 4547
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4548
4549 /* n will be zero except when it's a FT_UINT_BYTES */
4550 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4551
4552 if (encoding & ENC_STRING0x03000000) {
4553 if (failed)
4554 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4555
4556 if (bytes)
4557 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4558 else
4559 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4560
4561 if (created_bytes)
4562 g_byte_array_free(created_bytes, true1);
4563 }
4564 else {
4565 /* n will be zero except when it's a FT_UINT_BYTES */
4566 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4567
4568 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4569 * use the byte array created above in this case.
4570 */
4571 if (created_bytes)
4572 g_byte_array_free(created_bytes, true1);
4573
4574 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4575 (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)
;
4576 }
4577
4578 return proto_tree_add_node(tree, new_fi);
4579}
4580
4581
4582proto_item *
4583proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4584 const int start, int length, const unsigned encoding,
4585 nstime_t *retval, int *endoff, int *err)
4586{
4587 field_info *new_fi;
4588 nstime_t time_stamp;
4589 int saved_err = 0;
4590 header_field_info *hfinfo;
4591
4592 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", 4592, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4592,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4592, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4593
4594 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", 4594,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4595
4596 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,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 if(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 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4601 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4602 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4603
4604 nstime_set_zero(&time_stamp);
4605
4606 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4607 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", 4607, ((hfinfo))->abbrev))))
;
4608 /* The only string format that could be a relative time is
4609 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4610 * relative to "now" currently.
4611 */
4612 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4613 saved_err = EINVAL22;
4614 }
4615 else {
4616 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", 4616, ((hfinfo))->abbrev))))
;
4617 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4618
4619 tvb_ensure_bytes_exist(tvb, start, length);
4620 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4621 if (endoff) *endoff = start + length;
4622 }
4623
4624 if (err) *err = saved_err;
4625
4626 if (retval) {
4627 retval->secs = time_stamp.secs;
4628 retval->nsecs = time_stamp.nsecs;
4629 }
4630
4631 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4632
4633 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", 4633
, __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", 4633, "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", 4633, "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", 4633, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4634
4635 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4636
4637 proto_tree_set_time(new_fi, &time_stamp);
4638
4639 if (encoding & ENC_STRING0x03000000) {
4640 if (saved_err)
4641 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4642 }
4643 else {
4644 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4645 (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)
;
4646 }
4647
4648 return proto_tree_add_node(tree, new_fi);
4649}
4650
4651/* Add a FT_NONE to a proto_tree */
4652proto_item *
4653proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4654 const int start, int length, const char *format,
4655 ...)
4656{
4657 proto_item *pi;
4658 va_list ap;
4659 header_field_info *hfinfo;
4660
4661 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4662
4663 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", 4663
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4663, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4663, "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", 4663, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4664
4665 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", 4665
, ((hfinfo))->abbrev))))
;
4666
4667 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4668
4669 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4669, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4670
4671 va_start(ap, format)__builtin_va_start(ap, format);
4672 proto_tree_set_representation(pi, format, ap);
4673 va_end(ap)__builtin_va_end(ap);
4674
4675 /* no value to set for FT_NONE */
4676 return pi;
4677}
4678
4679/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4680 * offset, and returns proto_item* */
4681proto_item *
4682ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4683 const unsigned encoding)
4684{
4685 proto_item *item;
4686
4687 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4688 length, encoding);
4689
4690 return item;
4691}
4692
4693/* Advance the ptvcursor's offset within its tvbuff without
4694 * adding anything to the proto_tree. */
4695void
4696ptvcursor_advance(ptvcursor_t* ptvc, int length)
4697{
4698 ptvc->offset += length;
4699}
4700
4701
4702static void
4703proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4704{
4705 fvalue_set_protocol(fi->value, tvb, field_data, length);
4706}
4707
4708/* Add a FT_PROTOCOL to a proto_tree */
4709proto_item *
4710proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4711 int start, int length, const char *format, ...)
4712{
4713 proto_item *pi;
4714 tvbuff_t *protocol_tvb;
4715 va_list ap;
4716 header_field_info *hfinfo;
4717 char* protocol_rep;
4718
4719 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4720
4721 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", 4721
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4721, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4721, "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", 4721, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4722
4723 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"
, 4723, ((hfinfo))->abbrev))))
;
4724
4725 /*
4726 * This can throw an exception, so do it before we allocate anything.
4727 */
4728 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4729
4730 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4731
4732 va_start(ap, format)__builtin_va_start(ap, format);
4733 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4734 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4735 g_free(protocol_rep);
4736 va_end(ap)__builtin_va_end(ap);
4737
4738 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4738, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4739
4740 va_start(ap, format)__builtin_va_start(ap, format);
4741 proto_tree_set_representation(pi, format, ap);
4742 va_end(ap)__builtin_va_end(ap);
4743
4744 return pi;
4745}
4746
4747/* Add a FT_BYTES to a proto_tree */
4748proto_item *
4749proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4750 int length, const uint8_t *start_ptr)
4751{
4752 proto_item *pi;
4753 header_field_info *hfinfo;
4754 int item_length;
4755
4756 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", 4756, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4756,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4756, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4757 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4758 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4759
4760 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4761
4762 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", 4762
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4762, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4762, "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", 4762, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4763
4764 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",
4764, ((hfinfo))->abbrev))))
;
4765
4766 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4767 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4768
4769 return pi;
4770}
4771
4772/* Add a FT_BYTES to a proto_tree */
4773proto_item *
4774proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4775 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4776{
4777 proto_item *pi;
4778 header_field_info *hfinfo;
4779 int item_length;
4780
4781 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", 4781, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4781,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4781, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4782 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4783 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4784
4785 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4786
4787 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", 4787
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4787, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4787, "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", 4787, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4788
4789 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",
4789, ((hfinfo))->abbrev))))
;
4790
4791 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4792 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4793
4794 return pi;
4795}
4796
4797proto_item *
4798proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4799 int start, int length,
4800 const uint8_t *start_ptr,
4801 const char *format, ...)
4802{
4803 proto_item *pi;
4804 va_list ap;
4805
4806 if (start_ptr == NULL((void*)0))
4807 start_ptr = tvb_get_ptr(tvb, start, length);
4808
4809 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4810
4811 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; }
;
4812
4813 va_start(ap, format)__builtin_va_start(ap, format);
4814 proto_tree_set_representation_value(pi, format, ap);
4815 va_end(ap)__builtin_va_end(ap);
4816
4817 return pi;
4818}
4819
4820proto_item *
4821proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4822 int start, int length, const uint8_t *start_ptr,
4823 const char *format, ...)
4824{
4825 proto_item *pi;
4826 va_list ap;
4827
4828 if (start_ptr == NULL((void*)0))
4829 start_ptr = tvb_get_ptr(tvb, start, length);
4830
4831 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4832
4833 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; }
;
4834
4835 va_start(ap, format)__builtin_va_start(ap, format);
4836 proto_tree_set_representation(pi, format, ap);
4837 va_end(ap)__builtin_va_end(ap);
4838
4839 return pi;
4840}
4841
4842static void
4843proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4844{
4845 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4845, "length >= 0"
))))
;
4846 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", 4846, "start_ptr != ((void*)0) || length == 0"
))))
;
4847
4848 fvalue_set_bytes_data(fi->value, start_ptr, length);
4849}
4850
4851
4852static void
4853proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4854{
4855 tvb_ensure_bytes_exist(tvb, offset, length);
4856 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4857}
4858
4859static void
4860proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4861{
4862 GByteArray *bytes;
4863
4864 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4864, "value != ((void*)0)"
))))
;
4865
4866 bytes = byte_array_dup(value);
4867
4868 fvalue_set_byte_array(fi->value, bytes);
4869}
4870
4871/* Add a FT_*TIME to a proto_tree */
4872proto_item *
4873proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4874 int length, const nstime_t *value_ptr)
4875{
4876 proto_item *pi;
4877 header_field_info *hfinfo;
4878
4879 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4880
4881 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", 4881
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4881, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4881, "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", 4881, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4882
4883 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", 4883, ((hfinfo))->abbrev))))
;
4884
4885 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4886 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4887
4888 return pi;
4889}
4890
4891proto_item *
4892proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4893 int start, int length, nstime_t *value_ptr,
4894 const char *format, ...)
4895{
4896 proto_item *pi;
4897 va_list ap;
4898
4899 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4900 if (pi != tree) {
4901 va_start(ap, format)__builtin_va_start(ap, format);
4902 proto_tree_set_representation_value(pi, format, ap);
4903 va_end(ap)__builtin_va_end(ap);
4904 }
4905
4906 return pi;
4907}
4908
4909proto_item *
4910proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4911 int start, int length, nstime_t *value_ptr,
4912 const char *format, ...)
4913{
4914 proto_item *pi;
4915 va_list ap;
4916
4917 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4918 if (pi != tree) {
4919 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4919, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4920
4921 va_start(ap, format)__builtin_va_start(ap, format);
4922 proto_tree_set_representation(pi, format, ap);
4923 va_end(ap)__builtin_va_end(ap);
4924 }
4925
4926 return pi;
4927}
4928
4929/* Set the FT_*TIME value */
4930static void
4931proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4932{
4933 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4933, "value_ptr != ((void*)0)"
))))
;
4934
4935 fvalue_set_time(fi->value, value_ptr);
4936}
4937
4938/* Add a FT_IPXNET to a proto_tree */
4939proto_item *
4940proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4941 int length, uint32_t value)
4942{
4943 proto_item *pi;
4944 header_field_info *hfinfo;
4945
4946 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4947
4948 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", 4948
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4948, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4948, "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", 4948, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4949
4950 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"
, 4950, ((hfinfo))->abbrev))))
;
4951
4952 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4953 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
4954
4955 return pi;
4956}
4957
4958proto_item *
4959proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4960 int start, int length, uint32_t value,
4961 const char *format, ...)
4962{
4963 proto_item *pi;
4964 va_list ap;
4965
4966 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4967 if (pi != tree) {
4968 va_start(ap, format)__builtin_va_start(ap, format);
4969 proto_tree_set_representation_value(pi, format, ap);
4970 va_end(ap)__builtin_va_end(ap);
4971 }
4972
4973 return pi;
4974}
4975
4976proto_item *
4977proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4978 int start, int length, uint32_t value,
4979 const char *format, ...)
4980{
4981 proto_item *pi;
4982 va_list ap;
4983
4984 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4985 if (pi != tree) {
4986 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4986, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4987
4988 va_start(ap, format)__builtin_va_start(ap, format);
4989 proto_tree_set_representation(pi, format, ap);
4990 va_end(ap)__builtin_va_end(ap);
4991 }
4992
4993 return pi;
4994}
4995
4996/* Set the FT_IPXNET value */
4997static void
4998proto_tree_set_ipxnet(field_info *fi, uint32_t value)
4999{
5000 fvalue_set_uinteger(fi->value, value);
5001}
5002
5003/* Add a FT_IPv4 to a proto_tree */
5004proto_item *
5005proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5006 int length, ws_in4_addr value)
5007{
5008 proto_item *pi;
5009 header_field_info *hfinfo;
5010
5011 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5012
5013 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", 5013
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5013, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5013, "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", 5013, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5014
5015 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", 5015
, ((hfinfo))->abbrev))))
;
5016
5017 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5018 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5019
5020 return pi;
5021}
5022
5023proto_item *
5024proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5025 int start, int length, ws_in4_addr value,
5026 const char *format, ...)
5027{
5028 proto_item *pi;
5029 va_list ap;
5030
5031 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5032 if (pi != tree) {
5033 va_start(ap, format)__builtin_va_start(ap, format);
5034 proto_tree_set_representation_value(pi, format, ap);
5035 va_end(ap)__builtin_va_end(ap);
5036 }
5037
5038 return pi;
5039}
5040
5041proto_item *
5042proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5043 int start, int length, ws_in4_addr value,
5044 const char *format, ...)
5045{
5046 proto_item *pi;
5047 va_list ap;
5048
5049 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5050 if (pi != tree) {
5051 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5051, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5052
5053 va_start(ap, format)__builtin_va_start(ap, format);
5054 proto_tree_set_representation(pi, format, ap);
5055 va_end(ap)__builtin_va_end(ap);
5056 }
5057
5058 return pi;
5059}
5060
5061/* Set the FT_IPv4 value */
5062static void
5063proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5064{
5065 ipv4_addr_and_mask ipv4;
5066 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5067 fvalue_set_ipv4(fi->value, &ipv4);
5068}
5069
5070/* Add a FT_IPv6 to a proto_tree */
5071proto_item *
5072proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5073 int length, const ws_in6_addr *value)
5074{
5075 proto_item *pi;
5076 header_field_info *hfinfo;
5077
5078 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5079
5080 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", 5080
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5080, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5080, "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", 5080, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5081
5082 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", 5082
, ((hfinfo))->abbrev))))
;
5083
5084 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5085 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5086
5087 return pi;
5088}
5089
5090proto_item *
5091proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5092 int start, int length,
5093 const ws_in6_addr *value_ptr,
5094 const char *format, ...)
5095{
5096 proto_item *pi;
5097 va_list ap;
5098
5099 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5100 if (pi != tree) {
5101 va_start(ap, format)__builtin_va_start(ap, format);
5102 proto_tree_set_representation_value(pi, format, ap);
5103 va_end(ap)__builtin_va_end(ap);
5104 }
5105
5106 return pi;
5107}
5108
5109proto_item *
5110proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5111 int start, int length,
5112 const ws_in6_addr *value_ptr,
5113 const char *format, ...)
5114{
5115 proto_item *pi;
5116 va_list ap;
5117
5118 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5119 if (pi != tree) {
5120 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5120, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5121
5122 va_start(ap, format)__builtin_va_start(ap, format);
5123 proto_tree_set_representation(pi, format, ap);
5124 va_end(ap)__builtin_va_end(ap);
5125 }
5126
5127 return pi;
5128}
5129
5130/* Set the FT_IPv6 value */
5131static void
5132proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5133{
5134 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5134, "value != ((void*)0)"
))))
;
5135 ipv6_addr_and_prefix ipv6;
5136 ipv6.addr = *value;
5137 ipv6.prefix = 128;
5138 fvalue_set_ipv6(fi->value, &ipv6);
5139}
5140
5141static void
5142proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5143{
5144 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5145}
5146
5147/* Set the FT_FCWWN value */
5148static void
5149proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5150{
5151 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5151, "value_ptr != ((void*)0)"
))))
;
5152 fvalue_set_fcwwn(fi->value, value_ptr);
5153}
5154
5155static void
5156proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5157{
5158 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5159}
5160
5161/* Add a FT_GUID to a proto_tree */
5162proto_item *
5163proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5164 int length, const e_guid_t *value_ptr)
5165{
5166 proto_item *pi;
5167 header_field_info *hfinfo;
5168
5169 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5170
5171 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", 5171
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5171, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5171, "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", 5171, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5172
5173 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", 5173
, ((hfinfo))->abbrev))))
;
5174
5175 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5176 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5177
5178 return pi;
5179}
5180
5181proto_item *
5182proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5183 int start, int length,
5184 const e_guid_t *value_ptr,
5185 const char *format, ...)
5186{
5187 proto_item *pi;
5188 va_list ap;
5189
5190 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5191 if (pi != tree) {
5192 va_start(ap, format)__builtin_va_start(ap, format);
5193 proto_tree_set_representation_value(pi, format, ap);
5194 va_end(ap)__builtin_va_end(ap);
5195 }
5196
5197 return pi;
5198}
5199
5200proto_item *
5201proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5202 int start, int length, const e_guid_t *value_ptr,
5203 const char *format, ...)
5204{
5205 proto_item *pi;
5206 va_list ap;
5207
5208 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5209 if (pi != tree) {
5210 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5210, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5211
5212 va_start(ap, format)__builtin_va_start(ap, format);
5213 proto_tree_set_representation(pi, format, ap);
5214 va_end(ap)__builtin_va_end(ap);
5215 }
5216
5217 return pi;
5218}
5219
5220/* Set the FT_GUID value */
5221static void
5222proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5223{
5224 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5224, "value_ptr != ((void*)0)"
))))
;
5225 fvalue_set_guid(fi->value, value_ptr);
5226}
5227
5228static void
5229proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5230 const unsigned encoding)
5231{
5232 e_guid_t guid;
5233
5234 tvb_get_guid(tvb, start, &guid, encoding);
5235 proto_tree_set_guid(fi, &guid);
5236}
5237
5238/* Add a FT_OID to a proto_tree */
5239proto_item *
5240proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5241 int length, const uint8_t* value_ptr)
5242{
5243 proto_item *pi;
5244 header_field_info *hfinfo;
5245
5246 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5247
5248 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", 5248
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5248, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5248, "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", 5248, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5249
5250 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", 5250
, ((hfinfo))->abbrev))))
;
5251
5252 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5253 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5254
5255 return pi;
5256}
5257
5258proto_item *
5259proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5260 int start, int length,
5261 const uint8_t* value_ptr,
5262 const char *format, ...)
5263{
5264 proto_item *pi;
5265 va_list ap;
5266
5267 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5268 if (pi != tree) {
5269 va_start(ap, format)__builtin_va_start(ap, format);
5270 proto_tree_set_representation_value(pi, format, ap);
5271 va_end(ap)__builtin_va_end(ap);
5272 }
5273
5274 return pi;
5275}
5276
5277proto_item *
5278proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5279 int start, int length, const uint8_t* value_ptr,
5280 const char *format, ...)
5281{
5282 proto_item *pi;
5283 va_list ap;
5284
5285 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5286 if (pi != tree) {
5287 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5287, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5288
5289 va_start(ap, format)__builtin_va_start(ap, format);
5290 proto_tree_set_representation(pi, format, ap);
5291 va_end(ap)__builtin_va_end(ap);
5292 }
5293
5294 return pi;
5295}
5296
5297/* Set the FT_OID value */
5298static void
5299proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5300{
5301 GByteArray *bytes;
5302
5303 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", 5303, "value_ptr != ((void*)0) || length == 0"
))))
;
5304
5305 bytes = g_byte_array_new();
5306 if (length > 0) {
5307 g_byte_array_append(bytes, value_ptr, length);
5308 }
5309 fvalue_set_byte_array(fi->value, bytes);
5310}
5311
5312static void
5313proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5314{
5315 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5316}
5317
5318/* Set the FT_SYSTEM_ID value */
5319static void
5320proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5321{
5322 GByteArray *bytes;
5323
5324 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", 5324, "value_ptr != ((void*)0) || length == 0"
))))
;
5325
5326 bytes = g_byte_array_new();
5327 if (length > 0) {
5328 g_byte_array_append(bytes, value_ptr, length);
5329 }
5330 fvalue_set_byte_array(fi->value, bytes);
5331}
5332
5333static void
5334proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5335{
5336 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5337}
5338
5339/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5340 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5341 * is destroyed. */
5342proto_item *
5343proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5344 int length, const char* value)
5345{
5346 proto_item *pi;
5347 header_field_info *hfinfo;
5348 int item_length;
5349
5350 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", 5350, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5350,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5350, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5351 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5352 /*
5353 * Special case - if the length is 0, skip the test, so that
5354 * we can have an empty string right after the end of the
5355 * packet. (This handles URL-encoded forms where the last field
5356 * has no value so the form ends right after the =.)
5357 */
5358 if (item_length != 0)
5359 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5360
5361 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5362
5363 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", 5363
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5363, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5363, "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", 5363, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5364
5365 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", 5365, ((hfinfo))->abbrev))))
;
5366
5367 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5368 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5368, "length >= 0"
))))
;
5369
5370 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", 5370, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5371 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5372
5373 return pi;
5374}
5375
5376proto_item *
5377proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5378 int start, int length, const char* value,
5379 const char *format,
5380 ...)
5381{
5382 proto_item *pi;
5383 va_list ap;
5384
5385 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5386 if (pi != tree) {
5387 va_start(ap, format)__builtin_va_start(ap, format);
5388 proto_tree_set_representation_value(pi, format, ap);
5389 va_end(ap)__builtin_va_end(ap);
5390 }
5391
5392 return pi;
5393}
5394
5395proto_item *
5396proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5397 int start, int length, const char* value,
5398 const char *format, ...)
5399{
5400 proto_item *pi;
5401 va_list ap;
5402
5403 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5404 if (pi != tree) {
5405 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5405, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5406
5407 va_start(ap, format)__builtin_va_start(ap, format);
5408 proto_tree_set_representation(pi, format, ap);
5409 va_end(ap)__builtin_va_end(ap);
5410 }
5411
5412 return pi;
5413}
5414
5415/* Set the FT_STRING value */
5416static void
5417proto_tree_set_string(field_info *fi, const char* value)
5418{
5419 if (value) {
5420 fvalue_set_string(fi->value, value);
5421 } else {
5422 /*
5423 * XXX - why is a null value for a string field
5424 * considered valid?
5425 */
5426 fvalue_set_string(fi->value, "[ Null ]");
5427 }
5428}
5429
5430/* Set the FT_AX25 value */
5431static void
5432proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5433{
5434 fvalue_set_ax25(fi->value, value);
5435}
5436
5437static void
5438proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5439{
5440 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5441}
5442
5443/* Set the FT_VINES value */
5444static void
5445proto_tree_set_vines(field_info *fi, const uint8_t* value)
5446{
5447 fvalue_set_vines(fi->value, value);
5448}
5449
5450static void
5451proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5452{
5453 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5454}
5455
5456/* Add a FT_ETHER to a proto_tree */
5457proto_item *
5458proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5459 int length, const uint8_t* value)
5460{
5461 proto_item *pi;
5462 header_field_info *hfinfo;
5463
5464 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5465
5466 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", 5466
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5466, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5466, "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", 5466, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5467
5468 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",
5468, ((hfinfo))->abbrev))))
;
5469
5470 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5471 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5472
5473 return pi;
5474}
5475
5476proto_item *
5477proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5478 int start, int length, const uint8_t* value,
5479 const char *format, ...)
5480{
5481 proto_item *pi;
5482 va_list ap;
5483
5484 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5485 if (pi != tree) {
5486 va_start(ap, format)__builtin_va_start(ap, format);
5487 proto_tree_set_representation_value(pi, format, ap);
5488 va_end(ap)__builtin_va_end(ap);
5489 }
5490
5491 return pi;
5492}
5493
5494proto_item *
5495proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5496 int start, int length, const uint8_t* value,
5497 const char *format, ...)
5498{
5499 proto_item *pi;
5500 va_list ap;
5501
5502 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5503 if (pi != tree) {
5504 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5504, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5505
5506 va_start(ap, format)__builtin_va_start(ap, format);
5507 proto_tree_set_representation(pi, format, ap);
5508 va_end(ap)__builtin_va_end(ap);
5509 }
5510
5511 return pi;
5512}
5513
5514/* Set the FT_ETHER value */
5515static void
5516proto_tree_set_ether(field_info *fi, const uint8_t* value)
5517{
5518 fvalue_set_ether(fi->value, value);
5519}
5520
5521static void
5522proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5523{
5524 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5525}
5526
5527/* Add a FT_BOOLEAN to a proto_tree */
5528proto_item *
5529proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5530 int length, uint64_t value)
5531{
5532 proto_item *pi;
5533 header_field_info *hfinfo;
5534
5535 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5536
5537 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", 5537
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5537, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5537, "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", 5537, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5538
5539 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"
, 5539, ((hfinfo))->abbrev))))
;
5540
5541 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5542 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5543
5544 return pi;
5545}
5546
5547proto_item *
5548proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5549 tvbuff_t *tvb, int start, int length,
5550 uint64_t value, const char *format, ...)
5551{
5552 proto_item *pi;
5553 va_list ap;
5554
5555 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5556 if (pi != tree) {
5557 va_start(ap, format)__builtin_va_start(ap, format);
5558 proto_tree_set_representation_value(pi, format, ap);
5559 va_end(ap)__builtin_va_end(ap);
5560 }
5561
5562 return pi;
5563}
5564
5565proto_item *
5566proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5567 int start, int length, uint64_t value,
5568 const char *format, ...)
5569{
5570 proto_item *pi;
5571 va_list ap;
5572
5573 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5574 if (pi != tree) {
5575 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5575, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5576
5577 va_start(ap, format)__builtin_va_start(ap, format);
5578 proto_tree_set_representation(pi, format, ap);
5579 va_end(ap)__builtin_va_end(ap);
5580 }
5581
5582 return pi;
5583}
5584
5585/* Set the FT_BOOLEAN value */
5586static void
5587proto_tree_set_boolean(field_info *fi, uint64_t value)
5588{
5589 proto_tree_set_uint64(fi, value);
5590}
5591
5592/* Generate, into "buf", a string showing the bits of a bitfield.
5593 Return a pointer to the character after that string. */
5594static char *
5595other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5596{
5597 int i = 0;
5598 uint64_t bit;
5599 char *p;
5600
5601 p = buf;
5602
5603 /* This is a devel error. It is safer to stop here. */
5604 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5604, "width >= 1"
))))
;
5605
5606 bit = UINT64_C(1)1UL << (width - 1);
5607 for (;;) {
5608 if (mask & bit) {
5609 /* This bit is part of the field. Show its value. */
5610 if (val & bit)
5611 *p++ = '1';
5612 else
5613 *p++ = '0';
5614 } else {
5615 /* This bit is not part of the field. */
5616 *p++ = '.';
5617 }
5618 bit >>= 1;
5619 i++;
5620 if (i >= width)
5621 break;
5622 if (i % 4 == 0)
5623 *p++ = ' ';
5624 }
5625 *p = '\0';
5626 return p;
5627}
5628
5629static char *
5630decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5631{
5632 char *p;
5633
5634 p = other_decode_bitfield_value(buf, val, mask, width);
5635 p = g_stpcpy(p, " = ");
5636
5637 return p;
5638}
5639
5640static char *
5641other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5642{
5643 int i = 0;
5644 uint64_t bit;
5645 char *p;
5646
5647 p = buf;
5648
5649 /* This is a devel error. It is safer to stop here. */
5650 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5650, "width >= 1"
))))
;
5651
5652 bit = UINT64_C(1)1UL << (width - 1);
5653 for (;;) {
5654 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5655 (mask & bit)) {
5656 /* This bit is part of the field. Show its value. */
5657 if (val & bit)
5658 *p++ = '1';
5659 else
5660 *p++ = '0';
5661 } else {
5662 /* This bit is not part of the field. */
5663 *p++ = '.';
5664 }
5665 bit >>= 1;
5666 i++;
5667 if (i >= width)
5668 break;
5669 if (i % 4 == 0)
5670 *p++ = ' ';
5671 }
5672
5673 *p = '\0';
5674 return p;
5675}
5676
5677static char *
5678decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5679{
5680 char *p;
5681
5682 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5683 p = g_stpcpy(p, " = ");
5684
5685 return p;
5686}
5687
5688/* Add a FT_FLOAT to a proto_tree */
5689proto_item *
5690proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5691 int length, float value)
5692{
5693 proto_item *pi;
5694 header_field_info *hfinfo;
5695
5696 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5697
5698 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", 5698
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5698, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5698, "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", 5698, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5699
5700 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",
5700, ((hfinfo))->abbrev))))
;
5701
5702 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5703 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5704
5705 return pi;
5706}
5707
5708proto_item *
5709proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5710 int start, int length, float value,
5711 const char *format, ...)
5712{
5713 proto_item *pi;
5714 va_list ap;
5715
5716 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5717 if (pi != tree) {
5718 va_start(ap, format)__builtin_va_start(ap, format);
5719 proto_tree_set_representation_value(pi, format, ap);
5720 va_end(ap)__builtin_va_end(ap);
5721 }
5722
5723 return pi;
5724}
5725
5726proto_item *
5727proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5728 int start, int length, float value,
5729 const char *format, ...)
5730{
5731 proto_item *pi;
5732 va_list ap;
5733
5734 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5735 if (pi != tree) {
5736 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5736, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5737
5738 va_start(ap, format)__builtin_va_start(ap, format);
5739 proto_tree_set_representation(pi, format, ap);
5740 va_end(ap)__builtin_va_end(ap);
5741 }
5742
5743 return pi;
5744}
5745
5746/* Set the FT_FLOAT value */
5747static void
5748proto_tree_set_float(field_info *fi, float value)
5749{
5750 fvalue_set_floating(fi->value, value);
5751}
5752
5753/* Add a FT_DOUBLE to a proto_tree */
5754proto_item *
5755proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5756 int length, double value)
5757{
5758 proto_item *pi;
5759 header_field_info *hfinfo;
5760
5761 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5762
5763 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", 5763
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5763, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5763, "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", 5763, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5764
5765 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"
, 5765, ((hfinfo))->abbrev))))
;
5766
5767 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5768 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5769
5770 return pi;
5771}
5772
5773proto_item *
5774proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5775 int start, int length, double value,
5776 const char *format, ...)
5777{
5778 proto_item *pi;
5779 va_list ap;
5780
5781 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5782 if (pi != tree) {
5783 va_start(ap, format)__builtin_va_start(ap, format);
5784 proto_tree_set_representation_value(pi, format, ap);
5785 va_end(ap)__builtin_va_end(ap);
5786 }
5787
5788 return pi;
5789}
5790
5791proto_item *
5792proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5793 int start, int length, double value,
5794 const char *format, ...)
5795{
5796 proto_item *pi;
5797 va_list ap;
5798
5799 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5800 if (pi != tree) {
5801 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5801, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5802
5803 va_start(ap, format)__builtin_va_start(ap, format);
5804 proto_tree_set_representation(pi, format, ap);
5805 va_end(ap)__builtin_va_end(ap);
5806 }
5807
5808 return pi;
5809}
5810
5811/* Set the FT_DOUBLE value */
5812static void
5813proto_tree_set_double(field_info *fi, double value)
5814{
5815 fvalue_set_floating(fi->value, value);
5816}
5817
5818/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5819proto_item *
5820proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5821 int length, uint32_t value)
5822{
5823 proto_item *pi = NULL((void*)0);
5824 header_field_info *hfinfo;
5825
5826 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5827
5828 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", 5828
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5828, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5828, "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", 5828, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5829
5830 switch (hfinfo->type) {
5831 case FT_CHAR:
5832 case FT_UINT8:
5833 case FT_UINT16:
5834 case FT_UINT24:
5835 case FT_UINT32:
5836 case FT_FRAMENUM:
5837 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5838 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5839 break;
5840
5841 default:
5842 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)
5843 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)
;
5844 }
5845
5846 return pi;
5847}
5848
5849proto_item *
5850proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5851 int start, int length, uint32_t value,
5852 const char *format, ...)
5853{
5854 proto_item *pi;
5855 va_list ap;
5856
5857 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5858 if (pi != tree) {
5859 va_start(ap, format)__builtin_va_start(ap, format);
5860 proto_tree_set_representation_value(pi, format, ap);
5861 va_end(ap)__builtin_va_end(ap);
5862 }
5863
5864 return pi;
5865}
5866
5867proto_item *
5868proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5869 int start, int length, uint32_t value,
5870 const char *format, ...)
5871{
5872 proto_item *pi;
5873 va_list ap;
5874
5875 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5876 if (pi != tree) {
5877 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5877, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5878
5879 va_start(ap, format)__builtin_va_start(ap, format);
5880 proto_tree_set_representation(pi, format, ap);
5881 va_end(ap)__builtin_va_end(ap);
5882 }
5883
5884 return pi;
5885}
5886
5887/* Set the FT_UINT{8,16,24,32} value */
5888static void
5889proto_tree_set_uint(field_info *fi, uint32_t value)
5890{
5891 const header_field_info *hfinfo;
5892 uint32_t integer;
5893
5894 hfinfo = fi->hfinfo;
5895 integer = value;
5896
5897 if (hfinfo->bitmask) {
5898 /* Mask out irrelevant portions */
5899 integer &= (uint32_t)(hfinfo->bitmask);
5900
5901 /* Shift bits */
5902 integer >>= hfinfo_bitshift(hfinfo);
5903
5904 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
5905 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 8)); } while(0)
;
5906 }
5907
5908 fvalue_set_uinteger(fi->value, integer);
5909}
5910
5911/* Add FT_UINT{40,48,56,64} to a proto_tree */
5912proto_item *
5913proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5914 int length, uint64_t value)
5915{
5916 proto_item *pi = NULL((void*)0);
5917 header_field_info *hfinfo;
5918
5919 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5920
5921 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", 5921
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5921, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5921, "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", 5921, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5922
5923 switch (hfinfo->type) {
5924 case FT_UINT40:
5925 case FT_UINT48:
5926 case FT_UINT56:
5927 case FT_UINT64:
5928 case FT_FRAMENUM:
5929 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5930 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5931 break;
5932
5933 default:
5934 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)
5935 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)
;
5936 }
5937
5938 return pi;
5939}
5940
5941proto_item *
5942proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5943 int start, int length, uint64_t value,
5944 const char *format, ...)
5945{
5946 proto_item *pi;
5947 va_list ap;
5948
5949 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5950 if (pi != tree) {
5951 va_start(ap, format)__builtin_va_start(ap, format);
5952 proto_tree_set_representation_value(pi, format, ap);
5953 va_end(ap)__builtin_va_end(ap);
5954 }
5955
5956 return pi;
5957}
5958
5959proto_item *
5960proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5961 int start, int length, uint64_t value,
5962 const char *format, ...)
5963{
5964 proto_item *pi;
5965 va_list ap;
5966
5967 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5968 if (pi != tree) {
5969 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5969, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5970
5971 va_start(ap, format)__builtin_va_start(ap, format);
5972 proto_tree_set_representation(pi, format, ap);
5973 va_end(ap)__builtin_va_end(ap);
5974 }
5975
5976 return pi;
5977}
5978
5979/* Set the FT_UINT{40,48,56,64} value */
5980static void
5981proto_tree_set_uint64(field_info *fi, uint64_t value)
5982{
5983 const header_field_info *hfinfo;
5984 uint64_t integer;
5985
5986 hfinfo = fi->hfinfo;
5987 integer = value;
5988
5989 if (hfinfo->bitmask) {
5990 /* Mask out irrelevant portions */
5991 integer &= hfinfo->bitmask;
5992
5993 /* Shift bits */
5994 integer >>= hfinfo_bitshift(hfinfo);
5995
5996 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
5997 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 8)); } while(0)
;
5998 }
5999
6000 fvalue_set_uinteger64(fi->value, integer);
6001}
6002
6003/* Add FT_INT{8,16,24,32} to a proto_tree */
6004proto_item *
6005proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6006 int length, int32_t value)
6007{
6008 proto_item *pi = NULL((void*)0);
6009 header_field_info *hfinfo;
6010
6011 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6012
6013 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", 6013
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6013, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6013, "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", 6013, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6014
6015 switch (hfinfo->type) {
6016 case FT_INT8:
6017 case FT_INT16:
6018 case FT_INT24:
6019 case FT_INT32:
6020 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6021 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6022 break;
6023
6024 default:
6025 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)
6026 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6027 }
6028
6029 return pi;
6030}
6031
6032proto_item *
6033proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6034 int start, int length, int32_t value,
6035 const char *format, ...)
6036{
6037 proto_item *pi;
6038 va_list ap;
6039
6040 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6041 if (pi != tree) {
6042 va_start(ap, format)__builtin_va_start(ap, format);
6043 proto_tree_set_representation_value(pi, format, ap);
6044 va_end(ap)__builtin_va_end(ap);
6045 }
6046
6047 return pi;
6048}
6049
6050proto_item *
6051proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6052 int start, int length, int32_t value,
6053 const char *format, ...)
6054{
6055 proto_item *pi;
6056 va_list ap;
6057
6058 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6059 if (pi != tree) {
6060 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6060, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6061
6062 va_start(ap, format)__builtin_va_start(ap, format);
6063 proto_tree_set_representation(pi, format, ap);
6064 va_end(ap)__builtin_va_end(ap);
6065 }
6066
6067 return pi;
6068}
6069
6070/* Set the FT_INT{8,16,24,32} value */
6071static void
6072proto_tree_set_int(field_info *fi, int32_t value)
6073{
6074 const header_field_info *hfinfo;
6075 uint32_t integer;
6076 int no_of_bits;
6077
6078 hfinfo = fi->hfinfo;
6079 integer = (uint32_t) value;
6080
6081 if (hfinfo->bitmask) {
6082 /* Mask out irrelevant portions */
6083 integer &= (uint32_t)(hfinfo->bitmask);
6084
6085 /* Shift bits */
6086 integer >>= hfinfo_bitshift(hfinfo);
6087
6088 no_of_bits = ws_count_ones(hfinfo->bitmask);
6089 integer = ws_sign_ext32(integer, no_of_bits);
6090
6091 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
6092 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 8)); } while(0)
;
6093 }
6094
6095 fvalue_set_sinteger(fi->value, integer);
6096}
6097
6098/* Add FT_INT{40,48,56,64} to a proto_tree */
6099proto_item *
6100proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6101 int length, int64_t value)
6102{
6103 proto_item *pi = NULL((void*)0);
6104 header_field_info *hfinfo;
6105
6106 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6107
6108 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", 6108
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6108, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6108, "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", 6108, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6109
6110 switch (hfinfo->type) {
6111 case FT_INT40:
6112 case FT_INT48:
6113 case FT_INT56:
6114 case FT_INT64:
6115 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6116 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6117 break;
6118
6119 default:
6120 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)
6121 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6122 }
6123
6124 return pi;
6125}
6126
6127proto_item *
6128proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6129 int start, int length, int64_t value,
6130 const char *format, ...)
6131{
6132 proto_item *pi;
6133 va_list ap;
6134
6135 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6136 if (pi != tree) {
6137 va_start(ap, format)__builtin_va_start(ap, format);
6138 proto_tree_set_representation_value(pi, format, ap);
6139 va_end(ap)__builtin_va_end(ap);
6140 }
6141
6142 return pi;
6143}
6144
6145/* Set the FT_INT{40,48,56,64} value */
6146static void
6147proto_tree_set_int64(field_info *fi, int64_t value)
6148{
6149 const header_field_info *hfinfo;
6150 uint64_t integer;
6151 int no_of_bits;
6152
6153 hfinfo = fi->hfinfo;
6154 integer = value;
6155
6156 if (hfinfo->bitmask) {
6157 /* Mask out irrelevant portions */
6158 integer &= hfinfo->bitmask;
6159
6160 /* Shift bits */
6161 integer >>= hfinfo_bitshift(hfinfo);
6162
6163 no_of_bits = ws_count_ones(hfinfo->bitmask);
6164 integer = ws_sign_ext64(integer, no_of_bits);
6165
6166 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
6167 FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth
(hfinfo)) & 63) << 8)); } while(0)
;
6168 }
6169
6170 fvalue_set_sinteger64(fi->value, integer);
6171}
6172
6173proto_item *
6174proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6175 int start, int length, int64_t value,
6176 const char *format, ...)
6177{
6178 proto_item *pi;
6179 va_list ap;
6180
6181 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6182 if (pi != tree) {
6183 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6183, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6184
6185 va_start(ap, format)__builtin_va_start(ap, format);
6186 proto_tree_set_representation(pi, format, ap);
6187 va_end(ap)__builtin_va_end(ap);
6188 }
6189
6190 return pi;
6191}
6192
6193/* Add a FT_EUI64 to a proto_tree */
6194proto_item *
6195proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6196 int length, const uint64_t value)
6197{
6198 proto_item *pi;
6199 header_field_info *hfinfo;
6200
6201 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6202
6203 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", 6203
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6203, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6203, "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", 6203, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6204
6205 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",
6205, ((hfinfo))->abbrev))))
;
6206
6207 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6208 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6209
6210 return pi;
6211}
6212
6213proto_item *
6214proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6215 int start, int length, const uint64_t value,
6216 const char *format, ...)
6217{
6218 proto_item *pi;
6219 va_list ap;
6220
6221 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6222 if (pi != tree) {
6223 va_start(ap, format)__builtin_va_start(ap, format);
6224 proto_tree_set_representation_value(pi, format, ap);
6225 va_end(ap)__builtin_va_end(ap);
6226 }
6227
6228 return pi;
6229}
6230
6231proto_item *
6232proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6233 int start, int length, const uint64_t value,
6234 const char *format, ...)
6235{
6236 proto_item *pi;
6237 va_list ap;
6238
6239 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6240 if (pi != tree) {
6241 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6241, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6242
6243 va_start(ap, format)__builtin_va_start(ap, format);
6244 proto_tree_set_representation(pi, format, ap);
6245 va_end(ap)__builtin_va_end(ap);
6246 }
6247
6248 return pi;
6249}
6250
6251/* Set the FT_EUI64 value */
6252static void
6253proto_tree_set_eui64(field_info *fi, const uint64_t value)
6254{
6255 fvalue_set_uinteger64(fi->value, value);
6256}
6257static void
6258proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6259{
6260 if (encoding)
6261 {
6262 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6263 } else {
6264 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6265 }
6266}
6267
6268proto_item *
6269proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6270 const mac_hf_list_t *list_generic,
6271 int idx, tvbuff_t *tvb,
6272 proto_tree *tree, int offset)
6273{
6274 const uint8_t addr[6];
6275 const char *addr_name = NULL((void*)0);
6276 const char *oui_name = NULL((void*)0);
6277 proto_item *addr_item = NULL((void*)0);
6278 proto_tree *addr_tree = NULL((void*)0);
6279 proto_item *ret_val = NULL((void*)0);
6280
6281 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6282 return NULL((void*)0);
6283 }
6284
6285 /* Resolve what we can of the address */
6286 tvb_memcpy(tvb, (void *)addr, offset, 6);
6287 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6288 addr_name = get_ether_name(addr);
6289 }
6290 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6291 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6292 }
6293
6294 /* Add the item for the specific address type */
6295 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_NA0x00000000);
6296 if (idx >= 0) {
6297 addr_tree = proto_item_add_subtree(ret_val, idx);
6298 }
6299 else {
6300 addr_tree = tree;
6301 }
6302
6303 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6304 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6305 tvb, offset, 6, addr_name);
6306 proto_item_set_generated(addr_item);
6307 proto_item_set_hidden(addr_item);
6308 }
6309
6310 if (list_specific->hf_oui != NULL((void*)0)) {
6311 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_NA0x00000000);
6312 proto_item_set_generated(addr_item);
6313 proto_item_set_hidden(addr_item);
6314
6315 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6316 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6317 proto_item_set_generated(addr_item);
6318 proto_item_set_hidden(addr_item);
6319 }
6320 }
6321
6322 if (list_specific->hf_lg != NULL((void*)0)) {
6323 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6324 }
6325 if (list_specific->hf_ig != NULL((void*)0)) {
6326 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6327 }
6328
6329 /* Were we given a list for generic address fields? If not, stop here */
6330 if (list_generic == NULL((void*)0)) {
6331 return ret_val;
6332 }
6333
6334 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_NA0x00000000);
6335 proto_item_set_hidden(addr_item);
6336
6337 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6338 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6339 tvb, offset, 6, addr_name);
6340 proto_item_set_generated(addr_item);
6341 proto_item_set_hidden(addr_item);
6342 }
6343
6344 if (list_generic->hf_oui != NULL((void*)0)) {
6345 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_NA0x00000000);
6346 proto_item_set_generated(addr_item);
6347 proto_item_set_hidden(addr_item);
6348
6349 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6350 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6351 proto_item_set_generated(addr_item);
6352 proto_item_set_hidden(addr_item);
6353 }
6354 }
6355
6356 if (list_generic->hf_lg != NULL((void*)0)) {
6357 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6358 proto_item_set_hidden(addr_item);
6359 }
6360 if (list_generic->hf_ig != NULL((void*)0)) {
6361 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6362 proto_item_set_hidden(addr_item);
6363 }
6364 return ret_val;
6365}
6366
6367static proto_item *
6368proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6369{
6370 proto_node *pnode, *tnode, *sibling;
6371 field_info *tfi;
6372 unsigned depth = 1;
6373
6374 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6374, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6375
6376 /*
6377 * Restrict our depth. proto_tree_traverse_pre_order and
6378 * proto_tree_traverse_post_order (and possibly others) are recursive
6379 * so we need to be mindful of our stack size.
6380 */
6381 if (tree->first_child == NULL((void*)0)) {
6382 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6383 depth++;
6384 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6385 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__)), 6388)))
6386 "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__)), 6388)))
6387 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__)), 6388)))
6388 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__)), 6388)))
;
6389 }
6390 }
6391 }
6392
6393 /*
6394 * Make sure "tree" is ready to have subtrees under it, by
6395 * checking whether it's been given an ett_ value.
6396 *
6397 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6398 * node of the protocol tree. That node is not displayed,
6399 * so it doesn't need an ett_ value to remember whether it
6400 * was expanded.
6401 */
6402 tnode = tree;
6403 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6404 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6405 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"
, 6406)
6406 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"
, 6406)
;
6407 /* XXX - is it safe to continue here? */
6408 }
6409
6410 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6411 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6412 pnode->parent = tnode;
6413 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6414 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6415 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6416
6417 if (tnode->last_child != NULL((void*)0)) {
6418 sibling = tnode->last_child;
6419 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6419, "sibling->next == ((void*)0)"
))))
;
6420 sibling->next = pnode;
6421 } else
6422 tnode->first_child = pnode;
6423 tnode->last_child = pnode;
6424
6425 /* We should not be adding a fake node for an interesting field */
6426 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", 6426, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6427
6428 /* XXX - Should the proto_item have a header_field_info member, at least
6429 * for faked items, to know what hfi was faked? (Some dissectors look at
6430 * the tree items directly.)
6431 */
6432 return (proto_item *)pnode;
6433}
6434
6435/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6436static proto_item *
6437proto_tree_add_node(proto_tree *tree, field_info *fi)
6438{
6439 proto_node *pnode, *tnode, *sibling;
6440 field_info *tfi;
6441 unsigned depth = 1;
6442
6443 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6443, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6444
6445 /*
6446 * Restrict our depth. proto_tree_traverse_pre_order and
6447 * proto_tree_traverse_post_order (and possibly others) are recursive
6448 * so we need to be mindful of our stack size.
6449 */
6450 if (tree->first_child == NULL((void*)0)) {
6451 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6452 depth++;
6453 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6454 fvalue_free(fi->value);
6455 fi->value = NULL((void*)0);
6456 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__)), 6459)))
6457 "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__)), 6459)))
6458 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__)), 6459)))
6459 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__)), 6459)))
;
6460 }
6461 }
6462 }
6463
6464 /*
6465 * Make sure "tree" is ready to have subtrees under it, by
6466 * checking whether it's been given an ett_ value.
6467 *
6468 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6469 * node of the protocol tree. That node is not displayed,
6470 * so it doesn't need an ett_ value to remember whether it
6471 * was expanded.
6472 */
6473 tnode = tree;
6474 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6475 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6476 /* Since we are not adding fi to a node, its fvalue won't get
6477 * freed by proto_tree_free_node(), so free it now.
6478 */
6479 fvalue_free(fi->value);
6480 fi->value = NULL((void*)0);
6481 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", 6482)
6482 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", 6482)
;
6483 /* XXX - is it safe to continue here? */
6484 }
6485
6486 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6487 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6488 pnode->parent = tnode;
6489 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6490 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6491 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6492
6493 if (tnode->last_child != NULL((void*)0)) {
6494 sibling = tnode->last_child;
6495 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6495, "sibling->next == ((void*)0)"
))))
;
6496 sibling->next = pnode;
6497 } else
6498 tnode->first_child = pnode;
6499 tnode->last_child = pnode;
6500
6501 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6502
6503 return (proto_item *)pnode;
6504}
6505
6506
6507/* Generic way to allocate field_info and add to proto_tree.
6508 * Sets *pfi to address of newly-allocated field_info struct */
6509static proto_item *
6510proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6511 int *length)
6512{
6513 proto_item *pi;
6514 field_info *fi;
6515 int item_length;
6516
6517 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6518 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6519 pi = proto_tree_add_node(tree, fi);
6520
6521 return pi;
6522}
6523
6524
6525static void
6526get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6527 int *item_length, const unsigned encoding)
6528{
6529 int length_remaining;
6530
6531 /*
6532 * We only allow a null tvbuff if the item has a zero length,
6533 * i.e. if there's no data backing it.
6534 */
6535 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", 6535, "tvb != ((void*)0) || *length == 0"
))))
;
6536
6537 /*
6538 * XXX - in some protocols, there are 32-bit unsigned length
6539 * fields, so lengths in protocol tree and tvbuff routines
6540 * should really be unsigned. We should have, for those
6541 * field types for which "to the end of the tvbuff" makes sense,
6542 * additional routines that take no length argument and
6543 * add fields that run to the end of the tvbuff.
6544 */
6545 if (*length == -1) {
6546 /*
6547 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6548 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6549 * of -1 means "set the length to what remains in the
6550 * tvbuff".
6551 *
6552 * The assumption is either that
6553 *
6554 * 1) the length of the item can only be determined
6555 * by dissection (typically true of items with
6556 * subitems, which are probably FT_NONE or
6557 * FT_PROTOCOL)
6558 *
6559 * or
6560 *
6561 * 2) if the tvbuff is "short" (either due to a short
6562 * snapshot length or due to lack of reassembly of
6563 * fragments/segments/whatever), we want to display
6564 * what's available in the field (probably FT_BYTES
6565 * or FT_STRING) and then throw an exception later
6566 *
6567 * or
6568 *
6569 * 3) the field is defined to be "what's left in the
6570 * packet"
6571 *
6572 * so we set the length to what remains in the tvbuff so
6573 * that, if we throw an exception while dissecting, it
6574 * has what is probably the right value.
6575 *
6576 * For FT_STRINGZ, it means "the string is null-terminated,
6577 * not null-padded; set the length to the actual length
6578 * of the string", and if the tvbuff if short, we just
6579 * throw an exception.
6580 *
6581 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV, it means "find the end of the string",
6582 * and if the tvbuff if short, we just throw an exception.
6583 *
6584 * It's not valid for any other type of field. For those
6585 * fields, we treat -1 the same way we treat other
6586 * negative values - we assume the length is a Really
6587 * Big Positive Number, and throw a ReportedBoundsError
6588 * exception, under the assumption that the Really Big
6589 * Length would run past the end of the packet.
6590 */
6591 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
))
)) {
6592 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6593 /*
6594 * Leave the length as -1, so our caller knows
6595 * it was -1.
6596 */
6597 *item_length = *length;
6598 return;
6599 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6600 switch (tvb_get_uint8(tvb, start) >> 6)
6601 {
6602 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6603 *item_length = 1;
6604 break;
6605 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6606 *item_length = 2;
6607 break;
6608 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6609 *item_length = 4;
6610 break;
6611 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6612 *item_length = 8;
6613 break;
6614 }
6615 }
6616 }
6617
6618 switch (hfinfo->type) {
6619
6620 case FT_PROTOCOL:
6621 case FT_NONE:
6622 case FT_BYTES:
6623 case FT_STRING:
6624 case FT_STRINGZPAD:
6625 case FT_STRINGZTRUNC:
6626 /*
6627 * We allow FT_PROTOCOLs to be zero-length -
6628 * for example, an ONC RPC NULL procedure has
6629 * neither arguments nor reply, so the
6630 * payload for that protocol is empty.
6631 *
6632 * We also allow the others to be zero-length -
6633 * because that's the way the code has been for a
6634 * long, long time.
6635 *
6636 * However, we want to ensure that the start
6637 * offset is not *past* the byte past the end
6638 * of the tvbuff: we throw an exception in that
6639 * case.
6640 */
6641 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6642 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6642, "*length >= 0"
))))
;
6643 break;
6644
6645 case FT_STRINGZ:
6646 /*
6647 * Leave the length as -1, so our caller knows
6648 * it was -1.
6649 */
6650 break;
6651
6652 default:
6653 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6654 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6654))
;
6655 }
6656 *item_length = *length;
6657 } else {
6658 *item_length = *length;
6659 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6660 /*
6661 * These types are for interior nodes of the
6662 * tree, and don't have data associated with
6663 * them; if the length is negative (XXX - see
6664 * above) or goes past the end of the tvbuff,
6665 * cut it short at the end of the tvbuff.
6666 * That way, if this field is selected in
6667 * Wireshark, we don't highlight stuff past
6668 * the end of the data.
6669 */
6670 /* XXX - what to do, if we don't have a tvb? */
6671 if (tvb) {
6672 length_remaining = tvb_captured_length_remaining(tvb, start);
6673 if (*item_length < 0 ||
6674 (*item_length > 0 &&
6675 (length_remaining < *item_length)))
6676 *item_length = length_remaining;
6677 }
6678 }
6679 if (*item_length < 0) {
6680 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6681 }
6682 }
6683}
6684
6685static int
6686get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6687 int length, unsigned item_length, const int encoding)
6688{
6689 uint32_t n;
6690
6691 /*
6692 * We need to get the correct item length here.
6693 * That's normally done by proto_tree_new_item(),
6694 * but we won't be calling it.
6695 */
6696 switch (hfinfo->type) {
6697
6698 case FT_NONE:
6699 case FT_PROTOCOL:
6700 case FT_BYTES:
6701 /*
6702 * The length is the specified length.
6703 */
6704 break;
6705
6706 case FT_UINT_BYTES:
6707 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6708 item_length += n;
6709 if ((int)item_length < length) {
6710 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6711 }
6712 break;
6713
6714 /* XXX - make these just FT_UINT? */
6715 case FT_UINT8:
6716 case FT_UINT16:
6717 case FT_UINT24:
6718 case FT_UINT32:
6719 case FT_UINT40:
6720 case FT_UINT48:
6721 case FT_UINT56:
6722 case FT_UINT64:
6723 /* XXX - make these just FT_INT? */
6724 case FT_INT8:
6725 case FT_INT16:
6726 case FT_INT24:
6727 case FT_INT32:
6728 case FT_INT40:
6729 case FT_INT48:
6730 case FT_INT56:
6731 case FT_INT64:
6732 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6733 if (length < -1) {
6734 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6735 }
6736 if (length == -1) {
6737 uint64_t dummy;
6738 /* This can throw an exception */
6739 /* XXX - do this without fetching the varint? */
6740 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6741 if (length == 0) {
6742 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6743 }
6744 }
6745 item_length = length;
6746 break;
6747 }
6748
6749 /*
6750 * The length is the specified length.
6751 */
6752 break;
6753
6754 case FT_BOOLEAN:
6755 case FT_CHAR:
6756 case FT_IPv4:
6757 case FT_IPXNET:
6758 case FT_IPv6:
6759 case FT_FCWWN:
6760 case FT_AX25:
6761 case FT_VINES:
6762 case FT_ETHER:
6763 case FT_EUI64:
6764 case FT_GUID:
6765 case FT_OID:
6766 case FT_REL_OID:
6767 case FT_SYSTEM_ID:
6768 case FT_FLOAT:
6769 case FT_DOUBLE:
6770 case FT_STRING:
6771 /*
6772 * The length is the specified length.
6773 */
6774 break;
6775
6776 case FT_STRINGZ:
6777 if (length < -1) {
6778 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6779 }
6780 if (length == -1) {
6781 /* This can throw an exception */
6782 /* XXX - do this without fetching the string? */
6783 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6784 }
6785 item_length = length;
6786 break;
6787
6788 case FT_UINT_STRING:
6789 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6790 item_length += n;
6791 if ((int)item_length < length) {
6792 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6793 }
6794 break;
6795
6796 case FT_STRINGZPAD:
6797 case FT_STRINGZTRUNC:
6798 case FT_ABSOLUTE_TIME:
6799 case FT_RELATIVE_TIME:
6800 case FT_IEEE_11073_SFLOAT:
6801 case FT_IEEE_11073_FLOAT:
6802 /*
6803 * The length is the specified length.
6804 */
6805 break;
6806
6807 default:
6808 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
))
6809 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
))
6810 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
))
6811 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
))
;
6812 break;
6813 }
6814 return item_length;
6815}
6816
6817// This was arbitrarily chosen, but if you're adding 50K items to the tree
6818// without advancing the offset you should probably take a long, hard look
6819// at what you're doing.
6820// We *could* make this a configurable option, but I (Gerald) would like to
6821// avoid adding yet another nerd knob.
6822# define PROTO_TREE_MAX_IDLE50000 50000
6823static field_info *
6824new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6825 const int start, const int item_length)
6826{
6827 field_info *fi;
6828
6829 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6830
6831 fi->hfinfo = hfinfo;
6832 fi->start = start;
6833 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6834 // If our start offset hasn't advanced after adding many items it probably
6835 // means we're in a large or infinite loop.
6836 if (fi->start > 0) {
6837 if (fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6838 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6839 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", 6839, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6840 } else {
6841 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6842 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6843 }
6844 }
6845 fi->length = item_length;
6846 fi->tree_type = -1;
6847 fi->flags = 0;
6848 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6849 /* If the tree is not visible, set the item hidden, unless we
6850 * need the representation or length and can't fake them.
6851 */
6852 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6853 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6854 }
6855 }
6856 fi->value = fvalue_new(fi->hfinfo->type);
6857 fi->rep = NULL((void*)0);
6858
6859 /* add the data source tvbuff */
6860 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6861
6862 fi->appendix_start = 0;
6863 fi->appendix_length = 0;
6864
6865 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6866 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6867
6868 return fi;
6869}
6870
6871static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6872{
6873 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6874 return 0;
6875 }
6876
6877 /* Search for field name */
6878 char *ptr = strstr(representation, hfinfo->name);
6879 if (!ptr) {
6880 return 0;
6881 }
6882
6883 /* Check if field name ends with the ": " delimiter */
6884 ptr += strlen(hfinfo->name);
6885 if (strncmp(ptr, ": ", 2) == 0) {
6886 ptr += 2;
6887 }
6888
6889 /* Return offset to after field name */
6890 return ptr - representation;
6891}
6892
6893/* If the protocol tree is to be visible, set the representation of a
6894 proto_tree entry with the name of the field for the item and with
6895 the value formatted with the supplied printf-style format and
6896 argument list. */
6897static void
6898proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6899{
6900 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6900, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6901
6902 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6903 * items string representation */
6904 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6905 size_t name_pos, ret = 0;
6906 char *str;
6907 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6908 const header_field_info *hf;
6909
6910 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6910, "fi"))))
;
6911
6912 hf = fi->hfinfo;
6913
6914 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;
;
6915 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))
)) {
6916 uint64_t val;
6917 char *p;
6918
6919 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)
)
6920 val = fvalue_get_uinteger(fi->value);
6921 else
6922 val = fvalue_get_uinteger64(fi->value);
6923
6924 val <<= hfinfo_bitshift(hf);
6925
6926 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6927 ret = (p - fi->rep->representation);
6928 }
6929
6930 /* put in the hf name */
6931 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
6932
6933 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
6934 /* If possible, Put in the value of the string */
6935 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6936 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"
, 6936, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6937 fi->rep->value_pos = ret;
6938 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
6939 if (ret >= ITEM_LABEL_LENGTH240) {
6940 /* Uh oh, we don't have enough room. Tell the user
6941 * that the field is truncated.
6942 */
6943 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6944 }
6945 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6946 }
6947}
6948
6949/* If the protocol tree is to be visible, set the representation of a
6950 proto_tree entry with the representation formatted with the supplied
6951 printf-style format and argument list. */
6952static void
6953proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6954{
6955 size_t ret; /*tmp return value */
6956 char *str;
6957 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6958
6959 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6959, "fi"))))
;
6960
6961 if (!proto_item_is_hidden(pi)) {
6962 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;
;
6963
6964 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6965 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"
, 6965, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6966 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
6967 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
6968 if (ret >= ITEM_LABEL_LENGTH240) {
6969 /* Uh oh, we don't have enough room. Tell the user
6970 * that the field is truncated.
6971 */
6972 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
6973 }
6974 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6975 }
6976}
6977
6978static int
6979protoo_strlcpy(char *dest, const char *src, size_t dest_size)
6980{
6981 if (dest_size == 0) return 0;
6982
6983 size_t res = g_strlcpy(dest, src, dest_size);
6984
6985 /* At most dest_size - 1 characters will be copied
6986 * (unless dest_size is 0). */
6987 if (res >= dest_size)
6988 res = dest_size - 1;
6989 return (int) res;
6990}
6991
6992static header_field_info *
6993hfinfo_same_name_get_prev(const header_field_info *hfinfo)
6994{
6995 header_field_info *dup_hfinfo;
6996
6997 if (hfinfo->same_name_prev_id == -1)
6998 return NULL((void*)0);
6999 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", 6999
, __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", 6999, "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", 6999,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7000 return dup_hfinfo;
7001}
7002
7003static void
7004hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7005{
7006 g_free(last_field_name);
7007 last_field_name = NULL((void*)0);
7008
7009 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7010 /* No hfinfo with the same name */
7011 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
7012 return;
7013 }
7014
7015 if (hfinfo->same_name_next) {
7016 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7017 }
7018
7019 if (hfinfo->same_name_prev_id != -1) {
7020 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7021 same_name_prev->same_name_next = hfinfo->same_name_next;
7022 if (!hfinfo->same_name_next) {
7023 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7024 g_hash_table_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7025 }
7026 }
7027}
7028
7029int
7030proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7031{
7032 const header_field_info *hfinfo = finfo->hfinfo;
7033 int label_len = 0;
7034 char *tmp_str;
7035 const char *str;
7036 const uint8_t *bytes;
7037 uint32_t number;
7038 uint64_t number64;
7039 const char *hf_str_val;
7040 char number_buf[NUMBER_LABEL_LENGTH80];
7041 const char *number_out;
7042 address addr;
7043 const ipv4_addr_and_mask *ipv4;
7044 const ipv6_addr_and_prefix *ipv6;
7045
7046 switch (hfinfo->type) {
7047
7048 case FT_NONE:
7049 case FT_PROTOCOL:
7050 return protoo_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7051
7052 case FT_UINT_BYTES:
7053 case FT_BYTES:
7054 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7055 hfinfo,
7056 fvalue_get_bytes_data(finfo->value),
7057 (unsigned)fvalue_length2(finfo->value),
7058 label_str_size);
7059 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7060 wmem_free(NULL((void*)0), tmp_str);
7061 break;
7062
7063 case FT_ABSOLUTE_TIME:
7064 {
7065 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7066 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7067 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7068 }
7069 tmp_str = abs_time_to_str_ex(NULL((void*)0), fvalue_get_time(finfo->value), hfinfo->display, flags);
7070 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7071 wmem_free(NULL((void*)0), tmp_str);
7072 break;
7073 }
7074
7075 case FT_RELATIVE_TIME:
7076 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7077 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7078 wmem_free(NULL((void*)0), tmp_str);
7079 break;
7080
7081 case FT_BOOLEAN:
7082 number64 = fvalue_get_uinteger64(finfo->value);
7083 label_len = protoo_strlcpy(display_label_str,
7084 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7085 break;
7086
7087 case FT_CHAR:
7088 number = fvalue_get_uinteger(finfo->value);
7089
7090 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7091 char tmp[ITEM_LABEL_LENGTH240];
7092 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7093
7094 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7094, "fmtfunc"))))
;
7095 fmtfunc(tmp, number);
7096
7097 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
7098
7099 } else if (hfinfo->strings) {
7100 number_out = hf_try_val_to_str(number, hfinfo);
7101
7102 if (!number_out) {
7103 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7104 }
7105
7106 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7107
7108 } else {
7109 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7110
7111 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7112 }
7113
7114 break;
7115
7116 /* XXX - make these just FT_NUMBER? */
7117 case FT_INT8:
7118 case FT_INT16:
7119 case FT_INT24:
7120 case FT_INT32:
7121 case FT_UINT8:
7122 case FT_UINT16:
7123 case FT_UINT24:
7124 case FT_UINT32:
7125 case FT_FRAMENUM:
7126 hf_str_val = NULL((void*)0);
7127 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
))
?
7128 (uint32_t) fvalue_get_sinteger(finfo->value) :
7129 fvalue_get_uinteger(finfo->value);
7130
7131 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7132 char tmp[ITEM_LABEL_LENGTH240];
7133 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7134
7135 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7135, "fmtfunc"))))
;
7136 fmtfunc(tmp, number);
7137
7138 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
7139
7140 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7141 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7142 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7143 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7144 hf_str_val = hf_try_val_to_str(number, hfinfo);
7145 label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7146 } else {
7147 number_out = hf_try_val_to_str(number, hfinfo);
7148
7149 if (!number_out) {
7150 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7151 }
7152
7153 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7154 }
7155 } else {
7156 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7157
7158 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7159 }
7160
7161 break;
7162
7163 case FT_INT40:
7164 case FT_INT48:
7165 case FT_INT56:
7166 case FT_INT64:
7167 case FT_UINT40:
7168 case FT_UINT48:
7169 case FT_UINT56:
7170 case FT_UINT64:
7171 hf_str_val = NULL((void*)0);
7172 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
))
?
7173 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7174 fvalue_get_uinteger64(finfo->value);
7175
7176 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7177 char tmp[ITEM_LABEL_LENGTH240];
7178 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7179
7180 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7180, "fmtfunc64"
))))
;
7181 fmtfunc64(tmp, number64);
7182
7183 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
7184 } else if (hfinfo->strings) {
7185 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7186 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7187 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7188 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7189 label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7190 } else {
7191 number_out = hf_try_val64_to_str(number64, hfinfo);
7192
7193 if (!number_out)
7194 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7195
7196 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7197 }
7198 } else {
7199 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7200
7201 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7202 }
7203
7204 break;
7205
7206 case FT_EUI64:
7207 tmp_str = eui64_to_str(NULL((void*)0), fvalue_get_uinteger64(finfo->value));
7208 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7209 wmem_free(NULL((void*)0), tmp_str);
7210 break;
7211
7212 case FT_IPv4:
7213 ipv4 = fvalue_get_ipv4(finfo->value);
7214 //XXX: Should we ignore the mask?
7215 set_address_ipv4(&addr, ipv4);
7216 tmp_str = address_to_display(NULL((void*)0), &addr);
7217 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7218 wmem_free(NULL((void*)0), tmp_str);
7219 free_address(&addr);
7220 break;
7221
7222 case FT_IPv6:
7223 ipv6 = fvalue_get_ipv6(finfo->value);
7224 set_address_ipv6(&addr, ipv6);
7225 tmp_str = address_to_display(NULL((void*)0), &addr);
7226 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7227 wmem_free(NULL((void*)0), tmp_str);
7228 free_address(&addr);
7229 break;
7230
7231 case FT_FCWWN:
7232 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7233 tmp_str = address_to_display(NULL((void*)0), &addr);
7234 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7235 wmem_free(NULL((void*)0), tmp_str);
7236 break;
7237
7238 case FT_ETHER:
7239 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7240 tmp_str = address_to_display(NULL((void*)0), &addr);
7241 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7242 wmem_free(NULL((void*)0), tmp_str);
7243 break;
7244
7245 case FT_GUID:
7246 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7247 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7248 wmem_free(NULL((void*)0), tmp_str);
7249 break;
7250
7251 case FT_REL_OID:
7252 bytes = fvalue_get_bytes_data(finfo->value);
7253 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7254 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7255 wmem_free(NULL((void*)0), tmp_str);
7256 break;
7257
7258 case FT_OID:
7259 bytes = fvalue_get_bytes_data(finfo->value);
7260 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7261 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7262 wmem_free(NULL((void*)0), tmp_str);
7263 break;
7264
7265 case FT_SYSTEM_ID:
7266 bytes = fvalue_get_bytes_data(finfo->value);
7267 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7268 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7269 wmem_free(NULL((void*)0), tmp_str);
7270 break;
7271
7272 case FT_FLOAT:
7273 case FT_DOUBLE:
7274 label_len = (int)fill_display_label_float(finfo, display_label_str);
7275 break;
7276
7277 case FT_STRING:
7278 case FT_STRINGZ:
7279 case FT_UINT_STRING:
7280 case FT_STRINGZPAD:
7281 case FT_STRINGZTRUNC:
7282 str = fvalue_get_string(finfo->value);
7283 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7284 if (label_len >= label_str_size) {
7285 /* Truncation occurred. Get the real length
7286 * copied (not including '\0') */
7287 label_len = label_str_size ? label_str_size - 1 : 0;
7288 }
7289 break;
7290
7291 default:
7292 /* First try ftype string representation */
7293 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7294 if (!tmp_str) {
7295 /* Default to show as bytes */
7296 bytes = fvalue_get_bytes_data(finfo->value);
7297 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7298 }
7299 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7300 wmem_free(NULL((void*)0), tmp_str);
7301 break;
7302 }
7303 return label_len;
7304}
7305
7306/* -------------------------- */
7307/* Sets the text for a custom column from proto fields.
7308 *
7309 * @param[out] result The "resolved" column text (human readable, uses strings)
7310 * @param[out] expr The "unresolved" column text (values, display repr)
7311 * @return The filter (abbrev) for the field (XXX: Only the first if multifield)
7312 */
7313const char *
7314proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7315 char *result, char *expr, const int size)
7316{
7317 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7318 GPtrArray *finfos;
7319 field_info *finfo = NULL((void*)0);
7320 header_field_info* hfinfo;
7321 const char *abbrev = NULL((void*)0);
7322
7323 const char *hf_str_val;
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 += protoo_strlcpy(result+offset_r, str, size-offset_r);
7377 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
7378 g_free(str);
7379 }
7380 g_ptr_array_unref(fvals);
7381 } else if (passed) {
7382 // XXX - Occurrence doesn't make sense for a test
7383 // output, it should be applied to the operands.
7384 if (offset_r && (offset_r < (size - 1)))
7385 result[offset_r++] = ',';
7386 if (offset_e && (offset_e < (size - 1)))
7387 expr[offset_e++] = ',';
7388 /* Prevent multiple check marks */
7389 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7390 offset_r += protoo_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7391 } else {
7392 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7393 }
7394 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7395 offset_e += protoo_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7396 } else {
7397 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7398 }
7399 }
7400 continue;
7401 }
7402 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", 7402
, __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", 7402,
"(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", 7402,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7403
7404 /* do we need to rewind ? */
7405 if (!hfinfo)
7406 return "";
7407
7408 if (occurrence < 0) {
7409 /* Search other direction */
7410 while (hfinfo->same_name_prev_id != -1) {
7411 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", 7411
, __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", 7411, "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", 7411,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7412 }
7413 }
7414
7415 prev_len = 0; /* Reset handled occurrences */
7416
7417 while (hfinfo) {
7418 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7419
7420 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7421 if (occurrence < 0) {
7422 hfinfo = hfinfo->same_name_next;
7423 } else {
7424 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7425 }
7426 continue;
7427 }
7428
7429 /* Are there enough occurrences of the field? */
7430 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7431 if (occurrence < 0) {
7432 hfinfo = hfinfo->same_name_next;
7433 } else {
7434 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7435 }
7436 prev_len += len;
7437 continue;
7438 }
7439
7440 /* Calculate single index or set outer boundaries */
7441 if (occurrence < 0) {
7442 i = occurrence + len + prev_len;
7443 last = i;
7444 } else if (occurrence > 0) {
7445 i = occurrence - 1 - prev_len;
7446 last = i;
7447 } else {
7448 i = 0;
7449 last = len - 1;
7450 }
7451
7452 prev_len += len; /* Count handled occurrences */
7453
7454 while (i <= last) {
7455 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7456
7457 if (offset_r && (offset_r < (size - 1)))
7458 result[offset_r++] = ',';
7459
7460 if (display_details) {
7461 char representation[ITEM_LABEL_LENGTH240];
7462 size_t offset = 0;
7463
7464 if (finfo->rep && finfo->rep->value_len) {
7465 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7466 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7467 } else {
7468 proto_item_fill_label(finfo, representation, &offset);
7469 }
7470 offset_r += protoo_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7471 } else {
7472 switch (hfinfo->type) {
7473
7474 case FT_NONE:
7475 case FT_PROTOCOL:
7476 /* Prevent multiple check marks */
7477 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7478 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7479 } else {
7480 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7481 }
7482 break;
7483
7484 default:
7485 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7486 break;
7487 }
7488 }
7489
7490 if (offset_e && (offset_e < (size - 1)))
7491 expr[offset_e++] = ',';
7492
7493 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
))
)) {
7494 /* Integer types with BASE_NONE never get the numeric value. */
7495 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7496 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7497 } 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
)
) {
7498 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7499 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7500 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7501 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7502 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7503 }
7504 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7505 offset_e = (int)strlen(expr);
7506 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7507 /* Prevent multiple check marks */
7508 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7509 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7510 } else {
7511 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7512 }
7513 } else {
7514 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7515 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
7516 wmem_free(NULL((void*)0), str);
7517 }
7518 i++;
7519 }
7520
7521 /* XXX: Why is only the first abbreviation returned for a multifield
7522 * custom column? */
7523 if (!abbrev) {
7524 /* Store abbrev for return value */
7525 abbrev = hfinfo->abbrev;
7526 }
7527
7528 if (occurrence == 0) {
7529 /* Fetch next hfinfo with same name (abbrev) */
7530 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7531 } else {
7532 hfinfo = NULL((void*)0);
7533 }
7534 }
7535 }
7536
7537 if (offset_r >= (size - 1)) {
7538 mark_truncated(result, 0, size, NULL((void*)0));
7539 }
7540 if (offset_e >= (size - 1)) {
7541 mark_truncated(expr, 0, size, NULL((void*)0));
7542 }
7543 return abbrev ? abbrev : "";
7544}
7545
7546char *
7547proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7548{
7549 int len, prev_len, last, i;
7550 GPtrArray *finfos;
7551 field_info *finfo = NULL((void*)0);
7552 header_field_info* hfinfo;
7553
7554 char *filter = NULL((void*)0);
7555 GPtrArray *filter_array;
7556
7557 col_custom_t *col_custom;
7558 int field_id;
7559
7560 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7560, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7561 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7562 for (GSList *iter = field_ids; iter; iter = iter->next) {
7563 col_custom = (col_custom_t*)iter->data;
7564 field_id = col_custom->field_id;
7565 if (field_id == 0) {
7566 GPtrArray *fvals = NULL((void*)0);
7567 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7568 if (fvals != NULL((void*)0)) {
7569 // XXX - Handling occurrences is unusual when more
7570 // than one field is involved, e.g. there's four
7571 // results for tcp.port + tcp.port. We really
7572 // want to apply it to the operands, not the output.
7573 /* Calculate single index or set outer boundaries */
7574 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7575 if (occurrence < 0) {
7576 i = occurrence + len;
7577 last = i;
7578 } else if (occurrence > 0) {
7579 i = occurrence - 1;
7580 last = i;
7581 } else {
7582 i = 0;
7583 last = len - 1;
7584 }
7585 if (i < 0 || i >= len) {
7586 g_ptr_array_unref(fvals);
7587 continue;
7588 }
7589 for (; i <= last; i++) {
7590 /* XXX - Should multiple values for one
7591 * field use set membership to reduce
7592 * verbosity, here and below? */
7593 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7594 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7595 wmem_free(NULL((void*)0), str);
7596 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7597 g_ptr_array_add(filter_array, filter);
7598 }
7599 }
7600 g_ptr_array_unref(fvals);
7601 } else if (passed) {
7602 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7603 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7604 g_ptr_array_add(filter_array, filter);
7605 }
7606 } else {
7607 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7608 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7609 g_ptr_array_add(filter_array, filter);
7610 }
7611 }
7612 continue;
7613 }
7614
7615 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", 7615
, __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", 7615,
"(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", 7615,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7616
7617 /* do we need to rewind ? */
7618 if (!hfinfo)
7619 return NULL((void*)0);
7620
7621 if (occurrence < 0) {
7622 /* Search other direction */
7623 while (hfinfo->same_name_prev_id != -1) {
7624 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", 7624
, __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", 7624, "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", 7624,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7625 }
7626 }
7627
7628 prev_len = 0; /* Reset handled occurrences */
7629
7630 while (hfinfo) {
7631 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7632
7633 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7634 if (occurrence < 0) {
7635 hfinfo = hfinfo->same_name_next;
7636 } else {
7637 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7638 }
7639 continue;
7640 }
7641
7642 /* Are there enough occurrences of the field? */
7643 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7644 if (occurrence < 0) {
7645 hfinfo = hfinfo->same_name_next;
7646 } else {
7647 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7648 }
7649 prev_len += len;
7650 continue;
7651 }
7652
7653 /* Calculate single index or set outer boundaries */
7654 if (occurrence < 0) {
7655 i = occurrence + len + prev_len;
7656 last = i;
7657 } else if (occurrence > 0) {
7658 i = occurrence - 1 - prev_len;
7659 last = i;
7660 } else {
7661 i = 0;
7662 last = len - 1;
7663 }
7664
7665 prev_len += len; /* Count handled occurrences */
7666
7667 while (i <= last) {
7668 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7669
7670 filter = proto_construct_match_selected_string(finfo, edt);
7671 if (filter) {
7672 /* Only add the same expression once (especially for FT_PROTOCOL).
7673 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7674 */
7675 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7676 g_ptr_array_add(filter_array, filter);
7677 }
7678 }
7679 i++;
7680 }
7681
7682 if (occurrence == 0) {
7683 /* Fetch next hfinfo with same name (abbrev) */
7684 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7685 } else {
7686 hfinfo = NULL((void*)0);
7687 }
7688 }
7689 }
7690
7691 g_ptr_array_add(filter_array, NULL((void*)0));
7692
7693 /* XXX: Should this be || or && ? */
7694 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7695
7696 g_ptr_array_free(filter_array, true1);
7697
7698 return output;
7699}
7700
7701/* Set text of proto_item after having already been created. */
7702void
7703proto_item_set_text(proto_item *pi, const char *format, ...)
7704{
7705 field_info *fi = NULL((void*)0);
7706 va_list ap;
7707
7708 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7709
7710 fi = PITEM_FINFO(pi)((pi)->finfo);
7711 if (fi == NULL((void*)0))
7712 return;
7713
7714 if (fi->rep) {
7715 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7716 fi->rep = NULL((void*)0);
7717 }
7718
7719 va_start(ap, format)__builtin_va_start(ap, format);
7720 proto_tree_set_representation(pi, format, ap);
7721 va_end(ap)__builtin_va_end(ap);
7722}
7723
7724/* Append to text of proto_item after having already been created. */
7725void
7726proto_item_append_text(proto_item *pi, const char *format, ...)
7727{
7728 field_info *fi = NULL((void*)0);
7729 size_t curlen;
7730 char *str;
7731 va_list ap;
7732
7733 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7734
7735 fi = PITEM_FINFO(pi)((pi)->finfo);
7736 if (fi == NULL((void*)0)) {
7737 return;
7738 }
7739
7740 if (!proto_item_is_hidden(pi)) {
7741 /*
7742 * If we don't already have a representation,
7743 * generate the default representation.
7744 */
7745 if (fi->rep == NULL((void*)0)) {
7746 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;
;
7747 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7748 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7749 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7750 (strncmp(format, ": ", 2) == 0)) {
7751 fi->rep->value_pos += 2;
7752 }
7753 }
7754 if (fi->rep) {
7755 curlen = strlen(fi->rep->representation);
7756 /* curlen doesn't include the \0 byte.
7757 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7758 * the representation has already been truncated (of an up
7759 * to 4 byte UTF-8 character) or is just at the maximum length
7760 * unless we search for " [truncated]" (which may not be
7761 * at the start.)
7762 * It's safer to do nothing.
7763 */
7764 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7765 va_start(ap, format)__builtin_va_start(ap, format);
7766 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7767 va_end(ap)__builtin_va_end(ap);
7768 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"
, 7768, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7769 /* Keep fi->rep->value_pos */
7770 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7771 if (curlen >= ITEM_LABEL_LENGTH240) {
7772 /* Uh oh, we don't have enough room. Tell the user
7773 * that the field is truncated.
7774 */
7775 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7776 }
7777 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7778 }
7779 }
7780 }
7781}
7782
7783/* Prepend to text of proto_item after having already been created. */
7784void
7785proto_item_prepend_text(proto_item *pi, const char *format, ...)
7786{
7787 field_info *fi = NULL((void*)0);
7788 size_t pos;
7789 char representation[ITEM_LABEL_LENGTH240];
7790 char *str;
7791 va_list ap;
7792
7793 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7794
7795 fi = PITEM_FINFO(pi)((pi)->finfo);
7796 if (fi == NULL((void*)0)) {
7797 return;
7798 }
7799
7800 if (!proto_item_is_hidden(pi)) {
7801 /*
7802 * If we don't already have a representation,
7803 * generate the default representation.
7804 */
7805 if (fi->rep == NULL((void*)0)) {
7806 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;
;
7807 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7808 } else
7809 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7810
7811 va_start(ap, format)__builtin_va_start(ap, format);
7812 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7813 va_end(ap)__builtin_va_end(ap);
7814 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"
, 7814, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7815 fi->rep->value_pos += strlen(str);
7816 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7817 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7818 /* XXX: As above, if the old representation is close to the label
7819 * length, it might already be marked as truncated. */
7820 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7821 /* Uh oh, we don't have enough room. Tell the user
7822 * that the field is truncated.
7823 */
7824 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7825 }
7826 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7827 }
7828}
7829
7830static void
7831finfo_set_len(field_info *fi, const int length)
7832{
7833 int length_remaining;
7834
7835 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", 7835,
"length >= 0", fi->hfinfo->abbrev))))
;
7836 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7837 if (length > length_remaining)
7838 fi->length = length_remaining;
7839 else
7840 fi->length = length;
7841
7842 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7843 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7844 fvalue_set_protocol_length(fi->value, fi->length);
7845 }
7846
7847 /*
7848 * You cannot just make the "len" field of a GByteArray
7849 * larger, if there's no data to back that length;
7850 * you can only make it smaller.
7851 */
7852 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7853 GBytes *bytes = fvalue_get_bytes(fi->value);
7854 size_t size;
7855 const void *data = g_bytes_get_data(bytes, &size);
7856 if ((size_t)fi->length <= size) {
7857 fvalue_set_bytes_data(fi->value, data, fi->length);
7858 }
7859 g_bytes_unref(bytes);
7860 }
7861}
7862
7863void
7864proto_item_set_len(proto_item *pi, const int length)
7865{
7866 field_info *fi;
7867
7868 if (pi == NULL((void*)0))
7869 return;
7870
7871 fi = PITEM_FINFO(pi)((pi)->finfo);
7872 if (fi == NULL((void*)0))
7873 return;
7874
7875 finfo_set_len(fi, length);
7876}
7877
7878/*
7879 * Sets the length of the item based on its start and on the specified
7880 * offset, which is the offset past the end of the item; as the start
7881 * in the item is relative to the beginning of the data source tvbuff,
7882 * we need to pass in a tvbuff - the end offset is relative to the beginning
7883 * of that tvbuff.
7884 */
7885void
7886proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7887{
7888 field_info *fi;
7889 int length;
7890
7891 if (pi == NULL((void*)0))
7892 return;
7893
7894 fi = PITEM_FINFO(pi)((pi)->finfo);
7895 if (fi == NULL((void*)0))
7896 return;
7897
7898 end += tvb_raw_offset(tvb);
7899 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7899, "end >= fi->start"
))))
;
7900 length = end - fi->start;
7901
7902 finfo_set_len(fi, length);
7903}
7904
7905int
7906proto_item_get_len(const proto_item *pi)
7907{
7908 field_info *fi;
7909
7910 if (!pi)
7911 return -1;
7912 fi = PITEM_FINFO(pi)((pi)->finfo);
7913 return fi ? fi->length : -1;
7914}
7915
7916void
7917proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7918 if (!ti) {
7919 return;
7920 }
7921 FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_OFFSET(bits_offset))do { if (((ti)->finfo)) (((ti)->finfo))->flags = (((
ti)->finfo))->flags | ((((bits_offset) & 7) <<
5)); } while(0)
;
7922 FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_SIZE(bits_len))do { if (((ti)->finfo)) (((ti)->finfo))->flags = (((
ti)->finfo))->flags | ((((bits_len) & 63) << 8
)); } while(0)
;
7923}
7924
7925char *
7926proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7927{
7928 field_info *fi;
7929
7930 if (!pi)
7931 return wmem_strdup(scope, "");
7932 fi = PITEM_FINFO(pi)((pi)->finfo);
7933 if (!fi)
7934 return wmem_strdup(scope, "");
7935 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7935, "fi->hfinfo != ((void*)0)"
))))
;
7936 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7937}
7938
7939proto_tree *
7940proto_tree_create_root(packet_info *pinfo)
7941{
7942 proto_node *pnode;
7943
7944 /* Initialize the proto_node */
7945 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
7946 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
7947 pnode->parent = NULL((void*)0);
7948 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
7949 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
7950
7951 /* Make sure we can access pinfo everywhere */
7952 pnode->tree_data->pinfo = pinfo;
7953
7954 /* Don't initialize the tree_data_t. Wait until we know we need it */
7955 pnode->tree_data->interesting_hfids = NULL((void*)0);
7956
7957 /* Set the default to false so it's easier to
7958 * find errors; if we expect to see the protocol tree
7959 * but for some reason the default 'visible' is not
7960 * changed, then we'll find out very quickly. */
7961 pnode->tree_data->visible = false0;
7962
7963 /* Make sure that we fake protocols (if possible) */
7964 pnode->tree_data->fake_protocols = true1;
7965
7966 /* Keep track of the number of children */
7967 pnode->tree_data->count = 0;
7968
7969 /* Initialize our loop checks */
7970 pnode->tree_data->max_start = 0;
7971 pnode->tree_data->start_idle_count = 0;
7972
7973 return (proto_tree *)pnode;
7974}
7975
7976
7977/* "prime" a proto_tree with a single hfid that a dfilter
7978 * is interested in. */
7979void
7980proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
7981{
7982 header_field_info *hfinfo;
7983
7984 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", 7984, __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", 7984, "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", 7984, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
7985 /* this field is referenced by a filter so increase the refcount.
7986 also increase the refcount for the parent, i.e the protocol.
7987 Don't increase the refcount if we're already printing the
7988 type, as that is a superset of direct reference.
7989 */
7990 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
7991 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
7992 }
7993 /* only increase the refcount if there is a parent.
7994 if this is a protocol and not a field then parent will be -1
7995 and there is no parent to add any refcounting for.
7996 */
7997 if (hfinfo->parent != -1) {
7998 header_field_info *parent_hfinfo;
7999 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", 7999
, __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", 7999,
"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", 7999,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8000
8001 /* Mark parent as indirectly referenced unless it is already directly
8002 * referenced, i.e. the user has specified the parent in a filter.
8003 */
8004 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8005 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8006 }
8007}
8008
8009/* "prime" a proto_tree with a single hfid that a dfilter
8010 * is interested in. */
8011void
8012proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8013{
8014 header_field_info *hfinfo;
8015
8016 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", 8016, __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", 8016, "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", 8016, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8017 /* this field is referenced by an (output) filter so increase the refcount.
8018 also increase the refcount for the parent, i.e the protocol.
8019 */
8020 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8021 /* only increase the refcount if there is a parent.
8022 if this is a protocol and not a field then parent will be -1
8023 and there is no parent to add any refcounting for.
8024 */
8025 if (hfinfo->parent != -1) {
8026 header_field_info *parent_hfinfo;
8027 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", 8027
, __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", 8027,
"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", 8027,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8028
8029 /* Mark parent as indirectly referenced unless it is already directly
8030 * referenced, i.e. the user has specified the parent in a filter.
8031 */
8032 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8033 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8034 }
8035}
8036
8037proto_tree *
8038proto_item_add_subtree(proto_item *pi, const int idx) {
8039 field_info *fi;
8040
8041 if (!pi)
8042 return NULL((void*)0);
8043
8044 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", 8044, "idx >= 0 && idx < num_tree_types"
))))
;
8045
8046 fi = PITEM_FINFO(pi)((pi)->finfo);
8047 if (!fi)
8048 return (proto_tree *)pi;
8049
8050 fi->tree_type = idx;
8051
8052 return (proto_tree *)pi;
8053}
8054
8055proto_tree *
8056proto_item_get_subtree(proto_item *pi) {
8057 field_info *fi;
8058
8059 if (!pi)
8060 return NULL((void*)0);
8061 fi = PITEM_FINFO(pi)((pi)->finfo);
8062 if ( (fi) && (fi->tree_type == -1) )
8063 return NULL((void*)0);
8064 return (proto_tree *)pi;
8065}
8066
8067proto_item *
8068proto_item_get_parent(const proto_item *ti) {
8069 if (!ti)
8070 return NULL((void*)0);
8071 return ti->parent;
8072}
8073
8074proto_item *
8075proto_item_get_parent_nth(proto_item *ti, int gen) {
8076 if (!ti)
8077 return NULL((void*)0);
8078 while (gen--) {
8079 ti = ti->parent;
8080 if (!ti)
8081 return NULL((void*)0);
8082 }
8083 return ti;
8084}
8085
8086
8087proto_item *
8088proto_tree_get_parent(proto_tree *tree) {
8089 if (!tree)
8090 return NULL((void*)0);
8091 return (proto_item *)tree;
8092}
8093
8094proto_tree *
8095proto_tree_get_parent_tree(proto_tree *tree) {
8096 if (!tree)
8097 return NULL((void*)0);
8098
8099 /* we're the root tree, there's no parent
8100 return ourselves so the caller has at least a tree to attach to */
8101 if (!tree->parent)
8102 return tree;
8103
8104 return (proto_tree *)tree->parent;
8105}
8106
8107proto_tree *
8108proto_tree_get_root(proto_tree *tree) {
8109 if (!tree)
8110 return NULL((void*)0);
8111 while (tree->parent) {
8112 tree = tree->parent;
8113 }
8114 return tree;
8115}
8116
8117void
8118proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8119 proto_item *item_to_move)
8120{
8121 /* This function doesn't generate any values. It only reorganizes the prococol tree
8122 * so we can bail out immediately if it isn't visible. */
8123 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8124 return;
8125
8126 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", 8126, "item_to_move->parent == tree"
))))
;
8127 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", 8127, "fixed_item->parent == tree"
))))
;
8128
8129 /*** cut item_to_move out ***/
8130
8131 /* is item_to_move the first? */
8132 if (tree->first_child == item_to_move) {
8133 /* simply change first child to next */
8134 tree->first_child = item_to_move->next;
8135
8136 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", 8136, "tree->last_child != item_to_move"
))))
;
8137 } else {
8138 proto_item *curr_item;
8139 /* find previous and change it's next */
8140 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8141 if (curr_item->next == item_to_move) {
8142 break;
8143 }
8144 }
8145
8146 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8146, "curr_item"
))))
;
8147
8148 curr_item->next = item_to_move->next;
8149
8150 /* fix last_child if required */
8151 if (tree->last_child == item_to_move) {
8152 tree->last_child = curr_item;
8153 }
8154 }
8155
8156 /*** insert to_move after fixed ***/
8157 item_to_move->next = fixed_item->next;
8158 fixed_item->next = item_to_move;
8159 if (tree->last_child == fixed_item) {
8160 tree->last_child = item_to_move;
8161 }
8162}
8163
8164void
8165proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8166 const int length)
8167{
8168 field_info *fi;
8169
8170 if (tree == NULL((void*)0))
8171 return;
8172
8173 fi = PTREE_FINFO(tree)((tree)->finfo);
8174 if (fi == NULL((void*)0))
8175 return;
8176
8177 start += tvb_raw_offset(tvb);
8178 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8178, "start >= 0"
))))
;
8179 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8179, "length >= 0"
))))
;
8180
8181 fi->appendix_start = start;
8182 fi->appendix_length = length;
8183}
8184
8185static void
8186check_protocol_filter_name_or_fail(const char *filter_name)
8187{
8188 /* Require at least two characters. */
8189 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8190 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)
;
8191 }
8192
8193 if (proto_check_field_name(filter_name) != '\0') {
8194 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)
8195 " 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)
8196 " 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)
;
8197 }
8198
8199 /* Check that it doesn't match some very common numeric forms. */
8200 if (filter_name[0] == '0' &&
8201 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8202 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8203 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])
8204 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])
;
8205 }
8206
8207 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8208
8209 /* Check that it contains at least one letter. */
8210 bool_Bool have_letter = false0;
8211 for (const char *s = filter_name; *s != '\0'; s++) {
8212 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8213 have_letter = true1;
8214 break;
8215 }
8216 }
8217 if (!have_letter) {
8218 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)
8219 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8220 }
8221
8222 /* Check for reserved keywords. */
8223 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8224 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)
8225 " 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)
;
8226 }
8227}
8228
8229int
8230proto_register_protocol(const char *name, const char *short_name,
8231 const char *filter_name)
8232{
8233 protocol_t *protocol;
8234 header_field_info *hfinfo;
8235
8236 /*
8237 * Make sure there's not already a protocol with any of those
8238 * names. Crash if there is, as that's an error in the code
8239 * or an inappropriate plugin.
8240 * This situation has to be fixed to not register more than one
8241 * protocol with the same name.
8242 */
8243
8244 if (g_hash_table_lookup(proto_names, name)) {
8245 /* ws_error will terminate the program */
8246 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)
8247 " 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)
;
8248 }
8249
8250 if (g_hash_table_lookup(proto_short_names, short_name)) {
8251 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)
8252 " 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)
;
8253 }
8254
8255 check_protocol_filter_name_or_fail(filter_name);
8256
8257 if (g_hash_table_lookup(proto_filter_names, filter_name)) {
8258 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)
8259 " 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)
;
8260 }
8261
8262 /*
8263 * Add this protocol to the list of known protocols;
8264 * the list is sorted by protocol short name.
8265 */
8266 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8267 protocol->name = name;
8268 protocol->short_name = short_name;
8269 protocol->filter_name = filter_name;
8270 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8271 protocol->is_enabled = true1; /* protocol is enabled by default */
8272 protocol->enabled_by_default = true1; /* see previous comment */
8273 protocol->can_toggle = true1;
8274 protocol->parent_proto_id = -1;
8275 protocol->heur_list = NULL((void*)0);
8276
8277 /* List will be sorted later by name, when all protocols completed registering */
8278 protocols = g_list_prepend(protocols, protocol);
8279 g_hash_table_insert(proto_names, (void *)name, protocol);
8280 g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol);
8281 g_hash_table_insert(proto_short_names, (void *)short_name, protocol);
8282
8283 /* Here we allocate a new header_field_info struct */
8284 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8285 hfinfo->name = name;
8286 hfinfo->abbrev = filter_name;
8287 hfinfo->type = FT_PROTOCOL;
8288 hfinfo->display = BASE_NONE;
8289 hfinfo->strings = protocol;
8290 hfinfo->bitmask = 0;
8291 hfinfo->ref_type = HF_REF_TYPE_NONE;
8292 hfinfo->blurb = NULL((void*)0);
8293 hfinfo->parent = -1; /* This field differentiates protos and fields */
8294
8295 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8296 return protocol->proto_id;
8297}
8298
8299int
8300proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8301{
8302 protocol_t *protocol;
8303 header_field_info *hfinfo;
8304
8305 /*
8306 * Helper protocols don't need the strict rules as a "regular" protocol
8307 * Just register it in a list and make a hf_ field from it
8308 */
8309 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8310 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)
;
8311 }
8312
8313 if (parent_proto <= 0) {
8314 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)
8315 " 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)
;
8316 }
8317
8318 check_protocol_filter_name_or_fail(filter_name);
8319
8320 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8321 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8322 protocol->name = name;
8323 protocol->short_name = short_name;
8324 protocol->filter_name = filter_name;
8325 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8326
8327 /* Enabling and toggling is really determined by parent protocol,
8328 but provide default values here */
8329 protocol->is_enabled = true1;
8330 protocol->enabled_by_default = true1;
8331 protocol->can_toggle = true1;
8332
8333 protocol->parent_proto_id = parent_proto;
8334 protocol->heur_list = NULL((void*)0);
8335
8336 /* List will be sorted later by name, when all protocols completed registering */
8337 protocols = g_list_prepend(protocols, protocol);
8338
8339 /* Here we allocate a new header_field_info struct */
8340 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8341 hfinfo->name = name;
8342 hfinfo->abbrev = filter_name;
8343 hfinfo->type = field_type;
8344 hfinfo->display = BASE_NONE;
8345 if (field_type == FT_BYTES) {
8346 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8347 }
8348 hfinfo->strings = protocol;
8349 hfinfo->bitmask = 0;
8350 hfinfo->ref_type = HF_REF_TYPE_NONE;
8351 hfinfo->blurb = NULL((void*)0);
8352 hfinfo->parent = -1; /* This field differentiates protos and fields */
8353
8354 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8355 return protocol->proto_id;
8356}
8357
8358bool_Bool
8359proto_deregister_protocol(const char *short_name)
8360{
8361 protocol_t *protocol;
8362 header_field_info *hfinfo;
8363 int proto_id;
8364 unsigned i;
8365
8366 proto_id = proto_get_id_by_short_name(short_name);
8367 protocol = find_protocol_by_id(proto_id);
8368 if (protocol == NULL((void*)0))
8369 return false0;
8370
8371 g_hash_table_remove(proto_names, protocol->name);
8372 g_hash_table_remove(proto_short_names, (void *)short_name);
8373 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8374
8375 if (protocol->fields) {
8376 for (i = 0; i < protocol->fields->len; i++) {
8377 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8378 hfinfo_remove_from_gpa_name_map(hfinfo);
8379 expert_deregister_expertinfo(hfinfo->abbrev);
8380 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8381 }
8382 g_ptr_array_free(protocol->fields, true1);
8383 protocol->fields = NULL((void*)0);
8384 }
8385
8386 g_list_free(protocol->heur_list);
8387
8388 /* Remove this protocol from the list of known protocols */
8389 protocols = g_list_remove(protocols, protocol);
8390
8391 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8392 g_hash_table_steal(gpa_name_map, protocol->filter_name);
8393
8394 g_free(last_field_name);
8395 last_field_name = NULL((void*)0);
8396
8397 return true1;
8398}
8399
8400void
8401proto_register_alias(const int proto_id, const char *alias_name)
8402{
8403 protocol_t *protocol;
8404
8405 protocol = find_protocol_by_id(proto_id);
8406 if (alias_name && protocol) {
8407 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8408 }
8409}
8410
8411/*
8412 * Routines to use to iterate over the protocols.
8413 * The argument passed to the iterator routines is an opaque cookie to
8414 * their callers; it's the GList pointer for the current element in
8415 * the list.
8416 * The ID of the protocol is returned, or -1 if there is no protocol.
8417 */
8418int
8419proto_get_first_protocol(void **cookie)
8420{
8421 protocol_t *protocol;
8422
8423 if (protocols == NULL((void*)0))
8424 return -1;
8425 *cookie = protocols;
8426 protocol = (protocol_t *)protocols->data;
8427 return protocol->proto_id;
8428}
8429
8430int
8431proto_get_data_protocol(void *cookie)
8432{
8433 GList *list_item = (GList *)cookie;
8434
8435 protocol_t *protocol = (protocol_t *)list_item->data;
8436 return protocol->proto_id;
8437}
8438
8439int
8440proto_get_next_protocol(void **cookie)
8441{
8442 GList *list_item = (GList *)*cookie;
8443 protocol_t *protocol;
8444
8445 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8446 if (list_item == NULL((void*)0))
8447 return -1;
8448 *cookie = list_item;
8449 protocol = (protocol_t *)list_item->data;
8450 return protocol->proto_id;
8451}
8452
8453header_field_info *
8454proto_get_first_protocol_field(const int proto_id, void **cookie)
8455{
8456 protocol_t *protocol = find_protocol_by_id(proto_id);
8457
8458 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8459 return NULL((void*)0);
8460
8461 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8462 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8463}
8464
8465header_field_info *
8466proto_get_next_protocol_field(const int proto_id, void **cookie)
8467{
8468 protocol_t *protocol = find_protocol_by_id(proto_id);
8469 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8470
8471 i++;
8472
8473 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8474 return NULL((void*)0);
8475
8476 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8477 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8478}
8479
8480protocol_t *
8481find_protocol_by_id(const int proto_id)
8482{
8483 header_field_info *hfinfo;
8484
8485 if (proto_id <= 0)
8486 return NULL((void*)0);
8487
8488 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", 8488, __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", 8488,
"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", 8488, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8489 if (hfinfo->type != FT_PROTOCOL) {
8490 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", 8490, "hfinfo->display & 0x00004000"
))))
;
8491 }
8492 return (protocol_t *)hfinfo->strings;
8493}
8494
8495int
8496proto_get_id(const protocol_t *protocol)
8497{
8498 return protocol->proto_id;
8499}
8500
8501bool_Bool
8502proto_name_already_registered(const char *name)
8503{
8504 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8504, "name", "No name present"))))
;
8505
8506 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8507 return true1;
8508 return false0;
8509}
8510
8511int
8512proto_get_id_by_filter_name(const char *filter_name)
8513{
8514 const protocol_t *protocol = NULL((void*)0);
8515
8516 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", 8516,
"filter_name", "No filter name present"))))
;
8517
8518 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8519
8520 if (protocol == NULL((void*)0))
8521 return -1;
8522 return protocol->proto_id;
8523}
8524
8525int
8526proto_get_id_by_short_name(const char *short_name)
8527{
8528 const protocol_t *protocol = NULL((void*)0);
8529
8530 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", 8530,
"short_name", "No short name present"))))
;
8531
8532 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8533
8534 if (protocol == NULL((void*)0))
8535 return -1;
8536 return protocol->proto_id;
8537}
8538
8539const char *
8540proto_get_protocol_name(const int proto_id)
8541{
8542 protocol_t *protocol;
8543
8544 protocol = find_protocol_by_id(proto_id);
8545
8546 if (protocol == NULL((void*)0))
8547 return NULL((void*)0);
8548 return protocol->name;
8549}
8550
8551const char *
8552proto_get_protocol_short_name(const protocol_t *protocol)
8553{
8554 if (protocol == NULL((void*)0))
8555 return "(none)";
8556 return protocol->short_name;
8557}
8558
8559const char *
8560proto_get_protocol_long_name(const protocol_t *protocol)
8561{
8562 if (protocol == NULL((void*)0))
8563 return "(none)";
8564 return protocol->name;
8565}
8566
8567const char *
8568proto_get_protocol_filter_name(const int proto_id)
8569{
8570 protocol_t *protocol;
8571
8572 protocol = find_protocol_by_id(proto_id);
8573 if (protocol == NULL((void*)0))
8574 return "(none)";
8575 return protocol->filter_name;
8576}
8577
8578void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8579{
8580 heur_dtbl_entry_t* heuristic_dissector;
8581
8582 if (protocol == NULL((void*)0))
8583 return;
8584
8585 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8586 if (heuristic_dissector != NULL((void*)0))
8587 {
8588 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8589 }
8590}
8591
8592void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8593{
8594 if (protocol == NULL((void*)0))
8595 return;
8596
8597 g_list_foreach(protocol->heur_list, func, user_data);
8598}
8599
8600void
8601proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8602 bool_Bool *is_tcp, bool_Bool *is_udp,
8603 bool_Bool *is_sctp, bool_Bool *is_tls,
8604 bool_Bool *is_rtp,
8605 bool_Bool *is_lte_rlc)
8606{
8607 wmem_list_frame_t *protos = wmem_list_head(layers);
8608 int proto_id;
8609 const char *proto_name;
8610
8611 /* Walk the list of a available protocols in the packet and
8612 attempt to find "major" ones. */
8613 /* It might make more sense to assemble and return a bitfield. */
8614 while (protos != NULL((void*)0))
8615 {
8616 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8617 proto_name = proto_get_protocol_filter_name(proto_id);
8618
8619 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8620 (!strcmp(proto_name, "ipv6")))) {
8621 *is_ip = true1;
8622 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8623 *is_tcp = true1;
8624 } else if (is_udp && !strcmp(proto_name, "udp")) {
8625 *is_udp = true1;
8626 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8627 *is_sctp = true1;
8628 } else if (is_tls && !strcmp(proto_name, "tls")) {
8629 *is_tls = true1;
8630 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8631 *is_rtp = true1;
8632 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8633 *is_lte_rlc = true1;
8634 }
8635
8636 protos = wmem_list_frame_next(protos);
8637 }
8638}
8639
8640bool_Bool
8641proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8642{
8643 wmem_list_frame_t *protos = wmem_list_head(layers);
8644 int proto_id;
8645 const char *name;
8646
8647 /* Walk the list of a available protocols in the packet and
8648 attempt to find the specified protocol. */
8649 while (protos != NULL((void*)0))
8650 {
8651 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8652 name = proto_get_protocol_filter_name(proto_id);
8653
8654 if (!strcmp(name, proto_name))
8655 {
8656 return true1;
8657 }
8658
8659 protos = wmem_list_frame_next(protos);
8660 }
8661
8662 return false0;
8663}
8664
8665char *
8666proto_list_layers(const packet_info *pinfo)
8667{
8668 wmem_strbuf_t *buf;
8669 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8670
8671 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8672
8673 /* Walk the list of layers in the packet and
8674 return a string of all entries. */
8675 while (layers != NULL((void*)0))
8676 {
8677 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8678
8679 layers = wmem_list_frame_next(layers);
8680 if (layers != NULL((void*)0)) {
8681 wmem_strbuf_append_c(buf, ':');
8682 }
8683 }
8684
8685 return wmem_strbuf_finalize(buf);
8686}
8687
8688bool_Bool
8689proto_is_pino(const protocol_t *protocol)
8690{
8691 return (protocol->parent_proto_id != -1);
8692}
8693
8694bool_Bool
8695// NOLINTNEXTLINE(misc-no-recursion)
8696proto_is_protocol_enabled(const protocol_t *protocol)
8697{
8698 if (protocol == NULL((void*)0))
8699 return false0;
8700
8701 //parent protocol determines enable/disable for helper dissectors
8702 if (proto_is_pino(protocol))
8703 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8704
8705 return protocol->is_enabled;
8706}
8707
8708bool_Bool
8709// NOLINTNEXTLINE(misc-no-recursion)
8710proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8711{
8712 //parent protocol determines enable/disable for helper dissectors
8713 if (proto_is_pino(protocol))
8714 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8715
8716 return protocol->enabled_by_default;
8717}
8718
8719bool_Bool
8720// NOLINTNEXTLINE(misc-no-recursion)
8721proto_can_toggle_protocol(const int proto_id)
8722{
8723 protocol_t *protocol;
8724
8725 protocol = find_protocol_by_id(proto_id);
8726 //parent protocol determines toggling for helper dissectors
8727 if (proto_is_pino(protocol))
8728 return proto_can_toggle_protocol(protocol->parent_proto_id);
8729
8730 return protocol->can_toggle;
8731}
8732
8733void
8734proto_disable_by_default(const int proto_id)
8735{
8736 protocol_t *protocol;
8737
8738 protocol = find_protocol_by_id(proto_id);
8739 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8739, "protocol->can_toggle"
))))
;
8740 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", 8740, "proto_is_pino(protocol) == 0"
))))
;
8741 protocol->is_enabled = false0;
8742 protocol->enabled_by_default = false0;
8743}
8744
8745void
8746proto_set_decoding(const int proto_id, const bool_Bool enabled)
8747{
8748 protocol_t *protocol;
8749
8750 protocol = find_protocol_by_id(proto_id);
8751 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8751, "protocol->can_toggle"
))))
;
8752 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", 8752, "proto_is_pino(protocol) == 0"
))))
;
8753 protocol->is_enabled = enabled;
8754}
8755
8756void
8757proto_disable_all(void)
8758{
8759 /* This doesn't explicitly disable heuristic protocols,
8760 * but the heuristic doesn't get called if the parent
8761 * protocol isn't enabled.
8762 */
8763 protocol_t *protocol;
8764 GList *list_item = protocols;
8765
8766 if (protocols == NULL((void*)0))
8767 return;
8768
8769 while (list_item) {
8770 protocol = (protocol_t *)list_item->data;
8771 if (protocol->can_toggle) {
8772 protocol->is_enabled = false0;
8773 }
8774 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8775 }
8776}
8777
8778static void
8779heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8780{
8781 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8782
8783 heur->enabled = heur->enabled_by_default;
8784}
8785
8786void
8787proto_reenable_all(void)
8788{
8789 protocol_t *protocol;
8790 GList *list_item = protocols;
8791
8792 if (protocols == NULL((void*)0))
8793 return;
8794
8795 while (list_item) {
8796 protocol = (protocol_t *)list_item->data;
8797 if (protocol->can_toggle)
8798 protocol->is_enabled = protocol->enabled_by_default;
8799 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8800 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8801 }
8802}
8803
8804void
8805proto_set_cant_toggle(const int proto_id)
8806{
8807 protocol_t *protocol;
8808
8809 protocol = find_protocol_by_id(proto_id);
8810 protocol->can_toggle = false0;
8811}
8812
8813static int
8814proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8815{
8816 if (proto != NULL((void*)0)) {
8817 g_ptr_array_add(proto->fields, hfi);
8818 }
8819
8820 return proto_register_field_init(hfi, parent);
8821}
8822
8823/* for use with static arrays only, since we don't allocate our own copies
8824of the header_field_info struct contained within the hf_register_info struct */
8825void
8826proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8827{
8828 hf_register_info *ptr = hf;
8829 protocol_t *proto;
8830 int i;
8831
8832 proto = find_protocol_by_id(parent);
8833
8834 if (proto->fields == NULL((void*)0)) {
8835 proto->fields = g_ptr_array_sized_new(num_records);
8836 }
8837
8838 for (i = 0; i < num_records; i++, ptr++) {
8839 /*
8840 * Make sure we haven't registered this yet.
8841 * Most fields have variables associated with them
8842 * that are initialized to -1; some have array elements,
8843 * or possibly uninitialized variables, so we also allow
8844 * 0 (which is unlikely to be the field ID we get back
8845 * from "proto_register_field_init()").
8846 */
8847 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8848 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8849 "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)
8850 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8851 return;
8852 }
8853
8854 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8855 }
8856}
8857
8858/* deregister already registered fields */
8859void
8860proto_deregister_field (const int parent, int hf_id)
8861{
8862 header_field_info *hfi;
8863 protocol_t *proto;
8864 unsigned i;
8865
8866 g_free(last_field_name);
8867 last_field_name = NULL((void*)0);
8868
8869 if (hf_id == -1 || hf_id == 0)
8870 return;
8871
8872 proto = find_protocol_by_id (parent);
8873 if (!proto || proto->fields == NULL((void*)0)) {
8874 return;
8875 }
8876
8877 for (i = 0; i < proto->fields->len; i++) {
8878 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8879 if (hfi->id == hf_id) {
8880 /* Found the hf_id in this protocol */
8881 g_hash_table_steal(gpa_name_map, hfi->abbrev);
8882 g_ptr_array_remove_index_fast(proto->fields, i);
8883 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8884 return;
8885 }
8886 }
8887}
8888
8889void
8890proto_add_deregistered_data (void *data)
8891{
8892 g_ptr_array_add(deregistered_data, data);
8893}
8894
8895void
8896proto_add_deregistered_slice (size_t block_size, void *mem_block)
8897{
8898 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
)))
;
8899
8900 slice_data->block_size = block_size;
8901 slice_data->mem_block = mem_block;
8902
8903 g_ptr_array_add(deregistered_slice, slice_data);
8904}
8905
8906void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8907{
8908 if (field_strings == NULL((void*)0)) {
8909 return;
8910 }
8911
8912 switch (field_type) {
8913 case FT_FRAMENUM:
8914 /* This is just an integer represented as a pointer */
8915 break;
8916 case FT_PROTOCOL: {
8917 protocol_t *protocol = (protocol_t *)field_strings;
8918 g_free((char *)protocol->short_name);
8919 break;
8920 }
8921 case FT_BOOLEAN: {
8922 true_false_string *tf = (true_false_string *)field_strings;
8923 g_free((char *)tf->true_string);
8924 g_free((char *)tf->false_string);
8925 break;
8926 }
8927 case FT_UINT40:
8928 case FT_INT40:
8929 case FT_UINT48:
8930 case FT_INT48:
8931 case FT_UINT56:
8932 case FT_INT56:
8933 case FT_UINT64:
8934 case FT_INT64: {
8935 if (field_display & BASE_UNIT_STRING0x00001000) {
8936 unit_name_string *unit = (unit_name_string *)field_strings;
8937 g_free((char *)unit->singular);
8938 g_free((char *)unit->plural);
8939 } else if (field_display & BASE_RANGE_STRING0x00000100) {
8940 range_string *rs = (range_string *)field_strings;
8941 while (rs->strptr) {
8942 g_free((char *)rs->strptr);
8943 rs++;
8944 }
8945 } else if (field_display & BASE_EXT_STRING0x00000200) {
8946 val64_string_ext *vse = (val64_string_ext *)field_strings;
8947 val64_string *vs = (val64_string *)vse->_vs_p;
8948 while (vs->strptr) {
8949 g_free((char *)vs->strptr);
8950 vs++;
8951 }
8952 val64_string_ext_free(vse);
8953 field_strings = NULL((void*)0);
8954 } else if (field_display == BASE_CUSTOM) {
8955 /* this will be a pointer to a function, don't free that */
8956 field_strings = NULL((void*)0);
8957 } else {
8958 val64_string *vs64 = (val64_string *)field_strings;
8959 while (vs64->strptr) {
8960 g_free((char *)vs64->strptr);
8961 vs64++;
8962 }
8963 }
8964 break;
8965 }
8966 case FT_CHAR:
8967 case FT_UINT8:
8968 case FT_INT8:
8969 case FT_UINT16:
8970 case FT_INT16:
8971 case FT_UINT24:
8972 case FT_INT24:
8973 case FT_UINT32:
8974 case FT_INT32:
8975 case FT_FLOAT:
8976 case FT_DOUBLE: {
8977 if (field_display & BASE_UNIT_STRING0x00001000) {
8978 unit_name_string *unit = (unit_name_string *)field_strings;
8979 g_free((char *)unit->singular);
8980 g_free((char *)unit->plural);
8981 } else if (field_display & BASE_RANGE_STRING0x00000100) {
8982 range_string *rs = (range_string *)field_strings;
8983 while (rs->strptr) {
8984 g_free((char *)rs->strptr);
8985 rs++;
8986 }
8987 } else if (field_display & BASE_EXT_STRING0x00000200) {
8988 value_string_ext *vse = (value_string_ext *)field_strings;
8989 value_string *vs = (value_string *)vse->_vs_p;
8990 while (vs->strptr) {
8991 g_free((char *)vs->strptr);
8992 vs++;
8993 }
8994 value_string_ext_free(vse);
8995 field_strings = NULL((void*)0);
8996 } else if (field_display == BASE_CUSTOM) {
8997 /* this will be a pointer to a function, don't free that */
8998 field_strings = NULL((void*)0);
8999 } else {
9000 value_string *vs = (value_string *)field_strings;
9001 while (vs->strptr) {
9002 g_free((char *)vs->strptr);
9003 vs++;
9004 }
9005 }
9006 break;
9007 default:
9008 break;
9009 }
9010 }
9011
9012 if (field_type != FT_FRAMENUM) {
9013 g_free((void *)field_strings);
9014 }
9015}
9016
9017static void
9018free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9019{
9020 header_field_info *hfi = (header_field_info *) data;
9021 int hf_id = hfi->id;
9022
9023 g_free((char *)hfi->name);
9024 g_free((char *)hfi->abbrev);
9025 g_free((char *)hfi->blurb);
9026
9027 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9028
9029 if (hfi->parent == -1)
9030 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)
;
9031
9032 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9033}
9034
9035static void
9036free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9037{
9038 g_free (data);
9039}
9040
9041static void
9042free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9043{
9044 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9045
9046 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9047 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)
;
9048}
9049
9050/* free deregistered fields and data */
9051void
9052proto_free_deregistered_fields (void)
9053{
9054 expert_free_deregistered_expertinfos();
9055
9056 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9057 g_ptr_array_free(deregistered_fields, true1);
9058 deregistered_fields = g_ptr_array_new();
9059
9060 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9061 g_ptr_array_free(deregistered_data, true1);
9062 deregistered_data = g_ptr_array_new();
9063
9064 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9065 g_ptr_array_free(deregistered_slice, true1);
9066 deregistered_slice = g_ptr_array_new();
9067}
9068
9069static const value_string hf_display[] = {
9070 { BASE_NONE, "BASE_NONE" },
9071 { BASE_DEC, "BASE_DEC" },
9072 { BASE_HEX, "BASE_HEX" },
9073 { BASE_OCT, "BASE_OCT" },
9074 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9075 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9076 { BASE_CUSTOM, "BASE_CUSTOM" },
9077 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9078 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9079 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9080 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9081 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9082 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9083 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9084 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9085 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9086 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9087 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9088 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9089 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9090 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9091 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9092 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9093 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9094 { BASE_PT_UDP, "BASE_PT_UDP" },
9095 { BASE_PT_TCP, "BASE_PT_TCP" },
9096 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9097 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9098 { BASE_OUI, "BASE_OUI" },
9099 { 0, NULL((void*)0) } };
9100
9101const char* proto_field_display_to_string(int field_display)
9102{
9103 return val_to_str_const(field_display, hf_display, "Unknown");
9104}
9105
9106static inline port_type
9107display_to_port_type(field_display_e e)
9108{
9109 switch (e) {
9110 case BASE_PT_UDP:
9111 return PT_UDP;
9112 case BASE_PT_TCP:
9113 return PT_TCP;
9114 case BASE_PT_DCCP:
9115 return PT_DCCP;
9116 case BASE_PT_SCTP:
9117 return PT_SCTP;
9118 default:
9119 break;
9120 }
9121 return PT_NONE;
9122}
9123
9124/* temporary function containing assert part for easier profiling */
9125static void
9126tmp_fld_check_assert(header_field_info *hfinfo)
9127{
9128 char* tmp_str;
9129
9130 /* The field must have a name (with length > 0) */
9131 if (!hfinfo->name || !hfinfo->name[0]) {
9132 if (hfinfo->abbrev)
9133 /* Try to identify the field */
9134 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)
9135 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9136 else
9137 /* Hum, no luck */
9138 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)"
)
;
9139 }
9140
9141 /* fields with an empty string for an abbreviation aren't filterable */
9142 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9143 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)
;
9144
9145 /* These types of fields are allowed to have value_strings,
9146 * true_false_strings or a protocol_t struct
9147 */
9148 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9149 switch (hfinfo->type) {
9150
9151 /*
9152 * These types are allowed to support display value_strings,
9153 * value64_strings, the extended versions of the previous
9154 * two, range strings, or unit strings.
9155 */
9156 case FT_CHAR:
9157 case FT_UINT8:
9158 case FT_UINT16:
9159 case FT_UINT24:
9160 case FT_UINT32:
9161 case FT_UINT40:
9162 case FT_UINT48:
9163 case FT_UINT56:
9164 case FT_UINT64:
9165 case FT_INT8:
9166 case FT_INT16:
9167 case FT_INT24:
9168 case FT_INT32:
9169 case FT_INT40:
9170 case FT_INT48:
9171 case FT_INT56:
9172 case FT_INT64:
9173 case FT_BOOLEAN:
9174 case FT_PROTOCOL:
9175 break;
9176
9177 /*
9178 * This is allowed to have a value of type
9179 * enum ft_framenum_type to indicate what relationship
9180 * the frame in question has to the frame in which
9181 * the field is put.
9182 */
9183 case FT_FRAMENUM:
9184 break;
9185
9186 /*
9187 * These types are allowed to support only unit strings.
9188 */
9189 case FT_FLOAT:
9190 case FT_DOUBLE:
9191 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9192 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))
9193 " (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))
9194 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))
;
9195 }
9196 break;
9197
9198 /*
9199 * This type is only allowed to support a string if it's
9200 * a protocol (for pinos).
9201 */
9202 case FT_BYTES:
9203 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9204 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))
9205 " (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))
9206 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))
;
9207 }
9208 break;
9209
9210 default:
9211 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))
9212 " (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))
9213 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))
;
9214 }
9215 }
9216
9217 /* TODO: This check may slow down startup, and output quite a few warnings.
9218 It would be good to be able to enable this (and possibly other checks?)
9219 in non-release builds. */
9220#ifdef ENABLE_CHECK_FILTER
9221 /* Check for duplicate value_string values.
9222 There are lots that have the same value *and* string, so for now only
9223 report those that have same value but different string. */
9224 if ((hfinfo->strings != NULL((void*)0)) &&
9225 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9226 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9227 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9228 (
9229 (hfinfo->type == FT_CHAR) ||
9230 (hfinfo->type == FT_UINT8) ||
9231 (hfinfo->type == FT_UINT16) ||
9232 (hfinfo->type == FT_UINT24) ||
9233 (hfinfo->type == FT_UINT32) ||
9234 (hfinfo->type == FT_INT8) ||
9235 (hfinfo->type == FT_INT16) ||
9236 (hfinfo->type == FT_INT24) ||
9237 (hfinfo->type == FT_INT32) )) {
9238
9239 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9240 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9241 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9242 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9243 } else {
9244 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9245 CHECK_HF_VALUE(value_string, "u", start_values);
9246 }
9247 } else {
9248 const value_string *start_values = (const value_string*)hfinfo->strings;
9249 CHECK_HF_VALUE(value_string, "u", start_values);
9250 }
9251 }
9252
9253 if (hfinfo->type == FT_BOOLEAN) {
9254 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9255 if (tfs) {
9256 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9257 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"
, 9259, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9258 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9259, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9259 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9259, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9260 }
9261 }
9262 }
9263
9264 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9265 const range_string *rs = (const range_string*)(hfinfo->strings);
9266 if (rs) {
9267 const range_string *this_it = rs;
9268
9269 do {
9270 if (this_it->value_max < this_it->value_min) {
9271 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"
, 9275, __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)
9272 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9275, __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)
9273 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9275, __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)
9274 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9275, __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)
9275 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9275, __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)
;
9276 ++this_it;
9277 continue;
9278 }
9279
9280 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9281 /* Not OK if this one is completely hidden by an earlier one! */
9282 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9283 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"
, 9289, __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)
9284 "(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"
, 9289, __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)
9285 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9289, __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)
9286 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9289, __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)
9287 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9289, __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)
9288 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9289, __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)
9289 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9289, __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)
;
9290 }
9291 }
9292 ++this_it;
9293 } while (this_it->strptr);
9294 }
9295 }
9296#endif
9297
9298 switch (hfinfo->type) {
9299
9300 case FT_CHAR:
9301 /* Require the char type to have BASE_HEX, BASE_OCT,
9302 * BASE_CUSTOM, or BASE_NONE as its base.
9303 *
9304 * If the display value is BASE_NONE and there is a
9305 * strings conversion then the dissector writer is
9306 * telling us that the field's numerical value is
9307 * meaningless; we'll avoid showing the value to the
9308 * user.
9309 */
9310 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9311 case BASE_HEX:
9312 case BASE_OCT:
9313 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9314 break;
9315 case BASE_NONE:
9316 if (hfinfo->strings == NULL((void*)0))
9317 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
))
9318 " 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
))
9319 " 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
))
9320 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
))
9321 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
))
;
9322 break;
9323 default:
9324 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9325 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)
9326 " 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)
9327 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)
9328 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)
;
9329 //wmem_free(NULL, tmp_str);
9330 }
9331 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9332 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
))
9333 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
))
9334 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
))
;
9335 }
9336 break;
9337 case FT_INT8:
9338 case FT_INT16:
9339 case FT_INT24:
9340 case FT_INT32:
9341 case FT_INT40:
9342 case FT_INT48:
9343 case FT_INT56:
9344 case FT_INT64:
9345 /* Hexadecimal and octal are, in printf() and everywhere
9346 * else, unsigned so don't allow dissectors to register a
9347 * signed field to be displayed unsigned. (Else how would
9348 * we display negative values?)
9349 */
9350 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9351 case BASE_HEX:
9352 case BASE_OCT:
9353 case BASE_DEC_HEX:
9354 case BASE_HEX_DEC:
9355 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9356 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)
9357 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)
9358 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)
;
9359 //wmem_free(NULL, tmp_str);
9360 }
9361 /* FALL THROUGH */
9362 case FT_UINT8:
9363 case FT_UINT16:
9364 case FT_UINT24:
9365 case FT_UINT32:
9366 case FT_UINT40:
9367 case FT_UINT48:
9368 case FT_UINT56:
9369 case FT_UINT64:
9370 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
))
) {
9371 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9372 if (hfinfo->type != FT_UINT16) {
9373 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))
9374 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))
9375 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))
;
9376 }
9377 if (hfinfo->strings != NULL((void*)0)) {
9378 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)
9379 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)
9380 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)
;
9381 }
9382 if (hfinfo->bitmask != 0) {
9383 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)
9384 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)
9385 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)
;
9386 }
9387 wmem_free(NULL((void*)0), tmp_str);
9388 break;
9389 }
9390
9391 if (hfinfo->display == BASE_OUI) {
9392 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9393 if (hfinfo->type != FT_UINT24) {
9394 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))
9395 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))
9396 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))
;
9397 }
9398 if (hfinfo->strings != NULL((void*)0)) {
9399 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)
9400 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)
9401 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)
;
9402 }
9403 if (hfinfo->bitmask != 0) {
9404 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)
9405 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)
9406 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)
;
9407 }
9408 wmem_free(NULL((void*)0), tmp_str);
9409 break;
9410 }
9411
9412 /* Require integral types (other than frame number,
9413 * which is always displayed in decimal) to have a
9414 * number base.
9415 *
9416 * If the display value is BASE_NONE and there is a
9417 * strings conversion then the dissector writer is
9418 * telling us that the field's numerical value is
9419 * meaningless; we'll avoid showing the value to the
9420 * user.
9421 */
9422 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9423 case BASE_DEC:
9424 case BASE_HEX:
9425 case BASE_OCT:
9426 case BASE_DEC_HEX:
9427 case BASE_HEX_DEC:
9428 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9429 break;
9430 case BASE_NONE:
9431 if (hfinfo->strings == NULL((void*)0)) {
9432 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
))
9433 " 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
))
9434 " 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
))
9435 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
))
9436 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
))
;
9437 }
9438 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9439 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
))
9440 " 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
))
9441 " 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
))
9442 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
))
9443 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
))
;
9444 }
9445 break;
9446
9447 default:
9448 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9449 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)
9450 " 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)
9451 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)
9452 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)
;
9453 //wmem_free(NULL, tmp_str);
9454 }
9455 break;
9456 case FT_BYTES:
9457 case FT_UINT_BYTES:
9458 /* Require bytes to have a "display type" that could
9459 * add a character between displayed bytes.
9460 */
9461 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9462 case BASE_NONE:
9463 case SEP_DOT:
9464 case SEP_DASH:
9465 case SEP_COLON:
9466 case SEP_SPACE:
9467 break;
9468 default:
9469 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9470 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)
9471 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)
;
9472 //wmem_free(NULL, tmp_str);
9473 }
9474 if (hfinfo->bitmask != 0)
9475 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
))
9476 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
))
9477 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
))
;
9478 //allowed to support string if its a protocol (for pinos)
9479 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9480 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
))
9481 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
))
9482 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
))
;
9483 break;
9484
9485 case FT_PROTOCOL:
9486 case FT_FRAMENUM:
9487 if (hfinfo->display != BASE_NONE) {
9488 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9489 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)
9490 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)
9491 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)
;
9492 //wmem_free(NULL, tmp_str);
9493 }
9494 if (hfinfo->bitmask != 0)
9495 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
))
9496 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
))
9497 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
))
;
9498 break;
9499
9500 case FT_BOOLEAN:
9501 break;
9502
9503 case FT_ABSOLUTE_TIME:
9504 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9505 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9506 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)
9507 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)
;
9508 //wmem_free(NULL, tmp_str);
9509 }
9510 if (hfinfo->bitmask != 0)
9511 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
))
9512 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
))
9513 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
))
;
9514 break;
9515
9516 case FT_STRING:
9517 case FT_STRINGZ:
9518 case FT_UINT_STRING:
9519 case FT_STRINGZPAD:
9520 case FT_STRINGZTRUNC:
9521 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9522 case BASE_NONE:
9523 case BASE_STR_WSP:
9524 break;
9525
9526 default:
9527 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9528 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)
9529 " 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)
9530 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)
9531 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)
;
9532 //wmem_free(NULL, tmp_str);
9533 }
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 if (hfinfo->strings != NULL((void*)0))
9540 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
))
9541 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
))
9542 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
))
;
9543 break;
9544
9545 case FT_IPv4:
9546 switch (hfinfo->display) {
9547 case BASE_NONE:
9548 case BASE_NETMASK:
9549 break;
9550
9551 default:
9552 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9553 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)
9554 " 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)
9555 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)
9556 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)
;
9557 //wmem_free(NULL, tmp_str);
9558 break;
9559 }
9560 break;
9561 case FT_FLOAT:
9562 case FT_DOUBLE:
9563 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9564 case BASE_NONE:
9565 case BASE_DEC:
9566 case BASE_HEX:
9567 case BASE_EXP:
9568 case BASE_CUSTOM:
9569 break;
9570 default:
9571 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9572 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)
9573 " 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)
9574 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)
9575 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)
;
9576 //wmem_free(NULL, tmp_str);
9577 }
9578 if (hfinfo->bitmask != 0)
9579 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
))
9580 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
))
9581 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
))
;
9582 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9583 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
))
9584 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
))
9585 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
))
;
9586 break;
9587 default:
9588 if (hfinfo->display != BASE_NONE) {
9589 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9590 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)
9591 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)
9592 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)
9593 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)
;
9594 //wmem_free(NULL, tmp_str);
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}
9607
9608static void
9609register_type_length_mismatch(void)
9610{
9611 static ei_register_info ei[] = {
9612 { &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)}}
}},
9613 { &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)}}
}},
9614 };
9615
9616 expert_module_t* expert_type_length_mismatch;
9617
9618 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9619
9620 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9621 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9622
9623 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9624 disabling them makes no sense. */
9625 proto_set_cant_toggle(proto_type_length_mismatch);
9626}
9627
9628static void
9629register_byte_array_string_decodinws_error(void)
9630{
9631 static ei_register_info ei[] = {
9632 { &ei_byte_array_string_decoding_failed_error,
9633 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9634 "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)}}
9635 }
9636 },
9637 };
9638
9639 expert_module_t* expert_byte_array_string_decoding_error;
9640
9641 proto_byte_array_string_decoding_error =
9642 proto_register_protocol("Byte Array-String Decoding Error",
9643 "Byte Array-string decoding error",
9644 "_ws.byte_array_string.decoding_error");
9645
9646 expert_byte_array_string_decoding_error =
9647 expert_register_protocol(proto_byte_array_string_decoding_error);
9648 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9649
9650 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9651 disabling them makes no sense. */
9652 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9653}
9654
9655static void
9656register_date_time_string_decodinws_error(void)
9657{
9658 static ei_register_info ei[] = {
9659 { &ei_date_time_string_decoding_failed_error,
9660 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9661 "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)}}
9662 }
9663 },
9664 };
9665
9666 expert_module_t* expert_date_time_string_decoding_error;
9667
9668 proto_date_time_string_decoding_error =
9669 proto_register_protocol("Date and Time-String Decoding Error",
9670 "Date and Time-string decoding error",
9671 "_ws.date_time_string.decoding_error");
9672
9673 expert_date_time_string_decoding_error =
9674 expert_register_protocol(proto_date_time_string_decoding_error);
9675 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9676
9677 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9678 disabling them makes no sense. */
9679 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9680}
9681
9682static void
9683register_string_errors(void)
9684{
9685 static ei_register_info ei[] = {
9686 { &ei_string_trailing_characters,
9687 { "_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)}}
}
9688 },
9689 };
9690
9691 expert_module_t* expert_string_errors;
9692
9693 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9694
9695 expert_string_errors = expert_register_protocol(proto_string_errors);
9696 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9697
9698 /* "String Errors" isn't really a protocol, it's an error indication;
9699 disabling them makes no sense. */
9700 proto_set_cant_toggle(proto_string_errors);
9701}
9702
9703#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
9704static int
9705proto_register_field_init(header_field_info *hfinfo, const int parent)
9706{
9707
9708 tmp_fld_check_assert(hfinfo);
9709
9710 hfinfo->parent = parent;
9711 hfinfo->same_name_next = NULL((void*)0);
9712 hfinfo->same_name_prev_id = -1;
9713
9714 /* if we always add and never delete, then id == len - 1 is correct */
9715 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9716 if (!gpa_hfinfo.hfi) {
9717 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9718 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9719 /* The entry with index 0 is not used. */
9720 gpa_hfinfo.hfi[0] = NULL((void*)0);
9721 gpa_hfinfo.len = 1;
9722 } else {
9723 gpa_hfinfo.allocated_len += 1000;
9724 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9725 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9726 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9727 }
9728 }
9729 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9730 gpa_hfinfo.len++;
9731 hfinfo->id = gpa_hfinfo.len - 1;
9732
9733 /* if we have real names, enter this field in the name tree */
9734 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
9735
9736 header_field_info *same_name_next_hfinfo;
9737 unsigned char c;
9738
9739 /* Check that the filter name (abbreviation) is legal;
9740 * it must contain only alphanumerics, '-', "_", and ".". */
9741 c = proto_check_field_name(hfinfo->abbrev);
9742 if (c) {
9743 if (c == '.') {
9744 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)
;
9745 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9746 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)
;
9747 } else {
9748 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)
;
9749 }
9750 }
9751
9752 /* We allow multiple hfinfo's to be registered under the same
9753 * abbreviation. This was done for X.25, as, depending
9754 * on whether it's modulo-8 or modulo-128 operation,
9755 * some bitfield fields may be in different bits of
9756 * a byte, and we want to be able to refer to that field
9757 * with one name regardless of whether the packets
9758 * are modulo-8 or modulo-128 packets. */
9759
9760 same_name_hfinfo = NULL((void*)0);
9761
9762 g_hash_table_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9763 /* GLIB 2.x - if it is already present
9764 * the previous hfinfo with the same name is saved
9765 * to same_name_hfinfo by value destroy callback */
9766 if (same_name_hfinfo) {
9767 /* There's already a field with this name.
9768 * Put the current field *before* that field
9769 * in the list of fields with this name, Thus,
9770 * we end up with an effectively
9771 * doubly-linked-list of same-named hfinfo's,
9772 * with the head of the list (stored in the
9773 * hash) being the last seen hfinfo.
9774 */
9775 same_name_next_hfinfo =
9776 same_name_hfinfo->same_name_next;
9777
9778 hfinfo->same_name_next = same_name_next_hfinfo;
9779 if (same_name_next_hfinfo)
9780 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9781
9782 same_name_hfinfo->same_name_next = hfinfo;
9783 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9784#ifdef ENABLE_CHECK_FILTER
9785 while (same_name_hfinfo) {
9786 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9787 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"
, 9787, __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)
;
9788 same_name_hfinfo = same_name_hfinfo->same_name_next;
9789 }
9790#endif
9791 }
9792 }
9793
9794 return hfinfo->id;
9795}
9796
9797void
9798proto_register_subtree_array(int * const *indices, const int num_indices)
9799{
9800 int i;
9801 int *const *ptr = indices;
9802
9803 /*
9804 * If we've already allocated the array of tree types, expand
9805 * it; this lets plugins such as mate add tree types after
9806 * the initial startup. (If we haven't already allocated it,
9807 * we don't allocate it; on the first pass, we just assign
9808 * ett values and keep track of how many we've assigned, and
9809 * when we're finished registering all dissectors we allocate
9810 * the array, so that we do only one allocation rather than
9811 * wasting CPU time and memory by growing the array for each
9812 * dissector that registers ett values.)
9813 */
9814 if (tree_is_expanded != NULL((void*)0)) {
9815 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9816
9817 /* set new items to 0 */
9818 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9819 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9820 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9821 }
9822
9823 /*
9824 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9825 * returning the indices through the pointers in the array whose
9826 * first element is pointed to by "indices", and update
9827 * "num_tree_types" appropriately.
9828 */
9829 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9830 if (**ptr != -1 && **ptr != 0) {
9831 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.")
9832 " 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.")
9833 " 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.")
9834 " 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.")
;
9835 }
9836 **ptr = num_tree_types;
9837 }
9838}
9839
9840static void
9841mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
9842{
9843 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "]";
9844 const size_t trunc_len = sizeof(trunc_str)-1;
9845 char *last_char;
9846
9847 /* ..... field_name: dataaaaaaaaaaaaa
9848 * |
9849 * ^^^^^ name_pos
9850 *
9851 * ..... field_name […]: dataaaaaaaaaaaaa
9852 *
9853 * name_pos==0 means that we have only data or only a field_name
9854 */
9855
9856 if (name_pos < size - trunc_len) {
9857 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
9858 memcpy(label_str + name_pos, trunc_str, trunc_len);
9859
9860 /* in general, label_str is UTF-8
9861 we can truncate it only at the beginning of a new character
9862 we go backwards from the byte right after our buffer and
9863 find the next starting byte of a UTF-8 character, this is
9864 where we cut
9865 there's no need to use g_utf8_find_prev_char(), the search
9866 will always succeed since we copied trunc_str into the
9867 buffer */
9868 /* g_utf8_prev_char does not deference the memory address
9869 * passed in (until after decrementing it, so it is perfectly
9870 * legal to pass in a pointer one past the last element.
9871 */
9872 last_char = g_utf8_prev_char(label_str + size);
9873 *last_char = '\0';
9874
9875 if (value_pos && *value_pos > 0) {
9876 if (name_pos == 0) {
9877 *value_pos += trunc_len;
9878 } else {
9879 /* Move one back to include trunc_str in the value. */
9880 *value_pos -= 1;
9881 }
9882 }
9883 } else if (name_pos < size)
9884 (void) g_strlcpy(label_str + name_pos, trunc_str, size - name_pos);
9885}
9886
9887static void
9888label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
9889{
9890 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
9891}
9892
9893static size_t
9894label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
9895{
9896 size_t name_pos;
9897
9898 /* "%s: %s", hfinfo->name, text */
9899 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
9900 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
9901 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
9902 if (value_pos) {
9903 *value_pos = pos;
9904 }
9905 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
9906 }
9907
9908 if (pos >= ITEM_LABEL_LENGTH240) {
9909 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9910 label_mark_truncated(label_str, name_pos, value_pos);
9911 }
9912
9913 return pos;
9914}
9915
9916static size_t
9917label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
9918{
9919 size_t name_pos;
9920
9921 /* "%s: %s (%s)", hfinfo->name, text, descr */
9922 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
9923 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
9924 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
9925 if (value_pos) {
9926 *value_pos = pos;
9927 }
9928 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9929 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
9930 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
9931 } else {
9932 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
9933 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
9934 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
9935 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
9936 }
9937 }
9938
9939 if (pos >= ITEM_LABEL_LENGTH240) {
9940 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9941 label_mark_truncated(label_str, name_pos, value_pos);
9942 }
9943
9944 return pos;
9945}
9946
9947void
9948proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
9949{
9950 const header_field_info *hfinfo;
9951 const char *str;
9952 const uint8_t *bytes;
9953 uint32_t integer;
9954 uint64_t integer64;
9955 const ipv4_addr_and_mask *ipv4;
9956 const ipv6_addr_and_prefix *ipv6;
9957 const e_guid_t *guid;
9958 char *name;
9959 address addr;
9960 char *addr_str;
9961 char *tmp;
9962
9963 if (!label_str) {
9964 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9964, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
9965 return;
9966 }
9967
9968 label_str[0]= '\0';
9969
9970 if (!fi) {
9971 return;
9972 }
9973
9974 hfinfo = fi->hfinfo;
9975
9976 switch (hfinfo->type) {
9977 case FT_NONE:
9978 case FT_PROTOCOL:
9979 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
9980 if (value_pos) {
9981 *value_pos = strlen(hfinfo->name);
9982 }
9983 break;
9984
9985 case FT_BOOLEAN:
9986 fill_label_boolean(fi, label_str, value_pos);
9987 break;
9988
9989 case FT_BYTES:
9990 case FT_UINT_BYTES:
9991 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
9992 fvalue_get_bytes_data(fi->value),
9993 (unsigned)fvalue_length2(fi->value));
9994 label_fill(label_str, 0, hfinfo, tmp, value_pos);
9995 wmem_free(NULL((void*)0), tmp);
9996 break;
9997
9998 case FT_CHAR:
9999 if (hfinfo->bitmask) {
10000 fill_label_bitfield_char(fi, label_str, value_pos);
10001 } else {
10002 fill_label_char(fi, label_str, value_pos);
10003 }
10004 break;
10005
10006 /* Four types of integers to take care of:
10007 * Bitfield, with val_string
10008 * Bitfield, w/o val_string
10009 * Non-bitfield, with val_string
10010 * Non-bitfield, w/o val_string
10011 */
10012 case FT_UINT8:
10013 case FT_UINT16:
10014 case FT_UINT24:
10015 case FT_UINT32:
10016 if (hfinfo->bitmask) {
10017 fill_label_bitfield(fi, label_str, value_pos, false0);
10018 } else {
10019 fill_label_number(fi, label_str, value_pos, false0);
10020 }
10021 break;
10022
10023 case FT_FRAMENUM:
10024 fill_label_number(fi, label_str, value_pos, false0);
10025 break;
10026
10027 case FT_UINT40:
10028 case FT_UINT48:
10029 case FT_UINT56:
10030 case FT_UINT64:
10031 if (hfinfo->bitmask) {
10032 fill_label_bitfield64(fi, label_str, value_pos, false0);
10033 } else {
10034 fill_label_number64(fi, label_str, value_pos, false0);
10035 }
10036 break;
10037
10038 case FT_INT8:
10039 case FT_INT16:
10040 case FT_INT24:
10041 case FT_INT32:
10042 if (hfinfo->bitmask) {
10043 fill_label_bitfield(fi, label_str, value_pos, true1);
10044 } else {
10045 fill_label_number(fi, label_str, value_pos, true1);
10046 }
10047 break;
10048
10049 case FT_INT40:
10050 case FT_INT48:
10051 case FT_INT56:
10052 case FT_INT64:
10053 if (hfinfo->bitmask) {
10054 fill_label_bitfield64(fi, label_str, value_pos, true1);
10055 } else {
10056 fill_label_number64(fi, label_str, value_pos, true1);
10057 }
10058 break;
10059
10060 case FT_FLOAT:
10061 case FT_DOUBLE:
10062 fill_label_float(fi, label_str, value_pos);
10063 break;
10064
10065 case FT_ABSOLUTE_TIME:
10066 {
10067 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10068 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10069 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10070 }
10071 tmp = abs_time_to_str_ex(NULL((void*)0), fvalue_get_time(fi->value), hfinfo->display, flags);
10072 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10073 wmem_free(NULL((void*)0), tmp);
10074 break;
10075 }
10076 case FT_RELATIVE_TIME:
10077 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10078 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10079 wmem_free(NULL((void*)0), tmp);
10080 break;
10081
10082 case FT_IPXNET:
10083 integer = fvalue_get_uinteger(fi->value);
10084 tmp = get_ipxnet_name(NULL((void*)0), integer);
10085 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10086 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10087 wmem_free(NULL((void*)0), tmp);
10088 wmem_free(NULL((void*)0), addr_str);
10089 break;
10090
10091 case FT_VINES:
10092 addr.type = AT_VINES;
10093 addr.len = VINES_ADDR_LEN6;
10094 addr.data = fvalue_get_bytes_data(fi->value);
10095
10096 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10097 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10098 wmem_free(NULL((void*)0), addr_str);
10099 break;
10100
10101 case FT_ETHER:
10102 bytes = fvalue_get_bytes_data(fi->value);
10103
10104 addr.type = AT_ETHER;
10105 addr.len = 6;
10106 addr.data = bytes;
10107
10108 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10109 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10110 wmem_free(NULL((void*)0), addr_str);
10111 break;
10112
10113 case FT_IPv4:
10114 ipv4 = fvalue_get_ipv4(fi->value);
10115 set_address_ipv4(&addr, ipv4);
10116
10117 if (hfinfo->display == BASE_NETMASK) {
10118 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10119 } else {
10120 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10121 }
10122 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10123 wmem_free(NULL((void*)0), addr_str);
10124 free_address(&addr);
10125 break;
10126
10127 case FT_IPv6:
10128 ipv6 = fvalue_get_ipv6(fi->value);
10129 set_address_ipv6(&addr, ipv6);
10130
10131 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10132 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10133 wmem_free(NULL((void*)0), addr_str);
10134 free_address(&addr);
10135 break;
10136
10137 case FT_FCWWN:
10138 bytes = fvalue_get_bytes_data(fi->value);
10139 addr.type = AT_FCWWN;
10140 addr.len = FCWWN_ADDR_LEN8;
10141 addr.data = bytes;
10142
10143 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10144 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10145 wmem_free(NULL((void*)0), addr_str);
10146 break;
10147
10148 case FT_GUID:
10149 guid = fvalue_get_guid(fi->value);
10150 tmp = guid_to_str(NULL((void*)0), guid);
10151 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10152 wmem_free(NULL((void*)0), tmp);
10153 break;
10154
10155 case FT_OID:
10156 bytes = fvalue_get_bytes_data(fi->value);
10157 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10158 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10159 if (name) {
10160 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10161 wmem_free(NULL((void*)0), name);
10162 } else {
10163 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10164 }
10165 wmem_free(NULL((void*)0), tmp);
10166 break;
10167
10168 case FT_REL_OID:
10169 bytes = fvalue_get_bytes_data(fi->value);
10170 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10171 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10172 if (name) {
10173 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10174 wmem_free(NULL((void*)0), name);
10175 } else {
10176 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10177 }
10178 wmem_free(NULL((void*)0), tmp);
10179 break;
10180
10181 case FT_SYSTEM_ID:
10182 bytes = fvalue_get_bytes_data(fi->value);
10183 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10184 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10185 wmem_free(NULL((void*)0), tmp);
10186 break;
10187
10188 case FT_EUI64:
10189 integer64 = fvalue_get_uinteger64(fi->value);
10190 addr_str = eui64_to_str(NULL((void*)0), integer64);
10191 tmp = (char*)eui64_to_display(NULL((void*)0), integer64);
10192 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10193 wmem_free(NULL((void*)0), tmp);
10194 wmem_free(NULL((void*)0), addr_str);
10195 break;
10196 case FT_STRING:
10197 case FT_STRINGZ:
10198 case FT_UINT_STRING:
10199 case FT_STRINGZPAD:
10200 case FT_STRINGZTRUNC:
10201 case FT_AX25:
10202 str = fvalue_get_string(fi->value);
10203 label_fill(label_str, 0, hfinfo, str, value_pos);
10204 break;
10205
10206 case FT_IEEE_11073_SFLOAT:
10207 case FT_IEEE_11073_FLOAT:
10208 tmp = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, hfinfo->display);
10209 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10210 wmem_free(NULL((void*)0), tmp);
10211 break;
10212
10213 default:
10214 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
))
10215 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
))
10216 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
))
10217 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
))
;
10218 break;
10219 }
10220}
10221
10222static void
10223fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10224{
10225 char *p;
10226 int bitfield_byte_length = 0, bitwidth;
10227 uint64_t unshifted_value;
10228 uint64_t value;
10229
10230 const header_field_info *hfinfo = fi->hfinfo;
10231
10232 value = fvalue_get_uinteger64(fi->value);
10233 if (hfinfo->bitmask) {
10234 /* Figure out the bit width */
10235 bitwidth = hfinfo_container_bitwidth(hfinfo);
10236
10237 /* Un-shift bits */
10238 unshifted_value = value;
10239 unshifted_value <<= hfinfo_bitshift(hfinfo);
10240
10241 /* Create the bitfield first */
10242 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10243 bitfield_byte_length = (int) (p - label_str);
10244 }
10245
10246 /* Fill in the textual info */
10247 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10248}
10249
10250static const char *
10251hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10252{
10253 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10254 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10255
10256 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10257 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10258 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10259 else
10260 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10261 }
10262
10263 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10264 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10265
10266 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10267 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10268
10269 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10270}
10271
10272static const char *
10273hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10274{
10275 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10276 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10277 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10278 else
10279 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10280 }
10281
10282 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10283 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10284
10285 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10286 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10287
10288 /* If this is reached somebody registered a 64-bit field with a 32-bit
10289 * value-string, which isn't right. */
10290 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)
10291 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10292
10293 /* This is necessary to squelch MSVC errors; is there
10294 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10295 never returns? */
10296 return NULL((void*)0);
10297}
10298
10299static const char *
10300hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10301{
10302 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10303 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10304
10305 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)
;
10306
10307 /* This is necessary to squelch MSVC errors; is there
10308 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10309 never returns? */
10310 return NULL((void*)0);
10311}
10312
10313static const char *
10314hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10315{
10316 const char *str = hf_try_val_to_str(value, hfinfo);
10317
10318 return (str) ? str : unknown_str;
10319}
10320
10321static const char *
10322hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10323{
10324 const char *str = hf_try_val64_to_str(value, hfinfo);
10325
10326 return (str) ? str : unknown_str;
10327}
10328
10329/* Fills data for bitfield chars with val_strings */
10330static void
10331fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10332{
10333 char *p;
10334 int bitfield_byte_length, bitwidth;
10335 uint32_t unshifted_value;
10336 uint32_t value;
10337
10338 char buf[32];
10339 const char *out;
10340
10341 const header_field_info *hfinfo = fi->hfinfo;
10342
10343 /* Figure out the bit width */
10344 bitwidth = hfinfo_container_bitwidth(hfinfo);
10345
10346 /* Un-shift bits */
10347 value = fvalue_get_uinteger(fi->value);
10348
10349 unshifted_value = value;
10350 if (hfinfo->bitmask) {
10351 unshifted_value <<= hfinfo_bitshift(hfinfo);
10352 }
10353
10354 /* Create the bitfield first */
10355 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10356 bitfield_byte_length = (int) (p - label_str);
10357
10358 /* Fill in the textual info using stored (shifted) value */
10359 if (hfinfo->display == BASE_CUSTOM) {
10360 char tmp[ITEM_LABEL_LENGTH240];
10361 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10362
10363 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10363, "fmtfunc"))))
;
10364 fmtfunc(tmp, value);
10365 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10366 }
10367 else if (hfinfo->strings) {
10368 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10369
10370 out = hfinfo_char_vals_format(hfinfo, buf, value);
10371 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10372 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10373 else
10374 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10375 }
10376 else {
10377 out = hfinfo_char_value_format(hfinfo, buf, value);
10378
10379 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10380 }
10381}
10382
10383/* Fills data for bitfield ints with val_strings */
10384static void
10385fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10386{
10387 char *p;
10388 int bitfield_byte_length, bitwidth;
10389 uint32_t value, unshifted_value;
10390 char buf[NUMBER_LABEL_LENGTH80];
10391 const char *out;
10392
10393 const header_field_info *hfinfo = fi->hfinfo;
10394
10395 /* Figure out the bit width */
10396 if (fi->flags & FI_VARINT0x00004000)
10397 bitwidth = fi->length*8;
10398 else
10399 bitwidth = hfinfo_container_bitwidth(hfinfo);
10400
10401 /* Un-shift bits */
10402 if (is_signed)
10403 value = fvalue_get_sinteger(fi->value);
10404 else
10405 value = fvalue_get_uinteger(fi->value);
10406
10407 unshifted_value = value;
10408 if (hfinfo->bitmask) {
10409 unshifted_value <<= hfinfo_bitshift(hfinfo);
10410 }
10411
10412 /* Create the bitfield first */
10413 if (fi->flags & FI_VARINT0x00004000)
10414 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10415 else
10416 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10417 bitfield_byte_length = (int) (p - label_str);
10418
10419 /* Fill in the textual info using stored (shifted) value */
10420 if (hfinfo->display == BASE_CUSTOM) {
10421 char tmp[ITEM_LABEL_LENGTH240];
10422 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10423
10424 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10424, "fmtfunc"))))
;
10425 fmtfunc(tmp, value);
10426 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10427 }
10428 else if (hfinfo->strings) {
10429 const char *val_str = hf_try_val_to_str(value, hfinfo);
10430
10431 out = hfinfo_number_vals_format(hfinfo, buf, value);
10432 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10433 /*
10434 * Unique values only display value_string string
10435 * if there is a match. Otherwise it's just a number
10436 */
10437 if (val_str) {
10438 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10439 } else {
10440 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10441 }
10442 } else {
10443 if (val_str == NULL((void*)0))
10444 val_str = "Unknown";
10445
10446 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10447 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10448 else
10449 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10450 }
10451 }
10452 else {
10453 out = hfinfo_number_value_format(hfinfo, buf, value);
10454
10455 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10456 }
10457}
10458
10459static void
10460fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10461{
10462 char *p;
10463 int bitfield_byte_length, bitwidth;
10464 uint64_t value, unshifted_value;
10465 char buf[NUMBER_LABEL_LENGTH80];
10466 const char *out;
10467
10468 const header_field_info *hfinfo = fi->hfinfo;
10469
10470 /* Figure out the bit width */
10471 if (fi->flags & FI_VARINT0x00004000)
10472 bitwidth = fi->length*8;
10473 else
10474 bitwidth = hfinfo_container_bitwidth(hfinfo);
10475
10476 /* Un-shift bits */
10477 if (is_signed)
10478 value = fvalue_get_sinteger64(fi->value);
10479 else
10480 value = fvalue_get_uinteger64(fi->value);
10481
10482 unshifted_value = value;
10483 if (hfinfo->bitmask) {
10484 unshifted_value <<= hfinfo_bitshift(hfinfo);
10485 }
10486
10487 /* Create the bitfield first */
10488 if (fi->flags & FI_VARINT0x00004000)
10489 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10490 else
10491 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10492 bitfield_byte_length = (int) (p - label_str);
10493
10494 /* Fill in the textual info using stored (shifted) value */
10495 if (hfinfo->display == BASE_CUSTOM) {
10496 char tmp[ITEM_LABEL_LENGTH240];
10497 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10498
10499 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10499, "fmtfunc64"
))))
;
10500 fmtfunc64(tmp, value);
10501 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10502 }
10503 else if (hfinfo->strings) {
10504 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10505
10506 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10507 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10508 /*
10509 * Unique values only display value_string string
10510 * if there is a match. Otherwise it's just a number
10511 */
10512 if (val_str) {
10513 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10514 } else {
10515 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10516 }
10517 } else {
10518 if (val_str == NULL((void*)0))
10519 val_str = "Unknown";
10520
10521 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10522 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10523 else
10524 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10525 }
10526 }
10527 else {
10528 out = hfinfo_number_value_format64(hfinfo, buf, value);
10529
10530 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10531 }
10532}
10533
10534static void
10535fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10536{
10537 const header_field_info *hfinfo = fi->hfinfo;
10538 uint32_t value;
10539
10540 char buf[32];
10541 const char *out;
10542
10543 value = fvalue_get_uinteger(fi->value);
10544
10545 /* Fill in the textual info */
10546 if (hfinfo->display == BASE_CUSTOM) {
10547 char tmp[ITEM_LABEL_LENGTH240];
10548 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10549
10550 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10550, "fmtfunc"))))
;
10551 fmtfunc(tmp, value);
10552 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10553 }
10554 else if (hfinfo->strings) {
10555 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10556
10557 out = hfinfo_char_vals_format(hfinfo, buf, value);
10558 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10559 }
10560 else {
10561 out = hfinfo_char_value_format(hfinfo, buf, value);
10562
10563 label_fill(label_str, 0, hfinfo, out, value_pos);
10564 }
10565}
10566
10567static void
10568fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10569{
10570 const header_field_info *hfinfo = fi->hfinfo;
10571 uint32_t value;
10572
10573 char buf[NUMBER_LABEL_LENGTH80];
10574 const char *out;
10575
10576 if (is_signed)
10577 value = fvalue_get_sinteger(fi->value);
10578 else
10579 value = fvalue_get_uinteger(fi->value);
10580
10581 /* Fill in the textual info */
10582 if (hfinfo->display == BASE_CUSTOM) {
10583 char tmp[ITEM_LABEL_LENGTH240];
10584 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10585
10586 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10586, "fmtfunc"))))
;
10587 fmtfunc(tmp, value);
10588 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10589 }
10590 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10591 /*
10592 * It makes no sense to have a value-string table for a
10593 * frame-number field - they're just integers giving
10594 * the ordinal frame number.
10595 */
10596 const char *val_str = hf_try_val_to_str(value, hfinfo);
10597
10598 out = hfinfo_number_vals_format(hfinfo, buf, value);
10599 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10600 /*
10601 * Unique values only display value_string string
10602 * if there is a match. Otherwise it's just a number
10603 */
10604 if (val_str) {
10605 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10606 } else {
10607 label_fill(label_str, 0, hfinfo, out, value_pos);
10608 }
10609 } else {
10610 if (val_str == NULL((void*)0))
10611 val_str = "Unknown";
10612
10613 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10614 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10615 else
10616 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10617 }
10618 }
10619 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
))
) {
10620 char tmp[ITEM_LABEL_LENGTH240];
10621
10622 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10623 display_to_port_type((field_display_e)hfinfo->display), value);
10624 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10625 }
10626 else {
10627 out = hfinfo_number_value_format(hfinfo, buf, value);
10628
10629 label_fill(label_str, 0, hfinfo, out, value_pos);
10630 }
10631}
10632
10633static void
10634fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10635{
10636 const header_field_info *hfinfo = fi->hfinfo;
10637 uint64_t value;
10638
10639 char buf[NUMBER_LABEL_LENGTH80];
10640 const char *out;
10641
10642 if (is_signed)
10643 value = fvalue_get_sinteger64(fi->value);
10644 else
10645 value = fvalue_get_uinteger64(fi->value);
10646
10647 /* Fill in the textual info */
10648 if (hfinfo->display == BASE_CUSTOM) {
10649 char tmp[ITEM_LABEL_LENGTH240];
10650 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10651
10652 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10652, "fmtfunc64"
))))
;
10653 fmtfunc64(tmp, value);
10654 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10655 }
10656 else if (hfinfo->strings) {
10657 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10658
10659 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10660 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10661 /*
10662 * Unique values only display value_string string
10663 * if there is a match. Otherwise it's just a number
10664 */
10665 if (val_str) {
10666 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10667 } else {
10668 label_fill(label_str, 0, hfinfo, out, value_pos);
10669 }
10670 } else {
10671 if (val_str == NULL((void*)0))
10672 val_str = "Unknown";
10673
10674 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10675 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10676 else
10677 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10678 }
10679 }
10680 else {
10681 out = hfinfo_number_value_format64(hfinfo, buf, value);
10682
10683 label_fill(label_str, 0, hfinfo, out, value_pos);
10684 }
10685}
10686
10687static size_t
10688fill_display_label_float(const field_info *fi, char *label_str)
10689{
10690 int display;
10691 int digits;
10692 int n;
10693 double value;
10694
10695 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10696 value = fvalue_get_floating(fi->value);
10697
10698 if (display == BASE_CUSTOM) {
10699 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10700 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10700, "fmtfunc"))))
;
10701 fmtfunc(label_str, value);
10702 return strlen(label_str);
10703 }
10704
10705 switch (display) {
10706 case BASE_NONE:
10707 if (fi->hfinfo->type == FT_FLOAT)
10708 digits = FLT_DIG6;
10709 else
10710 digits = DBL_DIG15;
10711
10712 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%.*g", digits, value);
10713 break;
10714 case BASE_DEC:
10715 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%f", value);
10716 break;
10717 case BASE_HEX:
10718 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%a", value);
10719 break;
10720 case BASE_EXP:
10721 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%e", value);
10722 break;
10723 default:
10724 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10724
, __func__, "assertion \"not reached\" failed")
;
10725 }
10726 if (n < 0) {
10727 return 0; /* error */
10728 }
10729 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10730 const char *hf_str_val;
10731 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10732 n += protoo_strlcpy(label_str + n, hf_str_val, ITEM_LABEL_LENGTH240 - n);
10733 }
10734 if (n > ITEM_LABEL_LENGTH240) {
10735 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10735, __func__, "label length too small"); } } while (0)
;
10736 return strlen(label_str);
10737 }
10738
10739 return n;
10740}
10741
10742void
10743fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10744{
10745 char tmp[ITEM_LABEL_LENGTH240];
10746
10747 fill_display_label_float(fi, tmp);
10748 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10749}
10750
10751int
10752hfinfo_bitshift(const header_field_info *hfinfo)
10753{
10754 return ws_ctz(hfinfo->bitmask);
10755}
10756
10757
10758static int
10759hfinfo_bitoffset(const header_field_info *hfinfo)
10760{
10761 if (!hfinfo->bitmask) {
10762 return 0;
10763 }
10764
10765 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10766 * as the first bit */
10767 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10768}
10769
10770static int
10771hfinfo_mask_bitwidth(const header_field_info *hfinfo)
10772{
10773 if (!hfinfo->bitmask) {
10774 return 0;
10775 }
10776
10777 /* ilog2 = first set bit, ctz = last set bit */
10778 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
10779}
10780
10781static int
10782hfinfo_type_bitwidth(enum ftenum type)
10783{
10784 int bitwidth = 0;
10785
10786 switch (type) {
10787 case FT_CHAR:
10788 case FT_UINT8:
10789 case FT_INT8:
10790 bitwidth = 8;
10791 break;
10792 case FT_UINT16:
10793 case FT_INT16:
10794 bitwidth = 16;
10795 break;
10796 case FT_UINT24:
10797 case FT_INT24:
10798 bitwidth = 24;
10799 break;
10800 case FT_UINT32:
10801 case FT_INT32:
10802 bitwidth = 32;
10803 break;
10804 case FT_UINT40:
10805 case FT_INT40:
10806 bitwidth = 40;
10807 break;
10808 case FT_UINT48:
10809 case FT_INT48:
10810 bitwidth = 48;
10811 break;
10812 case FT_UINT56:
10813 case FT_INT56:
10814 bitwidth = 56;
10815 break;
10816 case FT_UINT64:
10817 case FT_INT64:
10818 bitwidth = 64;
10819 break;
10820 default:
10821 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 10821))
;
10822 ;
10823 }
10824 return bitwidth;
10825}
10826
10827
10828static int
10829hfinfo_container_bitwidth(const header_field_info *hfinfo)
10830{
10831 if (!hfinfo->bitmask) {
10832 return 0;
10833 }
10834
10835 if (hfinfo->type == FT_BOOLEAN) {
10836 return hfinfo->display; /* hacky? :) */
10837 }
10838
10839 return hfinfo_type_bitwidth(hfinfo->type);
10840}
10841
10842static int
10843hfinfo_hex_digits(const header_field_info *hfinfo)
10844{
10845 int bitwidth;
10846
10847 /* If we have a bitmask, hfinfo->type is the width of the container, so not
10848 * appropriate to determine the number of hex digits for the field.
10849 * So instead, we compute it from the bitmask.
10850 */
10851 if (hfinfo->bitmask != 0) {
10852 bitwidth = hfinfo_mask_bitwidth(hfinfo);
10853 } else {
10854 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
10855 }
10856
10857 /* Divide by 4, rounding up, to get number of hex digits. */
10858 return (bitwidth + 3) / 4;
10859}
10860
10861const char *
10862hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
10863{
10864 char *ptr = &buf[6];
10865 static const char hex_digits[16] =
10866 { '0', '1', '2', '3', '4', '5', '6', '7',
10867 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
10868
10869 *ptr = '\0';
10870 *(--ptr) = '\'';
10871 /* Properly format value */
10872 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
10873 /*
10874 * Printable, so just show the character, and, if it needs
10875 * to be escaped, escape it.
10876 */
10877 *(--ptr) = value;
10878 if (value == '\\' || value == '\'')
10879 *(--ptr) = '\\';
10880 } else {
10881 /*
10882 * Non-printable; show it as an escape sequence.
10883 */
10884 switch (value) {
10885
10886 case '\0':
10887 /*
10888 * Show a NUL with only one digit.
10889 */
10890 *(--ptr) = '0';
10891 break;
10892
10893 case '\a':
10894 *(--ptr) = 'a';
10895 break;
10896
10897 case '\b':
10898 *(--ptr) = 'b';
10899 break;
10900
10901 case '\f':
10902 *(--ptr) = 'f';
10903 break;
10904
10905 case '\n':
10906 *(--ptr) = 'n';
10907 break;
10908
10909 case '\r':
10910 *(--ptr) = 'r';
10911 break;
10912
10913 case '\t':
10914 *(--ptr) = 't';
10915 break;
10916
10917 case '\v':
10918 *(--ptr) = 'v';
10919 break;
10920
10921 default:
10922 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
10923
10924 case BASE_OCT:
10925 *(--ptr) = (value & 0x7) + '0';
10926 value >>= 3;
10927 *(--ptr) = (value & 0x7) + '0';
10928 value >>= 3;
10929 *(--ptr) = (value & 0x7) + '0';
10930 break;
10931
10932 case BASE_HEX:
10933 *(--ptr) = hex_digits[value & 0x0F];
10934 value >>= 4;
10935 *(--ptr) = hex_digits[value & 0x0F];
10936 *(--ptr) = 'x';
10937 break;
10938
10939 default:
10940 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
10941 }
10942 }
10943 *(--ptr) = '\\';
10944 }
10945 *(--ptr) = '\'';
10946 return ptr;
10947}
10948
10949static const char *
10950hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
10951{
10952 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
10953 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
))
;
10954
10955 *ptr = '\0';
10956 /* Properly format value */
10957 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
10958 case BASE_DEC:
10959 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
10960
10961 case BASE_DEC_HEX:
10962 *(--ptr) = ')';
10963 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10964 *(--ptr) = '(';
10965 *(--ptr) = ' ';
10966 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
10967 return ptr;
10968
10969 case BASE_OCT:
10970 return oct_to_str_back(ptr, value);
10971
10972 case BASE_HEX:
10973 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10974
10975 case BASE_HEX_DEC:
10976 *(--ptr) = ')';
10977 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
10978 *(--ptr) = '(';
10979 *(--ptr) = ' ';
10980 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10981 return ptr;
10982
10983 case BASE_PT_UDP:
10984 case BASE_PT_TCP:
10985 case BASE_PT_DCCP:
10986 case BASE_PT_SCTP:
10987 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
10988 display_to_port_type((field_display_e)display), value);
10989 return buf;
10990 case BASE_OUI:
10991 {
10992 uint8_t p_oui[3];
10993 const char *manuf_name;
10994
10995 p_oui[0] = value >> 16 & 0xFF;
10996 p_oui[1] = value >> 8 & 0xFF;
10997 p_oui[2] = value & 0xFF;
10998
10999 /* Attempt an OUI lookup. */
11000 manuf_name = uint_get_manuf_name_if_known(value);
11001 if (manuf_name == NULL((void*)0)) {
11002 /* Could not find an OUI. */
11003 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11004 }
11005 else {
11006 /* Found an address string. */
11007 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11008 }
11009 return buf;
11010 }
11011
11012 default:
11013 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11014 }
11015 return ptr;
11016}
11017
11018static const char *
11019hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11020{
11021 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11022 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
))
;
11023
11024 *ptr = '\0';
11025 /* Properly format value */
11026 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11027 case BASE_DEC:
11028 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11029
11030 case BASE_DEC_HEX:
11031 *(--ptr) = ')';
11032 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11033 *(--ptr) = '(';
11034 *(--ptr) = ' ';
11035 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11036 return ptr;
11037
11038 case BASE_OCT:
11039 return oct64_to_str_back(ptr, value);
11040
11041 case BASE_HEX:
11042 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11043
11044 case BASE_HEX_DEC:
11045 *(--ptr) = ')';
11046 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11047 *(--ptr) = '(';
11048 *(--ptr) = ' ';
11049 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11050 return ptr;
11051
11052 default:
11053 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11054 }
11055
11056 return ptr;
11057}
11058
11059static const char *
11060hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11061{
11062 int display = hfinfo->display;
11063
11064 if (hfinfo->type == FT_FRAMENUM) {
11065 /*
11066 * Frame numbers are always displayed in decimal.
11067 */
11068 display = BASE_DEC;
11069 }
11070
11071 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11072}
11073
11074static const char *
11075hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11076{
11077 int display = hfinfo->display;
11078
11079 if (hfinfo->type == FT_FRAMENUM) {
11080 /*
11081 * Frame numbers are always displayed in decimal.
11082 */
11083 display = BASE_DEC;
11084 }
11085
11086 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11087}
11088
11089static const char *
11090hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11091{
11092 /* Get the underlying BASE_ value */
11093 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11094
11095 return hfinfo_char_value_format_display(display, buf, value);
11096}
11097
11098static const char *
11099hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11100{
11101 /* Get the underlying BASE_ value */
11102 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11103
11104 if (hfinfo->type == FT_FRAMENUM) {
11105 /*
11106 * Frame numbers are always displayed in decimal.
11107 */
11108 display = BASE_DEC;
11109 }
11110
11111 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11112 display = BASE_DEC;
11113 } else if (display == BASE_OUI) {
11114 display = BASE_HEX;
11115 }
11116
11117 switch (display) {
11118 case BASE_NONE:
11119 /* case BASE_DEC: */
11120 case BASE_DEC_HEX:
11121 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11122 case BASE_CUSTOM:
11123 display = BASE_DEC;
11124 break;
11125
11126 /* case BASE_HEX: */
11127 case BASE_HEX_DEC:
11128 display = BASE_HEX;
11129 break;
11130 }
11131
11132 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11133}
11134
11135static const char *
11136hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11137{
11138 /* Get the underlying BASE_ value */
11139 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11140
11141 if (hfinfo->type == FT_FRAMENUM) {
11142 /*
11143 * Frame numbers are always displayed in decimal.
11144 */
11145 display = BASE_DEC;
11146 }
11147
11148 switch (display) {
11149 case BASE_NONE:
11150 /* case BASE_DEC: */
11151 case BASE_DEC_HEX:
11152 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11153 case BASE_CUSTOM:
11154 display = BASE_DEC;
11155 break;
11156
11157 /* case BASE_HEX: */
11158 case BASE_HEX_DEC:
11159 display = BASE_HEX;
11160 break;
11161 }
11162
11163 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11164}
11165
11166static const char *
11167hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11168{
11169 /* Get the underlying BASE_ value */
11170 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11171
11172 return hfinfo_char_value_format_display(display, buf, value);
11173}
11174
11175static const char *
11176hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11177{
11178 /* Get the underlying BASE_ value */
11179 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11180
11181 if (display == BASE_NONE)
11182 return NULL((void*)0);
11183
11184 if (display == BASE_DEC_HEX)
11185 display = BASE_DEC;
11186 if (display == BASE_HEX_DEC)
11187 display = BASE_HEX;
11188
11189 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11190}
11191
11192static const char *
11193hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11194{
11195 /* Get the underlying BASE_ value */
11196 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11197
11198 if (display == BASE_NONE)
11199 return NULL((void*)0);
11200
11201 if (display == BASE_DEC_HEX)
11202 display = BASE_DEC;
11203 if (display == BASE_HEX_DEC)
11204 display = BASE_HEX;
11205
11206 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11207}
11208
11209const char *
11210proto_registrar_get_name(const int n)
11211{
11212 header_field_info *hfinfo;
11213
11214 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", 11214
, __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", 11214
, "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", 11214, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11215 return hfinfo->name;
11216}
11217
11218const char *
11219proto_registrar_get_abbrev(const int n)
11220{
11221 header_field_info *hfinfo;
11222
11223 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", 11223
, __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", 11223
, "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", 11223, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11224 return hfinfo->abbrev;
11225}
11226
11227enum ftenum
11228proto_registrar_get_ftype(const int n)
11229{
11230 header_field_info *hfinfo;
11231
11232 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", 11232
, __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", 11232
, "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", 11232, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11233 return hfinfo->type;
11234}
11235
11236int
11237proto_registrar_get_parent(const int n)
11238{
11239 header_field_info *hfinfo;
11240
11241 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", 11241
, __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", 11241
, "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", 11241, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11242 return hfinfo->parent;
11243}
11244
11245bool_Bool
11246proto_registrar_is_protocol(const int n)
11247{
11248 header_field_info *hfinfo;
11249
11250 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", 11250
, __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", 11250
, "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", 11250, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11251 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11252}
11253
11254/* Returns length of field in packet (not necessarily the length
11255 * in our internal representation, as in the case of IPv4).
11256 * 0 means undeterminable at time of registration
11257 * -1 means the field is not registered. */
11258int
11259proto_registrar_get_length(const int n)
11260{
11261 header_field_info *hfinfo;
11262
11263 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", 11263
, __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", 11263
, "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", 11263, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11264 return ftype_wire_size(hfinfo->type);
11265}
11266
11267/* Looks for a protocol or a field in a proto_tree. Returns true if
11268 * it exists anywhere, or false if it exists nowhere. */
11269bool_Bool
11270proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11271{
11272 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11273
11274 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11275 return true1;
11276 }
11277 else {
11278 return false0;
11279 }
11280}
11281
11282/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11283 * This only works if the hfindex was "primed" before the dissection
11284 * took place, as we just pass back the already-created GPtrArray*.
11285 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11286 * handles that. */
11287GPtrArray *
11288proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11289{
11290 if (!tree)
11291 return NULL((void*)0);
11292
11293 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11294 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11295 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11296 else
11297 return NULL((void*)0);
11298}
11299
11300bool_Bool
11301proto_tracking_interesting_fields(const proto_tree *tree)
11302{
11303 GHashTable *interesting_hfids;
11304
11305 if (!tree)
11306 return false0;
11307
11308 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11309
11310 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11311}
11312
11313/* Helper struct for proto_find_info() and proto_all_finfos() */
11314typedef struct {
11315 GPtrArray *array;
11316 int id;
11317} ffdata_t;
11318
11319/* Helper function for proto_find_info() */
11320static bool_Bool
11321find_finfo(proto_node *node, void * data)
11322{
11323 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11324 if (fi && fi->hfinfo) {
11325 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11326 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11327 }
11328 }
11329
11330 /* Don't stop traversing. */
11331 return false0;
11332}
11333
11334/* Helper function for proto_find_first_info() */
11335static bool_Bool
11336find_first_finfo(proto_node *node, void *data)
11337{
11338 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11339 if (fi && fi->hfinfo) {
11340 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11341 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11342
11343 /* Stop traversing. */
11344 return true1;
11345 }
11346 }
11347
11348 /* Continue traversing. */
11349 return false0;
11350}
11351
11352/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11353* This works on any proto_tree, primed or unprimed, but actually searches
11354* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11355* The caller does need to free the returned GPtrArray with
11356* g_ptr_array_free(<array>, true).
11357*/
11358GPtrArray *
11359proto_find_finfo(proto_tree *tree, const int id)
11360{
11361 ffdata_t ffdata;
11362
11363 ffdata.array = g_ptr_array_new();
11364 ffdata.id = id;
11365
11366 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11367
11368 return ffdata.array;
11369}
11370
11371/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11372* This works on any proto_tree, primed or unprimed, but actually searches
11373* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11374* The caller does need to free the returned GPtrArray with
11375* g_ptr_array_free(<array>, true).
11376*/
11377GPtrArray *
11378proto_find_first_finfo(proto_tree *tree, const int id)
11379{
11380 ffdata_t ffdata;
11381
11382 ffdata.array = g_ptr_array_new();
11383 ffdata.id = id;
11384
11385 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11386
11387 return ffdata.array;
11388}
11389
11390/* Helper function for proto_all_finfos() */
11391static bool_Bool
11392every_finfo(proto_node *node, void * data)
11393{
11394 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11395 if (fi && fi->hfinfo) {
11396 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11397 }
11398
11399 /* Don't stop traversing. */
11400 return false0;
11401}
11402
11403/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11404 * The caller does need to free the returned GPtrArray with
11405 * g_ptr_array_free(<array>, true).
11406 */
11407GPtrArray *
11408proto_all_finfos(proto_tree *tree)
11409{
11410 ffdata_t ffdata;
11411
11412 /* Pre allocate enough space to hold all fields in most cases */
11413 ffdata.array = g_ptr_array_sized_new(512);
11414 ffdata.id = 0;
11415
11416 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11417
11418 return ffdata.array;
11419}
11420
11421
11422typedef struct {
11423 unsigned offset;
11424 field_info *finfo;
11425 tvbuff_t *tvb;
11426} offset_search_t;
11427
11428static bool_Bool
11429check_for_offset(proto_node *node, void * data)
11430{
11431 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11432 offset_search_t *offsearch = (offset_search_t *)data;
11433
11434 /* !fi == the top most container node which holds nothing */
11435 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11436 if (offsearch->offset >= (unsigned) fi->start &&
11437 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11438
11439 offsearch->finfo = fi;
11440 return false0; /* keep traversing */
11441 }
11442 }
11443 return false0; /* keep traversing */
11444}
11445
11446/* Search a proto_tree backwards (from leaves to root) looking for the field
11447 * whose start/length occupies 'offset' */
11448/* XXX - I couldn't find an easy way to search backwards, so I search
11449 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11450 * the one I want to return to the user. This algorithm is inefficient
11451 * and could be re-done, but I'd have to handle all the children and
11452 * siblings of each node myself. When I have more time I'll do that.
11453 * (yeah right) */
11454field_info *
11455proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11456{
11457 offset_search_t offsearch;
11458
11459 offsearch.offset = offset;
11460 offsearch.finfo = NULL((void*)0);
11461 offsearch.tvb = tvb;
11462
11463 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11464
11465 return offsearch.finfo;
11466}
11467
11468typedef struct {
11469 int length;
11470 char *buf;
11471} decoded_data_t;
11472
11473static bool_Bool
11474check_for_undecoded(proto_node *node, void * data)
11475{
11476 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11477 decoded_data_t* decoded = (decoded_data_t*)data;
11478 int i;
11479 unsigned byte;
11480 unsigned bit;
11481
11482 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11483 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11484 byte = i / 8;
11485 bit = i % 8;
11486 decoded->buf[byte] |= (1 << bit);
11487 }
11488 }
11489
11490 return false0;
11491}
11492
11493char*
11494proto_find_undecoded_data(proto_tree *tree, unsigned length)
11495{
11496 decoded_data_t decoded;
11497 decoded.length = length;
11498 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11499
11500 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11501 return decoded.buf;
11502}
11503
11504/* Dumps the protocols in the registration database to stdout. An independent
11505 * program can take this output and format it into nice tables or HTML or
11506 * whatever.
11507 *
11508 * There is one record per line. The fields are tab-delimited.
11509 *
11510 * Field 1 = protocol name
11511 * Field 2 = protocol short name
11512 * Field 3 = protocol filter name
11513 * Field 4 = protocol enabled
11514 * Field 5 = protocol enabled by default
11515 * Field 6 = protocol can toggle
11516 */
11517void
11518proto_registrar_dump_protocols(void)
11519{
11520 protocol_t *protocol;
11521 int i;
11522 void *cookie = NULL((void*)0);
11523
11524
11525 i = proto_get_first_protocol(&cookie);
11526 while (i != -1) {
11527 protocol = find_protocol_by_id(i);
11528 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11529 protocol->name,
11530 protocol->short_name,
11531 protocol->filter_name,
11532 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11533 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11534 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11535 i = proto_get_next_protocol(&cookie);
11536 }
11537}
11538
11539/* Dumps the value_strings, extended value string headers, range_strings
11540 * or true/false strings for fields that have them.
11541 * There is one record per line. Fields are tab-delimited.
11542 * There are four types of records: Value String, Extended Value String Header,
11543 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11544 * the type of record.
11545 *
11546 * Note that a record will be generated only if the value_string,... is referenced
11547 * in a registered hfinfo entry.
11548 *
11549 *
11550 * Value Strings
11551 * -------------
11552 * Field 1 = 'V'
11553 * Field 2 = Field abbreviation to which this value string corresponds
11554 * Field 3 = Integer value
11555 * Field 4 = String
11556 *
11557 * Extended Value String Headers
11558 * -----------------------------
11559 * Field 1 = 'E'
11560 * Field 2 = Field abbreviation to which this extended value string header corresponds
11561 * Field 3 = Extended Value String "Name"
11562 * Field 4 = Number of entries in the associated value_string array
11563 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11564 *
11565 * Range Strings
11566 * -------------
11567 * Field 1 = 'R'
11568 * Field 2 = Field abbreviation to which this range string corresponds
11569 * Field 3 = Integer value: lower bound
11570 * Field 4 = Integer value: upper bound
11571 * Field 5 = String
11572 *
11573 * True/False Strings
11574 * ------------------
11575 * Field 1 = 'T'
11576 * Field 2 = Field abbreviation to which this true/false string corresponds
11577 * Field 3 = True String
11578 * Field 4 = False String
11579 */
11580void
11581proto_registrar_dump_values(void)
11582{
11583 header_field_info *hfinfo;
11584 int i, len, vi;
11585 const value_string *vals;
11586 const val64_string *vals64;
11587 const range_string *range;
11588 const true_false_string *tfs;
11589 const unit_name_string *units;
11590
11591 len = gpa_hfinfo.len;
11592 for (i = 0; i < len ; i++) {
11593 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11594 continue; /* This is a deregistered protocol or field */
11595
11596 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", 11596
, __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", 11596
, "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", 11596, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11597
11598 if (hfinfo->id == hf_text_only) {
11599 continue;
11600 }
11601
11602 /* ignore protocols */
11603 if (proto_registrar_is_protocol(i)) {
11604 continue;
11605 }
11606 /* process header fields */
11607#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11608 /*
11609 * If this field isn't at the head of the list of
11610 * fields with this name, skip this field - all
11611 * fields with the same name are really just versions
11612 * of the same field stored in different bits, and
11613 * should have the same type/radix/value list, and
11614 * just differ in their bit masks. (If a field isn't
11615 * a bitfield, but can be, say, 1 or 2 bytes long,
11616 * it can just be made FT_UINT16, meaning the
11617 * *maximum* length is 2 bytes, and be used
11618 * for all lengths.)
11619 */
11620 if (hfinfo->same_name_prev_id != -1)
11621 continue;
11622#endif
11623 vals = NULL((void*)0);
11624 vals64 = NULL((void*)0);
11625 range = NULL((void*)0);
11626 tfs = NULL((void*)0);
11627 units = NULL((void*)0);
11628
11629 if (hfinfo->strings != NULL((void*)0)) {
11630 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11631 (hfinfo->type == FT_CHAR ||
11632 hfinfo->type == FT_UINT8 ||
11633 hfinfo->type == FT_UINT16 ||
11634 hfinfo->type == FT_UINT24 ||
11635 hfinfo->type == FT_UINT32 ||
11636 hfinfo->type == FT_UINT40 ||
11637 hfinfo->type == FT_UINT48 ||
11638 hfinfo->type == FT_UINT56 ||
11639 hfinfo->type == FT_UINT64 ||
11640 hfinfo->type == FT_INT8 ||
11641 hfinfo->type == FT_INT16 ||
11642 hfinfo->type == FT_INT24 ||
11643 hfinfo->type == FT_INT32 ||
11644 hfinfo->type == FT_INT40 ||
11645 hfinfo->type == FT_INT48 ||
11646 hfinfo->type == FT_INT56 ||
11647 hfinfo->type == FT_INT64 ||
11648 hfinfo->type == FT_FLOAT ||
11649 hfinfo->type == FT_DOUBLE)) {
11650
11651 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11652 range = (const range_string *)hfinfo->strings;
11653 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11654 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11655 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11656 } else {
11657 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11658 }
11659 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11660 vals64 = (const val64_string *)hfinfo->strings;
11661 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11662 units = (const unit_name_string *)hfinfo->strings;
11663 } else {
11664 vals = (const value_string *)hfinfo->strings;
11665 }
11666 }
11667 else if (hfinfo->type == FT_BOOLEAN) {
11668 tfs = (const struct true_false_string *)hfinfo->strings;
11669 }
11670 }
11671
11672 /* Print value strings? */
11673 if (vals) {
11674 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11675 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11676 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11677 if (!val64_string_ext_validate(vse_p)) {
11678 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11678, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11679 continue;
11680 }
11681 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11682 printf("E\t%s\t%u\t%s\t%s\n",
11683 hfinfo->abbrev,
11684 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11685 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11686 val64_string_ext_match_type_str(vse_p));
11687 } else {
11688 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11689 if (!value_string_ext_validate(vse_p)) {
11690 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11690, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11691 continue;
11692 }
11693 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11694 printf("E\t%s\t%u\t%s\t%s\n",
11695 hfinfo->abbrev,
11696 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11697 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11698 value_string_ext_match_type_str(vse_p));
11699 }
11700 }
11701 vi = 0;
11702 while (vals[vi].strptr) {
11703 /* Print in the proper base */
11704 if (hfinfo->type == FT_CHAR) {
11705 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11706 printf("V\t%s\t'%c'\t%s\n",
11707 hfinfo->abbrev,
11708 vals[vi].value,
11709 vals[vi].strptr);
11710 } else {
11711 if (hfinfo->display == BASE_HEX) {
11712 printf("V\t%s\t'\\x%02x'\t%s\n",
11713 hfinfo->abbrev,
11714 vals[vi].value,
11715 vals[vi].strptr);
11716 }
11717 else {
11718 printf("V\t%s\t'\\%03o'\t%s\n",
11719 hfinfo->abbrev,
11720 vals[vi].value,
11721 vals[vi].strptr);
11722 }
11723 }
11724 } else {
11725 if (hfinfo->display == BASE_HEX) {
11726 printf("V\t%s\t0x%x\t%s\n",
11727 hfinfo->abbrev,
11728 vals[vi].value,
11729 vals[vi].strptr);
11730 }
11731 else {
11732 printf("V\t%s\t%u\t%s\n",
11733 hfinfo->abbrev,
11734 vals[vi].value,
11735 vals[vi].strptr);
11736 }
11737 }
11738 vi++;
11739 }
11740 }
11741 else if (vals64) {
11742 vi = 0;
11743 while (vals64[vi].strptr) {
11744 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11745 hfinfo->abbrev,
11746 vals64[vi].value,
11747 vals64[vi].strptr);
11748 vi++;
11749 }
11750 }
11751
11752 /* print range strings? */
11753 else if (range) {
11754 vi = 0;
11755 while (range[vi].strptr) {
11756 /* Print in the proper base */
11757 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11758 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11759 hfinfo->abbrev,
11760 range[vi].value_min,
11761 range[vi].value_max,
11762 range[vi].strptr);
11763 }
11764 else {
11765 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11766 hfinfo->abbrev,
11767 range[vi].value_min,
11768 range[vi].value_max,
11769 range[vi].strptr);
11770 }
11771 vi++;
11772 }
11773 }
11774
11775 /* Print true/false strings? */
11776 else if (tfs) {
11777 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11778 tfs->true_string, tfs->false_string);
11779 }
11780 /* Print unit strings? */
11781 else if (units) {
11782 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11783 units->singular, units->plural ? units->plural : "(no plural)");
11784 }
11785 }
11786}
11787
11788/* Prints the number of registered fields.
11789 * Useful for determining an appropriate value for
11790 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
11791 *
11792 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
11793 * the number of fields, true otherwise.
11794 */
11795bool_Bool
11796proto_registrar_dump_fieldcount(void)
11797{
11798 uint32_t i;
11799 header_field_info *hfinfo;
11800 uint32_t deregistered_count = 0;
11801 uint32_t same_name_count = 0;
11802 uint32_t protocol_count = 0;
11803
11804 for (i = 0; i < gpa_hfinfo.len; i++) {
11805 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
11806 deregistered_count++;
11807 continue; /* This is a deregistered protocol or header field */
11808 }
11809
11810 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", 11810
, __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", 11810
, "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", 11810, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11811
11812 if (proto_registrar_is_protocol(i))
11813 protocol_count++;
11814
11815 if (hfinfo->same_name_prev_id != -1)
11816 same_name_count++;
11817 }
11818
11819 printf("There are %u header fields registered, of which:\n"
11820 "\t%u are deregistered\n"
11821 "\t%u are protocols\n"
11822 "\t%u have the same name as another field\n\n",
11823 gpa_hfinfo.len, deregistered_count, protocol_count,
11824 same_name_count);
11825
11826 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
11827 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
11828 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
11829 "\n");
11830
11831 printf("The header field table consumes %u KiB of memory.\n",
11832 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
11833 printf("The fields themselves consume %u KiB of memory.\n",
11834 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
11835
11836 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
11837}
11838
11839static void
11840elastic_add_base_mapping(json_dumper *dumper)
11841{
11842 json_dumper_set_member_name(dumper, "settings");
11843 json_dumper_begin_object(dumper);
11844 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
11845 json_dumper_value_anyf(dumper, "%d", 1000000);
11846 json_dumper_end_object(dumper);
11847}
11848
11849static char*
11850ws_type_to_elastic(unsigned type _U___attribute__((unused)))
11851{
11852 switch(type) {
11853 case FT_UINT16:
11854 case FT_INT16:
11855 case FT_INT32:
11856 case FT_UINT24:
11857 case FT_INT24:
11858 return "integer";
11859 case FT_INT8:
11860 case FT_UINT8:
11861 return "short";
11862 case FT_FRAMENUM:
11863 case FT_UINT32:
11864 case FT_UINT40:
11865 case FT_UINT48:
11866 case FT_UINT56:
11867 case FT_UINT64: // Actually it's not handled by 'long' elastic type.
11868 case FT_INT48:
11869 case FT_INT64:
11870 return "long";
11871 case FT_FLOAT:
11872 case FT_DOUBLE:
11873 return "float";
11874 case FT_IPv6:
11875 case FT_IPv4:
11876 return "ip";
11877 case FT_ABSOLUTE_TIME:
11878 case FT_RELATIVE_TIME:
11879 return "date";
11880 case FT_BYTES:
11881 case FT_UINT_BYTES:
11882 return "byte";
11883 case FT_BOOLEAN:
11884 return "boolean";
11885 default:
11886 return NULL((void*)0);
11887 }
11888}
11889
11890static char*
11891dot_to_underscore(char* str)
11892{
11893 unsigned i;
11894 for (i = 0; i < strlen(str); i++) {
11895 if (str[i] == '.')
11896 str[i] = '_';
11897 }
11898 return str;
11899}
11900
11901/* Dumps a mapping file for ElasticSearch
11902 */
11903void
11904proto_registrar_dump_elastic(const char* filter)
11905{
11906 header_field_info *hfinfo;
11907 header_field_info *parent_hfinfo;
11908 unsigned i;
11909 bool_Bool open_object = true1;
11910 const char* prev_proto = NULL((void*)0);
11911 char* str;
11912 char** protos = NULL((void*)0);
11913 char* proto;
11914 bool_Bool found;
11915 unsigned j;
11916 char* type;
11917 char* prev_item = NULL((void*)0);
11918
11919 /* We have filtering protocols. Extract them. */
11920 if (filter) {
11921 protos = g_strsplit(filter, ",", -1);
11922 }
11923
11924 /*
11925 * To help tracking down the json tree, objects have been appended with a comment:
11926 * n.label -> where n is the indentation level and label the name of the object
11927 */
11928
11929 json_dumper dumper = {
11930 .output_file = stdoutstdout,
11931 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
11932 };
11933 json_dumper_begin_object(&dumper); // 1.root
11934 elastic_add_base_mapping(&dumper);
11935
11936 json_dumper_set_member_name(&dumper, "mappings");
11937 json_dumper_begin_object(&dumper); // 2.mappings
11938 json_dumper_set_member_name(&dumper, "dynamic");
11939 json_dumper_value_anyf(&dumper, "false");
11940
11941 json_dumper_set_member_name(&dumper, "properties");
11942 json_dumper_begin_object(&dumper); // 3.properties
11943 json_dumper_set_member_name(&dumper, "timestamp");
11944 json_dumper_begin_object(&dumper); // 4.timestamp
11945 json_dumper_set_member_name(&dumper, "type");
11946 json_dumper_value_string(&dumper, "date");
11947 json_dumper_end_object(&dumper); // 4.timestamp
11948
11949 json_dumper_set_member_name(&dumper, "layers");
11950 json_dumper_begin_object(&dumper); // 4.layers
11951 json_dumper_set_member_name(&dumper, "properties");
11952 json_dumper_begin_object(&dumper); // 5.properties
11953
11954 for (i = 0; i < gpa_hfinfo.len; i++) {
11955 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11956 continue; /* This is a deregistered protocol or header field */
11957
11958 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", 11958
, __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", 11958
, "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", 11958, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11959
11960 /*
11961 * Skip the pseudo-field for "proto_tree_add_text()" since
11962 * we don't want it in the list of filterable protocols.
11963 */
11964 if (hfinfo->id == hf_text_only)
11965 continue;
11966
11967 if (!proto_registrar_is_protocol(i)) {
11968 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", 11968
, __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", 11968
, "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", 11968
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
11969
11970 /*
11971 * Skip the field if filter protocols have been set and this one's
11972 * parent is not listed.
11973 */
11974 if (protos) {
11975 found = false0;
11976 j = 0;
11977 proto = protos[0];
11978 while(proto) {
11979 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
11980 found = true1;
11981 break;
11982 }
11983 j++;
11984 proto = protos[j];
11985 }
11986 if (!found)
11987 continue;
11988 }
11989
11990 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
11991 json_dumper_end_object(&dumper); // 7.properties
11992 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
11993 open_object = true1;
11994 }
11995
11996 prev_proto = parent_hfinfo->abbrev;
11997
11998 if (open_object) {
11999 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12000 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12001 json_dumper_set_member_name(&dumper, "properties");
12002 json_dumper_begin_object(&dumper); // 7.properties
12003 open_object = false0;
12004 }
12005 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12006 type = ws_type_to_elastic(hfinfo->type);
12007 /* when type is NULL, we have the default mapping: string */
12008 if (type) {
12009 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12010 dot_to_underscore(str);
12011 if (g_strcmp0(prev_item, str)) {
12012 json_dumper_set_member_name(&dumper, str);
12013 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12014 json_dumper_set_member_name(&dumper, "type");
12015 json_dumper_value_string(&dumper, type);
12016 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12017 }
12018 g_free(prev_item);
12019 prev_item = str;
12020 }
12021 }
12022 }
12023 g_free(prev_item);
12024
12025 if (prev_proto) {
12026 json_dumper_end_object(&dumper); // 7.properties
12027 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12028 }
12029
12030 json_dumper_end_object(&dumper); // 5.properties
12031 json_dumper_end_object(&dumper); // 4.layers
12032 json_dumper_end_object(&dumper); // 3.properties
12033 json_dumper_end_object(&dumper); // 2.mappings
12034 json_dumper_end_object(&dumper); // 1.root
12035 bool_Bool ret = json_dumper_finish(&dumper);
12036 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12036, "ret"))))
;
12037
12038 g_strfreev(protos);
12039}
12040
12041/* Dumps the contents of the registration database to stdout. An independent
12042 * program can take this output and format it into nice tables or HTML or
12043 * whatever.
12044 *
12045 * There is one record per line. Each record is either a protocol or a header
12046 * field, differentiated by the first field. The fields are tab-delimited.
12047 *
12048 * Protocols
12049 * ---------
12050 * Field 1 = 'P'
12051 * Field 2 = descriptive protocol name
12052 * Field 3 = protocol abbreviation
12053 *
12054 * Header Fields
12055 * -------------
12056 * Field 1 = 'F'
12057 * Field 2 = descriptive field name
12058 * Field 3 = field abbreviation
12059 * Field 4 = type ( textual representation of the ftenum type )
12060 * Field 5 = parent protocol abbreviation
12061 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12062 * Field 7 = bitmask: format: hex: 0x....
12063 * Field 8 = blurb describing field
12064 */
12065void
12066proto_registrar_dump_fields(void)
12067{
12068 header_field_info *hfinfo, *parent_hfinfo;
12069 int i, len;
12070 const char *enum_name;
12071 const char *base_name;
12072 const char *blurb;
12073 char width[5];
12074
12075 len = gpa_hfinfo.len;
12076 for (i = 0; i < len ; i++) {
12077 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12078 continue; /* This is a deregistered protocol or header field */
12079
12080 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", 12080
, __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", 12080
, "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", 12080, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12081
12082 /*
12083 * Skip the pseudo-field for "proto_tree_add_text()" since
12084 * we don't want it in the list of filterable fields.
12085 */
12086 if (hfinfo->id == hf_text_only)
12087 continue;
12088
12089 /* format for protocols */
12090 if (proto_registrar_is_protocol(i)) {
12091 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12092 }
12093 /* format for header fields */
12094 else {
12095 /*
12096 * If this field isn't at the head of the list of
12097 * fields with this name, skip this field - all
12098 * fields with the same name are really just versions
12099 * of the same field stored in different bits, and
12100 * should have the same type/radix/value list, and
12101 * just differ in their bit masks. (If a field isn't
12102 * a bitfield, but can be, say, 1 or 2 bytes long,
12103 * it can just be made FT_UINT16, meaning the
12104 * *maximum* length is 2 bytes, and be used
12105 * for all lengths.)
12106 */
12107 if (hfinfo->same_name_prev_id != -1)
12108 continue;
12109
12110 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", 12110
, __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", 12110
, "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", 12110
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12111
12112 enum_name = ftype_name(hfinfo->type);
12113 base_name = "";
12114
12115 if (hfinfo->type == FT_CHAR ||
12116 hfinfo->type == FT_UINT8 ||
12117 hfinfo->type == FT_UINT16 ||
12118 hfinfo->type == FT_UINT24 ||
12119 hfinfo->type == FT_UINT32 ||
12120 hfinfo->type == FT_UINT40 ||
12121 hfinfo->type == FT_UINT48 ||
12122 hfinfo->type == FT_UINT56 ||
12123 hfinfo->type == FT_UINT64 ||
12124 hfinfo->type == FT_INT8 ||
12125 hfinfo->type == FT_INT16 ||
12126 hfinfo->type == FT_INT24 ||
12127 hfinfo->type == FT_INT32 ||
12128 hfinfo->type == FT_INT40 ||
12129 hfinfo->type == FT_INT48 ||
12130 hfinfo->type == FT_INT56 ||
12131 hfinfo->type == FT_INT64) {
12132
12133 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12134 case BASE_NONE:
12135 case BASE_DEC:
12136 case BASE_HEX:
12137 case BASE_OCT:
12138 case BASE_DEC_HEX:
12139 case BASE_HEX_DEC:
12140 case BASE_CUSTOM:
12141 case BASE_PT_UDP:
12142 case BASE_PT_TCP:
12143 case BASE_PT_DCCP:
12144 case BASE_PT_SCTP:
12145 case BASE_OUI:
12146 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12147 break;
12148 default:
12149 base_name = "????";
12150 break;
12151 }
12152 } else if (hfinfo->type == FT_BOOLEAN) {
12153 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12154 snprintf(width, sizeof(width), "%d", hfinfo->display);
12155 base_name = width;
12156 }
12157
12158 blurb = hfinfo->blurb;
12159 if (blurb == NULL((void*)0))
12160 blurb = "";
12161 else if (strlen(blurb) == 0)
12162 blurb = "\"\"";
12163
12164 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12165 hfinfo->name, hfinfo->abbrev, enum_name,
12166 parent_hfinfo->abbrev, base_name,
12167 hfinfo->bitmask, blurb);
12168 }
12169 }
12170}
12171
12172/* Dumps all abbreviated field and protocol completions of the given string to
12173 * stdout. An independent program may use this for command-line tab completion
12174 * of fields.
12175 */
12176bool_Bool
12177proto_registrar_dump_field_completions(const char *prefix)
12178{
12179 header_field_info *hfinfo;
12180 int i, len;
12181 size_t prefix_len;
12182 bool_Bool matched = false0;
12183
12184 prefix_len = strlen(prefix);
12185 len = gpa_hfinfo.len;
12186 for (i = 0; i < len ; i++) {
12187 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12188 continue; /* This is a deregistered protocol or header field */
12189
12190 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", 12190
, __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", 12190
, "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", 12190, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12191
12192 /*
12193 * Skip the pseudo-field for "proto_tree_add_text()" since
12194 * we don't want it in the list of filterable fields.
12195 */
12196 if (hfinfo->id == hf_text_only)
12197 continue;
12198
12199 /* format for protocols */
12200 if (proto_registrar_is_protocol(i)) {
12201 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12202 matched = true1;
12203 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12204 }
12205 }
12206 /* format for header fields */
12207 else {
12208 /*
12209 * If this field isn't at the head of the list of
12210 * fields with this name, skip this field - all
12211 * fields with the same name are really just versions
12212 * of the same field stored in different bits, and
12213 * should have the same type/radix/value list, and
12214 * just differ in their bit masks. (If a field isn't
12215 * a bitfield, but can be, say, 1 or 2 bytes long,
12216 * it can just be made FT_UINT16, meaning the
12217 * *maximum* length is 2 bytes, and be used
12218 * for all lengths.)
12219 */
12220 if (hfinfo->same_name_prev_id != -1)
12221 continue;
12222
12223 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12224 matched = true1;
12225 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12226 }
12227 }
12228 }
12229 return matched;
12230}
12231
12232/* Dumps field types and descriptive names to stdout. An independent
12233 * program can take this output and format it into nice tables or HTML or
12234 * whatever.
12235 *
12236 * There is one record per line. The fields are tab-delimited.
12237 *
12238 * Field 1 = field type name, e.g. FT_UINT8
12239 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12240 */
12241void
12242proto_registrar_dump_ftypes(void)
12243{
12244 int fte;
12245
12246 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12247 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12248 }
12249}
12250
12251/* This function indicates whether it's possible to construct a
12252 * "match selected" display filter string for the specified field,
12253 * returns an indication of whether it's possible, and, if it's
12254 * possible and "filter" is non-null, constructs the filter and
12255 * sets "*filter" to point to it.
12256 * You do not need to [g_]free() this string since it will be automatically
12257 * freed once the next packet is dissected.
12258 */
12259static bool_Bool
12260construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12261 char **filter)
12262{
12263 const header_field_info *hfinfo;
12264 char *ptr;
12265 int buf_len;
12266 int i;
12267 int start, length, length_remaining;
12268 uint8_t c;
12269
12270 if (!finfo)
12271 return false0;
12272
12273 hfinfo = finfo->hfinfo;
12274 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12274, "hfinfo"))))
;
12275
12276 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12277 * then "the numeric value ... is not used when preparing
12278 * filters for the field in question." If it's any other
12279 * base, we'll generate the filter normally (which will
12280 * be numeric, even though the human-readable string does
12281 * work for filtering.)
12282 *
12283 * XXX - It might be nice to use fvalue_to_string_repr() in
12284 * "proto_item_fill_label()" as well, although, there, you'd
12285 * have to deal with the base *and* with resolved values for
12286 * addresses.
12287 *
12288 * Perhaps in addition to taking the repr type (DISPLAY
12289 * or DFILTER) and the display (base), fvalue_to_string_repr()
12290 * should have the the "strings" values in the header_field_info
12291 * structure for the field as a parameter, so it can have
12292 * if the field is Boolean or an enumerated integer type,
12293 * the tables used to generate human-readable values.
12294 */
12295 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12296 const char *str = NULL((void*)0);
12297
12298 switch (hfinfo->type) {
12299
12300 case FT_INT8:
12301 case FT_INT16:
12302 case FT_INT24:
12303 case FT_INT32:
12304 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12305 break;
12306
12307 case FT_CHAR:
12308 case FT_UINT8:
12309 case FT_UINT16:
12310 case FT_UINT24:
12311 case FT_UINT32:
12312 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12313 break;
12314
12315 default:
12316 break;
12317 }
12318
12319 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12320 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12321 return true1;
12322 }
12323 }
12324
12325 switch (hfinfo->type) {
12326
12327 case FT_PROTOCOL:
12328 if (filter != NULL((void*)0))
12329 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12330 break;
12331
12332 case FT_NONE:
12333 /*
12334 * If the length is 0, just match the name of the
12335 * field.
12336 *
12337 * (Also check for negative values, just in case,
12338 * as we'll cast it to an unsigned value later.)
12339 */
12340 length = finfo->length;
12341 if (length == 0) {
12342 if (filter != NULL((void*)0))
12343 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12344 break;
12345 }
12346 if (length < 0)
12347 return false0;
12348
12349 /*
12350 * This doesn't have a value, so we'd match
12351 * on the raw bytes at this address.
12352 *
12353 * Should we be allowed to access to the raw bytes?
12354 * If "edt" is NULL, the answer is "no".
12355 */
12356 if (edt == NULL((void*)0))
12357 return false0;
12358
12359 /*
12360 * Is this field part of the raw frame tvbuff?
12361 * If not, we can't use "frame[N:M]" to match
12362 * it.
12363 *
12364 * XXX - should this be frame-relative, or
12365 * protocol-relative?
12366 *
12367 * XXX - does this fallback for non-registered
12368 * fields even make sense?
12369 */
12370 if (finfo->ds_tvb != edt->tvb)
12371 return false0; /* you lose */
12372
12373 /*
12374 * Don't go past the end of that tvbuff.
12375 */
12376 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12377 if (length > length_remaining)
12378 length = length_remaining;
12379 if (length <= 0)
12380 return false0;
12381
12382 if (filter != NULL((void*)0)) {
12383 start = finfo->start;
12384 buf_len = 32 + length * 3;
12385 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12386 ptr = *filter;
12387
12388 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12389 "frame[%d:%d] == ", finfo->start, length);
12390 for (i=0; i<length; i++) {
12391 c = tvb_get_uint8(finfo->ds_tvb, start);
12392 start++;
12393 if (i == 0 ) {
12394 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12395 }
12396 else {
12397 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12398 }
12399 }
12400 }
12401 break;
12402
12403 /* By default, use the fvalue's "to_string_repr" method. */
12404 default:
12405 if (filter != NULL((void*)0)) {
12406 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12407 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12408 wmem_free(NULL((void*)0), str);
12409 }
12410 break;
12411 }
12412
12413 return true1;
12414}
12415
12416/*
12417 * Returns true if we can do a "match selected" on the field, false
12418 * otherwise.
12419 */
12420bool_Bool
12421proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12422{
12423 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12424}
12425
12426/* This function attempts to construct a "match selected" display filter
12427 * string for the specified field; if it can do so, it returns a pointer
12428 * to the string, otherwise it returns NULL.
12429 *
12430 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12431 */
12432char *
12433proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12434{
12435 char *filter = NULL((void*)0);
12436
12437 if (!construct_match_selected_string(finfo, edt, &filter))
12438 {
12439 wmem_free(NULL((void*)0), filter);
12440 return NULL((void*)0);
12441 }
12442 return filter;
12443}
12444
12445/* This function is common code for all proto_tree_add_bitmask... functions.
12446 */
12447
12448static bool_Bool
12449proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12450 const int len, const int ett, int * const *fields,
12451 const int flags, bool_Bool first,
12452 bool_Bool use_parent_tree,
12453 proto_tree* tree, uint64_t value)
12454{
12455 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12456 uint64_t bitmask = 0;
12457 uint64_t tmpval;
12458 header_field_info *hf;
12459 uint32_t integer32;
12460 int bit_offset;
12461 int no_of_bits;
12462
12463 if (!*fields)
12464 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"
)
;
12465
12466 if (len < 0 || len > 8)
12467 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12468 /**
12469 * packet-frame.c uses len=0 since the value is taken from the packet
12470 * metadata, not the packet bytes. In that case, assume that all bits
12471 * in the provided value are valid.
12472 */
12473 if (len > 0) {
12474 available_bits >>= (8 - (unsigned)len)*8;
12475 }
12476
12477 if (use_parent_tree == false0)
12478 tree = proto_item_add_subtree(item, ett);
12479
12480 while (*fields) {
12481 uint64_t present_bits;
12482 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", 12482, __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", 12482
, "**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", 12482, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12483 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", 12483
, "hf->bitmask != 0", hf->abbrev))))
;
12484
12485 bitmask |= hf->bitmask;
12486
12487 /* Skip fields that aren't fully present */
12488 present_bits = available_bits & hf->bitmask;
12489 if (present_bits != hf->bitmask) {
12490 fields++;
12491 continue;
12492 }
12493
12494 switch (hf->type) {
12495 case FT_CHAR:
12496 case FT_UINT8:
12497 case FT_UINT16:
12498 case FT_UINT24:
12499 case FT_UINT32:
12500 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12501 break;
12502
12503 case FT_INT8:
12504 case FT_INT16:
12505 case FT_INT24:
12506 case FT_INT32:
12507 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12508 break;
12509
12510 case FT_UINT40:
12511 case FT_UINT48:
12512 case FT_UINT56:
12513 case FT_UINT64:
12514 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12515 break;
12516
12517 case FT_INT40:
12518 case FT_INT48:
12519 case FT_INT56:
12520 case FT_INT64:
12521 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12522 break;
12523
12524 case FT_BOOLEAN:
12525 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12526 break;
12527
12528 default:
12529 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))
12530 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))
12531 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))
12532 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))
;
12533 break;
12534 }
12535 if (flags & BMT_NO_APPEND0x01) {
12536 fields++;
12537 continue;
12538 }
12539 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12540
12541 /* XXX: README.developer and the comments have always defined
12542 * BMT_NO_INT as "only boolean flags are added to the title /
12543 * don't add non-boolean (integral) fields", but the
12544 * implementation has always added BASE_CUSTOM and fields with
12545 * value_strings, though not fields with unit_strings.
12546 * Possibly this is because some dissectors use a FT_UINT8
12547 * with a value_string for fields that should be a FT_BOOLEAN.
12548 */
12549 switch (hf->type) {
12550 case FT_CHAR:
12551 if (hf->display == BASE_CUSTOM) {
12552 char lbl[ITEM_LABEL_LENGTH240];
12553 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12554
12555 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12555, "fmtfunc"))))
;
12556 fmtfunc(lbl, (uint32_t) tmpval);
12557 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12558 hf->name, lbl);
12559 first = false0;
12560 }
12561 else if (hf->strings) {
12562 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12563 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12564 first = false0;
12565 }
12566 else if (!(flags & BMT_NO_INT0x02)) {
12567 char buf[32];
12568 const char *out;
12569
12570 if (!first) {
12571 proto_item_append_text(item, ", ");
12572 }
12573
12574 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12575 proto_item_append_text(item, "%s: %s", hf->name, out);
12576 first = false0;
12577 }
12578
12579 break;
12580
12581 case FT_UINT8:
12582 case FT_UINT16:
12583 case FT_UINT24:
12584 case FT_UINT32:
12585 if (hf->display == BASE_CUSTOM) {
12586 char lbl[ITEM_LABEL_LENGTH240];
12587 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12588
12589 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12589, "fmtfunc"))))
;
12590 fmtfunc(lbl, (uint32_t) tmpval);
12591 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12592 hf->name, lbl);
12593 first = false0;
12594 }
12595 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12596 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12597 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12598 first = false0;
12599 }
12600 else if (!(flags & BMT_NO_INT0x02)) {
12601 char buf[NUMBER_LABEL_LENGTH80];
12602 const char *out = NULL((void*)0);
12603
12604 if (!first) {
12605 proto_item_append_text(item, ", ");
12606 }
12607
12608 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12609 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12610 }
12611 if (out == NULL((void*)0)) {
12612 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12613 }
12614 proto_item_append_text(item, "%s: %s", hf->name, out);
12615 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12616 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12617 }
12618 first = false0;
12619 }
12620
12621 break;
12622
12623 case FT_INT8:
12624 case FT_INT16:
12625 case FT_INT24:
12626 case FT_INT32:
12627 integer32 = (uint32_t) tmpval;
12628 if (hf->bitmask) {
12629 no_of_bits = ws_count_ones(hf->bitmask);
12630 integer32 = ws_sign_ext32(integer32, no_of_bits);
12631 }
12632 if (hf->display == BASE_CUSTOM) {
12633 char lbl[ITEM_LABEL_LENGTH240];
12634 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12635
12636 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12636, "fmtfunc"))))
;
12637 fmtfunc(lbl, (int32_t) integer32);
12638 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12639 hf->name, lbl);
12640 first = false0;
12641 }
12642 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12643 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12644 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12645 first = false0;
12646 }
12647 else if (!(flags & BMT_NO_INT0x02)) {
12648 char buf[NUMBER_LABEL_LENGTH80];
12649 const char *out = NULL((void*)0);
12650
12651 if (!first) {
12652 proto_item_append_text(item, ", ");
12653 }
12654
12655 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12656 out = hf_try_val_to_str((int32_t) integer32, hf);
12657 }
12658 if (out == NULL((void*)0)) {
12659 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12660 }
12661 proto_item_append_text(item, "%s: %s", hf->name, out);
12662 if (hf->display & BASE_UNIT_STRING0x00001000) {
12663 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12664 }
12665 first = false0;
12666 }
12667
12668 break;
12669
12670 case FT_UINT40:
12671 case FT_UINT48:
12672 case FT_UINT56:
12673 case FT_UINT64:
12674 if (hf->display == BASE_CUSTOM) {
12675 char lbl[ITEM_LABEL_LENGTH240];
12676 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12677
12678 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12678, "fmtfunc"))))
;
12679 fmtfunc(lbl, tmpval);
12680 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12681 hf->name, lbl);
12682 first = false0;
12683 }
12684 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12685 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12686 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12687 first = false0;
12688 }
12689 else if (!(flags & BMT_NO_INT0x02)) {
12690 char buf[NUMBER_LABEL_LENGTH80];
12691 const char *out = NULL((void*)0);
12692
12693 if (!first) {
12694 proto_item_append_text(item, ", ");
12695 }
12696
12697 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12698 out = hf_try_val64_to_str(tmpval, hf);
12699 }
12700 if (out == NULL((void*)0)) {
12701 out = hfinfo_number_value_format64(hf, buf, tmpval);
12702 }
12703 proto_item_append_text(item, "%s: %s", hf->name, out);
12704 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12705 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12706 }
12707 first = false0;
12708 }
12709
12710 break;
12711
12712 case FT_INT40:
12713 case FT_INT48:
12714 case FT_INT56:
12715 case FT_INT64:
12716 if (hf->bitmask) {
12717 no_of_bits = ws_count_ones(hf->bitmask);
12718 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12719 }
12720 if (hf->display == BASE_CUSTOM) {
12721 char lbl[ITEM_LABEL_LENGTH240];
12722 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12723
12724 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12724, "fmtfunc"))))
;
12725 fmtfunc(lbl, (int64_t) tmpval);
12726 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12727 hf->name, lbl);
12728 first = false0;
12729 }
12730 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12731 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12732 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12733 first = false0;
12734 }
12735 else if (!(flags & BMT_NO_INT0x02)) {
12736 char buf[NUMBER_LABEL_LENGTH80];
12737 const char *out = NULL((void*)0);
12738
12739 if (!first) {
12740 proto_item_append_text(item, ", ");
12741 }
12742
12743 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12744 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12745 }
12746 if (out == NULL((void*)0)) {
12747 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12748 }
12749 proto_item_append_text(item, "%s: %s", hf->name, out);
12750 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12751 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12752 }
12753 first = false0;
12754 }
12755
12756 break;
12757
12758 case FT_BOOLEAN:
12759 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12760 /* If we have true/false strings, emit full - otherwise messages
12761 might look weird */
12762 const struct true_false_string *tfs =
12763 (const struct true_false_string *)hf->strings;
12764
12765 if (tmpval) {
12766 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12767 hf->name, tfs->true_string);
12768 first = false0;
12769 } else if (!(flags & BMT_NO_FALSE0x04)) {
12770 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12771 hf->name, tfs->false_string);
12772 first = false0;
12773 }
12774 } else if (hf->bitmask & value) {
12775 /* If the flag is set, show the name */
12776 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12777 first = false0;
12778 }
12779 break;
12780 default:
12781 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))
12782 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))
12783 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))
12784 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))
;
12785 break;
12786 }
12787
12788 fields++;
12789 }
12790
12791 /* XXX: We don't pass the hfi into this function. Perhaps we should,
12792 * but then again most dissectors don't set the bitmask field for
12793 * the higher level bitmask hfi, so calculate the bitmask from the
12794 * fields present. */
12795 if (item) {
12796 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
12797 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
12798 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset) & 7) <<
5)); } while(0)
;
12799 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) <<
8)); } while(0)
;
12800 }
12801 return first;
12802}
12803
12804/* This function will dissect a sequence of bytes that describe a
12805 * bitmask and supply the value of that sequence through a pointer.
12806 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12807 * to be dissected.
12808 * This field will form an expansion under which the individual fields of the
12809 * bitmask is dissected and displayed.
12810 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12811 *
12812 * fields is an array of pointers to int that lists all the fields of the
12813 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12814 * or another integer of the same type/size as hf_hdr with a mask specified.
12815 * This array is terminated by a NULL entry.
12816 *
12817 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12818 * FT_integer fields that have a value_string attached will have the
12819 * matched string displayed on the expansion line.
12820 */
12821proto_item *
12822proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
12823 const unsigned offset, const int hf_hdr,
12824 const int ett, int * const *fields,
12825 const unsigned encoding, uint64_t *retval)
12826{
12827 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);
12828}
12829
12830/* This function will dissect a sequence of bytes that describe a
12831 * bitmask.
12832 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12833 * to be dissected.
12834 * This field will form an expansion under which the individual fields of the
12835 * bitmask is dissected and displayed.
12836 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12837 *
12838 * fields is an array of pointers to int that lists all the fields of the
12839 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12840 * or another integer of the same type/size as hf_hdr with a mask specified.
12841 * This array is terminated by a NULL entry.
12842 *
12843 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12844 * FT_integer fields that have a value_string attached will have the
12845 * matched string displayed on the expansion line.
12846 */
12847proto_item *
12848proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
12849 const unsigned offset, const int hf_hdr,
12850 const int ett, int * const *fields,
12851 const unsigned encoding)
12852{
12853 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
12854}
12855
12856/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12857 * what data is appended to the header.
12858 */
12859proto_item *
12860proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12861 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
12862 uint64_t *retval)
12863{
12864 proto_item *item = NULL((void*)0);
12865 header_field_info *hf;
12866 int len;
12867 uint64_t value;
12868
12869 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", 12869, __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", 12869
, "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", 12869, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12870 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", 12870, (hf)->abbrev)))
;
12871 len = ftype_wire_size(hf->type);
12872 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12873
12874 if (parent_tree) {
12875 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12876 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12877 flags, false0, false0, NULL((void*)0), value);
12878 }
12879
12880 *retval = value;
12881 if (hf->bitmask) {
12882 /* Mask out irrelevant portions */
12883 *retval &= hf->bitmask;
12884 /* Shift bits */
12885 *retval >>= hfinfo_bitshift(hf);
12886 }
12887
12888 return item;
12889}
12890
12891/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12892 * what data is appended to the header.
12893 */
12894proto_item *
12895proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12896 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
12897{
12898 proto_item *item = NULL((void*)0);
12899 header_field_info *hf;
12900 int len;
12901 uint64_t value;
12902
12903 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", 12903, __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", 12903
, "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", 12903, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12904 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", 12904, (hf)->abbrev)))
;
12905
12906 if (parent_tree) {
12907 len = ftype_wire_size(hf->type);
12908 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12909 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12910 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12911 flags, false0, false0, NULL((void*)0), value);
12912 }
12913
12914 return item;
12915}
12916
12917/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
12918 can't be retrieved directly from tvb) */
12919proto_item *
12920proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12921 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
12922{
12923 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
12924 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
12925}
12926
12927/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
12928WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
12929proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12930 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
12931{
12932 proto_item *item = NULL((void*)0);
12933 header_field_info *hf;
12934 int len;
12935
12936 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", 12936, __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", 12936
, "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", 12936, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12937 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", 12937, (hf)->abbrev)))
;
12938 /* the proto_tree_add_uint/_uint64() calls below
12939 will fail if tvb==NULL and len!=0 */
12940 len = tvb ? ftype_wire_size(hf->type) : 0;
12941
12942 if (parent_tree) {
12943 if (len <= 4)
12944 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
12945 else
12946 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
12947
12948 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12949 flags, false0, false0, NULL((void*)0), value);
12950 }
12951
12952 return item;
12953}
12954
12955/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
12956void
12957proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
12958 const int len, int * const *fields, const unsigned encoding)
12959{
12960 uint64_t value;
12961
12962 if (tree) {
12963 value = get_uint64_value(tree, tvb, offset, len, encoding);
12964 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
12965 BMT_NO_APPEND0x01, false0, true1, tree, value);
12966 }
12967}
12968
12969WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
12970proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
12971 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
12972{
12973 uint64_t value;
12974
12975 value = get_uint64_value(tree, tvb, offset, len, encoding);
12976 if (tree) {
12977 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
12978 BMT_NO_APPEND0x01, false0, true1, tree, value);
12979 }
12980 if (retval) {
12981 *retval = value;
12982 }
12983}
12984
12985WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
12986proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
12987 const int len, int * const *fields, const uint64_t value)
12988{
12989 if (tree) {
12990 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
12991 BMT_NO_APPEND0x01, false0, true1, tree, value);
12992 }
12993}
12994
12995
12996/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
12997 * This is intended to support bitmask fields whose lengths can vary, perhaps
12998 * as the underlying standard evolves over time.
12999 * With this API there is the possibility of being called to display more or
13000 * less data than the dissector was coded to support.
13001 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13002 * Thus when presented with "too much" or "too little" data, MSbits will be
13003 * ignored or MSfields sacrificed.
13004 *
13005 * Only fields for which all defined bits are available are displayed.
13006 */
13007proto_item *
13008proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13009 const unsigned offset, const unsigned len, const int hf_hdr,
13010 const int ett, int * const *fields, struct expert_field* exp,
13011 const unsigned encoding)
13012{
13013 proto_item *item = NULL((void*)0);
13014 header_field_info *hf;
13015 unsigned decodable_len;
13016 unsigned decodable_offset;
13017 uint32_t decodable_value;
13018 uint64_t value;
13019
13020 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", 13020, __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", 13020
, "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", 13020, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13021 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", 13021, (hf)->abbrev)))
;
13022
13023 decodable_offset = offset;
13024 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13025
13026 /* If we are ftype_wire_size-limited,
13027 * make sure we decode as many LSBs as possible.
13028 */
13029 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13030 decodable_offset += (len - decodable_len);
13031 }
13032
13033 if (parent_tree) {
13034 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13035 decodable_len, encoding);
13036
13037 /* The root item covers all the bytes even if we can't decode them all */
13038 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13039 decodable_value);
13040 }
13041
13042 if (decodable_len < len) {
13043 /* Dissector likely requires updating for new protocol revision */
13044 expert_add_info_format(NULL((void*)0), item, exp,
13045 "Only least-significant %d of %d bytes decoded",
13046 decodable_len, len);
13047 }
13048
13049 if (item) {
13050 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13051 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13052 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13053 }
13054
13055 return item;
13056}
13057
13058/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13059proto_item *
13060proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13061 const unsigned offset, const unsigned len,
13062 const char *name, const char *fallback,
13063 const int ett, int * const *fields,
13064 const unsigned encoding, const int flags)
13065{
13066 proto_item *item = NULL((void*)0);
13067 uint64_t value;
13068
13069 if (parent_tree) {
13070 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13071 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13072 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13073 flags, true1, false0, NULL((void*)0), value) && fallback) {
13074 /* Still at first item - append 'fallback' text if any */
13075 proto_item_append_text(item, "%s", fallback);
13076 }
13077 }
13078
13079 return item;
13080}
13081
13082proto_item *
13083proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13084 const unsigned bit_offset, const int no_of_bits,
13085 const unsigned encoding)
13086{
13087 header_field_info *hfinfo;
13088 int octet_length;
13089 int octet_offset;
13090
13091 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", 13091, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13091
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13091, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13092
13093 if (no_of_bits < 0) {
13094 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13095 }
13096 octet_length = (no_of_bits + 7) >> 3;
13097 octet_offset = bit_offset >> 3;
13098 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13099
13100 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13101 * but only after doing a bunch more work (which we can, in the common
13102 * case, shortcut here).
13103 */
13104 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13105 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", 13105
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13105, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13105, "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", 13105, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13106
13107 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13108}
13109
13110/*
13111 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13112 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13113 * Offset should be given in bits from the start of the tvb.
13114 */
13115
13116static proto_item *
13117_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13118 const unsigned bit_offset, const int no_of_bits,
13119 uint64_t *return_value, const unsigned encoding)
13120{
13121 int offset;
13122 unsigned length;
13123 uint8_t tot_no_bits;
13124 char *bf_str;
13125 char lbl_str[ITEM_LABEL_LENGTH240];
13126 uint64_t value = 0;
13127 uint8_t *bytes = NULL((void*)0);
13128 size_t bytes_length = 0;
13129
13130 proto_item *pi;
13131 header_field_info *hf_field;
13132
13133 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13134 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", 13134, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13134
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13134, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13135
13136 if (hf_field->bitmask != 0) {
13137 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)
13138 " 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)
13139 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)
;
13140 }
13141
13142 if (no_of_bits < 0) {
13143 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13144 } else if (no_of_bits == 0) {
13145 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)
13146 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)
;
13147 }
13148
13149 /* Byte align offset */
13150 offset = bit_offset>>3;
13151
13152 /*
13153 * Calculate the number of octets used to hold the bits
13154 */
13155 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13156 length = (tot_no_bits + 7) >> 3;
13157
13158 if (no_of_bits < 65) {
13159 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13160 } else if (hf_field->type != FT_BYTES) {
13161 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 65",proto_report_dissector_bug("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 65"
, hf_field->abbrev, no_of_bits)
13162 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 > 65"
, hf_field->abbrev, no_of_bits)
;
13163 return NULL((void*)0);
13164 }
13165
13166 /* Sign extend for signed types */
13167 switch (hf_field->type) {
13168 case FT_INT8:
13169 case FT_INT16:
13170 case FT_INT24:
13171 case FT_INT32:
13172 case FT_INT40:
13173 case FT_INT48:
13174 case FT_INT56:
13175 case FT_INT64:
13176 value = ws_sign_ext64(value, no_of_bits);
13177 break;
13178
13179 default:
13180 break;
13181 }
13182
13183 if (return_value) {
13184 *return_value = value;
13185 }
13186
13187 /* Coast clear. Try and fake it */
13188 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13189 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", 13189
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13189, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13189, "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", 13189, __func__, "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); } } }
;
13190
13191 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13192
13193 switch (hf_field->type) {
13194 case FT_BOOLEAN:
13195 /* Boolean field */
13196 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13197 "%s = %s: %s",
13198 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13199 break;
13200
13201 case FT_CHAR:
13202 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13203 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13204 break;
13205
13206 case FT_UINT8:
13207 case FT_UINT16:
13208 case FT_UINT24:
13209 case FT_UINT32:
13210 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13211 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13212 break;
13213
13214 case FT_INT8:
13215 case FT_INT16:
13216 case FT_INT24:
13217 case FT_INT32:
13218 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13219 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13220 break;
13221
13222 case FT_UINT40:
13223 case FT_UINT48:
13224 case FT_UINT56:
13225 case FT_UINT64:
13226 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13227 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13228 break;
13229
13230 case FT_INT40:
13231 case FT_INT48:
13232 case FT_INT56:
13233 case FT_INT64:
13234 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13235 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13236 break;
13237
13238 case FT_BYTES:
13239 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13240 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13241 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13242 proto_item_set_text(pi, "%s", lbl_str);
13243 return pi;
13244
13245 /* TODO: should handle FT_UINT_BYTES ? */
13246
13247 default:
13248 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))
13249 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))
13250 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))
13251 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))
;
13252 return NULL((void*)0);
13253 }
13254
13255 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13256 return pi;
13257}
13258
13259proto_item *
13260proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13261 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13262 uint64_t *return_value)
13263{
13264 proto_item *pi;
13265 int no_of_bits;
13266 int octet_offset;
13267 unsigned mask_initial_bit_offset;
13268 unsigned mask_greatest_bit_offset;
13269 unsigned octet_length;
13270 uint8_t i;
13271 char bf_str[256];
13272 char lbl_str[ITEM_LABEL_LENGTH240];
13273 uint64_t value;
13274 uint64_t composite_bitmask;
13275 uint64_t composite_bitmap;
13276
13277 header_field_info *hf_field;
13278
13279 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13280 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", 13280, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13280
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13280, "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
13281
13282 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13283 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)
13284 " 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)
13285 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)
;
13286 }
13287
13288 mask_initial_bit_offset = bit_offset % 8;
13289
13290 no_of_bits = 0;
13291 value = 0;
13292 i = 0;
13293 mask_greatest_bit_offset = 0;
13294 composite_bitmask = 0;
13295 composite_bitmap = 0;
13296
13297 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
13298 uint64_t crumb_mask, crumb_value;
13299 uint8_t crumb_end_bit_offset;
13300
13301 crumb_value = tvb_get_bits64(tvb,
13302 bit_offset + crumb_spec[i].crumb_bit_offset,
13303 crumb_spec[i].crumb_bit_length,
13304 ENC_BIG_ENDIAN0x00000000);
13305 value += crumb_value;
13306 no_of_bits += crumb_spec[i].crumb_bit_length;
13307 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", 13307
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13308
13309 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13310 octet containing the initial offset.
13311 If the mask is beyond 32 bits, then give up on bit map display.
13312 This could be improved in future, probably showing a table
13313 of 32 or 64 bits per row */
13314 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13315 crumb_end_bit_offset = mask_initial_bit_offset
13316 + crumb_spec[i].crumb_bit_offset
13317 + crumb_spec[i].crumb_bit_length;
13318 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'
13319
13320 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13321 mask_greatest_bit_offset = crumb_end_bit_offset;
13322 }
13323 /* Currently the bitmap of the crumbs are only shown if
13324 * smaller than 32 bits. Do not bother calculating the
13325 * mask if it is larger than that. */
13326 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13327 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'
13328 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13329 }
13330 }
13331 /* Shift left for the next segment */
13332 value <<= crumb_spec[++i].crumb_bit_length;
13333 }
13334
13335 /* Sign extend for signed types */
13336 switch (hf_field->type) {
13337 case FT_INT8:
13338 case FT_INT16:
13339 case FT_INT24:
13340 case FT_INT32:
13341 case FT_INT40:
13342 case FT_INT48:
13343 case FT_INT56:
13344 case FT_INT64:
13345 value = ws_sign_ext64(value, no_of_bits);
13346 break;
13347 default:
13348 break;
13349 }
13350
13351 if (return_value) {
13352 *return_value = value;
13353 }
13354
13355 /* Coast clear. Try and fake it */
13356 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13357 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", 13357
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13357, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13357, "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", 13357, __func__, "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); } } }
;
13358
13359 /* initialise the format string */
13360 bf_str[0] = '\0';
13361
13362 octet_offset = bit_offset >> 3;
13363
13364 /* Round up mask length to nearest octet */
13365 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13366 mask_greatest_bit_offset = octet_length << 3;
13367
13368 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13369 It would be a useful enhancement to eliminate this restriction. */
13370 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13371 other_decode_bitfield_value(bf_str,
13372 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13373 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13374 mask_greatest_bit_offset);
13375 } else {
13376 /* If the bitmask is too large, try to describe its contents. */
13377 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13378 }
13379
13380 switch (hf_field->type) {
13381 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13382 /* Boolean field */
13383 return proto_tree_add_boolean_format(tree, hfindex,
13384 tvb, octet_offset, octet_length, value,
13385 "%s = %s: %s",
13386 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13387 break;
13388
13389 case FT_CHAR:
13390 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13391 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13392 break;
13393
13394 case FT_UINT8:
13395 case FT_UINT16:
13396 case FT_UINT24:
13397 case FT_UINT32:
13398 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13399 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13400 break;
13401
13402 case FT_INT8:
13403 case FT_INT16:
13404 case FT_INT24:
13405 case FT_INT32:
13406 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13407 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13408 break;
13409
13410 case FT_UINT40:
13411 case FT_UINT48:
13412 case FT_UINT56:
13413 case FT_UINT64:
13414 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13415 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13416 break;
13417
13418 case FT_INT40:
13419 case FT_INT48:
13420 case FT_INT56:
13421 case FT_INT64:
13422 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13423 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13424 break;
13425
13426 default:
13427 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))
13428 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))
13429 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))
13430 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))
;
13431 return NULL((void*)0);
13432 }
13433 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13434 return pi;
13435}
13436
13437void
13438proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13439 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13440{
13441 header_field_info *hfinfo;
13442 int start = bit_offset >> 3;
13443 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13444
13445 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13446 * so that we can use the tree's memory scope in calculating the string */
13447 if (length == -1) {
13448 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13449 } else {
13450 tvb_ensure_bytes_exist(tvb, start, length);
13451 }
13452 if (!tree) return;
13453
13454 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", 13454, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13454
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13454, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13455 proto_tree_add_text_internal(tree, tvb, start, length,
13456 "%s crumb %d of %s (decoded above)",
13457 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13458 tvb_get_bits(tvb,
13459 bit_offset,
13460 crumb_spec[crumb_index].crumb_bit_length,
13461 ENC_BIG_ENDIAN0x00000000),
13462 ENC_BIG_ENDIAN0x00000000),
13463 crumb_index,
13464 hfinfo->name);
13465}
13466
13467proto_item *
13468proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13469 const unsigned bit_offset, const int no_of_bits,
13470 uint64_t *return_value, const unsigned encoding)
13471{
13472 proto_item *item;
13473
13474 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13475 bit_offset, no_of_bits,
13476 return_value, encoding))) {
13477 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset) & 7) <<
5)); } while(0)
;
13478 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) <<
8)); } while(0)
;
13479 }
13480 return item;
13481}
13482
13483static proto_item *
13484_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13485 tvbuff_t *tvb, const unsigned bit_offset,
13486 const int no_of_bits, void *value_ptr,
13487 const unsigned encoding, char *value_str)
13488{
13489 int offset;
13490 unsigned length;
13491 uint8_t tot_no_bits;
13492 char *str;
13493 uint64_t value = 0;
13494 header_field_info *hf_field;
13495
13496 /* We do not have to return a value, try to fake it as soon as possible */
13497 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13498 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", 13498
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13498, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13498, "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", 13498, __func__, "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); } } }
;
13499
13500 if (hf_field->bitmask != 0) {
13501 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)
13502 " 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)
13503 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)
;
13504 }
13505
13506 if (no_of_bits < 0) {
13507 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13508 } else if (no_of_bits == 0) {
13509 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)
13510 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)
;
13511 }
13512
13513 /* Byte align offset */
13514 offset = bit_offset>>3;
13515
13516 /*
13517 * Calculate the number of octets used to hold the bits
13518 */
13519 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13520 length = tot_no_bits>>3;
13521 /* If we are using part of the next octet, increase length by 1 */
13522 if (tot_no_bits & 0x07)
13523 length++;
13524
13525 if (no_of_bits < 65) {
13526 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13527 } else {
13528 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)
13529 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)
;
13530 return NULL((void*)0);
13531 }
13532
13533 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13534
13535 (void) g_strlcat(str, " = ", 256+64);
13536 (void) g_strlcat(str, hf_field->name, 256+64);
13537
13538 /*
13539 * This function does not receive an actual value but a dimensionless pointer to that value.
13540 * For this reason, the type of the header field is examined in order to determine
13541 * what kind of value we should read from this address.
13542 * The caller of this function must make sure that for the specific header field type the address of
13543 * a compatible value is provided.
13544 */
13545 switch (hf_field->type) {
13546 case FT_BOOLEAN:
13547 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13548 "%s: %s", str, value_str);
13549 break;
13550
13551 case FT_CHAR:
13552 case FT_UINT8:
13553 case FT_UINT16:
13554 case FT_UINT24:
13555 case FT_UINT32:
13556 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13557 "%s: %s", str, value_str);
13558 break;
13559
13560 case FT_UINT40:
13561 case FT_UINT48:
13562 case FT_UINT56:
13563 case FT_UINT64:
13564 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13565 "%s: %s", str, value_str);
13566 break;
13567
13568 case FT_INT8:
13569 case FT_INT16:
13570 case FT_INT24:
13571 case FT_INT32:
13572 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13573 "%s: %s", str, value_str);
13574 break;
13575
13576 case FT_INT40:
13577 case FT_INT48:
13578 case FT_INT56:
13579 case FT_INT64:
13580 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13581 "%s: %s", str, value_str);
13582 break;
13583
13584 case FT_FLOAT:
13585 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13586 "%s: %s", str, value_str);
13587 break;
13588
13589 default:
13590 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))
13591 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))
13592 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))
13593 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))
;
13594 return NULL((void*)0);
13595 }
13596}
13597
13598static proto_item *
13599proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13600 tvbuff_t *tvb, const unsigned bit_offset,
13601 const int no_of_bits, void *value_ptr,
13602 const unsigned encoding, char *value_str)
13603{
13604 proto_item *item;
13605
13606 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13607 tvb, bit_offset, no_of_bits,
13608 value_ptr, encoding, value_str))) {
13609 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset) & 7) <<
5)); } while(0)
;
13610 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) <<
8)); } while(0)
;
13611 }
13612 return item;
13613}
13614
13615#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);
\
13616 va_start(ap, format)__builtin_va_start(ap, format); \
13617 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13618 va_end(ap)__builtin_va_end(ap);
13619
13620proto_item *
13621proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13622 tvbuff_t *tvb, const unsigned bit_offset,
13623 const int no_of_bits, uint32_t value,
13624 const unsigned encoding,
13625 const char *format, ...)
13626{
13627 va_list ap;
13628 char *dst;
13629 header_field_info *hf_field;
13630
13631 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13632
13633 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", 13633
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13633, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13633, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; 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", 13633, __func__, "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); } } }
;
13634
13635 switch (hf_field->type) {
13636 case FT_UINT8:
13637 case FT_UINT16:
13638 case FT_UINT24:
13639 case FT_UINT32:
13640 break;
13641
13642 default:
13643 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)
13644 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)
;
13645 return NULL((void*)0);
13646 }
13647
13648 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);
;
13649
13650 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13651}
13652
13653proto_item *
13654proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13655 tvbuff_t *tvb, const unsigned bit_offset,
13656 const int no_of_bits, uint64_t value,
13657 const unsigned encoding,
13658 const char *format, ...)
13659{
13660 va_list ap;
13661 char *dst;
13662 header_field_info *hf_field;
13663
13664 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13665
13666 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", 13666
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13666, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13666, "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", 13666, __func__, "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); } } }
;
13667
13668 switch (hf_field->type) {
13669 case FT_UINT40:
13670 case FT_UINT48:
13671 case FT_UINT56:
13672 case FT_UINT64:
13673 break;
13674
13675 default:
13676 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)
13677 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)
;
13678 return NULL((void*)0);
13679 }
13680
13681 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);
;
13682
13683 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13684}
13685
13686proto_item *
13687proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13688 tvbuff_t *tvb, const unsigned bit_offset,
13689 const int no_of_bits, float value,
13690 const unsigned encoding,
13691 const char *format, ...)
13692{
13693 va_list ap;
13694 char *dst;
13695 header_field_info *hf_field;
13696
13697 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13698
13699 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", 13699
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13699, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13699, "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", 13699, __func__, "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); } } }
;
13700
13701 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",
13701, ((hf_field))->abbrev))))
;
13702
13703 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);
;
13704
13705 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13706}
13707
13708proto_item *
13709proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13710 tvbuff_t *tvb, const unsigned bit_offset,
13711 const int no_of_bits, int32_t value,
13712 const unsigned encoding,
13713 const char *format, ...)
13714{
13715 va_list ap;
13716 char *dst;
13717 header_field_info *hf_field;
13718
13719 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13720
13721 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", 13721
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13721, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13721, "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", 13721, __func__, "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); } } }
;
13722
13723 switch (hf_field->type) {
13724 case FT_INT8:
13725 case FT_INT16:
13726 case FT_INT24:
13727 case FT_INT32:
13728 break;
13729
13730 default:
13731 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)
13732 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)
;
13733 return NULL((void*)0);
13734 }
13735
13736 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);
;
13737
13738 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13739}
13740
13741proto_item *
13742proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13743 tvbuff_t *tvb, const unsigned bit_offset,
13744 const int no_of_bits, int64_t value,
13745 const unsigned encoding,
13746 const char *format, ...)
13747{
13748 va_list ap;
13749 char *dst;
13750 header_field_info *hf_field;
13751
13752 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13753
13754 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", 13754
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13754, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13754, "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", 13754, __func__, "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); } } }
;
13755
13756 switch (hf_field->type) {
13757 case FT_INT40:
13758 case FT_INT48:
13759 case FT_INT56:
13760 case FT_INT64:
13761 break;
13762
13763 default:
13764 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)
13765 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)
;
13766 return NULL((void*)0);
13767 }
13768
13769 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);
;
13770
13771 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13772}
13773
13774proto_item *
13775proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13776 tvbuff_t *tvb, const unsigned bit_offset,
13777 const int no_of_bits, uint64_t value,
13778 const unsigned encoding,
13779 const char *format, ...)
13780{
13781 va_list ap;
13782 char *dst;
13783 header_field_info *hf_field;
13784
13785 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13786
13787 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", 13787
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13787, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13787, "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", 13787, __func__, "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); } } }
;
13788
13789 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"
, 13789, ((hf_field))->abbrev))))
;
13790
13791 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);
;
13792
13793 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13794}
13795
13796proto_item *
13797proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13798 const unsigned bit_offset, const int no_of_chars)
13799{
13800 proto_item *pi;
13801 header_field_info *hfinfo;
13802 int byte_length;
13803 int byte_offset;
13804 char *string;
13805
13806 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13807
13808 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", 13808
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13808, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13808, "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", 13808, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13809
13810 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"
, 13810, ((hfinfo))->abbrev))))
;
13811
13812 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13813 byte_offset = bit_offset >> 3;
13814
13815 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13816
13817 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13818 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13818, "byte_length >= 0"
))))
;
13819 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13820
13821 return pi;
13822}
13823
13824proto_item *
13825proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13826 const unsigned bit_offset, const int no_of_chars)
13827{
13828 proto_item *pi;
13829 header_field_info *hfinfo;
13830 int byte_length;
13831 int byte_offset;
13832 char *string;
13833
13834 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13835
13836 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", 13836
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13836, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13836, "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", 13836, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13837
13838 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"
, 13838, ((hfinfo))->abbrev))))
;
13839
13840 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13841 byte_offset = bit_offset >> 3;
13842
13843 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13844
13845 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13846 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13846, "byte_length >= 0"
))))
;
13847 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13848
13849 return pi;
13850}
13851
13852const value_string proto_checksum_vals[] = {
13853 { PROTO_CHECKSUM_E_BAD, "Bad" },
13854 { PROTO_CHECKSUM_E_GOOD, "Good" },
13855 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
13856 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
13857 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
13858
13859 { 0, NULL((void*)0) }
13860};
13861
13862proto_item *
13863proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13864 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
13865 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
13866{
13867 header_field_info *hfinfo;
13868 uint32_t checksum;
13869 uint32_t len;
13870 proto_item* ti = NULL((void*)0);
13871 proto_item* ti2;
13872 bool_Bool incorrect_checksum = true1;
13873
13874 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", 13874, __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", 13874
, "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", 13874, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
13875
13876 switch (hfinfo->type) {
13877 case FT_UINT8:
13878 len = 1;
13879 break;
13880 case FT_UINT16:
13881 len = 2;
13882 break;
13883 case FT_UINT24:
13884 len = 3;
13885 break;
13886 case FT_UINT32:
13887 len = 4;
13888 break;
13889 default:
13890 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)
13891 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
13892 }
13893
13894 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
13895 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
13896 proto_item_set_generated(ti);
13897 if (hf_checksum_status != -1) {
13898 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
13899 proto_item_set_generated(ti2);
13900 }
13901 return ti;
13902 }
13903
13904 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
13905 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
13906 proto_item_set_generated(ti);
13907 } else {
13908 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
13909 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
13910 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
13911 if (computed_checksum == 0) {
13912 proto_item_append_text(ti, " [correct]");
13913 if (hf_checksum_status != -1) {
13914 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13915 proto_item_set_generated(ti2);
13916 }
13917 incorrect_checksum = false0;
13918 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
13919 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
13920 }
13921 } else {
13922 if (checksum == computed_checksum) {
13923 proto_item_append_text(ti, " [correct]");
13924 if (hf_checksum_status != -1) {
13925 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13926 proto_item_set_generated(ti2);
13927 }
13928 incorrect_checksum = false0;
13929 }
13930 }
13931
13932 if (incorrect_checksum) {
13933 if (hf_checksum_status != -1) {
13934 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
13935 proto_item_set_generated(ti2);
13936 }
13937 if (flags & PROTO_CHECKSUM_ZERO0x08) {
13938 proto_item_append_text(ti, " [incorrect]");
13939 if (bad_checksum_expert != NULL((void*)0))
13940 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
13941 } else {
13942 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
13943 if (bad_checksum_expert != NULL((void*)0))
13944 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);
13945 }
13946 }
13947 } else {
13948 if (hf_checksum_status != -1) {
13949 proto_item_append_text(ti, " [unverified]");
13950 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
13951 proto_item_set_generated(ti2);
13952 }
13953 }
13954 }
13955
13956 return ti;
13957}
13958
13959proto_item *
13960proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13961 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
13962 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
13963{
13964 header_field_info *hfinfo;
13965 uint8_t *checksum = NULL((void*)0);
13966 proto_item* ti = NULL((void*)0);
13967 proto_item* ti2;
13968 bool_Bool incorrect_checksum = true1;
13969
13970 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", 13970, __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", 13970
, "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", 13970, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
13971
13972 if (hfinfo->type != FT_BYTES) {
13973 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)
13974 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
13975 }
13976
13977 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
13978 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
13979 proto_item_set_generated(ti);
13980 if (hf_checksum_status != -1) {
13981 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
13982 proto_item_set_generated(ti2);
13983 }
13984 return ti;
13985 }
13986
13987 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
13988 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
13989 proto_item_set_generated(ti);
13990 } else {
13991 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
))))))
;
13992 tvb_memcpy(tvb, checksum, offset, checksum_len);
13993 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
13994 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
13995 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
13996 if (computed_checksum == 0) {
13997 proto_item_append_text(ti, " [correct]");
13998 if (hf_checksum_status != -1) {
13999 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14000 proto_item_set_generated(ti2);
14001 }
14002 incorrect_checksum = false0;
14003 }
14004 } else {
14005 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14006 proto_item_append_text(ti, " [correct]");
14007 if (hf_checksum_status != -1) {
14008 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14009 proto_item_set_generated(ti2);
14010 }
14011 incorrect_checksum = false0;
14012 }
14013 }
14014
14015 if (incorrect_checksum) {
14016 if (hf_checksum_status != -1) {
14017 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14018 proto_item_set_generated(ti2);
14019 }
14020 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14021 proto_item_append_text(ti, " [incorrect]");
14022 if (bad_checksum_expert != NULL((void*)0))
14023 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14024 } else {
14025 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14026 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))))))
;
14027 for (size_t counter = 0; counter < checksum_len; ++counter) {
14028 snprintf(
14029 /* On ecah iteration inserts two characters */
14030 (char*)&computed_checksum_str[counter << 1],
14031 computed_checksum_str_len - (counter << 1),
14032 "%02x",
14033 computed_checksum[counter]);
14034 }
14035 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14036 if (bad_checksum_expert != NULL((void*)0))
14037 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14038 }
14039 }
14040 } else {
14041 if (hf_checksum_status != -1) {
14042 proto_item_append_text(ti, " [unverified]");
14043 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14044 proto_item_set_generated(ti2);
14045 }
14046 }
14047 }
14048
14049 return ti;
14050}
14051
14052unsigned char
14053proto_check_field_name(const char *field_name)
14054{
14055 return module_check_valid_name(field_name, false0);
14056}
14057
14058unsigned char
14059proto_check_field_name_lower(const char *field_name)
14060{
14061 return module_check_valid_name(field_name, true1);
14062}
14063
14064bool_Bool
14065tree_expanded(int tree_type)
14066{
14067 if (tree_type <= 0) {
14068 return false0;
14069 }
14070 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", 14070, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14071 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14072}
14073
14074void
14075tree_expanded_set(int tree_type, bool_Bool value)
14076{
14077 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", 14077, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14078
14079 if (value)
14080 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14081 else
14082 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14083}
14084
14085/*
14086 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14087 *
14088 * Local variables:
14089 * c-basic-offset: 8
14090 * tab-width: 8
14091 * indent-tabs-mode: t
14092 * End:
14093 *
14094 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14095 * :indentSize=8:tabSize=8:noTabs=false:
14096 */