Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13350, 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-20-100252-3912-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2024-11-20-100252-3912-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 NULL((void*)0)
526};
527
528static GHashTable *proto_reserved_filter_names;
529
530static int
531proto_compare_name(const void *p1_arg, const void *p2_arg)
532{
533 const protocol_t *p1 = (const protocol_t *)p1_arg;
534 const protocol_t *p2 = (const protocol_t *)p2_arg;
535
536 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
537}
538
539static GSList *dissector_plugins;
540
541#ifdef HAVE_PLUGINS1
542void
543proto_register_plugin(const proto_plugin *plug)
544{
545 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
546}
547#else /* HAVE_PLUGINS */
548void
549proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
550{
551 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 551, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
552}
553#endif /* HAVE_PLUGINS */
554
555static void
556call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
557{
558 proto_plugin *plug = (proto_plugin *)data;
559
560 if (plug->register_protoinfo) {
561 plug->register_protoinfo();
562 }
563}
564
565static void
566call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
567{
568 proto_plugin *plug = (proto_plugin *)data;
569
570 if (plug->register_handoff) {
571 plug->register_handoff();
572 }
573}
574
575/* initialize data structures and register protocols and fields */
576void
577proto_init(GSList *register_all_plugin_protocols_list,
578 GSList *register_all_plugin_handoffs_list,
579 register_cb cb,
580 void *client_data)
581{
582 proto_cleanup_base();
583
584 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
585 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
586 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
587
588 proto_reserved_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
589 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
590 /* GHashTable has no key destructor so the cast is safe. */
591 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
592 }
593
594 gpa_hfinfo.len = 0;
595 gpa_hfinfo.allocated_len = 0;
596 gpa_hfinfo.hfi = NULL((void*)0);
597 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL((void*)0), save_same_name_hfinfo);
598 gpa_protocol_aliases = g_hash_table_new(g_str_hash, g_str_equal);
599 deregistered_fields = g_ptr_array_new();
600 deregistered_data = g_ptr_array_new();
601 deregistered_slice = g_ptr_array_new();
602
603 /* Initialize the ftype subsystem */
604 ftypes_initialize();
605
606 /* Initialize the address type subsystem */
607 address_types_initialize();
608
609 /* Register one special-case FT_TEXT_ONLY field for use when
610 converting wireshark to new-style proto_tree. These fields
611 are merely strings on the GUI tree; they are not filterable */
612 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
613
614 /* Register the pseudo-protocols used for exceptions. */
615 register_show_exception();
616 register_type_length_mismatch();
617 register_byte_array_string_decodinws_error();
618 register_date_time_string_decodinws_error();
619 register_string_errors();
620 ftypes_register_pseudofields();
621 col_register_protocol();
622
623 /* Have each built-in dissector register its protocols, fields,
624 dissector tables, and dissectors to be called through a
625 handle, and do whatever one-time initialization it needs to
626 do. */
627 register_all_protocols(cb, client_data);
628
629 /* Now call the registration routines for all epan plugins. */
630 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
631 ((void (*)(register_cb, void *))l->data)(cb, client_data);
632 }
633
634 /* Now call the registration routines for all dissector plugins. */
635 if (cb)
636 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
637 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
638
639 /* Now call the "handoff registration" routines of all built-in
640 dissectors; those routines register the dissector in other
641 dissectors' handoff tables, and fetch any dissector handles
642 they need. */
643 register_all_protocol_handoffs(cb, client_data);
644
645 /* Now do the same with epan plugins. */
646 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
647 ((void (*)(register_cb, void *))l->data)(cb, client_data);
648 }
649
650 /* Now do the same with dissector plugins. */
651 if (cb)
652 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
653 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
654
655 /* sort the protocols by protocol name */
656 protocols = g_list_sort(protocols, proto_compare_name);
657
658 /* sort the dissector handles in dissector tables (for -G reports
659 * and -d error messages. The GUI sorts the handles itself.) */
660 packet_all_tables_sort_handles();
661
662 /* We've assigned all the subtree type values; allocate the array
663 for them, and zero it out. */
664 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
)))
;
665}
666
667static void
668proto_cleanup_base(void)
669{
670 protocol_t *protocol;
671 header_field_info *hfinfo;
672
673 /* Free the abbrev/ID hash table */
674 if (gpa_name_map) {
675 g_hash_table_destroy(gpa_name_map);
676 gpa_name_map = NULL((void*)0);
677 }
678 if (gpa_protocol_aliases) {
679 g_hash_table_destroy(gpa_protocol_aliases);
680 gpa_protocol_aliases = NULL((void*)0);
681 }
682 g_free(last_field_name);
683 last_field_name = NULL((void*)0);
684
685 while (protocols) {
686 protocol = (protocol_t *)protocols->data;
687 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", 687
, __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", 687, "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", 687, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
688 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", 688, "protocol->proto_id == hfinfo->id"
))))
;
689
690 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)
;
691 if (protocol->parent_proto_id != -1) {
692 // pino protocol
693 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 693, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
694 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"
, 694, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
695 } else {
696 if (protocol->fields) {
697 g_ptr_array_free(protocol->fields, true1);
698 }
699 g_list_free(protocol->heur_list);
700 }
701 protocols = g_list_remove(protocols, protocol);
702 g_free(protocol);
703 }
704
705 if (proto_names) {
706 g_hash_table_destroy(proto_names);
707 proto_names = NULL((void*)0);
708 }
709
710 if (proto_short_names) {
711 g_hash_table_destroy(proto_short_names);
712 proto_short_names = NULL((void*)0);
713 }
714
715 if (proto_filter_names) {
716 g_hash_table_destroy(proto_filter_names);
717 proto_filter_names = NULL((void*)0);
718 }
719
720 if (proto_reserved_filter_names) {
721 g_hash_table_destroy(proto_reserved_filter_names);
722 proto_reserved_filter_names = NULL((void*)0);
723 }
724
725 if (gpa_hfinfo.allocated_len) {
726 gpa_hfinfo.len = 0;
727 gpa_hfinfo.allocated_len = 0;
728 g_free(gpa_hfinfo.hfi);
729 gpa_hfinfo.hfi = NULL((void*)0);
730 }
731
732 if (deregistered_fields) {
733 g_ptr_array_free(deregistered_fields, true1);
734 deregistered_fields = NULL((void*)0);
735 }
736
737 if (deregistered_data) {
738 g_ptr_array_free(deregistered_data, true1);
739 deregistered_data = NULL((void*)0);
740 }
741
742 if (deregistered_slice) {
743 g_ptr_array_free(deregistered_slice, true1);
744 deregistered_slice = NULL((void*)0);
745 }
746
747 g_free(tree_is_expanded);
748 tree_is_expanded = NULL((void*)0);
749
750 if (prefixes)
751 g_hash_table_destroy(prefixes);
752}
753
754void
755proto_cleanup(void)
756{
757 proto_free_deregistered_fields();
758 proto_cleanup_base();
759
760 g_slist_free(dissector_plugins);
761 dissector_plugins = NULL((void*)0);
762}
763
764static bool_Bool
765// NOLINTNEXTLINE(misc-no-recursion)
766proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
767 void *data)
768{
769 proto_node *pnode = tree;
770 proto_node *child;
771 proto_node *current;
772
773 if (func(pnode, data))
774 return true1;
775
776 child = pnode->first_child;
777 while (child != NULL((void*)0)) {
778 /*
779 * The routine we call might modify the child, e.g. by
780 * freeing it, so we get the child's successor before
781 * calling that routine.
782 */
783 current = child;
784 child = current->next;
785 // We recurse here, but we're limited by prefs.gui_max_tree_depth
786 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
787 return true1;
788 }
789
790 return false0;
791}
792
793void
794proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
795 void *data)
796{
797 proto_node *node = tree;
798 proto_node *current;
799
800 if (!node)
801 return;
802
803 node = node->first_child;
804 while (node != NULL((void*)0)) {
805 current = node;
806 node = current->next;
807 func((proto_tree *)current, data);
808 }
809}
810
811static void
812free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
813{
814 GPtrArray *ptrs = (GPtrArray *)value;
815 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
816 header_field_info *hfinfo;
817
818 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", 818, __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", 818, "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", 818, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
819 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
820 /* when a field is referenced by a filter this also
821 affects the refcount for the parent protocol so we need
822 to adjust the refcount for the parent as well
823 */
824 if (hfinfo->parent != -1) {
825 header_field_info *parent_hfinfo;
826 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", 826
, __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", 826, "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", 826, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
827 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
828 }
829 hfinfo->ref_type = HF_REF_TYPE_NONE;
830 }
831
832 g_ptr_array_free(ptrs, true1);
833}
834
835static void
836proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
837{
838 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
839
840 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
841
842 if (finfo) {
843 fvalue_free(finfo->value);
844 finfo->value = NULL((void*)0);
845 }
846}
847
848void
849proto_tree_reset(proto_tree *tree)
850{
851 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
852
853 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
854
855 /* free tree data */
856 if (tree_data->interesting_hfids) {
857 /* Free all the GPtrArray's in the interesting_hfids hash. */
858 g_hash_table_foreach(tree_data->interesting_hfids,
859 free_GPtrArray_value, NULL((void*)0));
860
861 /* And then remove all values. */
862 g_hash_table_remove_all(tree_data->interesting_hfids);
863 }
864
865 /* Reset track of the number of children */
866 tree_data->count = 0;
867
868 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
869}
870
871/* frees the resources that the dissection a proto_tree uses */
872void
873proto_tree_free(proto_tree *tree)
874{
875 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
876
877 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
878
879 /* free tree data */
880 if (tree_data->interesting_hfids) {
881 /* Free all the GPtrArray's in the interesting_hfids hash. */
882 g_hash_table_foreach(tree_data->interesting_hfids,
883 free_GPtrArray_value, NULL((void*)0));
884
885 /* And then destroy the hash. */
886 g_hash_table_destroy(tree_data->interesting_hfids);
887 }
888
889 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)
;
890
891 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
892}
893
894/* Is the parsing being done for a visible proto_tree or an invisible one?
895 * By setting this correctly, the proto_tree creation is sped up by not
896 * having to call vsnprintf and copy strings around.
897 */
898bool_Bool
899proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
900{
901 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
902
903 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
904
905 return old_visible;
906}
907
908void
909proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
910{
911 if (tree)
912 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
913}
914
915/* Assume dissector set only its protocol fields.
916 This function is called by dissectors and allows the speeding up of filtering
917 in wireshark; if this function returns false it is safe to reset tree to NULL
918 and thus skip calling most of the expensive proto_tree_add_...()
919 functions.
920 If the tree is visible we implicitly assume the field is referenced.
921*/
922bool_Bool
923proto_field_is_referenced(proto_tree *tree, int proto_id)
924{
925 register header_field_info *hfinfo;
926
927
928 if (!tree)
929 return false0;
930
931 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
932 return true1;
933
934 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", 934, __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", 934, "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", 934, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
935 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
936 return true1;
937
938 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
939 return true1;
940
941 return false0;
942}
943
944
945/* Finds a record in the hfinfo array by id. */
946header_field_info *
947proto_registrar_get_nth(unsigned hfindex)
948{
949 register header_field_info *hfinfo;
950
951 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", 951, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 951, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 951, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
952 return hfinfo;
953}
954
955
956/* Prefix initialization
957 * this allows for a dissector to register a display filter name prefix
958 * so that it can delay the initialization of the hf array as long as
959 * possible.
960 */
961
962/* compute a hash for the part before the dot of a display filter */
963static unsigned
964prefix_hash (const void *key) {
965 /* end the string at the dot and compute its hash */
966 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
967 char* c = copy;
968 unsigned tmp;
969
970 for (; *c; c++) {
971 if (*c == '.') {
972 *c = 0;
973 break;
974 }
975 }
976
977 tmp = g_str_hash(copy);
978 g_free(copy);
979 return tmp;
980}
981
982/* are both strings equal up to the end or the dot? */
983static gboolean
984prefix_equal (const void *ap, const void *bp) {
985 const char* a = (const char *)ap;
986 const char* b = (const char *)bp;
987
988 do {
989 char ac = *a++;
990 char bc = *b++;
991
992 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
993
994 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
995 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
996
997 if (ac != bc) return FALSE(0);
998 } while (1);
999
1000 return FALSE(0);
1001}
1002
1003/* Register a new prefix for "delayed" initialization of field arrays */
1004void
1005proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1006 if (! prefixes ) {
1007 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1008 }
1009
1010 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1011}
1012
1013/* helper to call all prefix initializers */
1014static gboolean
1015initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1016 ((prefix_initializer_t)v)((const char *)k);
1017 return TRUE(!(0));
1018}
1019
1020/** Initialize every remaining uninitialized prefix. */
1021void
1022proto_initialize_all_prefixes(void) {
1023 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1024}
1025
1026/* Finds a record in the hfinfo array by name.
1027 * If it fails to find it in the already registered fields,
1028 * it tries to find and call an initializer in the prefixes
1029 * table and if so it looks again.
1030 */
1031
1032header_field_info *
1033proto_registrar_get_byname(const char *field_name)
1034{
1035 header_field_info *hfinfo;
1036 prefix_initializer_t pi;
1037
1038 if (!field_name)
1039 return NULL((void*)0);
1040
1041 if (g_strcmp0(field_name, last_field_name) == 0) {
1042 return last_hfinfo;
1043 }
1044
1045 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1046
1047 if (hfinfo) {
1048 g_free(last_field_name);
1049 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1050 last_hfinfo = hfinfo;
1051 return hfinfo;
1052 }
1053
1054 if (!prefixes)
1055 return NULL((void*)0);
1056
1057 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1058 pi(field_name);
1059 g_hash_table_remove(prefixes, field_name);
1060 } else {
1061 return NULL((void*)0);
1062 }
1063
1064 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1065
1066 if (hfinfo) {
1067 g_free(last_field_name);
1068 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1069 last_hfinfo = hfinfo;
1070 }
1071 return hfinfo;
1072}
1073
1074header_field_info*
1075proto_registrar_get_byalias(const char *alias_name)
1076{
1077 if (!alias_name) {
1078 return NULL((void*)0);
1079 }
1080
1081 /* Find our aliased protocol. */
1082 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1083 char *dot = strchr(an_copy, '.');
1084 if (dot) {
1085 *dot = '\0';
1086 }
1087 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1088 if (!proto_pfx) {
1089 g_free(an_copy);
1090 return NULL((void*)0);
1091 }
1092
1093 /* Construct our aliased field and look it up. */
1094 GString *filter_name = g_string_new(proto_pfx);
1095 if (dot) {
1096 g_string_append_printf(filter_name, ".%s", dot+1);
1097 }
1098 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1099 g_free(an_copy);
1100 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)))))
;
1101
1102 return hfinfo;
1103}
1104
1105int
1106proto_registrar_get_id_byname(const char *field_name)
1107{
1108 header_field_info *hfinfo;
1109
1110 hfinfo = proto_registrar_get_byname(field_name);
1111
1112 if (!hfinfo)
1113 return -1;
1114
1115 return hfinfo->id;
1116}
1117
1118static int
1119label_strcat_flags(const header_field_info *hfinfo)
1120{
1121 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1122 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1123
1124 return 0;
1125}
1126
1127static char *
1128format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1129 const uint8_t *bytes, unsigned length, size_t max_str_len)
1130{
1131 char *str = NULL((void*)0);
1132 const uint8_t *p;
1133 bool_Bool is_printable;
1134
1135 if (bytes) {
1136 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1137 /*
1138 * If all bytes are valid and printable UTF-8, show the
1139 * bytes as a string - in quotes to indicate that it's
1140 * a string.
1141 */
1142 if (isprint_utf8_string(bytes, length)) {
1143 str = wmem_strdup_printf(scope, "\"%.*s\"",
1144 (int)length, bytes);
1145 return str;
1146 }
1147 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1148 /*
1149 * Check whether all bytes are printable.
1150 */
1151 is_printable = true1;
1152 for (p = bytes; p < bytes+length; p++) {
1153 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1154 /* Not printable. */
1155 is_printable = false0;
1156 break;
1157 }
1158 }
1159
1160 /*
1161 * If all bytes are printable ASCII, show the bytes
1162 * as a string - in quotes to indicate that it's
1163 * a string.
1164 */
1165 if (is_printable) {
1166 str = wmem_strdup_printf(scope, "\"%.*s\"",
1167 (int)length, bytes);
1168 return str;
1169 }
1170 }
1171
1172 /*
1173 * Either it's not printable ASCII, or we don't care whether
1174 * it's printable ASCII; show it as hex bytes.
1175 */
1176 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1177 case SEP_DOT:
1178 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1179 break;
1180 case SEP_DASH:
1181 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1182 break;
1183 case SEP_COLON:
1184 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1185 break;
1186 case SEP_SPACE:
1187 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1188 break;
1189 case BASE_NONE:
1190 default:
1191 if (prefs.display_byte_fields_with_spaces) {
1192 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1193 } else {
1194 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1195 }
1196 break;
1197 }
1198 }
1199 else {
1200 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1201 str = wmem_strdup(scope, "<none>");
1202 } else {
1203 str = wmem_strdup(scope, "<MISSING>");
1204 }
1205 }
1206 return str;
1207}
1208
1209static char *
1210format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1211 const uint8_t *bytes, unsigned length)
1212{
1213 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1214}
1215
1216static void
1217ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1218{
1219 subtree_lvl *pushed_tree;
1220
1221 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"
, 1221, "ptvc->pushed_tree_max <= 256-8"))))
;
1222 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1223
1224 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1225 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1225, "pushed_tree != ((void*)0)"
))))
;
1226 ptvc->pushed_tree = pushed_tree;
1227}
1228
1229static void
1230ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1231{
1232 ptvc->pushed_tree = NULL((void*)0);
1233 ptvc->pushed_tree_max = 0;
1234 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", 1234, "ptvc->pushed_tree_index == 0"
))))
;
1235 ptvc->pushed_tree_index = 0;
1236}
1237
1238/* Allocates an initializes a ptvcursor_t with 3 variables:
1239 * proto_tree, tvbuff, and offset. */
1240ptvcursor_t *
1241ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1242{
1243 ptvcursor_t *ptvc;
1244
1245 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1246 ptvc->scope = scope;
1247 ptvc->tree = tree;
1248 ptvc->tvb = tvb;
1249 ptvc->offset = offset;
1250 ptvc->pushed_tree = NULL((void*)0);
1251 ptvc->pushed_tree_max = 0;
1252 ptvc->pushed_tree_index = 0;
1253 return ptvc;
1254}
1255
1256
1257/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1258void
1259ptvcursor_free(ptvcursor_t *ptvc)
1260{
1261 ptvcursor_free_subtree_levels(ptvc);
1262 /*g_free(ptvc);*/
1263}
1264
1265/* Returns tvbuff. */
1266tvbuff_t *
1267ptvcursor_tvbuff(ptvcursor_t *ptvc)
1268{
1269 return ptvc->tvb;
1270}
1271
1272/* Returns current offset. */
1273int
1274ptvcursor_current_offset(ptvcursor_t *ptvc)
1275{
1276 return ptvc->offset;
1277}
1278
1279proto_tree *
1280ptvcursor_tree(ptvcursor_t *ptvc)
1281{
1282 if (!ptvc)
1283 return NULL((void*)0);
1284
1285 return ptvc->tree;
1286}
1287
1288void
1289ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1290{
1291 ptvc->tree = tree;
1292}
1293
1294/* creates a subtree, sets it as the working tree and pushes the old working tree */
1295proto_tree *
1296ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1297{
1298 subtree_lvl *subtree;
1299 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1300 ptvcursor_new_subtree_levels(ptvc);
1301
1302 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1303 subtree->tree = ptvc->tree;
1304 subtree->it= NULL((void*)0);
1305 ptvc->pushed_tree_index++;
1306 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1307}
1308
1309/* pops a subtree */
1310void
1311ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1312{
1313 subtree_lvl *subtree;
1314
1315 if (ptvc->pushed_tree_index <= 0)
1316 return;
1317
1318 ptvc->pushed_tree_index--;
1319 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1320 if (subtree->it != NULL((void*)0))
1321 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1322
1323 ptvc->tree = subtree->tree;
1324}
1325
1326/* saves the current tvb offset and the item in the current subtree level */
1327static void
1328ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1329{
1330 subtree_lvl *subtree;
1331
1332 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", 1332, "ptvc->pushed_tree_index > 0"
))))
;
1333
1334 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1335 subtree->it = it;
1336 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1337}
1338
1339/* Creates a subtree and adds it to the cursor as the working tree but does not
1340 * save the old working tree */
1341proto_tree *
1342ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1343{
1344 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1345 return ptvc->tree;
1346}
1347
1348static proto_tree *
1349ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1350{
1351 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1352 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1353 ptvcursor_subtree_set_item(ptvc, it);
1354 return ptvcursor_tree(ptvc);
1355}
1356
1357/* Add an item to the tree and create a subtree
1358 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1359 * In this case, when the subtree will be closed, the parent item length will
1360 * be equal to the advancement of the cursor since the creation of the subtree.
1361 */
1362proto_tree *
1363ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1364 const unsigned encoding, int ett_subtree)
1365{
1366 proto_item *it;
1367
1368 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1369 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1370}
1371
1372static proto_item *
1373proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1374
1375/* Add a text node to the tree and create a subtree
1376 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1377 * In this case, when the subtree will be closed, the item length will be equal
1378 * to the advancement of the cursor since the creation of the subtree.
1379 */
1380proto_tree *
1381ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1382 int ett_subtree, const char *format, ...)
1383{
1384 proto_item *pi;
1385 va_list ap;
1386 header_field_info *hfinfo;
1387 proto_tree *tree;
1388
1389 tree = ptvcursor_tree(ptvc);
1390
1391 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1392
1393 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", 1393
, __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", 1393, "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", 1393, "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", 1393, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1394
1395 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1396 ptvcursor_current_offset(ptvc), length);
1397
1398 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1398, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1399
1400 va_start(ap, format)__builtin_va_start(ap, format);
1401 proto_tree_set_representation(pi, format, ap);
1402 va_end(ap)__builtin_va_end(ap);
1403
1404 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1405}
1406
1407/* Add a text-only node, leaving it to our caller to fill the text in */
1408static proto_item *
1409proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1410{
1411 proto_item *pi;
1412
1413 if (tree == NULL((void*)0))
1414 return NULL((void*)0);
1415
1416 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1417
1418 return pi;
1419}
1420
1421/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1422proto_item *
1423proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1424 const char *format, ...)
1425{
1426 proto_item *pi;
1427 va_list ap;
1428 header_field_info *hfinfo;
1429
1430 if (length == -1) {
1431 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1432 } else {
1433 tvb_ensure_bytes_exist(tvb, start, length);
1434 }
1435
1436 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1437
1438 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", 1438
, __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", 1438, "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", 1438, "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", 1438, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1439
1440 pi = proto_tree_add_text_node(tree, tvb, start, length);
1441
1442 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1442, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1443
1444 va_start(ap, format)__builtin_va_start(ap, format);
1445 proto_tree_set_representation(pi, format, ap);
1446 va_end(ap)__builtin_va_end(ap);
1447
1448 return pi;
1449}
1450
1451/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1452proto_item *
1453proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1454 int length, const char *format, va_list ap)
1455{
1456 proto_item *pi;
1457 header_field_info *hfinfo;
1458
1459 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1460 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1461 * the length to be what's in the tvbuff if length is -1, and the
1462 * minimum of length and what's in the tvbuff if not.
1463 */
1464
1465 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1466
1467 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", 1467
, __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", 1467, "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", 1467, "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", 1467, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1468
1469 pi = proto_tree_add_text_node(tree, tvb, start, length);
1470
1471 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1471, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1472
1473 proto_tree_set_representation(pi, format, ap);
1474
1475 return pi;
1476}
1477
1478/* Add a text-only node that creates a subtree underneath.
1479 */
1480proto_tree *
1481proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1482{
1483 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1484}
1485
1486/* Add a text-only node that creates a subtree underneath.
1487 */
1488proto_tree *
1489proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1490{
1491 proto_tree *pt;
1492 proto_item *pi;
1493 va_list ap;
1494
1495 va_start(ap, format)__builtin_va_start(ap, format);
1496 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1497 va_end(ap)__builtin_va_end(ap);
1498
1499 if (tree_item != NULL((void*)0))
1500 *tree_item = pi;
1501
1502 pt = proto_item_add_subtree(pi, idx);
1503
1504 return pt;
1505}
1506
1507/* Add a text-only node for debugging purposes. The caller doesn't need
1508 * to worry about tvbuff, start, or length. Debug message gets sent to
1509 * STDOUT, too */
1510proto_item *
1511proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1512{
1513 proto_item *pi;
1514 va_list ap;
1515
1516 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1517
1518 if (pi) {
1519 va_start(ap, format)__builtin_va_start(ap, format);
1520 proto_tree_set_representation(pi, format, ap);
1521 va_end(ap)__builtin_va_end(ap);
1522 }
1523 va_start(ap, format)__builtin_va_start(ap, format);
1524 vprintf(format, ap);
1525 va_end(ap)__builtin_va_end(ap);
1526 printf("\n");
1527
1528 return pi;
1529}
1530
1531proto_item *
1532proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1533{
1534 proto_item *pi;
1535 header_field_info *hfinfo;
1536
1537 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1538
1539 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", 1539
, __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", 1539, "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", 1539, "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", 1539, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1540
1541 pi = proto_tree_add_text_node(tree, tvb, start, length);
1542
1543 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1543, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1544
1545 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1546
1547 return pi;
1548}
1549
1550proto_item *
1551proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1552{
1553 proto_item *pi;
1554 header_field_info *hfinfo;
1555 char *str;
1556
1557 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1558
1559 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", 1559
, __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", 1559, "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", 1559, "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", 1559, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1560
1561 pi = proto_tree_add_text_node(tree, tvb, start, length);
1562
1563 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1563, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1564
1565 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1566 proto_item_set_text(pi, "%s", str);
1567 wmem_free(NULL((void*)0), str);
1568
1569 return pi;
1570}
1571
1572void proto_report_dissector_bug(const char *format, ...)
1573{
1574 va_list args;
1575
1576 if (wireshark_abort_on_dissector_bug) {
1577 /*
1578 * Try to have the error message show up in the crash
1579 * information.
1580 */
1581 va_start(args, format)__builtin_va_start(args, format);
1582 ws_vadd_crash_info(format, args);
1583 va_end(args)__builtin_va_end(args);
1584
1585 /*
1586 * Print the error message.
1587 */
1588 va_start(args, format)__builtin_va_start(args, format);
1589 vfprintf(stderrstderr, format, args);
1590 va_end(args)__builtin_va_end(args);
1591 putc('\n', stderrstderr);
1592
1593 /*
1594 * And crash.
1595 */
1596 abort();
1597 } else {
1598 va_start(args, format)__builtin_va_start(args, format);
1599 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1600 va_end(args)__builtin_va_end(args);
1601 }
1602}
1603
1604/* We could probably get away with changing is_error to a minimum length value. */
1605static void
1606report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1607{
1608 if (is_error) {
1609 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1610 } else {
1611 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1612 }
1613
1614 if (is_error) {
1615 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1616 }
1617}
1618
1619static uint32_t
1620get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1621{
1622 uint32_t value;
1623 bool_Bool length_error;
1624
1625 switch (length) {
1626
1627 case 1:
1628 value = tvb_get_uint8(tvb, offset);
1629 if (encoding & ENC_ZIGBEE0x40000000) {
1630 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1631 value = 0;
1632 }
1633 }
1634 break;
1635
1636 case 2:
1637 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1638 : tvb_get_ntohs(tvb, offset);
1639 if (encoding & ENC_ZIGBEE0x40000000) {
1640 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1641 value = 0;
1642 }
1643 }
1644 break;
1645
1646 case 3:
1647 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1648 : tvb_get_ntoh24(tvb, offset);
1649 break;
1650
1651 case 4:
1652 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1653 : tvb_get_ntohl(tvb, offset);
1654 break;
1655
1656 default:
1657 if (length < 1) {
1658 length_error = true1;
1659 value = 0;
1660 } else {
1661 length_error = false0;
1662 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1663 : tvb_get_ntohl(tvb, offset);
1664 }
1665 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1666 break;
1667 }
1668 return value;
1669}
1670
1671static inline uint64_t
1672get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1673{
1674 uint64_t value;
1675
1676 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1677
1678 if (length < 1 || length > 8) {
1679 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1680 }
1681
1682 return value;
1683}
1684
1685static int32_t
1686get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1687{
1688 int32_t value;
1689 bool_Bool length_error;
1690
1691 switch (length) {
1692
1693 case 1:
1694 value = tvb_get_int8(tvb, offset);
1695 break;
1696
1697 case 2:
1698 value = encoding ? tvb_get_letohis(tvb, offset)
1699 : tvb_get_ntohis(tvb, offset);
1700 break;
1701
1702 case 3:
1703 value = encoding ? tvb_get_letohi24(tvb, offset)
1704 : tvb_get_ntohi24(tvb, offset);
1705 break;
1706
1707 case 4:
1708 value = encoding ? tvb_get_letohil(tvb, offset)
1709 : tvb_get_ntohil(tvb, offset);
1710 break;
1711
1712 default:
1713 if (length < 1) {
1714 length_error = true1;
1715 value = 0;
1716 } else {
1717 length_error = false0;
1718 value = encoding ? tvb_get_letohil(tvb, offset)
1719 : tvb_get_ntohil(tvb, offset);
1720 }
1721 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1722 break;
1723 }
1724 return value;
1725}
1726
1727/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1728 * be cast-able as a int64_t. This is weird, but what the code has always done.
1729 */
1730static inline uint64_t
1731get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1732{
1733 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1734
1735 switch (length) {
1736 case 7:
1737 value = ws_sign_ext64(value, 56);
1738 break;
1739 case 6:
1740 value = ws_sign_ext64(value, 48);
1741 break;
1742 case 5:
1743 value = ws_sign_ext64(value, 40);
1744 break;
1745 case 4:
1746 value = ws_sign_ext64(value, 32);
1747 break;
1748 case 3:
1749 value = ws_sign_ext64(value, 24);
1750 break;
1751 case 2:
1752 value = ws_sign_ext64(value, 16);
1753 break;
1754 case 1:
1755 value = ws_sign_ext64(value, 8);
1756 break;
1757 }
1758
1759 return value;
1760}
1761
1762/* For FT_STRING */
1763static inline const uint8_t *
1764get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1765 int length, int *ret_length, const unsigned encoding)
1766{
1767 if (length == -1) {
1768 length = tvb_ensure_captured_length_remaining(tvb, start);
1769 }
1770 *ret_length = length;
1771 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1772}
1773
1774/* For FT_STRINGZ */
1775static inline const uint8_t *
1776get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1777 int start, int length, int *ret_length, const unsigned encoding)
1778{
1779 const uint8_t *value;
1780
1781 if (length < -1) {
1782 report_type_length_mismatch(tree, "a string", length, true1);
1783 }
1784 if (length == -1) {
1785 /* This can throw an exception */
1786 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1787 } else {
1788 /* In this case, length signifies the length of the string.
1789 *
1790 * This could either be a null-padded string, which doesn't
1791 * necessarily have a '\0' at the end, or a null-terminated
1792 * string, with a trailing '\0'. (Yes, there are cases
1793 * where you have a string that's both counted and null-
1794 * terminated.)
1795 *
1796 * In the first case, we must allocate a buffer of length
1797 * "length+1", to make room for a trailing '\0'.
1798 *
1799 * In the second case, we don't assume that there is a
1800 * trailing '\0' there, as the packet might be malformed.
1801 * (XXX - should we throw an exception if there's no
1802 * trailing '\0'?) Therefore, we allocate a buffer of
1803 * length "length+1", and put in a trailing '\0', just to
1804 * be safe.
1805 *
1806 * (XXX - this would change if we made string values counted
1807 * rather than null-terminated.)
1808 */
1809 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1810 }
1811 *ret_length = length;
1812 return value;
1813}
1814
1815/* For FT_UINT_STRING */
1816static inline const uint8_t *
1817get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1818 tvbuff_t *tvb, int start, int length, int *ret_length,
1819 const unsigned encoding)
1820{
1821 uint32_t n;
1822 const uint8_t *value;
1823
1824 /* I believe it's ok if this is called with a NULL tree */
1825 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1826 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1827 length += n;
1828 *ret_length = length;
1829 return value;
1830}
1831
1832/* For FT_STRINGZPAD */
1833static inline const uint8_t *
1834get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1835 int length, int *ret_length, const unsigned encoding)
1836{
1837 /*
1838 * XXX - currently, string values are null-
1839 * terminated, so a "zero-padded" string
1840 * isn't special. If we represent string
1841 * values as something that includes a counted
1842 * array of bytes, we'll need to strip the
1843 * trailing NULs.
1844 */
1845 if (length == -1) {
1846 length = tvb_ensure_captured_length_remaining(tvb, start);
1847 }
1848 *ret_length = length;
1849 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1850}
1851
1852/* For FT_STRINGZTRUNC */
1853static inline const uint8_t *
1854get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1855 int length, int *ret_length, const unsigned encoding)
1856{
1857 /*
1858 * XXX - currently, string values are null-
1859 * terminated, so a "zero-truncated" string
1860 * isn't special. If we represent string
1861 * values as something that includes a counted
1862 * array of bytes, we'll need to strip everything
1863 * starting with the terminating NUL.
1864 */
1865 if (length == -1) {
1866 length = tvb_ensure_captured_length_remaining(tvb, start);
1867 }
1868 *ret_length = length;
1869 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1870}
1871
1872/*
1873 * Deltas between the epochs for various non-UN*X time stamp formats and
1874 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1875 * stamp format.
1876 */
1877
1878/*
1879 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1880 * XXX - if it's OK if this is unsigned, can we just use
1881 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1882 */
1883#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1884
1885/*
1886 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1887 */
1888#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1889
1890/* this can be called when there is no tree, so tree may be null */
1891static void
1892get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1893 const int length, const unsigned encoding, nstime_t *time_stamp,
1894 const bool_Bool is_relative)
1895{
1896 uint32_t tmpsecs;
1897 uint64_t tmp64secs;
1898 uint64_t todusecs;
1899
1900 switch (encoding) {
1901
1902 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1903 /*
1904 * If the length is 16, 8-byte seconds, followed
1905 * by 8-byte fractional time in nanoseconds,
1906 * both big-endian.
1907 *
1908 * If the length is 12, 8-byte seconds, followed
1909 * by 4-byte fractional time in nanoseconds,
1910 * both big-endian.
1911 *
1912 * If the length is 8, 4-byte seconds, followed
1913 * by 4-byte fractional time in nanoseconds,
1914 * both big-endian.
1915 *
1916 * For absolute times, the seconds are seconds
1917 * since the UN*X epoch.
1918 */
1919 if (length == 16) {
1920 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1921 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1922 } else if (length == 12) {
1923 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1924 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1925 } else if (length == 8) {
1926 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1927 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1928 } else if (length == 4) {
1929 /*
1930 * Backwards compatibility.
1931 * ENC_TIME_SECS_NSECS is 0; using
1932 * ENC_BIG_ENDIAN by itself with a 4-byte
1933 * time-in-seconds value was done in the
1934 * past.
1935 */
1936 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1937 time_stamp->nsecs = 0;
1938 } else {
1939 time_stamp->secs = 0;
1940 time_stamp->nsecs = 0;
1941 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1942 }
1943 break;
1944
1945 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
1946 /*
1947 * If the length is 16, 8-byte seconds, followed
1948 * by 8-byte fractional time in nanoseconds,
1949 * both little-endian.
1950 *
1951 * If the length is 12, 8-byte seconds, followed
1952 * by 4-byte fractional time in nanoseconds,
1953 * both little-endian.
1954 *
1955 * If the length is 8, 4-byte seconds, followed
1956 * by 4-byte fractional time in nanoseconds,
1957 * both little-endian.
1958 *
1959 * For absolute times, the seconds are seconds
1960 * since the UN*X epoch.
1961 */
1962 if (length == 16) {
1963 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1964 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
1965 } else if (length == 12) {
1966 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1967 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1968 } else if (length == 8) {
1969 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1970 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1971 } else if (length == 4) {
1972 /*
1973 * Backwards compatibility.
1974 * ENC_TIME_SECS_NSECS is 0; using
1975 * ENC_LITTLE_ENDIAN by itself with a 4-byte
1976 * time-in-seconds value was done in the
1977 * past.
1978 */
1979 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1980 time_stamp->nsecs = 0;
1981 } else {
1982 time_stamp->secs = 0;
1983 time_stamp->nsecs = 0;
1984 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1985 }
1986 break;
1987
1988 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
1989 /*
1990 * NTP time stamp, big-endian.
1991 * Only supported for absolute times.
1992 */
1993 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1993, "!is_relative"
))))
;
1994
1995 /* We need a temporary variable here so the unsigned math
1996 * works correctly (for years > 2036 according to RFC 2030
1997 * chapter 3).
1998 *
1999 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2000 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2001 * If bit 0 is not set, the time is in the range 2036-2104 and
2002 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2003 */
2004 tmpsecs = tvb_get_ntohl(tvb, start);
2005 if ((tmpsecs & 0x80000000) != 0)
2006 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2007 else
2008 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2009
2010 if (length == 8) {
2011 tmp64secs = tvb_get_ntoh64(tvb, start);
2012 if (tmp64secs == 0) {
2013 //This is "NULL" time
2014 time_stamp->secs = 0;
2015 time_stamp->nsecs = 0;
2016 } else {
2017 /*
2018 * Convert 1/2^32s of a second to
2019 * nanoseconds.
2020 */
2021 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2022 }
2023 } else if (length == 4) {
2024 /*
2025 * Backwards compatibility.
2026 */
2027 if (tmpsecs == 0) {
2028 //This is "NULL" time
2029 time_stamp->secs = 0;
2030 }
2031 time_stamp->nsecs = 0;
2032 } else {
2033 time_stamp->secs = 0;
2034 time_stamp->nsecs = 0;
2035 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2036 }
2037 break;
2038
2039 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2040 /*
2041 * NTP time stamp, little-endian.
2042 * Only supported for absolute times.
2043 *
2044 * NTP doesn't use this, because it's an Internet format
2045 * and hence big-endian. Any implementation must decide
2046 * whether the NTP timestamp is a 64-bit unsigned fixed
2047 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2048 * with a 32-bit unsigned seconds field followed by a
2049 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2050 * the previous two).
2051 *
2052 * XXX: We do the latter, but no dissector uses this format.
2053 * OTOH, ERF timestamps do the former, so perhaps we
2054 * should switch the interpretation so that packet-erf.c
2055 * could use this directly?
2056 */
2057 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2057, "!is_relative"
))))
;
2058
2059 /* We need a temporary variable here so the unsigned math
2060 * works correctly (for years > 2036 according to RFC 2030
2061 * chapter 3).
2062 *
2063 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2064 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2065 * If bit 0 is not set, the time is in the range 2036-2104 and
2066 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2067 */
2068 tmpsecs = tvb_get_letohl(tvb, start);
2069 if ((tmpsecs & 0x80000000) != 0)
2070 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2071 else
2072 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2073
2074 if (length == 8) {
2075 tmp64secs = tvb_get_letoh64(tvb, start);
2076 if (tmp64secs == 0) {
2077 //This is "NULL" time
2078 time_stamp->secs = 0;
2079 time_stamp->nsecs = 0;
2080 } else {
2081 /*
2082 * Convert 1/2^32s of a second to
2083 * nanoseconds.
2084 */
2085 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2086 }
2087 } else if (length == 4) {
2088 /*
2089 * Backwards compatibility.
2090 */
2091 if (tmpsecs == 0) {
2092 //This is "NULL" time
2093 time_stamp->secs = 0;
2094 }
2095 time_stamp->nsecs = 0;
2096 } else {
2097 time_stamp->secs = 0;
2098 time_stamp->nsecs = 0;
2099 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2100 }
2101 break;
2102
2103 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2104 /*
2105 * S/3x0 and z/Architecture TOD clock time stamp,
2106 * big-endian. The epoch is January 1, 1900,
2107 * 00:00:00 (proleptic?) UTC.
2108 *
2109 * Only supported for absolute times.
2110 */
2111 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2111, "!is_relative"
))))
;
2112 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2112, "length == 8"
))))
;
2113
2114 if (length == 8) {
2115 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2116 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2117 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2118 } else {
2119 time_stamp->secs = 0;
2120 time_stamp->nsecs = 0;
2121 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2122 }
2123 break;
2124
2125 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2126 /*
2127 * S/3x0 and z/Architecture TOD clock time stamp,
2128 * little-endian. The epoch is January 1, 1900,
2129 * 00:00:00 (proleptic?) UTC.
2130 *
2131 * Only supported for absolute times.
2132 */
2133 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2133, "!is_relative"
))))
;
2134
2135 if (length == 8) {
2136 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2137 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2138 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2139 } else {
2140 time_stamp->secs = 0;
2141 time_stamp->nsecs = 0;
2142 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2143 }
2144 break;
2145
2146 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2147 /*
2148 * Time stamp using the same seconds/fraction format
2149 * as NTP, but with the origin of the time stamp being
2150 * the UNIX epoch rather than the NTP epoch; big-
2151 * endian.
2152 *
2153 * Only supported for absolute times.
2154 */
2155 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2155, "!is_relative"
))))
;
2156
2157 if (length == 8) {
2158 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2159 /*
2160 * Convert 1/2^32s of a second to nanoseconds.
2161 */
2162 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2163 } else {
2164 time_stamp->secs = 0;
2165 time_stamp->nsecs = 0;
2166 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2167 }
2168 break;
2169
2170 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2171 /*
2172 * Time stamp using the same seconds/fraction format
2173 * as NTP, but with the origin of the time stamp being
2174 * the UNIX epoch rather than the NTP epoch; little-
2175 * endian.
2176 *
2177 * Only supported for absolute times.
2178 *
2179 * The RTPS specification explicitly supports Little
2180 * Endian encoding. In one place, it states that its
2181 * Time_t representation "is the one defined by ...
2182 * RFC 1305", but in another explicitly defines it as
2183 * a struct consisting of an 32 bit unsigned seconds
2184 * field and a 32 bit unsigned fraction field, not a 64
2185 * bit fixed point, so we do that here.
2186 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2187 */
2188 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2188, "!is_relative"
))))
;
2189
2190 if (length == 8) {
2191 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2192 /*
2193 * Convert 1/2^32s of a second to nanoseconds.
2194 */
2195 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2196 } else {
2197 time_stamp->secs = 0;
2198 time_stamp->nsecs = 0;
2199 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2200 }
2201 break;
2202
2203 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2204 /*
2205 * MIP6 time stamp, big-endian.
2206 * A 64-bit unsigned integer field containing a timestamp. The
2207 * value indicates the number of seconds since January 1, 1970,
2208 * 00:00 UTC, by using a fixed point format. In this format, the
2209 * integer number of seconds is contained in the first 48 bits of
2210 * the field, and the remaining 16 bits indicate the number of
2211 * 1/65536 fractions of a second.
2212
2213 * Only supported for absolute times.
2214 */
2215 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2215, "!is_relative"
))))
;
2216
2217 if (length == 8) {
2218 /* We need a temporary variable here so the casting and fractions
2219 * of a second work correctly.
2220 */
2221 tmp64secs = tvb_get_ntoh48(tvb, start);
2222 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2223 tmpsecs <<= 16;
2224
2225 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2226 //This is "NULL" time
2227 time_stamp->secs = 0;
2228 time_stamp->nsecs = 0;
2229 } else {
2230 time_stamp->secs = (time_t)tmp64secs;
2231 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2232 }
2233 } else {
2234 time_stamp->secs = 0;
2235 time_stamp->nsecs = 0;
2236 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2237 }
2238 break;
2239
2240 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2241 /*
2242 * If the length is 16, 8-byte seconds, followed
2243 * by 8-byte fractional time in microseconds,
2244 * both big-endian.
2245 *
2246 * If the length is 12, 8-byte seconds, followed
2247 * by 4-byte fractional time in microseconds,
2248 * both big-endian.
2249 *
2250 * If the length is 8, 4-byte seconds, followed
2251 * by 4-byte fractional time in microseconds,
2252 * both big-endian.
2253 *
2254 * For absolute times, the seconds are seconds
2255 * since the UN*X epoch.
2256 */
2257 if (length == 16) {
2258 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2259 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2260 } else if (length == 12) {
2261 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2262 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2263 } else if (length == 8) {
2264 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2265 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2266 } else {
2267 time_stamp->secs = 0;
2268 time_stamp->nsecs = 0;
2269 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2270 }
2271 break;
2272
2273 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2274 /*
2275 * If the length is 16, 8-byte seconds, followed
2276 * by 8-byte fractional time in microseconds,
2277 * both little-endian.
2278 *
2279 * If the length is 12, 8-byte seconds, followed
2280 * by 4-byte fractional time in microseconds,
2281 * both little-endian.
2282 *
2283 * If the length is 8, 4-byte seconds, followed
2284 * by 4-byte fractional time in microseconds,
2285 * both little-endian.
2286 *
2287 * For absolute times, the seconds are seconds
2288 * since the UN*X epoch.
2289 */
2290 if (length == 16) {
2291 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2292 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2293 } else if (length == 12) {
2294 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2295 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2296 } else if (length == 8) {
2297 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2298 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2299 } else {
2300 time_stamp->secs = 0;
2301 time_stamp->nsecs = 0;
2302 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2303 }
2304 break;
2305
2306 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2307 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2308 /*
2309 * Seconds, 1 to 8 bytes.
2310 * For absolute times, it's seconds since the
2311 * UN*X epoch.
2312 */
2313 if (length >= 1 && length <= 8) {
2314 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2315 time_stamp->nsecs = 0;
2316 } else {
2317 time_stamp->secs = 0;
2318 time_stamp->nsecs = 0;
2319 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2320 }
2321 break;
2322
2323 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2324 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2325 /*
2326 * Milliseconds, 1 to 8 bytes.
2327 * For absolute times, it's milliseconds since the
2328 * UN*X epoch.
2329 */
2330 if (length >= 1 && length <= 8) {
2331 uint64_t msecs;
2332
2333 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2334 time_stamp->secs = (time_t)(msecs / 1000);
2335 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2336 } else {
2337 time_stamp->secs = 0;
2338 time_stamp->nsecs = 0;
2339 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2340 }
2341 break;
2342
2343 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2344 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2345 /*
2346 * Microseconds, 1 to 8 bytes.
2347 * For absolute times, it's microseconds since the
2348 * UN*X epoch.
2349 */
2350 if (length >= 1 && length <= 8) {
2351 uint64_t usecs;
2352
2353 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2354 time_stamp->secs = (time_t)(usecs / 1000000);
2355 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2356 } else {
2357 time_stamp->secs = 0;
2358 time_stamp->nsecs = 0;
2359 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2360 }
2361 break;
2362
2363 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2364 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2365 /*
2366 * nanoseconds, 1 to 8 bytes.
2367 * For absolute times, it's nanoseconds since the
2368 * UN*X epoch.
2369 */
2370
2371 if (length >= 1 && length <= 8) {
2372 uint64_t nsecs;
2373
2374 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2375 time_stamp->secs = (time_t)(nsecs / 1000000000);
2376 time_stamp->nsecs = (int)(nsecs % 1000000000);
2377 } else {
2378 time_stamp->secs = 0;
2379 time_stamp->nsecs = 0;
2380 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2381 }
2382 break;
2383
2384 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2385 /*
2386 * 1/64ths of a second since the UN*X epoch,
2387 * big-endian.
2388 *
2389 * Only supported for absolute times.
2390 */
2391 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2391, "!is_relative"
))))
;
2392
2393 if (length == 8) {
2394 /*
2395 * The upper 48 bits are seconds since the
2396 * UN*X epoch.
2397 */
2398 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2399 /*
2400 * The lower 16 bits are 1/2^16s of a second;
2401 * convert them to nanoseconds.
2402 *
2403 * XXX - this may give the impression of higher
2404 * precision than you actually get.
2405 */
2406 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2407 } else {
2408 time_stamp->secs = 0;
2409 time_stamp->nsecs = 0;
2410 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2411 }
2412 break;
2413
2414 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2415 /*
2416 * 1/64ths of a second since the UN*X epoch,
2417 * little-endian.
2418 *
2419 * Only supported for absolute times.
2420 */
2421 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2421, "!is_relative"
))))
;
2422
2423 if (length == 8) {
2424 /*
2425 * XXX - this is assuming that, if anybody
2426 * were ever to use this format - RFC 3971
2427 * doesn't, because that's an Internet
2428 * protocol, and those use network byte
2429 * order, i.e. big-endian - they'd treat it
2430 * as a 64-bit count of 1/2^16s of a second,
2431 * putting the upper 48 bits at the end.
2432 *
2433 * The lower 48 bits are seconds since the
2434 * UN*X epoch.
2435 */
2436 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2437 /*
2438 * The upper 16 bits are 1/2^16s of a second;
2439 * convert them to nanoseconds.
2440 *
2441 * XXX - this may give the impression of higher
2442 * precision than you actually get.
2443 */
2444 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2445 } else {
2446 time_stamp->secs = 0;
2447 time_stamp->nsecs = 0;
2448 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2449 }
2450 break;
2451
2452 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2453 /*
2454 * NTP time stamp, with 1-second resolution (i.e.,
2455 * seconds since the NTP epoch), big-endian.
2456 * Only supported for absolute times.
2457 */
2458 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2458, "!is_relative"
))))
;
2459
2460 if (length == 4) {
2461 /*
2462 * We need a temporary variable here so the unsigned math
2463 * works correctly (for years > 2036 according to RFC 2030
2464 * chapter 3).
2465 *
2466 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2467 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2468 * If bit 0 is not set, the time is in the range 2036-2104 and
2469 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2470 */
2471 tmpsecs = tvb_get_ntohl(tvb, start);
2472 if ((tmpsecs & 0x80000000) != 0)
2473 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2474 else
2475 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2476 time_stamp->nsecs = 0;
2477 } else {
2478 time_stamp->secs = 0;
2479 time_stamp->nsecs = 0;
2480 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2481 }
2482 break;
2483
2484 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2485 /*
2486 * NTP time stamp, with 1-second resolution (i.e.,
2487 * seconds since the NTP epoch), little-endian.
2488 * Only supported for absolute times.
2489 */
2490 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2490, "!is_relative"
))))
;
2491
2492 /*
2493 * We need a temporary variable here so the unsigned math
2494 * works correctly (for years > 2036 according to RFC 2030
2495 * chapter 3).
2496 *
2497 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2498 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2499 * If bit 0 is not set, the time is in the range 2036-2104 and
2500 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2501 */
2502 if (length == 4) {
2503 tmpsecs = tvb_get_letohl(tvb, start);
2504 if ((tmpsecs & 0x80000000) != 0)
2505 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2506 else
2507 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2508 time_stamp->nsecs = 0;
2509 } else {
2510 time_stamp->secs = 0;
2511 time_stamp->nsecs = 0;
2512 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2513 }
2514 break;
2515
2516 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2517 /*
2518 * Milliseconds, 6 to 8 bytes.
2519 * For absolute times, it's milliseconds since the
2520 * NTP epoch.
2521 *
2522 * ETSI TS 129.274 8.119 defines this as:
2523 * "a 48 bit unsigned integer in network order format
2524 * ...encoded as the number of milliseconds since
2525 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2526 * rounded value of 1000 x the value of the 64-bit
2527 * timestamp (Seconds + (Fraction / (1<<32))) defined
2528 * in clause 6 of IETF RFC 5905."
2529 *
2530 * Taken literally, the part after "i.e." would
2531 * mean that the value rolls over before reaching
2532 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2533 * when the 64 bit timestamp rolls over, and we have
2534 * to pick an NTP Era equivalence class to support
2535 * (such as 1968-01-20 to 2104-02-06).
2536 *
2537 * OTOH, the extra room might be used to store Era
2538 * information instead, in which case times until
2539 * 10819-08-03 can be represented with 6 bytes without
2540 * ambiguity. We handle both implementations, and assume
2541 * that times before 1968-01-20 are not represented.
2542 *
2543 * Only 6 bytes or more makes sense as an absolute
2544 * time. 5 bytes or fewer could express a span of
2545 * less than 35 years, either 1900-1934 or 2036-2070.
2546 */
2547 if (length >= 6 && length <= 8) {
2548 uint64_t msecs;
2549
2550 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2551 tmp64secs = (msecs / 1000);
2552 /*
2553 * Assume that times in the first half of NTP
2554 * Era 0 really represent times in the NTP
2555 * Era 1.
2556 */
2557 if (tmp64secs >= 0x80000000)
2558 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2559 else
2560 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2561 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2562 }
2563 else {
2564 time_stamp->secs = 0;
2565 time_stamp->nsecs = 0;
2566 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2567 }
2568 break;
2569
2570 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2571 /*
2572 * MP4 file time stamps, big-endian.
2573 * Only supported for absolute times.
2574 */
2575 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2575, "!is_relative"
))))
;
2576
2577 if (length == 8) {
2578 tmp64secs = tvb_get_ntoh64(tvb, start);
2579 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2580 time_stamp->nsecs = 0;
2581 } else if (length == 4) {
2582 tmpsecs = tvb_get_ntohl(tvb, start);
2583 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2584 time_stamp->nsecs = 0;
2585 } else {
2586 time_stamp->secs = 0;
2587 time_stamp->nsecs = 0;
2588 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2589 }
2590 break;
2591
2592 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2593 /*
2594 * Zigbee ZCL time stamps, big-endian.
2595 * Only supported for absolute times.
2596 */
2597 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2597, "!is_relative"
))))
;
2598
2599 if (length == 8) {
2600 tmp64secs = tvb_get_ntoh64(tvb, start);
2601 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)));
2602 time_stamp->nsecs = 0;
2603 } else if (length == 4) {
2604 tmpsecs = tvb_get_ntohl(tvb, start);
2605 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)));
2606 time_stamp->nsecs = 0;
2607 } else {
2608 time_stamp->secs = 0;
2609 time_stamp->nsecs = 0;
2610 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2611 }
2612 break;
2613
2614 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2615 /*
2616 * Zigbee ZCL time stamps, little-endian.
2617 * Only supported for absolute times.
2618 */
2619 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2619, "!is_relative"
))))
;
2620
2621 if (length == 8) {
2622 tmp64secs = tvb_get_letoh64(tvb, start);
2623 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)));
2624 time_stamp->nsecs = 0;
2625 } else if (length == 4) {
2626 tmpsecs = tvb_get_letohl(tvb, start);
2627 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)));
2628 time_stamp->nsecs = 0;
2629 } else {
2630 time_stamp->secs = 0;
2631 time_stamp->nsecs = 0;
2632 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2633 }
2634 break;
2635
2636 default:
2637 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2637))
;
2638 break;
2639 }
2640}
2641
2642static void
2643tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2644{
2645 const header_field_info *hfinfo = fi->hfinfo;
2646
2647 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2648 GPtrArray *ptrs = NULL((void*)0);
2649
2650 if (tree_data->interesting_hfids == NULL((void*)0)) {
2651 /* Initialize the hash because we now know that it is needed */
2652 tree_data->interesting_hfids =
2653 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2654 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2655 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2656 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2657 }
2658
2659 if (!ptrs) {
2660 /* First element triggers the creation of pointer array */
2661 ptrs = g_ptr_array_new();
2662 g_hash_table_insert(tree_data->interesting_hfids,
2663 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2664 }
2665
2666 g_ptr_array_add(ptrs, fi);
2667 }
2668}
2669
2670
2671/*
2672 * Validates that field length bytes are available starting from
2673 * start (pos/neg). Throws an exception if they aren't.
2674 */
2675static void
2676test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2677 int start, int length, const unsigned encoding)
2678{
2679 int size = length;
2680
2681 if (!tvb)
2682 return;
2683
2684 if ((hfinfo->type == FT_STRINGZ) ||
2685 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2686 (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
))
))) {
2687 /* If we're fetching until the end of the TVB, only validate
2688 * that the offset is within range.
2689 */
2690 if (length == -1)
2691 size = 0;
2692 }
2693
2694 tvb_ensure_bytes_exist(tvb, start, size);
2695}
2696
2697static void
2698detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2699{
2700 bool_Bool found_stray_character = false0;
2701
2702 if (!string)
2703 return;
2704
2705 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2706 case ENC_ASCII0x00000000:
2707 case ENC_UTF_80x00000002:
2708 for (int i = (int)strlen(string); i < length; i++) {
2709 if (string[i] != '\0') {
2710 found_stray_character = true1;
2711 break;
2712 }
2713 }
2714 break;
2715
2716 default:
2717 break;
2718 }
2719
2720 if (found_stray_character) {
2721 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2722 }
2723}
2724
2725static void
2726free_fvalue_cb(void *data)
2727{
2728 fvalue_t *fv = (fvalue_t*)data;
2729 fvalue_free(fv);
2730}
2731
2732/* Add an item to a proto_tree, using the text label registered to that item;
2733 the item is extracted from the tvbuff handed to it. */
2734static proto_item *
2735proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2736 tvbuff_t *tvb, int start, int length,
2737 unsigned encoding)
2738{
2739 proto_item *pi;
2740 uint32_t value, n;
2741 uint64_t value64;
2742 ws_in4_addr ipv4_value;
2743 float floatval;
2744 double doubleval;
2745 const char *stringval = NULL((void*)0);
2746 nstime_t time_stamp;
2747 bool_Bool length_error;
2748
2749 /* Ensure that the newly created fvalue_t is freed if we throw an
2750 * exception before adding it to the tree. (gcc creates clobbering
2751 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2752 * XXX: Move the new_field_info() call inside here?
2753 */
2754 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))
;
2755
2756 switch (new_fi->hfinfo->type) {
2757 case FT_NONE:
2758 /* no value to set for FT_NONE */
2759 break;
2760
2761 case FT_PROTOCOL:
2762 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2763 break;
2764
2765 case FT_BYTES:
2766 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2767 break;
2768
2769 case FT_UINT_BYTES:
2770 n = get_uint_value(tree, tvb, start, length, encoding);
2771 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2772
2773 /* Instead of calling proto_item_set_len(), since we don't yet
2774 * have a proto_item, we set the field_info's length ourselves. */
2775 new_fi->length = n + length;
2776 break;
2777
2778 case FT_BOOLEAN:
2779 /*
2780 * Map all non-zero values to little-endian for
2781 * backwards compatibility.
2782 */
2783 if (encoding)
2784 encoding = ENC_LITTLE_ENDIAN0x80000000;
2785 proto_tree_set_boolean(new_fi,
2786 get_uint64_value(tree, tvb, start, length, encoding));
2787 break;
2788
2789 case FT_CHAR:
2790 /* XXX - make these just FT_UINT? */
2791 case FT_UINT8:
2792 case FT_UINT16:
2793 case FT_UINT24:
2794 case FT_UINT32:
2795 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2796 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2797 value = (uint32_t)value64;
2798 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2799 new_fi->flags |= FI_VARINT0x00004000;
2800 }
2801 }
2802 else {
2803 /*
2804 * Map all non-zero values to little-endian for
2805 * backwards compatibility.
2806 */
2807 if (encoding)
2808 encoding = ENC_LITTLE_ENDIAN0x80000000;
2809
2810 value = get_uint_value(tree, tvb, start, length, encoding);
2811 }
2812 proto_tree_set_uint(new_fi, value);
2813 break;
2814
2815 case FT_UINT40:
2816 case FT_UINT48:
2817 case FT_UINT56:
2818 case FT_UINT64:
2819 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2820 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2821 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2822 new_fi->flags |= FI_VARINT0x00004000;
2823 }
2824 }
2825 else {
2826 /*
2827 * Map all other non-zero values to little-endian for
2828 * backwards compatibility.
2829 */
2830 if (encoding)
2831 encoding = ENC_LITTLE_ENDIAN0x80000000;
2832
2833 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2834 }
2835 proto_tree_set_uint64(new_fi, value64);
2836 break;
2837
2838 /* XXX - make these just FT_INT? */
2839 case FT_INT8:
2840 case FT_INT16:
2841 case FT_INT24:
2842 case FT_INT32:
2843 /*
2844 * Map all non-zero values to little-endian for
2845 * backwards compatibility.
2846 */
2847 if (encoding)
2848 encoding = ENC_LITTLE_ENDIAN0x80000000;
2849 proto_tree_set_int(new_fi,
2850 get_int_value(tree, tvb, start, length, encoding));
2851 break;
2852
2853 case FT_INT40:
2854 case FT_INT48:
2855 case FT_INT56:
2856 case FT_INT64:
2857 /*
2858 * Map all non-zero values to little-endian for
2859 * backwards compatibility.
2860 */
2861 if (encoding)
2862 encoding = ENC_LITTLE_ENDIAN0x80000000;
2863 proto_tree_set_int64(new_fi,
2864 get_int64_value(tree, tvb, start, length, encoding));
2865 break;
2866
2867 case FT_IPv4:
2868 /*
2869 * Map all non-zero values to little-endian for
2870 * backwards compatibility.
2871 */
2872 if (encoding)
2873 encoding = ENC_LITTLE_ENDIAN0x80000000;
2874 if (length != FT_IPv4_LEN4) {
2875 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2876 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2877 }
2878 ipv4_value = tvb_get_ipv4(tvb, start);
2879 /*
2880 * NOTE: to support code written when
2881 * proto_tree_add_item() took a bool as its
2882 * last argument, with false meaning "big-endian"
2883 * and true meaning "little-endian", we treat any
2884 * non-zero value of "encoding" as meaning
2885 * "little-endian".
2886 */
2887 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);
2888 break;
2889
2890 case FT_IPXNET:
2891 if (length != FT_IPXNET_LEN4) {
2892 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2893 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2894 }
2895 proto_tree_set_ipxnet(new_fi,
2896 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2897 break;
2898
2899 case FT_IPv6:
2900 if (length != FT_IPv6_LEN16) {
2901 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2902 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2903 }
2904 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2905 break;
2906
2907 case FT_FCWWN:
2908 if (length != FT_FCWWN_LEN8) {
2909 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2910 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2911 }
2912 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2913 break;
2914
2915 case FT_AX25:
2916 if (length != 7) {
2917 length_error = length < 7 ? true1 : false0;
2918 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2919 }
2920 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2921 break;
2922
2923 case FT_VINES:
2924 if (length != VINES_ADDR_LEN6) {
2925 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2926 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2927 }
2928 proto_tree_set_vines_tvb(new_fi, tvb, start);
2929 break;
2930
2931 case FT_ETHER:
2932 if (length != FT_ETHER_LEN6) {
2933 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2934 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2935 }
2936 proto_tree_set_ether_tvb(new_fi, tvb, start);
2937 break;
2938
2939 case FT_EUI64:
2940 /*
2941 * Map all non-zero values to little-endian for
2942 * backwards compatibility.
2943 */
2944 if (encoding)
2945 encoding = ENC_LITTLE_ENDIAN0x80000000;
2946 if (length != FT_EUI64_LEN8) {
2947 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
2948 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2949 }
2950 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2951 break;
2952 case FT_GUID:
2953 /*
2954 * Map all non-zero values to little-endian for
2955 * backwards compatibility.
2956 */
2957 if (encoding)
2958 encoding = ENC_LITTLE_ENDIAN0x80000000;
2959 if (length != FT_GUID_LEN16) {
2960 length_error = length < FT_GUID_LEN16 ? true1 : false0;
2961 report_type_length_mismatch(tree, "a GUID", length, length_error);
2962 }
2963 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2964 break;
2965
2966 case FT_OID:
2967 case FT_REL_OID:
2968 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2969 break;
2970
2971 case FT_SYSTEM_ID:
2972 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2973 break;
2974
2975 case FT_FLOAT:
2976 /*
2977 * NOTE: to support code written when
2978 * proto_tree_add_item() took a bool as its
2979 * last argument, with false meaning "big-endian"
2980 * and true meaning "little-endian", we treat any
2981 * non-zero value of "encoding" as meaning
2982 * "little-endian".
2983 *
2984 * At some point in the future, we might
2985 * support non-IEEE-binary floating-point
2986 * formats in the encoding as well
2987 * (IEEE decimal, System/3x0, VAX).
2988 */
2989 if (encoding)
2990 encoding = ENC_LITTLE_ENDIAN0x80000000;
2991 if (length != 4) {
2992 length_error = length < 4 ? true1 : false0;
2993 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
2994 }
2995 if (encoding)
2996 floatval = tvb_get_letohieee_float(tvb, start);
2997 else
2998 floatval = tvb_get_ntohieee_float(tvb, start);
2999 proto_tree_set_float(new_fi, floatval);
3000 break;
3001
3002 case FT_DOUBLE:
3003 /*
3004 * NOTE: to support code written when
3005 * proto_tree_add_item() took a bool as its
3006 * last argument, with false meaning "big-endian"
3007 * and true meaning "little-endian", we treat any
3008 * non-zero value of "encoding" as meaning
3009 * "little-endian".
3010 *
3011 * At some point in the future, we might
3012 * support non-IEEE-binary floating-point
3013 * formats in the encoding as well
3014 * (IEEE decimal, System/3x0, VAX).
3015 */
3016 if (encoding == true1)
3017 encoding = ENC_LITTLE_ENDIAN0x80000000;
3018 if (length != 8) {
3019 length_error = length < 8 ? true1 : false0;
3020 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3021 }
3022 if (encoding)
3023 doubleval = tvb_get_letohieee_double(tvb, start);
3024 else
3025 doubleval = tvb_get_ntohieee_double(tvb, start);
3026 proto_tree_set_double(new_fi, doubleval);
3027 break;
3028
3029 case FT_STRING:
3030 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3031 tvb, start, length, &length, encoding);
3032 proto_tree_set_string(new_fi, stringval);
3033
3034 /* Instead of calling proto_item_set_len(), since we
3035 * don't yet have a proto_item, we set the
3036 * field_info's length ourselves.
3037 *
3038 * XXX - our caller can't use that length to
3039 * advance an offset unless they arrange that
3040 * there always be a protocol tree into which
3041 * we're putting this item.
3042 */
3043 new_fi->length = length;
3044 break;
3045
3046 case FT_STRINGZ:
3047 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3048 tree, tvb, start, length, &length, encoding);
3049 proto_tree_set_string(new_fi, stringval);
3050
3051 /* Instead of calling proto_item_set_len(),
3052 * since we don't yet have a proto_item, we
3053 * set the field_info's length ourselves.
3054 *
3055 * XXX - our caller can't use that length to
3056 * advance an offset unless they arrange that
3057 * there always be a protocol tree into which
3058 * we're putting this item.
3059 */
3060 new_fi->length = length;
3061 break;
3062
3063 case FT_UINT_STRING:
3064 /*
3065 * NOTE: to support code written when
3066 * proto_tree_add_item() took a bool as its
3067 * last argument, with false meaning "big-endian"
3068 * and true meaning "little-endian", if the
3069 * encoding value is true, treat that as
3070 * ASCII with a little-endian length.
3071 *
3072 * This won't work for code that passes
3073 * arbitrary non-zero values; that code
3074 * will need to be fixed.
3075 */
3076 if (encoding == true1)
3077 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3078 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3079 tree, tvb, start, length, &length, encoding);
3080 proto_tree_set_string(new_fi, stringval);
3081
3082 /* Instead of calling proto_item_set_len(), since we
3083 * don't yet have a proto_item, we set the
3084 * field_info's length ourselves.
3085 *
3086 * XXX - our caller can't use that length to
3087 * advance an offset unless they arrange that
3088 * there always be a protocol tree into which
3089 * we're putting this item.
3090 */
3091 new_fi->length = length;
3092 break;
3093
3094 case FT_STRINGZPAD:
3095 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3096 tvb, start, length, &length, encoding);
3097 proto_tree_set_string(new_fi, stringval);
3098
3099 /* Instead of calling proto_item_set_len(), since we
3100 * don't yet have a proto_item, we set the
3101 * field_info's length ourselves.
3102 *
3103 * XXX - our caller can't use that length to
3104 * advance an offset unless they arrange that
3105 * there always be a protocol tree into which
3106 * we're putting this item.
3107 */
3108 new_fi->length = length;
3109 break;
3110
3111 case FT_STRINGZTRUNC:
3112 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3113 tvb, start, length, &length, encoding);
3114 proto_tree_set_string(new_fi, stringval);
3115
3116 /* Instead of calling proto_item_set_len(), since we
3117 * don't yet have a proto_item, we set the
3118 * field_info's length ourselves.
3119 *
3120 * XXX - our caller can't use that length to
3121 * advance an offset unless they arrange that
3122 * there always be a protocol tree into which
3123 * we're putting this item.
3124 */
3125 new_fi->length = length;
3126 break;
3127
3128 case FT_ABSOLUTE_TIME:
3129 /*
3130 * Absolute times can be in any of a number of
3131 * formats, and they can be big-endian or
3132 * little-endian.
3133 *
3134 * Historically FT_TIMEs were only timespecs;
3135 * the only question was whether they were stored
3136 * in big- or little-endian format.
3137 *
3138 * For backwards compatibility, we interpret an
3139 * encoding of 1 as meaning "little-endian timespec",
3140 * so that passing true is interpreted as that.
3141 */
3142 if (encoding == true1)
3143 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3144
3145 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3146
3147 proto_tree_set_time(new_fi, &time_stamp);
3148 break;
3149
3150 case FT_RELATIVE_TIME:
3151 /*
3152 * Relative times can be in any of a number of
3153 * formats, and they can be big-endian or
3154 * little-endian.
3155 *
3156 * Historically FT_TIMEs were only timespecs;
3157 * the only question was whether they were stored
3158 * in big- or little-endian format.
3159 *
3160 * For backwards compatibility, we interpret an
3161 * encoding of 1 as meaning "little-endian timespec",
3162 * so that passing true is interpreted as that.
3163 */
3164 if (encoding == true1)
3165 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3166
3167 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3168
3169 proto_tree_set_time(new_fi, &time_stamp);
3170 break;
3171 case FT_IEEE_11073_SFLOAT:
3172 if (encoding)
3173 encoding = ENC_LITTLE_ENDIAN0x80000000;
3174 if (length != 2) {
3175 length_error = length < 2 ? true1 : false0;
3176 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3177 }
3178
3179 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3180
3181 break;
3182 case FT_IEEE_11073_FLOAT:
3183 if (encoding)
3184 encoding = ENC_LITTLE_ENDIAN0x80000000;
3185 if (length != 4) {
3186 length_error = length < 4 ? true1 : false0;
3187 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3188 }
3189
3190 break;
3191 default:
3192 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))
3193 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))
3194 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))
3195 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))
;
3196 break;
3197 }
3198 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)
;
3199
3200 /* Don't add new node to proto_tree until now so that any exceptions
3201 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3202 /* XXX. wouldn't be better to add this item to tree, with some special
3203 * flag (FI_EXCEPTION?) to know which item caused exception? For
3204 * strings and bytes, we would have to set new_fi->value to something
3205 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3206 * could handle NULL values. */
3207 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3208 pi = proto_tree_add_node(tree, new_fi);
3209
3210 switch (new_fi->hfinfo->type) {
3211
3212 case FT_STRING:
3213 /* XXX: trailing stray character detection should be done
3214 * _before_ conversion to UTF-8, because conversion can change
3215 * the length, or else get_string_length should return a value
3216 * for the "length in bytes of the string after conversion
3217 * including internal nulls." (Noting that we do, for other
3218 * reasons, still need the "length in bytes in the field",
3219 * especially for FT_STRINGZ.)
3220 *
3221 * This is true even for ASCII and UTF-8, because
3222 * substituting REPLACEMENT CHARACTERS for illegal characters
3223 * can also do so (and for UTF-8 possibly even make the
3224 * string _shorter_).
3225 */
3226 detect_trailing_stray_characters(encoding, stringval, length, pi);
3227 break;
3228
3229 default:
3230 break;
3231 }
3232
3233 return pi;
3234}
3235
3236proto_item *
3237proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3238 const int start, int length,
3239 const unsigned encoding, int32_t *retval)
3240{
3241 header_field_info *hfinfo;
3242 field_info *new_fi;
3243 int32_t value;
3244
3245 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", 3245, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3245,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3245, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3246
3247 switch (hfinfo->type) {
3248 case FT_INT8:
3249 case FT_INT16:
3250 case FT_INT24:
3251 case FT_INT32:
3252 break;
3253 case FT_INT64:
3254 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)
3255 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3256 default:
3257 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)
3258 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3259 }
3260
3261 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3262 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3263 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3264 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3265 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3266 }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
3269 if (encoding & ENC_STRING0x03000000) {
3270 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3271 }
3272 /* I believe it's ok if this is called with a NULL tree */
3273 value = get_int_value(tree, tvb, start, length, encoding);
3274
3275 if (retval) {
3276 int no_of_bits;
3277 *retval = value;
3278 if (hfinfo->bitmask) {
3279 /* Mask out irrelevant portions */
3280 *retval &= (uint32_t)(hfinfo->bitmask);
3281 /* Shift bits */
3282 *retval >>= hfinfo_bitshift(hfinfo);
3283 }
3284 no_of_bits = ws_count_ones(hfinfo->bitmask);
3285 *retval = ws_sign_ext32(*retval, no_of_bits);
3286 }
3287
3288 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3289
3290 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", 3290
, __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", 3290, "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", 3290, "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", 3290, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3291
3292 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3293
3294 proto_tree_set_int(new_fi, value);
3295
3296 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3297
3298 return proto_tree_add_node(tree, new_fi);
3299}
3300
3301proto_item *
3302proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3303 const int start, int length,
3304 const unsigned encoding, uint32_t *retval)
3305{
3306 header_field_info *hfinfo;
3307 field_info *new_fi;
3308 uint32_t value;
3309
3310 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", 3310, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3310,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3310, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3311
3312 switch (hfinfo->type) {
3313 case FT_CHAR:
3314 case FT_UINT8:
3315 case FT_UINT16:
3316 case FT_UINT24:
3317 case FT_UINT32:
3318 break;
3319 default:
3320 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)
3321 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)
;
3322 }
3323
3324 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3325 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3326 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3327 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3328 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3329 }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
3332 if (encoding & ENC_STRING0x03000000) {
3333 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3334 }
3335 /* I believe it's ok if this is called with a NULL tree */
3336 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3337 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3338 uint64_t temp64;
3339 tvb_get_varint(tvb, start, length, &temp64, encoding);
3340 value = (uint32_t)temp64;
3341 } else {
3342 value = get_uint_value(tree, tvb, start, length, encoding);
3343 }
3344
3345 if (retval) {
3346 *retval = value;
3347 if (hfinfo->bitmask) {
3348 /* Mask out irrelevant portions */
3349 *retval &= (uint32_t)(hfinfo->bitmask);
3350 /* Shift bits */
3351 *retval >>= hfinfo_bitshift(hfinfo);
3352 }
3353 }
3354
3355 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3356
3357 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", 3357
, __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", 3357, "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", 3357, "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", 3357, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3358
3359 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3360
3361 proto_tree_set_uint(new_fi, value);
3362
3363 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3364 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3365 new_fi->flags |= FI_VARINT0x00004000;
3366 }
3367 return proto_tree_add_node(tree, new_fi);
3368}
3369
3370/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3371 * and returns proto_item* and uint value retreived*/
3372proto_item *
3373ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3374 const unsigned encoding, uint32_t *retval)
3375{
3376 field_info *new_fi;
3377 header_field_info *hfinfo;
3378 int item_length;
3379 int offset;
3380 uint32_t value;
3381
3382 offset = ptvc->offset;
3383 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", 3383, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3383,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3383, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3384
3385 switch (hfinfo->type) {
3386 case FT_CHAR:
3387 case FT_UINT8:
3388 case FT_UINT16:
3389 case FT_UINT24:
3390 case FT_UINT32:
3391 break;
3392 default:
3393 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)
3394 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)
;
3395 }
3396
3397 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3398 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3399
3400 /* I believe it's ok if this is called with a NULL tree */
3401 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3402 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3403
3404 if (retval) {
3405 *retval = value;
3406 if (hfinfo->bitmask) {
3407 /* Mask out irrelevant portions */
3408 *retval &= (uint32_t)(hfinfo->bitmask);
3409 /* Shift bits */
3410 *retval >>= hfinfo_bitshift(hfinfo);
3411 }
3412 }
3413
3414 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3415 item_length, encoding);
3416
3417 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3418
3419 /* Coast clear. Try and fake it */
3420 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", 3420
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3420, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3420, "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", 3420, __func__, "Adding %s would put more than %d 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); } } }
;
3421
3422 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3423
3424 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3425 offset, length, encoding);
3426}
3427
3428/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3429 * and returns proto_item* and int value retreived*/
3430proto_item *
3431ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3432 const unsigned encoding, int32_t *retval)
3433{
3434 field_info *new_fi;
3435 header_field_info *hfinfo;
3436 int item_length;
3437 int offset;
3438 uint32_t value;
3439
3440 offset = ptvc->offset;
3441 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", 3441, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3441,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3441, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3442
3443 switch (hfinfo->type) {
3444 case FT_INT8:
3445 case FT_INT16:
3446 case FT_INT24:
3447 case FT_INT32:
3448 break;
3449 default:
3450 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)
3451 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3452 }
3453
3454 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3455 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3456
3457 /* I believe it's ok if this is called with a NULL tree */
3458 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3459 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3460
3461 if (retval) {
3462 int no_of_bits;
3463 *retval = value;
3464 if (hfinfo->bitmask) {
3465 /* Mask out irrelevant portions */
3466 *retval &= (uint32_t)(hfinfo->bitmask);
3467 /* Shift bits */
3468 *retval >>= hfinfo_bitshift(hfinfo);
3469 }
3470 no_of_bits = ws_count_ones(hfinfo->bitmask);
3471 *retval = ws_sign_ext32(*retval, no_of_bits);
3472 }
3473
3474 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3475 item_length, encoding);
3476
3477 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3478
3479 /* Coast clear. Try and fake it */
3480 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", 3480
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3480, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3480, "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", 3480, __func__, "Adding %s would put more than %d 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); } } }
;
3481
3482 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3483
3484 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3485 offset, length, encoding);
3486}
3487
3488/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3489 * and returns proto_item* and string value retreived */
3490proto_item*
3491ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3492{
3493 header_field_info *hfinfo;
3494 field_info *new_fi;
3495 const uint8_t *value;
3496 int item_length;
3497 int offset;
3498
3499 offset = ptvc->offset;
3500
3501 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", 3501
, __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", 3501, "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", 3501, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3502
3503 switch (hfinfo->type) {
3504 case FT_STRING:
3505 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3506 break;
3507 case FT_STRINGZ:
3508 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3509 break;
3510 case FT_UINT_STRING:
3511 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3512 break;
3513 case FT_STRINGZPAD:
3514 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3515 break;
3516 case FT_STRINGZTRUNC:
3517 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3518 break;
3519 default:
3520 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)
3521 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)
;
3522 }
3523
3524 if (retval)
3525 *retval = value;
3526
3527 ptvc->offset += item_length;
3528
3529 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3530
3531 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", 3531, __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", 3531,
"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", 3531, "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", 3531
, __func__, "Adding %s would put more than %d 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); } } }
;
3532
3533 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3534
3535 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3536 offset, length, encoding);
3537}
3538
3539/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3540 * and returns proto_item* and boolean value retreived */
3541proto_item*
3542ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3543{
3544 header_field_info *hfinfo;
3545 field_info *new_fi;
3546 int item_length;
3547 int offset;
3548 uint64_t value, bitval;
3549
3550 offset = ptvc->offset;
3551 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", 3551, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3551,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3551, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3552
3553 if (hfinfo->type != FT_BOOLEAN) {
3554 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)
3555 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3556 }
3557
3558 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3559 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3560 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3561 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3562 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3563 }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
3566 if (encoding & ENC_STRING0x03000000) {
3567 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3568 }
3569
3570 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3571 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3572
3573 /* I believe it's ok if this is called with a NULL tree */
3574 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3575
3576 if (retval) {
3577 bitval = value;
3578 if (hfinfo->bitmask) {
3579 /* Mask out irrelevant portions */
3580 bitval &= hfinfo->bitmask;
3581 }
3582 *retval = (bitval != 0);
3583 }
3584
3585 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3586 item_length, encoding);
3587
3588 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3589
3590 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", 3590, __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", 3590,
"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", 3590, "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", 3590
, __func__, "Adding %s would put more than %d 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); } } }
;
3591
3592 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3593
3594 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3595 offset, length, encoding);
3596}
3597
3598proto_item *
3599proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3600 const int start, int length, const unsigned encoding, uint64_t *retval)
3601{
3602 header_field_info *hfinfo;
3603 field_info *new_fi;
3604 uint64_t value;
3605
3606 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", 3606, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3606,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3606, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3607
3608 switch (hfinfo->type) {
3609 case FT_UINT40:
3610 case FT_UINT48:
3611 case FT_UINT56:
3612 case FT_UINT64:
3613 break;
3614 default:
3615 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)
3616 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3617 }
3618
3619 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3620 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3621 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3622 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3623 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3624 }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
3627 if (encoding & ENC_STRING0x03000000) {
3628 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3629 }
3630 /* I believe it's ok if this is called with a NULL tree */
3631 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3632 tvb_get_varint(tvb, start, length, &value, encoding);
3633 } else {
3634 value = get_uint64_value(tree, tvb, start, length, encoding);
3635 }
3636
3637 if (retval) {
3638 *retval = value;
3639 if (hfinfo->bitmask) {
3640 /* Mask out irrelevant portions */
3641 *retval &= hfinfo->bitmask;
3642 /* Shift bits */
3643 *retval >>= hfinfo_bitshift(hfinfo);
3644 }
3645 }
3646
3647 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3648
3649 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", 3649
, __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", 3649, "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", 3649, "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", 3649, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3650
3651 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3652
3653 proto_tree_set_uint64(new_fi, value);
3654
3655 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3656 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3657 new_fi->flags |= FI_VARINT0x00004000;
3658 }
3659
3660 return proto_tree_add_node(tree, new_fi);
3661}
3662
3663proto_item *
3664proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3665 const int start, int length, const unsigned encoding, int64_t *retval)
3666{
3667 header_field_info *hfinfo;
3668 field_info *new_fi;
3669 int64_t value;
3670
3671 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", 3671, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3671,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3671, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3672
3673 switch (hfinfo->type) {
3674 case FT_INT40:
3675 case FT_INT48:
3676 case FT_INT56:
3677 case FT_INT64:
3678 break;
3679 default:
3680 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)
3681 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3682 }
3683
3684 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3685 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3686 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3687 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3688 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3689 }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
3692 if (encoding & ENC_STRING0x03000000) {
3693 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3694 }
3695 /* I believe it's ok if this is called with a NULL tree */
3696 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3697 tvb_get_varint(tvb, start, length, &value, encoding);
3698 }
3699 else {
3700 value = get_int64_value(tree, tvb, start, length, encoding);
3701 }
3702
3703 if (retval) {
3704 *retval = value;
3705 }
3706
3707 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3708
3709 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", 3709
, __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", 3709, "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", 3709, "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", 3709, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3710
3711 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3712
3713 proto_tree_set_int64(new_fi, value);
3714
3715 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3716 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3717 new_fi->flags |= FI_VARINT0x00004000;
3718 }
3719
3720 return proto_tree_add_node(tree, new_fi);
3721}
3722
3723proto_item *
3724proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3725 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3726{
3727 header_field_info *hfinfo;
3728 field_info *new_fi;
3729 uint64_t value;
3730
3731 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", 3731, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3731,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3731, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3732
3733 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
))
)) {
3734 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)
3735 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3736 }
3737
3738 /* length validation for native number encoding caught by get_uint64_value() */
3739 /* length has to be -1 or > 0 regardless of encoding */
3740 if (length == 0)
3741 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)
3742 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3743
3744 if (encoding & ENC_STRING0x03000000) {
3745 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3746 }
3747
3748 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3749
3750 if (retval) {
3751 *retval = value;
3752 if (hfinfo->bitmask) {
3753 /* Mask out irrelevant portions */
3754 *retval &= hfinfo->bitmask;
3755 /* Shift bits */
3756 *retval >>= hfinfo_bitshift(hfinfo);
3757 }
3758 }
3759
3760 if (lenretval) {
3761 *lenretval = length;
3762 }
3763
3764 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3765
3766 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", 3766
, __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", 3766, "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", 3766, "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", 3766, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3767
3768 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3769
3770 proto_tree_set_uint64(new_fi, value);
3771
3772 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3773 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3774 new_fi->flags |= FI_VARINT0x00004000;
3775 }
3776
3777 return proto_tree_add_node(tree, new_fi);
3778
3779}
3780
3781proto_item *
3782proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3783 const int start, int length,
3784 const unsigned encoding, bool_Bool *retval)
3785{
3786 header_field_info *hfinfo;
3787 field_info *new_fi;
3788 uint64_t value, bitval;
3789
3790 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", 3790, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3790,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3790, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3791
3792 if (hfinfo->type != FT_BOOLEAN) {
3793 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)
3794 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3795 }
3796
3797 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3798 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3799 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3800 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3801 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3802 }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
3805 if (encoding & ENC_STRING0x03000000) {
3806 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3807 }
3808 /* I believe it's ok if this is called with a NULL tree */
3809 value = get_uint64_value(tree, tvb, start, length, encoding);
3810
3811 if (retval) {
3812 bitval = value;
3813 if (hfinfo->bitmask) {
3814 /* Mask out irrelevant portions */
3815 bitval &= hfinfo->bitmask;
3816 }
3817 *retval = (bitval != 0);
3818 }
3819
3820 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3821
3822 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", 3822
, __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", 3822, "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", 3822, "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", 3822, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3823
3824 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3825
3826 proto_tree_set_boolean(new_fi, value);
3827
3828 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3829
3830 return proto_tree_add_node(tree, new_fi);
3831}
3832
3833proto_item *
3834proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3835 const int start, int length,
3836 const unsigned encoding, float *retval)
3837{
3838 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3839 field_info *new_fi;
3840 float value;
3841
3842 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", 3842,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3843
3844 if (hfinfo->type != FT_FLOAT) {
3845 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)
;
3846 }
3847
3848 if (length != 4) {
3849 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3850 }
3851
3852 /* treat any nonzero encoding as little endian for backwards compatibility */
3853 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3854 if (retval) {
3855 *retval = value;
3856 }
3857
3858 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3859
3860 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", 3860
, __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", 3860, "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", 3860, "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", 3860, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3861
3862 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3863 if (encoding) {
3864 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3865 }
3866
3867 proto_tree_set_float(new_fi, value);
3868
3869 return proto_tree_add_node(tree, new_fi);
3870}
3871
3872proto_item *
3873proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3874 const int start, int length,
3875 const unsigned encoding, double *retval)
3876{
3877 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3878 field_info *new_fi;
3879 double value;
3880
3881 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", 3881,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3882
3883 if (hfinfo->type != FT_DOUBLE) {
3884 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)
;
3885 }
3886
3887 if (length != 8) {
3888 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3889 }
3890
3891 /* treat any nonzero encoding as little endian for backwards compatibility */
3892 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3893 if (retval) {
3894 *retval = value;
3895 }
3896
3897 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3898
3899 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", 3899
, __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", 3899, "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", 3899, "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", 3899, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3900
3901 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3902 if (encoding) {
3903 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3904 }
3905
3906 proto_tree_set_double(new_fi, value);
3907
3908 return proto_tree_add_node(tree, new_fi);
3909}
3910
3911proto_item *
3912proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3913 const int start, int length,
3914 const unsigned encoding, ws_in4_addr *retval)
3915{
3916 header_field_info *hfinfo;
3917 field_info *new_fi;
3918 ws_in4_addr value;
3919
3920 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", 3920, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3920,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3920, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3921
3922 switch (hfinfo->type) {
3923 case FT_IPv4:
3924 break;
3925 default:
3926 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)
3927 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3928 }
3929
3930 if (length != FT_IPv4_LEN4)
3931 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)
3932 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3933
3934 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3935 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3936 }
3937
3938 /*
3939 * NOTE: to support code written when proto_tree_add_item() took
3940 * a bool as its last argument, with false meaning "big-endian"
3941 * and true meaning "little-endian", we treat any non-zero value
3942 * of "encoding" as meaning "little-endian".
3943 */
3944 value = tvb_get_ipv4(tvb, start);
3945 if (encoding)
3946 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))))
;
3947
3948 if (retval) {
3949 *retval = value;
3950 }
3951
3952 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3953
3954 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", 3954
, __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", 3954, "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", 3954, "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", 3954, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3955
3956 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3957
3958 proto_tree_set_ipv4(new_fi, value);
3959
3960 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3961 return proto_tree_add_node(tree, new_fi);
3962}
3963
3964proto_item *
3965proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3966 const int start, int length,
3967 const unsigned encoding, ws_in6_addr *addr)
3968{
3969 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3970 field_info *new_fi;
3971
3972 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", 3972,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3973
3974 switch (hfinfo->type) {
3975 case FT_IPv6:
3976 break;
3977 default:
3978 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)
3979 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
3980 }
3981
3982 if (length != FT_IPv6_LEN16)
3983 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)
3984 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
3985
3986 if (encoding) {
3987 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"
)
;
3988 }
3989
3990 tvb_get_ipv6(tvb, start, addr);
3991
3992 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3993
3994 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", 3994
, __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", 3994, "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", 3994, "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", 3994, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3995
3996 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3997
3998 proto_tree_set_ipv6(new_fi, addr);
3999
4000 return proto_tree_add_node(tree, new_fi);
4001}
4002
4003proto_item *
4004proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4005 const int start, int length, const unsigned encoding, uint8_t *retval) {
4006
4007 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4008 field_info *new_fi;
4009
4010 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", 4010,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4011
4012 switch (hfinfo->type) {
4013 case FT_ETHER:
4014 break;
4015 default:
4016 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)
4017 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4018 }
4019
4020 if (length != FT_ETHER_LEN6)
4021 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)
4022 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4023
4024 if (encoding) {
4025 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"
)
;
4026 }
4027
4028 tvb_memcpy(tvb, retval, start, length);
4029
4030 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4031
4032 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", 4032
, __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", 4032, "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", 4032, "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", 4032, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4033
4034 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4035
4036 proto_tree_set_ether(new_fi, retval);
4037
4038 return proto_tree_add_node(tree, new_fi);
4039}
4040
4041
4042proto_item *
4043proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4044 tvbuff_t *tvb,
4045 const int start, int length,
4046 const unsigned encoding,
4047 wmem_allocator_t *scope,
4048 const uint8_t **retval,
4049 int *lenretval)
4050{
4051 proto_item *pi;
4052 header_field_info *hfinfo;
4053 field_info *new_fi;
4054 const uint8_t *value;
4055
4056 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", 4056, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4056,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4056, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4057
4058 switch (hfinfo->type) {
4059 case FT_STRING:
4060 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4061 break;
4062 case FT_STRINGZ:
4063 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4064 break;
4065 case FT_UINT_STRING:
4066 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4067 break;
4068 case FT_STRINGZPAD:
4069 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4070 break;
4071 case FT_STRINGZTRUNC:
4072 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4073 break;
4074 default:
4075 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)
4076 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)
;
4077 }
4078
4079 if (retval)
4080 *retval = value;
4081
4082 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4083
4084 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", 4084
, __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", 4084, "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", 4084, "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", 4084, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4085
4086 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4087
4088 proto_tree_set_string(new_fi, value);
4089
4090 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4091
4092 pi = proto_tree_add_node(tree, new_fi);
4093
4094 switch (hfinfo->type) {
4095
4096 case FT_STRINGZ:
4097 case FT_STRINGZPAD:
4098 case FT_STRINGZTRUNC:
4099 case FT_UINT_STRING:
4100 break;
4101
4102 case FT_STRING:
4103 detect_trailing_stray_characters(encoding, value, length, pi);
4104 break;
4105
4106 default:
4107 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4107
, __func__, "assertion \"not reached\" failed")
;
4108 }
4109
4110 return pi;
4111}
4112
4113proto_item *
4114proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4115 const int start, int length,
4116 const unsigned encoding, wmem_allocator_t *scope,
4117 const uint8_t **retval)
4118{
4119 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4120 tvb, start, length, encoding, scope, retval, &length);
4121}
4122
4123proto_item *
4124proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4125 tvbuff_t *tvb,
4126 const int start, int length,
4127 const unsigned encoding,
4128 wmem_allocator_t *scope,
4129 char **retval,
4130 int *lenretval)
4131{
4132 proto_item *pi;
4133 header_field_info *hfinfo;
4134 field_info *new_fi;
4135 const uint8_t *value;
4136 uint32_t n = 0;
4137
4138 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", 4138, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4138,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4138, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4139
4140 switch (hfinfo->type) {
4141 case FT_STRING:
4142 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4143 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4144 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4145 break;
4146 case FT_STRINGZ:
4147 value = get_stringz_value(scope, tree, 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_UINT_STRING:
4152 value = get_uint_string_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_STRINGZPAD:
4157 value = get_stringzpad_value(scope, 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_STRINGZTRUNC:
4162 value = get_stringztrunc_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_BYTES:
4167 tvb_ensure_bytes_exist(tvb, start, length);
4168 value = tvb_get_ptr(tvb, start, length);
4169 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4170 *lenretval = length;
4171 break;
4172 case FT_UINT_BYTES:
4173 n = get_uint_value(tree, tvb, start, length, encoding);
4174 tvb_ensure_bytes_exist(tvb, start + length, n);
4175 value = tvb_get_ptr(tvb, start + length, n);
4176 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4177 *lenretval = length + n;
4178 break;
4179 default:
4180 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)
4181 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)
;
4182 }
4183
4184 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4185
4186 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", 4186
, __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", 4186, "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", 4186, "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", 4186, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4187
4188 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4189
4190 switch (hfinfo->type) {
4191
4192 case FT_STRING:
4193 case FT_STRINGZ:
4194 case FT_UINT_STRING:
4195 case FT_STRINGZPAD:
4196 case FT_STRINGZTRUNC:
4197 proto_tree_set_string(new_fi, value);
4198 break;
4199
4200 case FT_BYTES:
4201 proto_tree_set_bytes(new_fi, value, length);
4202 break;
4203
4204 case FT_UINT_BYTES:
4205 proto_tree_set_bytes(new_fi, value, n);
4206 break;
4207
4208 default:
4209 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4209
, __func__, "assertion \"not reached\" failed")
;
4210 }
4211
4212 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4213
4214 pi = proto_tree_add_node(tree, new_fi);
4215
4216 switch (hfinfo->type) {
4217
4218 case FT_STRINGZ:
4219 case FT_STRINGZPAD:
4220 case FT_STRINGZTRUNC:
4221 case FT_UINT_STRING:
4222 break;
4223
4224 case FT_STRING:
4225 detect_trailing_stray_characters(encoding, value, length, pi);
4226 break;
4227
4228 case FT_BYTES:
4229 case FT_UINT_BYTES:
4230 break;
4231
4232 default:
4233 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4233
, __func__, "assertion \"not reached\" failed")
;
4234 }
4235
4236 return pi;
4237}
4238
4239proto_item *
4240proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4241 tvbuff_t *tvb,
4242 const int start, int length,
4243 const unsigned encoding,
4244 wmem_allocator_t *scope,
4245 char **retval)
4246{
4247 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4248 tvb, start, length, encoding, scope, retval, &length);
4249}
4250
4251proto_item *
4252proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4253 tvbuff_t *tvb,
4254 const int start, int length, const unsigned encoding,
4255 wmem_allocator_t *scope, char **retval)
4256{
4257 header_field_info *hfinfo;
4258 field_info *new_fi;
4259 nstime_t time_stamp;
4260 int flags;
4261
4262 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", 4262, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4262,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4262, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4263
4264 switch (hfinfo->type) {
4265 case FT_ABSOLUTE_TIME:
4266 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4267 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4268 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4269 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4270 }
4271 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4272 break;
4273 case FT_RELATIVE_TIME:
4274 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4275 *retval = rel_time_to_secs_str(scope, &time_stamp);
4276 break;
4277 default:
4278 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)
4279 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4280 }
4281
4282 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4283
4284 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", 4284
, __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", 4284, "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", 4284, "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", 4284, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4285
4286 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4287
4288 switch (hfinfo->type) {
4289
4290 case FT_ABSOLUTE_TIME:
4291 case FT_RELATIVE_TIME:
4292 proto_tree_set_time(new_fi, &time_stamp);
4293 break;
4294 default:
4295 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4295
, __func__, "assertion \"not reached\" failed")
;
4296 }
4297
4298 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4299
4300 return proto_tree_add_node(tree, new_fi);
4301}
4302
4303/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4304 and returns proto_item* */
4305proto_item *
4306ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4307 const unsigned encoding)
4308{
4309 field_info *new_fi;
4310 header_field_info *hfinfo;
4311 int item_length;
4312 int offset;
4313
4314 offset = ptvc->offset;
4315 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", 4315, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4315,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4315, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4316 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4317 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4318
4319 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
4320 item_length, encoding);
4321
4322 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4323
4324 /* Coast clear. Try and fake it */
4325 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", 4325
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4325, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4325, "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", 4325, __func__, "Adding %s would put more than %d 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); } } }
;
4326
4327 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4328
4329 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4330 offset, length, encoding);
4331}
4332
4333/* Add an item to a proto_tree, using the text label registered to that item;
4334 the item is extracted from the tvbuff handed to it. */
4335proto_item *
4336proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4337 const int start, int length, const unsigned encoding)
4338{
4339 field_info *new_fi;
4340 int item_length;
4341
4342 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", 4342,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4343
4344 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4345 test_length(hfinfo, tvb, start, item_length, encoding);
4346
4347 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4348
4349 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", 4349
, __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", 4349, "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", 4349, "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", 4349, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4350
4351 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4352
4353 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4354}
4355
4356proto_item *
4357proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4358 const int start, int length, const unsigned encoding)
4359{
4360 register header_field_info *hfinfo;
4361
4362 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", 4362, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4362,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4362, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4363 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4364}
4365
4366/* Add an item to a proto_tree, using the text label registered to that item;
4367 the item is extracted from the tvbuff handed to it.
4368
4369 Return the length of the item through the pointer. */
4370proto_item *
4371proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4372 tvbuff_t *tvb, const int start,
4373 int length, const unsigned encoding,
4374 int *lenretval)
4375{
4376 field_info *new_fi;
4377 int item_length;
4378 proto_item *item;
4379
4380 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", 4380,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4381
4382 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4383 test_length(hfinfo, tvb, start, item_length, encoding);
4384
4385 if (!tree) {
4386 /*
4387 * We need to get the correct item length here.
4388 * That's normally done by proto_tree_new_item(),
4389 * but we won't be calling it.
4390 */
4391 *lenretval = get_full_length(hfinfo, tvb, start, length,
4392 item_length, encoding);
4393 return NULL((void*)0);
4394 }
4395
4396 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", 4403
, __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", 4403, "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", 4403, "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", 4403
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4397 /*((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", 4403
, __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", 4403, "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", 4403, "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", 4403
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4398 * 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", 4403
, __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", 4403, "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", 4403, "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", 4403
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4399 * 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", 4403
, __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", 4403, "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", 4403, "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", 4403
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4400 */((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4403
, __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", 4403, "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", 4403, "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", 4403
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4401 *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", 4403
, __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", 4403, "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", 4403, "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", 4403
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 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", 4403
, __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", 4403, "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", 4403, "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", 4403
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4403 })((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4403
, __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", 4403, "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", 4403, "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", 4403
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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
4405 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4406
4407 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4408 *lenretval = new_fi->length;
4409 return item;
4410}
4411
4412proto_item *
4413proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4414 const int start, int length,
4415 const unsigned encoding, int *lenretval)
4416{
4417 register header_field_info *hfinfo;
4418
4419 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", 4419, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4419,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4419, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4420 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4421}
4422
4423/* which FT_ types can use proto_tree_add_bytes_item() */
4424static inline bool_Bool
4425validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4426{
4427 return (type == FT_BYTES ||
4428 type == FT_UINT_BYTES ||
4429 type == FT_OID ||
4430 type == FT_REL_OID ||
4431 type == FT_SYSTEM_ID );
4432}
4433
4434/* Note: this does no validation that the byte array of an FT_OID or
4435 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4436 so I think it's ok to continue not validating it?
4437 */
4438proto_item *
4439proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4440 const int start, int length, const unsigned encoding,
4441 GByteArray *retval, int *endoff, int *err)
4442{
4443 field_info *new_fi;
4444 GByteArray *bytes = retval;
4445 GByteArray *created_bytes = NULL((void*)0);
4446 bool_Bool failed = false0;
4447 uint32_t n = 0;
4448 header_field_info *hfinfo;
4449 bool_Bool generate = (bytes || tree) ? true1 : false0;
4450
4451 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", 4451, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4451,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4451, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4452
4453 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", 4453,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4454
4455 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", 4456, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4456 "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", 4456, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4457
4458 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4459
4460 if (encoding & ENC_STR_NUM0x01000000) {
4461 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"
)
;
4462 }
4463
4464 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4465 if (hfinfo->type == FT_UINT_BYTES) {
4466 /* can't decode FT_UINT_BYTES from strings */
4467 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")
4468 "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")
;
4469 }
4470
4471 unsigned hex_encoding = encoding;
4472 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4473 /* If none of the separator values are used,
4474 * assume no separator (the common case). */
4475 hex_encoding |= ENC_SEP_NONE0x00010000;
4476#if 0
4477 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")
4478 "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")
;
4479#endif
4480 }
4481
4482 if (!bytes) {
4483 /* caller doesn't care about return value, but we need it to
4484 call tvb_get_string_bytes() and set the tree later */
4485 bytes = created_bytes = g_byte_array_new();
4486 }
4487
4488 /*
4489 * bytes might be NULL after this, but can't add expert
4490 * error until later; if it's NULL, just note that
4491 * it failed.
4492 */
4493 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4494 if (bytes == NULL((void*)0))
4495 failed = true1;
4496 }
4497 else if (generate) {
4498 tvb_ensure_bytes_exist(tvb, start, length);
4499
4500 if (hfinfo->type == FT_UINT_BYTES) {
4501 n = length; /* n is now the "header" length */
4502 length = get_uint_value(tree, tvb, start, n, encoding);
4503 /* length is now the value's length; only store the value in the array */
4504 tvb_ensure_bytes_exist(tvb, start + n, length);
4505 if (!bytes) {
4506 /* caller doesn't care about return value, but
4507 * we may need it to set the tree later */
4508 bytes = created_bytes = g_byte_array_new();
4509 }
4510 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4511 }
4512 else if (length > 0) {
4513 if (!bytes) {
4514 /* caller doesn't care about return value, but
4515 * we may need it to set the tree later */
4516 bytes = created_bytes = g_byte_array_new();
4517 }
4518 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4519 }
4520
4521 if (endoff)
4522 *endoff = start + n + length;
4523 }
4524
4525 if (err)
4526 *err = failed ? EINVAL22 : 0;
4527
4528 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); }
4529 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4530 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); }
4531 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); }
4532 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); }
4533 bytes = NULL;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
4536 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", 4542
, __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", 4542, "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", 4542, "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", 4542
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4537 {((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", 4542
, __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", 4542, "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", 4542, "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", 4542
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4538 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", 4542
, __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", 4542, "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", 4542, "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", 4542
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4539 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", 4542
, __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", 4542, "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", 4542, "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", 4542
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4540 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", 4542
, __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", 4542, "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", 4542, "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", 4542
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4541 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", 4542
, __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", 4542, "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", 4542, "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", 4542
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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", 4542
, __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", 4542, "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", 4542, "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", 4542
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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
4544 /* n will be zero except when it's a FT_UINT_BYTES */
4545 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4546
4547 if (encoding & ENC_STRING0x03000000) {
4548 if (failed)
4549 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4550
4551 if (bytes)
4552 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4553 else
4554 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4555
4556 if (created_bytes)
4557 g_byte_array_free(created_bytes, true1);
4558 }
4559 else {
4560 /* n will be zero except when it's a FT_UINT_BYTES */
4561 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4562
4563 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4564 * use the byte array created above in this case.
4565 */
4566 if (created_bytes)
4567 g_byte_array_free(created_bytes, true1);
4568
4569 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4570 (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)
;
4571 }
4572
4573 return proto_tree_add_node(tree, new_fi);
4574}
4575
4576
4577proto_item *
4578proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4579 const int start, int length, const unsigned encoding,
4580 nstime_t *retval, int *endoff, int *err)
4581{
4582 field_info *new_fi;
4583 nstime_t time_stamp;
4584 int saved_err = 0;
4585 header_field_info *hfinfo;
4586
4587 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", 4587, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4587,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4587, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4588
4589 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", 4589,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4590
4591 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4592 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4593 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4594 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4595 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4596 }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
4599 nstime_set_zero(&time_stamp);
4600
4601 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4602 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", 4602, ((hfinfo))->abbrev))))
;
4603 /* The only string format that could be a relative time is
4604 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4605 * relative to "now" currently.
4606 */
4607 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4608 saved_err = EINVAL22;
4609 }
4610 else {
4611 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", 4611, ((hfinfo))->abbrev))))
;
4612 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4613
4614 tvb_ensure_bytes_exist(tvb, start, length);
4615 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4616 if (endoff) *endoff = start + length;
4617 }
4618
4619 if (err) *err = saved_err;
4620
4621 if (retval) {
4622 retval->secs = time_stamp.secs;
4623 retval->nsecs = time_stamp.nsecs;
4624 }
4625
4626 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4627
4628 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", 4628
, __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", 4628, "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", 4628, "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", 4628, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4629
4630 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4631
4632 proto_tree_set_time(new_fi, &time_stamp);
4633
4634 if (encoding & ENC_STRING0x03000000) {
4635 if (saved_err)
4636 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4637 }
4638 else {
4639 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4640 (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)
;
4641 }
4642
4643 return proto_tree_add_node(tree, new_fi);
4644}
4645
4646/* Add a FT_NONE to a proto_tree */
4647proto_item *
4648proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4649 const int start, int length, const char *format,
4650 ...)
4651{
4652 proto_item *pi;
4653 va_list ap;
4654 header_field_info *hfinfo;
4655
4656 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4657
4658 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", 4658
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4658, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4658, "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", 4658, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4659
4660 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", 4660
, ((hfinfo))->abbrev))))
;
4661
4662 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4663
4664 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4664, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4665
4666 va_start(ap, format)__builtin_va_start(ap, format);
4667 proto_tree_set_representation(pi, format, ap);
4668 va_end(ap)__builtin_va_end(ap);
4669
4670 /* no value to set for FT_NONE */
4671 return pi;
4672}
4673
4674/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4675 * offset, and returns proto_item* */
4676proto_item *
4677ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4678 const unsigned encoding)
4679{
4680 proto_item *item;
4681
4682 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4683 length, encoding);
4684
4685 return item;
4686}
4687
4688/* Advance the ptvcursor's offset within its tvbuff without
4689 * adding anything to the proto_tree. */
4690void
4691ptvcursor_advance(ptvcursor_t* ptvc, int length)
4692{
4693 ptvc->offset += length;
4694}
4695
4696
4697static void
4698proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4699{
4700 fvalue_set_protocol(fi->value, tvb, field_data, length);
4701}
4702
4703/* Add a FT_PROTOCOL to a proto_tree */
4704proto_item *
4705proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4706 int start, int length, const char *format, ...)
4707{
4708 proto_item *pi;
4709 tvbuff_t *protocol_tvb;
4710 va_list ap;
4711 header_field_info *hfinfo;
4712 char* protocol_rep;
4713
4714 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4715
4716 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", 4716
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4716, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4716, "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", 4716, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4717
4718 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"
, 4718, ((hfinfo))->abbrev))))
;
4719
4720 /*
4721 * This can throw an exception, so do it before we allocate anything.
4722 */
4723 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4724
4725 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4726
4727 va_start(ap, format)__builtin_va_start(ap, format);
4728 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4729 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4730 g_free(protocol_rep);
4731 va_end(ap)__builtin_va_end(ap);
4732
4733 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4733, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4734
4735 va_start(ap, format)__builtin_va_start(ap, format);
4736 proto_tree_set_representation(pi, format, ap);
4737 va_end(ap)__builtin_va_end(ap);
4738
4739 return pi;
4740}
4741
4742/* Add a FT_BYTES to a proto_tree */
4743proto_item *
4744proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4745 int length, const uint8_t *start_ptr)
4746{
4747 proto_item *pi;
4748 header_field_info *hfinfo;
4749 int item_length;
4750
4751 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", 4751, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4751,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4751, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4752 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4753 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4754
4755 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4756
4757 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", 4757
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4757, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4757, "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", 4757, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4758
4759 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",
4759, ((hfinfo))->abbrev))))
;
4760
4761 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4762 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4763
4764 return pi;
4765}
4766
4767/* Add a FT_BYTES to a proto_tree */
4768proto_item *
4769proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4770 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4771{
4772 proto_item *pi;
4773 header_field_info *hfinfo;
4774 int item_length;
4775
4776 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", 4776, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4776,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4776, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4777 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4778 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4779
4780 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4781
4782 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", 4782
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4782, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4782, "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", 4782, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4783
4784 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",
4784, ((hfinfo))->abbrev))))
;
4785
4786 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4787 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4788
4789 return pi;
4790}
4791
4792proto_item *
4793proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4794 int start, int length,
4795 const uint8_t *start_ptr,
4796 const char *format, ...)
4797{
4798 proto_item *pi;
4799 va_list ap;
4800
4801 if (start_ptr == NULL((void*)0))
4802 start_ptr = tvb_get_ptr(tvb, start, length);
4803
4804 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4805
4806 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; }
;
4807
4808 va_start(ap, format)__builtin_va_start(ap, format);
4809 proto_tree_set_representation_value(pi, format, ap);
4810 va_end(ap)__builtin_va_end(ap);
4811
4812 return pi;
4813}
4814
4815proto_item *
4816proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4817 int start, int length, const uint8_t *start_ptr,
4818 const char *format, ...)
4819{
4820 proto_item *pi;
4821 va_list ap;
4822
4823 if (start_ptr == NULL((void*)0))
4824 start_ptr = tvb_get_ptr(tvb, start, length);
4825
4826 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4827
4828 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; }
;
4829
4830 va_start(ap, format)__builtin_va_start(ap, format);
4831 proto_tree_set_representation(pi, format, ap);
4832 va_end(ap)__builtin_va_end(ap);
4833
4834 return pi;
4835}
4836
4837static void
4838proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4839{
4840 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4840, "length >= 0"
))))
;
4841 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", 4841, "start_ptr != ((void*)0) || length == 0"
))))
;
4842
4843 fvalue_set_bytes_data(fi->value, start_ptr, length);
4844}
4845
4846
4847static void
4848proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4849{
4850 tvb_ensure_bytes_exist(tvb, offset, length);
4851 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4852}
4853
4854static void
4855proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4856{
4857 GByteArray *bytes;
4858
4859 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4859, "value != ((void*)0)"
))))
;
4860
4861 bytes = byte_array_dup(value);
4862
4863 fvalue_set_byte_array(fi->value, bytes);
4864}
4865
4866/* Add a FT_*TIME to a proto_tree */
4867proto_item *
4868proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4869 int length, const nstime_t *value_ptr)
4870{
4871 proto_item *pi;
4872 header_field_info *hfinfo;
4873
4874 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4875
4876 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", 4876
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4876, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4876, "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", 4876, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4877
4878 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", 4878, ((hfinfo))->abbrev))))
;
4879
4880 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4881 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4882
4883 return pi;
4884}
4885
4886proto_item *
4887proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4888 int start, int length, nstime_t *value_ptr,
4889 const char *format, ...)
4890{
4891 proto_item *pi;
4892 va_list ap;
4893
4894 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4895 if (pi != tree) {
4896 va_start(ap, format)__builtin_va_start(ap, format);
4897 proto_tree_set_representation_value(pi, format, ap);
4898 va_end(ap)__builtin_va_end(ap);
4899 }
4900
4901 return pi;
4902}
4903
4904proto_item *
4905proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4906 int start, int length, nstime_t *value_ptr,
4907 const char *format, ...)
4908{
4909 proto_item *pi;
4910 va_list ap;
4911
4912 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4913 if (pi != tree) {
4914 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4914, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4915
4916 va_start(ap, format)__builtin_va_start(ap, format);
4917 proto_tree_set_representation(pi, format, ap);
4918 va_end(ap)__builtin_va_end(ap);
4919 }
4920
4921 return pi;
4922}
4923
4924/* Set the FT_*TIME value */
4925static void
4926proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4927{
4928 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4928, "value_ptr != ((void*)0)"
))))
;
4929
4930 fvalue_set_time(fi->value, value_ptr);
4931}
4932
4933/* Add a FT_IPXNET to a proto_tree */
4934proto_item *
4935proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4936 int length, uint32_t value)
4937{
4938 proto_item *pi;
4939 header_field_info *hfinfo;
4940
4941 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4942
4943 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", 4943
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4943, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4943, "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", 4943, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4944
4945 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"
, 4945, ((hfinfo))->abbrev))))
;
4946
4947 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4948 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
4949
4950 return pi;
4951}
4952
4953proto_item *
4954proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4955 int start, int length, uint32_t value,
4956 const char *format, ...)
4957{
4958 proto_item *pi;
4959 va_list ap;
4960
4961 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4962 if (pi != tree) {
4963 va_start(ap, format)__builtin_va_start(ap, format);
4964 proto_tree_set_representation_value(pi, format, ap);
4965 va_end(ap)__builtin_va_end(ap);
4966 }
4967
4968 return pi;
4969}
4970
4971proto_item *
4972proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4973 int start, int length, uint32_t value,
4974 const char *format, ...)
4975{
4976 proto_item *pi;
4977 va_list ap;
4978
4979 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4980 if (pi != tree) {
4981 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4981, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4982
4983 va_start(ap, format)__builtin_va_start(ap, format);
4984 proto_tree_set_representation(pi, format, ap);
4985 va_end(ap)__builtin_va_end(ap);
4986 }
4987
4988 return pi;
4989}
4990
4991/* Set the FT_IPXNET value */
4992static void
4993proto_tree_set_ipxnet(field_info *fi, uint32_t value)
4994{
4995 fvalue_set_uinteger(fi->value, value);
4996}
4997
4998/* Add a FT_IPv4 to a proto_tree */
4999proto_item *
5000proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5001 int length, ws_in4_addr value)
5002{
5003 proto_item *pi;
5004 header_field_info *hfinfo;
5005
5006 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5007
5008 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", 5008
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5008, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5008, "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", 5008, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5009
5010 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", 5010
, ((hfinfo))->abbrev))))
;
5011
5012 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5013 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5014
5015 return pi;
5016}
5017
5018proto_item *
5019proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5020 int start, int length, ws_in4_addr value,
5021 const char *format, ...)
5022{
5023 proto_item *pi;
5024 va_list ap;
5025
5026 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5027 if (pi != tree) {
5028 va_start(ap, format)__builtin_va_start(ap, format);
5029 proto_tree_set_representation_value(pi, format, ap);
5030 va_end(ap)__builtin_va_end(ap);
5031 }
5032
5033 return pi;
5034}
5035
5036proto_item *
5037proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5038 int start, int length, ws_in4_addr value,
5039 const char *format, ...)
5040{
5041 proto_item *pi;
5042 va_list ap;
5043
5044 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5045 if (pi != tree) {
5046 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5046, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5047
5048 va_start(ap, format)__builtin_va_start(ap, format);
5049 proto_tree_set_representation(pi, format, ap);
5050 va_end(ap)__builtin_va_end(ap);
5051 }
5052
5053 return pi;
5054}
5055
5056/* Set the FT_IPv4 value */
5057static void
5058proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5059{
5060 ipv4_addr_and_mask ipv4;
5061 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5062 fvalue_set_ipv4(fi->value, &ipv4);
5063}
5064
5065/* Add a FT_IPv6 to a proto_tree */
5066proto_item *
5067proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5068 int length, const ws_in6_addr *value)
5069{
5070 proto_item *pi;
5071 header_field_info *hfinfo;
5072
5073 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5074
5075 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", 5075
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5075, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5075, "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", 5075, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5076
5077 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", 5077
, ((hfinfo))->abbrev))))
;
5078
5079 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5080 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5081
5082 return pi;
5083}
5084
5085proto_item *
5086proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5087 int start, int length,
5088 const ws_in6_addr *value_ptr,
5089 const char *format, ...)
5090{
5091 proto_item *pi;
5092 va_list ap;
5093
5094 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5095 if (pi != tree) {
5096 va_start(ap, format)__builtin_va_start(ap, format);
5097 proto_tree_set_representation_value(pi, format, ap);
5098 va_end(ap)__builtin_va_end(ap);
5099 }
5100
5101 return pi;
5102}
5103
5104proto_item *
5105proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5106 int start, int length,
5107 const ws_in6_addr *value_ptr,
5108 const char *format, ...)
5109{
5110 proto_item *pi;
5111 va_list ap;
5112
5113 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5114 if (pi != tree) {
5115 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5115, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5116
5117 va_start(ap, format)__builtin_va_start(ap, format);
5118 proto_tree_set_representation(pi, format, ap);
5119 va_end(ap)__builtin_va_end(ap);
5120 }
5121
5122 return pi;
5123}
5124
5125/* Set the FT_IPv6 value */
5126static void
5127proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5128{
5129 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5129, "value != ((void*)0)"
))))
;
5130 ipv6_addr_and_prefix ipv6;
5131 ipv6.addr = *value;
5132 ipv6.prefix = 128;
5133 fvalue_set_ipv6(fi->value, &ipv6);
5134}
5135
5136static void
5137proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5138{
5139 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5140}
5141
5142/* Set the FT_FCWWN value */
5143static void
5144proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5145{
5146 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5146, "value_ptr != ((void*)0)"
))))
;
5147 fvalue_set_fcwwn(fi->value, value_ptr);
5148}
5149
5150static void
5151proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5152{
5153 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5154}
5155
5156/* Add a FT_GUID to a proto_tree */
5157proto_item *
5158proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5159 int length, const e_guid_t *value_ptr)
5160{
5161 proto_item *pi;
5162 header_field_info *hfinfo;
5163
5164 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5165
5166 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", 5166
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5166, "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", 5166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5167
5168 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", 5168
, ((hfinfo))->abbrev))))
;
5169
5170 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5171 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5172
5173 return pi;
5174}
5175
5176proto_item *
5177proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5178 int start, int length,
5179 const e_guid_t *value_ptr,
5180 const char *format, ...)
5181{
5182 proto_item *pi;
5183 va_list ap;
5184
5185 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5186 if (pi != tree) {
5187 va_start(ap, format)__builtin_va_start(ap, format);
5188 proto_tree_set_representation_value(pi, format, ap);
5189 va_end(ap)__builtin_va_end(ap);
5190 }
5191
5192 return pi;
5193}
5194
5195proto_item *
5196proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5197 int start, int length, const e_guid_t *value_ptr,
5198 const char *format, ...)
5199{
5200 proto_item *pi;
5201 va_list ap;
5202
5203 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5204 if (pi != tree) {
5205 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5205, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5206
5207 va_start(ap, format)__builtin_va_start(ap, format);
5208 proto_tree_set_representation(pi, format, ap);
5209 va_end(ap)__builtin_va_end(ap);
5210 }
5211
5212 return pi;
5213}
5214
5215/* Set the FT_GUID value */
5216static void
5217proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5218{
5219 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5219, "value_ptr != ((void*)0)"
))))
;
5220 fvalue_set_guid(fi->value, value_ptr);
5221}
5222
5223static void
5224proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5225 const unsigned encoding)
5226{
5227 e_guid_t guid;
5228
5229 tvb_get_guid(tvb, start, &guid, encoding);
5230 proto_tree_set_guid(fi, &guid);
5231}
5232
5233/* Add a FT_OID to a proto_tree */
5234proto_item *
5235proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5236 int length, const uint8_t* value_ptr)
5237{
5238 proto_item *pi;
5239 header_field_info *hfinfo;
5240
5241 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5242
5243 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", 5243
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5243, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5243, "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", 5243, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5244
5245 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", 5245
, ((hfinfo))->abbrev))))
;
5246
5247 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5248 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5249
5250 return pi;
5251}
5252
5253proto_item *
5254proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5255 int start, int length,
5256 const uint8_t* value_ptr,
5257 const char *format, ...)
5258{
5259 proto_item *pi;
5260 va_list ap;
5261
5262 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5263 if (pi != tree) {
5264 va_start(ap, format)__builtin_va_start(ap, format);
5265 proto_tree_set_representation_value(pi, format, ap);
5266 va_end(ap)__builtin_va_end(ap);
5267 }
5268
5269 return pi;
5270}
5271
5272proto_item *
5273proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5274 int start, int length, const uint8_t* value_ptr,
5275 const char *format, ...)
5276{
5277 proto_item *pi;
5278 va_list ap;
5279
5280 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5281 if (pi != tree) {
5282 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5282, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5283
5284 va_start(ap, format)__builtin_va_start(ap, format);
5285 proto_tree_set_representation(pi, format, ap);
5286 va_end(ap)__builtin_va_end(ap);
5287 }
5288
5289 return pi;
5290}
5291
5292/* Set the FT_OID value */
5293static void
5294proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5295{
5296 GByteArray *bytes;
5297
5298 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", 5298, "value_ptr != ((void*)0) || length == 0"
))))
;
5299
5300 bytes = g_byte_array_new();
5301 if (length > 0) {
5302 g_byte_array_append(bytes, value_ptr, length);
5303 }
5304 fvalue_set_byte_array(fi->value, bytes);
5305}
5306
5307static void
5308proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5309{
5310 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5311}
5312
5313/* Set the FT_SYSTEM_ID value */
5314static void
5315proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5316{
5317 GByteArray *bytes;
5318
5319 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", 5319, "value_ptr != ((void*)0) || length == 0"
))))
;
5320
5321 bytes = g_byte_array_new();
5322 if (length > 0) {
5323 g_byte_array_append(bytes, value_ptr, length);
5324 }
5325 fvalue_set_byte_array(fi->value, bytes);
5326}
5327
5328static void
5329proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5330{
5331 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5332}
5333
5334/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5335 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5336 * is destroyed. */
5337proto_item *
5338proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5339 int length, const char* value)
5340{
5341 proto_item *pi;
5342 header_field_info *hfinfo;
5343 int item_length;
5344
5345 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", 5345, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5345,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5345, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5346 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5347 /*
5348 * Special case - if the length is 0, skip the test, so that
5349 * we can have an empty string right after the end of the
5350 * packet. (This handles URL-encoded forms where the last field
5351 * has no value so the form ends right after the =.)
5352 */
5353 if (item_length != 0)
5354 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5355
5356 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5357
5358 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", 5358
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5358, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5358, "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", 5358, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5359
5360 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", 5360, ((hfinfo))->abbrev))))
;
5361
5362 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5363 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5363, "length >= 0"
))))
;
5364
5365 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", 5365, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5366 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5367
5368 return pi;
5369}
5370
5371proto_item *
5372proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5373 int start, int length, const char* value,
5374 const char *format,
5375 ...)
5376{
5377 proto_item *pi;
5378 va_list ap;
5379
5380 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5381 if (pi != tree) {
5382 va_start(ap, format)__builtin_va_start(ap, format);
5383 proto_tree_set_representation_value(pi, format, ap);
5384 va_end(ap)__builtin_va_end(ap);
5385 }
5386
5387 return pi;
5388}
5389
5390proto_item *
5391proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5392 int start, int length, const char* value,
5393 const char *format, ...)
5394{
5395 proto_item *pi;
5396 va_list ap;
5397
5398 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5399 if (pi != tree) {
5400 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5400, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5401
5402 va_start(ap, format)__builtin_va_start(ap, format);
5403 proto_tree_set_representation(pi, format, ap);
5404 va_end(ap)__builtin_va_end(ap);
5405 }
5406
5407 return pi;
5408}
5409
5410/* Set the FT_STRING value */
5411static void
5412proto_tree_set_string(field_info *fi, const char* value)
5413{
5414 if (value) {
5415 fvalue_set_string(fi->value, value);
5416 } else {
5417 /*
5418 * XXX - why is a null value for a string field
5419 * considered valid?
5420 */
5421 fvalue_set_string(fi->value, "[ Null ]");
5422 }
5423}
5424
5425/* Set the FT_AX25 value */
5426static void
5427proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5428{
5429 fvalue_set_ax25(fi->value, value);
5430}
5431
5432static void
5433proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5434{
5435 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5436}
5437
5438/* Set the FT_VINES value */
5439static void
5440proto_tree_set_vines(field_info *fi, const uint8_t* value)
5441{
5442 fvalue_set_vines(fi->value, value);
5443}
5444
5445static void
5446proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5447{
5448 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5449}
5450
5451/* Add a FT_ETHER to a proto_tree */
5452proto_item *
5453proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5454 int length, const uint8_t* value)
5455{
5456 proto_item *pi;
5457 header_field_info *hfinfo;
5458
5459 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5460
5461 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", 5461
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5461, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5461, "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", 5461, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5462
5463 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",
5463, ((hfinfo))->abbrev))))
;
5464
5465 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5466 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5467
5468 return pi;
5469}
5470
5471proto_item *
5472proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5473 int start, int length, const uint8_t* value,
5474 const char *format, ...)
5475{
5476 proto_item *pi;
5477 va_list ap;
5478
5479 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5480 if (pi != tree) {
5481 va_start(ap, format)__builtin_va_start(ap, format);
5482 proto_tree_set_representation_value(pi, format, ap);
5483 va_end(ap)__builtin_va_end(ap);
5484 }
5485
5486 return pi;
5487}
5488
5489proto_item *
5490proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5491 int start, int length, const uint8_t* value,
5492 const char *format, ...)
5493{
5494 proto_item *pi;
5495 va_list ap;
5496
5497 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5498 if (pi != tree) {
5499 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5499, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5500
5501 va_start(ap, format)__builtin_va_start(ap, format);
5502 proto_tree_set_representation(pi, format, ap);
5503 va_end(ap)__builtin_va_end(ap);
5504 }
5505
5506 return pi;
5507}
5508
5509/* Set the FT_ETHER value */
5510static void
5511proto_tree_set_ether(field_info *fi, const uint8_t* value)
5512{
5513 fvalue_set_ether(fi->value, value);
5514}
5515
5516static void
5517proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5518{
5519 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5520}
5521
5522/* Add a FT_BOOLEAN to a proto_tree */
5523proto_item *
5524proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5525 int length, uint64_t value)
5526{
5527 proto_item *pi;
5528 header_field_info *hfinfo;
5529
5530 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5531
5532 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", 5532
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5532, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5532, "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", 5532, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5533
5534 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"
, 5534, ((hfinfo))->abbrev))))
;
5535
5536 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5537 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5538
5539 return pi;
5540}
5541
5542proto_item *
5543proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5544 tvbuff_t *tvb, int start, int length,
5545 uint64_t value, const char *format, ...)
5546{
5547 proto_item *pi;
5548 va_list ap;
5549
5550 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5551 if (pi != tree) {
5552 va_start(ap, format)__builtin_va_start(ap, format);
5553 proto_tree_set_representation_value(pi, format, ap);
5554 va_end(ap)__builtin_va_end(ap);
5555 }
5556
5557 return pi;
5558}
5559
5560proto_item *
5561proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5562 int start, int length, uint64_t value,
5563 const char *format, ...)
5564{
5565 proto_item *pi;
5566 va_list ap;
5567
5568 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5569 if (pi != tree) {
5570 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5570, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5571
5572 va_start(ap, format)__builtin_va_start(ap, format);
5573 proto_tree_set_representation(pi, format, ap);
5574 va_end(ap)__builtin_va_end(ap);
5575 }
5576
5577 return pi;
5578}
5579
5580/* Set the FT_BOOLEAN value */
5581static void
5582proto_tree_set_boolean(field_info *fi, uint64_t value)
5583{
5584 proto_tree_set_uint64(fi, value);
5585}
5586
5587/* Generate, into "buf", a string showing the bits of a bitfield.
5588 Return a pointer to the character after that string. */
5589static char *
5590other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5591{
5592 int i = 0;
5593 uint64_t bit;
5594 char *p;
5595
5596 p = buf;
5597
5598 /* This is a devel error. It is safer to stop here. */
5599 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5599, "width >= 1"
))))
;
5600
5601 bit = UINT64_C(1)1UL << (width - 1);
5602 for (;;) {
5603 if (mask & bit) {
5604 /* This bit is part of the field. Show its value. */
5605 if (val & bit)
5606 *p++ = '1';
5607 else
5608 *p++ = '0';
5609 } else {
5610 /* This bit is not part of the field. */
5611 *p++ = '.';
5612 }
5613 bit >>= 1;
5614 i++;
5615 if (i >= width)
5616 break;
5617 if (i % 4 == 0)
5618 *p++ = ' ';
5619 }
5620 *p = '\0';
5621 return p;
5622}
5623
5624static char *
5625decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5626{
5627 char *p;
5628
5629 p = other_decode_bitfield_value(buf, val, mask, width);
5630 p = g_stpcpy(p, " = ");
5631
5632 return p;
5633}
5634
5635static char *
5636other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5637{
5638 int i = 0;
5639 uint64_t bit;
5640 char *p;
5641
5642 p = buf;
5643
5644 /* This is a devel error. It is safer to stop here. */
5645 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5645, "width >= 1"
))))
;
5646
5647 bit = UINT64_C(1)1UL << (width - 1);
5648 for (;;) {
5649 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5650 (mask & bit)) {
5651 /* This bit is part of the field. Show its value. */
5652 if (val & bit)
5653 *p++ = '1';
5654 else
5655 *p++ = '0';
5656 } else {
5657 /* This bit is not part of the field. */
5658 *p++ = '.';
5659 }
5660 bit >>= 1;
5661 i++;
5662 if (i >= width)
5663 break;
5664 if (i % 4 == 0)
5665 *p++ = ' ';
5666 }
5667
5668 *p = '\0';
5669 return p;
5670}
5671
5672static char *
5673decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5674{
5675 char *p;
5676
5677 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5678 p = g_stpcpy(p, " = ");
5679
5680 return p;
5681}
5682
5683/* Add a FT_FLOAT to a proto_tree */
5684proto_item *
5685proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5686 int length, float value)
5687{
5688 proto_item *pi;
5689 header_field_info *hfinfo;
5690
5691 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5692
5693 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", 5693
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5693, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5693, "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", 5693, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5694
5695 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",
5695, ((hfinfo))->abbrev))))
;
5696
5697 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5698 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5699
5700 return pi;
5701}
5702
5703proto_item *
5704proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5705 int start, int length, float value,
5706 const char *format, ...)
5707{
5708 proto_item *pi;
5709 va_list ap;
5710
5711 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5712 if (pi != tree) {
5713 va_start(ap, format)__builtin_va_start(ap, format);
5714 proto_tree_set_representation_value(pi, format, ap);
5715 va_end(ap)__builtin_va_end(ap);
5716 }
5717
5718 return pi;
5719}
5720
5721proto_item *
5722proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5723 int start, int length, float value,
5724 const char *format, ...)
5725{
5726 proto_item *pi;
5727 va_list ap;
5728
5729 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5730 if (pi != tree) {
5731 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5731, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5732
5733 va_start(ap, format)__builtin_va_start(ap, format);
5734 proto_tree_set_representation(pi, format, ap);
5735 va_end(ap)__builtin_va_end(ap);
5736 }
5737
5738 return pi;
5739}
5740
5741/* Set the FT_FLOAT value */
5742static void
5743proto_tree_set_float(field_info *fi, float value)
5744{
5745 fvalue_set_floating(fi->value, value);
5746}
5747
5748/* Add a FT_DOUBLE to a proto_tree */
5749proto_item *
5750proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5751 int length, double value)
5752{
5753 proto_item *pi;
5754 header_field_info *hfinfo;
5755
5756 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5757
5758 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", 5758
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5758, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5758, "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", 5758, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5759
5760 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"
, 5760, ((hfinfo))->abbrev))))
;
5761
5762 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5763 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5764
5765 return pi;
5766}
5767
5768proto_item *
5769proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5770 int start, int length, double value,
5771 const char *format, ...)
5772{
5773 proto_item *pi;
5774 va_list ap;
5775
5776 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5777 if (pi != tree) {
5778 va_start(ap, format)__builtin_va_start(ap, format);
5779 proto_tree_set_representation_value(pi, format, ap);
5780 va_end(ap)__builtin_va_end(ap);
5781 }
5782
5783 return pi;
5784}
5785
5786proto_item *
5787proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5788 int start, int length, double value,
5789 const char *format, ...)
5790{
5791 proto_item *pi;
5792 va_list ap;
5793
5794 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5795 if (pi != tree) {
5796 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5796, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5797
5798 va_start(ap, format)__builtin_va_start(ap, format);
5799 proto_tree_set_representation(pi, format, ap);
5800 va_end(ap)__builtin_va_end(ap);
5801 }
5802
5803 return pi;
5804}
5805
5806/* Set the FT_DOUBLE value */
5807static void
5808proto_tree_set_double(field_info *fi, double value)
5809{
5810 fvalue_set_floating(fi->value, value);
5811}
5812
5813/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5814proto_item *
5815proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5816 int length, uint32_t value)
5817{
5818 proto_item *pi = NULL((void*)0);
5819 header_field_info *hfinfo;
5820
5821 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5822
5823 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", 5823
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5823, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5823, "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", 5823, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5824
5825 switch (hfinfo->type) {
5826 case FT_CHAR:
5827 case FT_UINT8:
5828 case FT_UINT16:
5829 case FT_UINT24:
5830 case FT_UINT32:
5831 case FT_FRAMENUM:
5832 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5833 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5834 break;
5835
5836 default:
5837 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)
5838 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)
;
5839 }
5840
5841 return pi;
5842}
5843
5844proto_item *
5845proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5846 int start, int length, uint32_t value,
5847 const char *format, ...)
5848{
5849 proto_item *pi;
5850 va_list ap;
5851
5852 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5853 if (pi != tree) {
5854 va_start(ap, format)__builtin_va_start(ap, format);
5855 proto_tree_set_representation_value(pi, format, ap);
5856 va_end(ap)__builtin_va_end(ap);
5857 }
5858
5859 return pi;
5860}
5861
5862proto_item *
5863proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5864 int start, int length, uint32_t value,
5865 const char *format, ...)
5866{
5867 proto_item *pi;
5868 va_list ap;
5869
5870 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5871 if (pi != tree) {
5872 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5872, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5873
5874 va_start(ap, format)__builtin_va_start(ap, format);
5875 proto_tree_set_representation(pi, format, ap);
5876 va_end(ap)__builtin_va_end(ap);
5877 }
5878
5879 return pi;
5880}
5881
5882/* Set the FT_UINT{8,16,24,32} value */
5883static void
5884proto_tree_set_uint(field_info *fi, uint32_t value)
5885{
5886 const header_field_info *hfinfo;
5887 uint32_t integer;
5888
5889 hfinfo = fi->hfinfo;
5890 integer = value;
5891
5892 if (hfinfo->bitmask) {
5893 /* Mask out irrelevant portions */
5894 integer &= (uint32_t)(hfinfo->bitmask);
5895
5896 /* Shift bits */
5897 integer >>= hfinfo_bitshift(hfinfo);
5898
5899 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
5900 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)
;
5901 }
5902
5903 fvalue_set_uinteger(fi->value, integer);
5904}
5905
5906/* Add FT_UINT{40,48,56,64} to a proto_tree */
5907proto_item *
5908proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5909 int length, uint64_t value)
5910{
5911 proto_item *pi = NULL((void*)0);
5912 header_field_info *hfinfo;
5913
5914 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5915
5916 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", 5916
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5916, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5916, "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", 5916, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5917
5918 switch (hfinfo->type) {
5919 case FT_UINT40:
5920 case FT_UINT48:
5921 case FT_UINT56:
5922 case FT_UINT64:
5923 case FT_FRAMENUM:
5924 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5925 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5926 break;
5927
5928 default:
5929 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)
5930 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)
;
5931 }
5932
5933 return pi;
5934}
5935
5936proto_item *
5937proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5938 int start, int length, uint64_t value,
5939 const char *format, ...)
5940{
5941 proto_item *pi;
5942 va_list ap;
5943
5944 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5945 if (pi != tree) {
5946 va_start(ap, format)__builtin_va_start(ap, format);
5947 proto_tree_set_representation_value(pi, format, ap);
5948 va_end(ap)__builtin_va_end(ap);
5949 }
5950
5951 return pi;
5952}
5953
5954proto_item *
5955proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5956 int start, int length, uint64_t value,
5957 const char *format, ...)
5958{
5959 proto_item *pi;
5960 va_list ap;
5961
5962 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5963 if (pi != tree) {
5964 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5964, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5965
5966 va_start(ap, format)__builtin_va_start(ap, format);
5967 proto_tree_set_representation(pi, format, ap);
5968 va_end(ap)__builtin_va_end(ap);
5969 }
5970
5971 return pi;
5972}
5973
5974/* Set the FT_UINT{40,48,56,64} value */
5975static void
5976proto_tree_set_uint64(field_info *fi, uint64_t value)
5977{
5978 const header_field_info *hfinfo;
5979 uint64_t integer;
5980
5981 hfinfo = fi->hfinfo;
5982 integer = value;
5983
5984 if (hfinfo->bitmask) {
5985 /* Mask out irrelevant portions */
5986 integer &= hfinfo->bitmask;
5987
5988 /* Shift bits */
5989 integer >>= hfinfo_bitshift(hfinfo);
5990
5991 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
5992 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)
;
5993 }
5994
5995 fvalue_set_uinteger64(fi->value, integer);
5996}
5997
5998/* Add FT_INT{8,16,24,32} to a proto_tree */
5999proto_item *
6000proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6001 int length, int32_t value)
6002{
6003 proto_item *pi = NULL((void*)0);
6004 header_field_info *hfinfo;
6005
6006 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6007
6008 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", 6008
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6008, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6008, "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", 6008, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6009
6010 switch (hfinfo->type) {
6011 case FT_INT8:
6012 case FT_INT16:
6013 case FT_INT24:
6014 case FT_INT32:
6015 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6016 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6017 break;
6018
6019 default:
6020 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)
6021 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6022 }
6023
6024 return pi;
6025}
6026
6027proto_item *
6028proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6029 int start, int length, int32_t value,
6030 const char *format, ...)
6031{
6032 proto_item *pi;
6033 va_list ap;
6034
6035 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6036 if (pi != tree) {
6037 va_start(ap, format)__builtin_va_start(ap, format);
6038 proto_tree_set_representation_value(pi, format, ap);
6039 va_end(ap)__builtin_va_end(ap);
6040 }
6041
6042 return pi;
6043}
6044
6045proto_item *
6046proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6047 int start, int length, int32_t value,
6048 const char *format, ...)
6049{
6050 proto_item *pi;
6051 va_list ap;
6052
6053 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6054 if (pi != tree) {
6055 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6055, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6056
6057 va_start(ap, format)__builtin_va_start(ap, format);
6058 proto_tree_set_representation(pi, format, ap);
6059 va_end(ap)__builtin_va_end(ap);
6060 }
6061
6062 return pi;
6063}
6064
6065/* Set the FT_INT{8,16,24,32} value */
6066static void
6067proto_tree_set_int(field_info *fi, int32_t value)
6068{
6069 const header_field_info *hfinfo;
6070 uint32_t integer;
6071 int no_of_bits;
6072
6073 hfinfo = fi->hfinfo;
6074 integer = (uint32_t) value;
6075
6076 if (hfinfo->bitmask) {
6077 /* Mask out irrelevant portions */
6078 integer &= (uint32_t)(hfinfo->bitmask);
6079
6080 /* Shift bits */
6081 integer >>= hfinfo_bitshift(hfinfo);
6082
6083 no_of_bits = ws_count_ones(hfinfo->bitmask);
6084 integer = ws_sign_ext32(integer, no_of_bits);
6085
6086 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
6087 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)
;
6088 }
6089
6090 fvalue_set_sinteger(fi->value, integer);
6091}
6092
6093/* Add FT_INT{40,48,56,64} to a proto_tree */
6094proto_item *
6095proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6096 int length, int64_t value)
6097{
6098 proto_item *pi = NULL((void*)0);
6099 header_field_info *hfinfo;
6100
6101 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6102
6103 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", 6103
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6103, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6103, "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", 6103, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6104
6105 switch (hfinfo->type) {
6106 case FT_INT40:
6107 case FT_INT48:
6108 case FT_INT56:
6109 case FT_INT64:
6110 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6111 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6112 break;
6113
6114 default:
6115 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)
6116 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6117 }
6118
6119 return pi;
6120}
6121
6122proto_item *
6123proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6124 int start, int length, int64_t value,
6125 const char *format, ...)
6126{
6127 proto_item *pi;
6128 va_list ap;
6129
6130 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6131 if (pi != tree) {
6132 va_start(ap, format)__builtin_va_start(ap, format);
6133 proto_tree_set_representation_value(pi, format, ap);
6134 va_end(ap)__builtin_va_end(ap);
6135 }
6136
6137 return pi;
6138}
6139
6140/* Set the FT_INT{40,48,56,64} value */
6141static void
6142proto_tree_set_int64(field_info *fi, int64_t value)
6143{
6144 const header_field_info *hfinfo;
6145 uint64_t integer;
6146 int no_of_bits;
6147
6148 hfinfo = fi->hfinfo;
6149 integer = value;
6150
6151 if (hfinfo->bitmask) {
6152 /* Mask out irrelevant portions */
6153 integer &= hfinfo->bitmask;
6154
6155 /* Shift bits */
6156 integer >>= hfinfo_bitshift(hfinfo);
6157
6158 no_of_bits = ws_count_ones(hfinfo->bitmask);
6159 integer = ws_sign_ext64(integer, no_of_bits);
6160
6161 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
6162 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)
;
6163 }
6164
6165 fvalue_set_sinteger64(fi->value, integer);
6166}
6167
6168proto_item *
6169proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6170 int start, int length, int64_t value,
6171 const char *format, ...)
6172{
6173 proto_item *pi;
6174 va_list ap;
6175
6176 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6177 if (pi != tree) {
6178 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6178, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6179
6180 va_start(ap, format)__builtin_va_start(ap, format);
6181 proto_tree_set_representation(pi, format, ap);
6182 va_end(ap)__builtin_va_end(ap);
6183 }
6184
6185 return pi;
6186}
6187
6188/* Add a FT_EUI64 to a proto_tree */
6189proto_item *
6190proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6191 int length, const uint64_t value)
6192{
6193 proto_item *pi;
6194 header_field_info *hfinfo;
6195
6196 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6197
6198 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", 6198
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6198, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6198, "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", 6198, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6199
6200 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",
6200, ((hfinfo))->abbrev))))
;
6201
6202 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6203 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6204
6205 return pi;
6206}
6207
6208proto_item *
6209proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6210 int start, int length, const uint64_t value,
6211 const char *format, ...)
6212{
6213 proto_item *pi;
6214 va_list ap;
6215
6216 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6217 if (pi != tree) {
6218 va_start(ap, format)__builtin_va_start(ap, format);
6219 proto_tree_set_representation_value(pi, format, ap);
6220 va_end(ap)__builtin_va_end(ap);
6221 }
6222
6223 return pi;
6224}
6225
6226proto_item *
6227proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6228 int start, int length, const uint64_t value,
6229 const char *format, ...)
6230{
6231 proto_item *pi;
6232 va_list ap;
6233
6234 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6235 if (pi != tree) {
6236 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6236, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6237
6238 va_start(ap, format)__builtin_va_start(ap, format);
6239 proto_tree_set_representation(pi, format, ap);
6240 va_end(ap)__builtin_va_end(ap);
6241 }
6242
6243 return pi;
6244}
6245
6246/* Set the FT_EUI64 value */
6247static void
6248proto_tree_set_eui64(field_info *fi, const uint64_t value)
6249{
6250 fvalue_set_uinteger64(fi->value, value);
6251}
6252static void
6253proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6254{
6255 if (encoding)
6256 {
6257 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6258 } else {
6259 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6260 }
6261}
6262
6263proto_item *
6264proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6265 const mac_hf_list_t *list_generic,
6266 int idx, tvbuff_t *tvb,
6267 proto_tree *tree, int offset)
6268{
6269 const uint8_t addr[6];
6270 const char *addr_name = NULL((void*)0);
6271 const char *oui_name = NULL((void*)0);
6272 proto_item *addr_item = NULL((void*)0);
6273 proto_tree *addr_tree = NULL((void*)0);
6274 proto_item *ret_val = NULL((void*)0);
6275
6276 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6277 return NULL((void*)0);
6278 }
6279
6280 /* Resolve what we can of the address */
6281 tvb_memcpy(tvb, (void *)addr, offset, 6);
6282 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6283 addr_name = get_ether_name(addr);
6284 }
6285 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6286 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6287 }
6288
6289 /* Add the item for the specific address type */
6290 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_NA0x00000000);
6291 if (idx >= 0) {
6292 addr_tree = proto_item_add_subtree(ret_val, idx);
6293 }
6294 else {
6295 addr_tree = tree;
6296 }
6297
6298 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6299 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6300 tvb, offset, 6, addr_name);
6301 proto_item_set_generated(addr_item);
6302 proto_item_set_hidden(addr_item);
6303 }
6304
6305 if (list_specific->hf_oui != NULL((void*)0)) {
6306 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_NA0x00000000);
6307 proto_item_set_generated(addr_item);
6308 proto_item_set_hidden(addr_item);
6309
6310 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6311 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6312 proto_item_set_generated(addr_item);
6313 proto_item_set_hidden(addr_item);
6314 }
6315 }
6316
6317 if (list_specific->hf_lg != NULL((void*)0)) {
6318 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6319 }
6320 if (list_specific->hf_ig != NULL((void*)0)) {
6321 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6322 }
6323
6324 /* Were we given a list for generic address fields? If not, stop here */
6325 if (list_generic == NULL((void*)0)) {
6326 return ret_val;
6327 }
6328
6329 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_NA0x00000000);
6330 proto_item_set_hidden(addr_item);
6331
6332 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6333 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6334 tvb, offset, 6, addr_name);
6335 proto_item_set_generated(addr_item);
6336 proto_item_set_hidden(addr_item);
6337 }
6338
6339 if (list_generic->hf_oui != NULL((void*)0)) {
6340 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_NA0x00000000);
6341 proto_item_set_generated(addr_item);
6342 proto_item_set_hidden(addr_item);
6343
6344 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6345 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6346 proto_item_set_generated(addr_item);
6347 proto_item_set_hidden(addr_item);
6348 }
6349 }
6350
6351 if (list_generic->hf_lg != NULL((void*)0)) {
6352 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6353 proto_item_set_hidden(addr_item);
6354 }
6355 if (list_generic->hf_ig != NULL((void*)0)) {
6356 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6357 proto_item_set_hidden(addr_item);
6358 }
6359 return ret_val;
6360}
6361
6362static proto_item *
6363proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6364{
6365 proto_node *pnode, *tnode, *sibling;
6366 field_info *tfi;
6367 unsigned depth = 1;
6368
6369 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6369, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6370
6371 /*
6372 * Restrict our depth. proto_tree_traverse_pre_order and
6373 * proto_tree_traverse_post_order (and possibly others) are recursive
6374 * so we need to be mindful of our stack size.
6375 */
6376 if (tree->first_child == NULL((void*)0)) {
6377 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6378 depth++;
6379 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6380 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__)), 6383)))
6381 "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__)), 6383)))
6382 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__)), 6383)))
6383 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__)), 6383)))
;
6384 }
6385 }
6386 }
6387
6388 /*
6389 * Make sure "tree" is ready to have subtrees under it, by
6390 * checking whether it's been given an ett_ value.
6391 *
6392 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6393 * node of the protocol tree. That node is not displayed,
6394 * so it doesn't need an ett_ value to remember whether it
6395 * was expanded.
6396 */
6397 tnode = tree;
6398 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6399 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6400 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"
, 6401)
6401 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"
, 6401)
;
6402 /* XXX - is it safe to continue here? */
6403 }
6404
6405 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6406 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6407 pnode->parent = tnode;
6408 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6409 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6410 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6411
6412 if (tnode->last_child != NULL((void*)0)) {
6413 sibling = tnode->last_child;
6414 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6414, "sibling->next == ((void*)0)"
))))
;
6415 sibling->next = pnode;
6416 } else
6417 tnode->first_child = pnode;
6418 tnode->last_child = pnode;
6419
6420 /* We should not be adding a fake node for an interesting field */
6421 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", 6421, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6422
6423 /* XXX - Should the proto_item have a header_field_info member, at least
6424 * for faked items, to know what hfi was faked? (Some dissectors look at
6425 * the tree items directly.)
6426 */
6427 return (proto_item *)pnode;
6428}
6429
6430/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6431static proto_item *
6432proto_tree_add_node(proto_tree *tree, field_info *fi)
6433{
6434 proto_node *pnode, *tnode, *sibling;
6435 field_info *tfi;
6436 unsigned depth = 1;
6437
6438 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6438, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6439
6440 /*
6441 * Restrict our depth. proto_tree_traverse_pre_order and
6442 * proto_tree_traverse_post_order (and possibly others) are recursive
6443 * so we need to be mindful of our stack size.
6444 */
6445 if (tree->first_child == NULL((void*)0)) {
6446 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6447 depth++;
6448 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6449 fvalue_free(fi->value);
6450 fi->value = NULL((void*)0);
6451 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__)), 6454)))
6452 "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__)), 6454)))
6453 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__)), 6454)))
6454 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__)), 6454)))
;
6455 }
6456 }
6457 }
6458
6459 /*
6460 * Make sure "tree" is ready to have subtrees under it, by
6461 * checking whether it's been given an ett_ value.
6462 *
6463 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6464 * node of the protocol tree. That node is not displayed,
6465 * so it doesn't need an ett_ value to remember whether it
6466 * was expanded.
6467 */
6468 tnode = tree;
6469 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6470 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6471 /* Since we are not adding fi to a node, its fvalue won't get
6472 * freed by proto_tree_free_node(), so free it now.
6473 */
6474 fvalue_free(fi->value);
6475 fi->value = NULL((void*)0);
6476 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", 6477)
6477 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", 6477)
;
6478 /* XXX - is it safe to continue here? */
6479 }
6480
6481 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6482 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6483 pnode->parent = tnode;
6484 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6485 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6486 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6487
6488 if (tnode->last_child != NULL((void*)0)) {
6489 sibling = tnode->last_child;
6490 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6490, "sibling->next == ((void*)0)"
))))
;
6491 sibling->next = pnode;
6492 } else
6493 tnode->first_child = pnode;
6494 tnode->last_child = pnode;
6495
6496 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6497
6498 return (proto_item *)pnode;
6499}
6500
6501
6502/* Generic way to allocate field_info and add to proto_tree.
6503 * Sets *pfi to address of newly-allocated field_info struct */
6504static proto_item *
6505proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6506 int *length)
6507{
6508 proto_item *pi;
6509 field_info *fi;
6510 int item_length;
6511
6512 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6513 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6514 pi = proto_tree_add_node(tree, fi);
6515
6516 return pi;
6517}
6518
6519
6520static void
6521get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6522 int *item_length, const unsigned encoding)
6523{
6524 int length_remaining;
6525
6526 /*
6527 * We only allow a null tvbuff if the item has a zero length,
6528 * i.e. if there's no data backing it.
6529 */
6530 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", 6530, "tvb != ((void*)0) || *length == 0"
))))
;
6531
6532 /*
6533 * XXX - in some protocols, there are 32-bit unsigned length
6534 * fields, so lengths in protocol tree and tvbuff routines
6535 * should really be unsigned. We should have, for those
6536 * field types for which "to the end of the tvbuff" makes sense,
6537 * additional routines that take no length argument and
6538 * add fields that run to the end of the tvbuff.
6539 */
6540 if (*length == -1) {
6541 /*
6542 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6543 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6544 * of -1 means "set the length to what remains in the
6545 * tvbuff".
6546 *
6547 * The assumption is either that
6548 *
6549 * 1) the length of the item can only be determined
6550 * by dissection (typically true of items with
6551 * subitems, which are probably FT_NONE or
6552 * FT_PROTOCOL)
6553 *
6554 * or
6555 *
6556 * 2) if the tvbuff is "short" (either due to a short
6557 * snapshot length or due to lack of reassembly of
6558 * fragments/segments/whatever), we want to display
6559 * what's available in the field (probably FT_BYTES
6560 * or FT_STRING) and then throw an exception later
6561 *
6562 * or
6563 *
6564 * 3) the field is defined to be "what's left in the
6565 * packet"
6566 *
6567 * so we set the length to what remains in the tvbuff so
6568 * that, if we throw an exception while dissecting, it
6569 * has what is probably the right value.
6570 *
6571 * For FT_STRINGZ, it means "the string is null-terminated,
6572 * not null-padded; set the length to the actual length
6573 * of the string", and if the tvbuff if short, we just
6574 * throw an exception.
6575 *
6576 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV, it means "find the end of the string",
6577 * and if the tvbuff if short, we just throw an exception.
6578 *
6579 * It's not valid for any other type of field. For those
6580 * fields, we treat -1 the same way we treat other
6581 * negative values - we assume the length is a Really
6582 * Big Positive Number, and throw a ReportedBoundsError
6583 * exception, under the assumption that the Really Big
6584 * Length would run past the end of the packet.
6585 */
6586 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
))
)) {
6587 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6588 /*
6589 * Leave the length as -1, so our caller knows
6590 * it was -1.
6591 */
6592 *item_length = *length;
6593 return;
6594 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6595 switch (tvb_get_uint8(tvb, start) >> 6)
6596 {
6597 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6598 *item_length = 1;
6599 break;
6600 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6601 *item_length = 2;
6602 break;
6603 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6604 *item_length = 4;
6605 break;
6606 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6607 *item_length = 8;
6608 break;
6609 }
6610 }
6611 }
6612
6613 switch (hfinfo->type) {
6614
6615 case FT_PROTOCOL:
6616 case FT_NONE:
6617 case FT_BYTES:
6618 case FT_STRING:
6619 case FT_STRINGZPAD:
6620 case FT_STRINGZTRUNC:
6621 /*
6622 * We allow FT_PROTOCOLs to be zero-length -
6623 * for example, an ONC RPC NULL procedure has
6624 * neither arguments nor reply, so the
6625 * payload for that protocol is empty.
6626 *
6627 * We also allow the others to be zero-length -
6628 * because that's the way the code has been for a
6629 * long, long time.
6630 *
6631 * However, we want to ensure that the start
6632 * offset is not *past* the byte past the end
6633 * of the tvbuff: we throw an exception in that
6634 * case.
6635 */
6636 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6637 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6637, "*length >= 0"
))))
;
6638 break;
6639
6640 case FT_STRINGZ:
6641 /*
6642 * Leave the length as -1, so our caller knows
6643 * it was -1.
6644 */
6645 break;
6646
6647 default:
6648 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6649 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6649))
;
6650 }
6651 *item_length = *length;
6652 } else {
6653 *item_length = *length;
6654 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6655 /*
6656 * These types are for interior nodes of the
6657 * tree, and don't have data associated with
6658 * them; if the length is negative (XXX - see
6659 * above) or goes past the end of the tvbuff,
6660 * cut it short at the end of the tvbuff.
6661 * That way, if this field is selected in
6662 * Wireshark, we don't highlight stuff past
6663 * the end of the data.
6664 */
6665 /* XXX - what to do, if we don't have a tvb? */
6666 if (tvb) {
6667 length_remaining = tvb_captured_length_remaining(tvb, start);
6668 if (*item_length < 0 ||
6669 (*item_length > 0 &&
6670 (length_remaining < *item_length)))
6671 *item_length = length_remaining;
6672 }
6673 }
6674 if (*item_length < 0) {
6675 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6676 }
6677 }
6678}
6679
6680static int
6681get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6682 int length, unsigned item_length, const int encoding)
6683{
6684 uint32_t n;
6685
6686 /*
6687 * We need to get the correct item length here.
6688 * That's normally done by proto_tree_new_item(),
6689 * but we won't be calling it.
6690 */
6691 switch (hfinfo->type) {
6692
6693 case FT_NONE:
6694 case FT_PROTOCOL:
6695 case FT_BYTES:
6696 /*
6697 * The length is the specified length.
6698 */
6699 break;
6700
6701 case FT_UINT_BYTES:
6702 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6703 item_length += n;
6704 if ((int)item_length < length) {
6705 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6706 }
6707 break;
6708
6709 /* XXX - make these just FT_UINT? */
6710 case FT_UINT8:
6711 case FT_UINT16:
6712 case FT_UINT24:
6713 case FT_UINT32:
6714 case FT_UINT40:
6715 case FT_UINT48:
6716 case FT_UINT56:
6717 case FT_UINT64:
6718 /* XXX - make these just FT_INT? */
6719 case FT_INT8:
6720 case FT_INT16:
6721 case FT_INT24:
6722 case FT_INT32:
6723 case FT_INT40:
6724 case FT_INT48:
6725 case FT_INT56:
6726 case FT_INT64:
6727 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6728 if (length < -1) {
6729 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6730 }
6731 if (length == -1) {
6732 uint64_t dummy;
6733 /* This can throw an exception */
6734 /* XXX - do this without fetching the varint? */
6735 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6736 if (length == 0) {
6737 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6738 }
6739 }
6740 item_length = length;
6741 break;
6742 }
6743
6744 /*
6745 * The length is the specified length.
6746 */
6747 break;
6748
6749 case FT_BOOLEAN:
6750 case FT_CHAR:
6751 case FT_IPv4:
6752 case FT_IPXNET:
6753 case FT_IPv6:
6754 case FT_FCWWN:
6755 case FT_AX25:
6756 case FT_VINES:
6757 case FT_ETHER:
6758 case FT_EUI64:
6759 case FT_GUID:
6760 case FT_OID:
6761 case FT_REL_OID:
6762 case FT_SYSTEM_ID:
6763 case FT_FLOAT:
6764 case FT_DOUBLE:
6765 case FT_STRING:
6766 /*
6767 * The length is the specified length.
6768 */
6769 break;
6770
6771 case FT_STRINGZ:
6772 if (length < -1) {
6773 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6774 }
6775 if (length == -1) {
6776 /* This can throw an exception */
6777 /* XXX - do this without fetching the string? */
6778 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6779 }
6780 item_length = length;
6781 break;
6782
6783 case FT_UINT_STRING:
6784 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6785 item_length += n;
6786 if ((int)item_length < length) {
6787 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6788 }
6789 break;
6790
6791 case FT_STRINGZPAD:
6792 case FT_STRINGZTRUNC:
6793 case FT_ABSOLUTE_TIME:
6794 case FT_RELATIVE_TIME:
6795 case FT_IEEE_11073_SFLOAT:
6796 case FT_IEEE_11073_FLOAT:
6797 /*
6798 * The length is the specified length.
6799 */
6800 break;
6801
6802 default:
6803 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
))
6804 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
))
6805 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
))
6806 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
))
;
6807 break;
6808 }
6809 return item_length;
6810}
6811
6812static field_info *
6813new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6814 const int start, const int item_length)
6815{
6816 field_info *fi;
6817
6818 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6819
6820 fi->hfinfo = hfinfo;
6821 fi->start = start;
6822 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6823 fi->length = item_length;
6824 fi->tree_type = -1;
6825 fi->flags = 0;
6826 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6827 /* If the tree is not visible, set the item hidden, unless we
6828 * need the representation or length and can't fake them.
6829 */
6830 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6831 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6832 }
6833 }
6834 fi->value = fvalue_new(fi->hfinfo->type);
6835 fi->rep = NULL((void*)0);
6836
6837 /* add the data source tvbuff */
6838 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6839
6840 fi->appendix_start = 0;
6841 fi->appendix_length = 0;
6842
6843 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6844 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6845
6846 return fi;
6847}
6848
6849static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6850{
6851 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6852 return 0;
6853 }
6854
6855 /* Search for field name */
6856 char *ptr = strstr(representation, hfinfo->name);
6857 if (!ptr) {
6858 return 0;
6859 }
6860
6861 /* Check if field name ends with the ": " delimiter */
6862 ptr += strlen(hfinfo->name);
6863 if (strncmp(ptr, ": ", 2) == 0) {
6864 ptr += 2;
6865 }
6866
6867 /* Return offset to after field name */
6868 return ptr - representation;
6869}
6870
6871/* If the protocol tree is to be visible, set the representation of a
6872 proto_tree entry with the name of the field for the item and with
6873 the value formatted with the supplied printf-style format and
6874 argument list. */
6875static void
6876proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6877{
6878 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6878, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6879
6880 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6881 * items string representation */
6882 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6883 size_t name_pos, ret = 0;
6884 char *str;
6885 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6886 const header_field_info *hf;
6887
6888 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6888, "fi"))))
;
6889
6890 hf = fi->hfinfo;
6891
6892 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;
;
6893 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))
)) {
6894 uint64_t val;
6895 char *p;
6896
6897 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)
)
6898 val = fvalue_get_uinteger(fi->value);
6899 else
6900 val = fvalue_get_uinteger64(fi->value);
6901
6902 val <<= hfinfo_bitshift(hf);
6903
6904 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6905 ret = (p - fi->rep->representation);
6906 }
6907
6908 /* put in the hf name */
6909 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
6910
6911 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
6912 /* If possible, Put in the value of the string */
6913 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6914 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"
, 6914, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6915 fi->rep->value_pos = ret;
6916 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
6917 if (ret >= ITEM_LABEL_LENGTH240) {
6918 /* Uh oh, we don't have enough room. Tell the user
6919 * that the field is truncated.
6920 */
6921 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6922 }
6923 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6924 }
6925}
6926
6927/* If the protocol tree is to be visible, set the representation of a
6928 proto_tree entry with the representation formatted with the supplied
6929 printf-style format and argument list. */
6930static void
6931proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6932{
6933 size_t ret; /*tmp return value */
6934 char *str;
6935 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6936
6937 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6937, "fi"))))
;
6938
6939 if (!proto_item_is_hidden(pi)) {
6940 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;
;
6941
6942 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6943 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"
, 6943, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6944 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
6945 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
6946 if (ret >= ITEM_LABEL_LENGTH240) {
6947 /* Uh oh, we don't have enough room. Tell the user
6948 * that the field is truncated.
6949 */
6950 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
6951 }
6952 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6953 }
6954}
6955
6956static int
6957protoo_strlcpy(char *dest, const char *src, size_t dest_size)
6958{
6959 if (dest_size == 0) return 0;
6960
6961 size_t res = g_strlcpy(dest, src, dest_size);
6962
6963 /* At most dest_size - 1 characters will be copied
6964 * (unless dest_size is 0). */
6965 if (res >= dest_size)
6966 res = dest_size - 1;
6967 return (int) res;
6968}
6969
6970static header_field_info *
6971hfinfo_same_name_get_prev(const header_field_info *hfinfo)
6972{
6973 header_field_info *dup_hfinfo;
6974
6975 if (hfinfo->same_name_prev_id == -1)
6976 return NULL((void*)0);
6977 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", 6977
, __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", 6977, "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", 6977,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
6978 return dup_hfinfo;
6979}
6980
6981static void
6982hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
6983{
6984 g_free(last_field_name);
6985 last_field_name = NULL((void*)0);
6986
6987 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
6988 /* No hfinfo with the same name */
6989 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
6990 return;
6991 }
6992
6993 if (hfinfo->same_name_next) {
6994 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
6995 }
6996
6997 if (hfinfo->same_name_prev_id != -1) {
6998 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
6999 same_name_prev->same_name_next = hfinfo->same_name_next;
7000 if (!hfinfo->same_name_next) {
7001 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7002 g_hash_table_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7003 }
7004 }
7005}
7006
7007int
7008proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7009{
7010 const header_field_info *hfinfo = finfo->hfinfo;
7011 int label_len = 0;
7012 char *tmp_str;
7013 const char *str;
7014 const uint8_t *bytes;
7015 uint32_t number;
7016 uint64_t number64;
7017 const char *hf_str_val;
7018 char number_buf[NUMBER_LABEL_LENGTH80];
7019 const char *number_out;
7020 address addr;
7021 const ipv4_addr_and_mask *ipv4;
7022 const ipv6_addr_and_prefix *ipv6;
7023
7024 switch (hfinfo->type) {
7025
7026 case FT_NONE:
7027 case FT_PROTOCOL:
7028 return protoo_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7029
7030 case FT_UINT_BYTES:
7031 case FT_BYTES:
7032 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7033 hfinfo,
7034 fvalue_get_bytes_data(finfo->value),
7035 (unsigned)fvalue_length2(finfo->value),
7036 label_str_size);
7037 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7038 wmem_free(NULL((void*)0), tmp_str);
7039 break;
7040
7041 case FT_ABSOLUTE_TIME:
7042 {
7043 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7044 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7045 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7046 }
7047 tmp_str = abs_time_to_str_ex(NULL((void*)0), fvalue_get_time(finfo->value), hfinfo->display, flags);
7048 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7049 wmem_free(NULL((void*)0), tmp_str);
7050 break;
7051 }
7052
7053 case FT_RELATIVE_TIME:
7054 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7055 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7056 wmem_free(NULL((void*)0), tmp_str);
7057 break;
7058
7059 case FT_BOOLEAN:
7060 number64 = fvalue_get_uinteger64(finfo->value);
7061 label_len = protoo_strlcpy(display_label_str,
7062 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7063 break;
7064
7065 case FT_CHAR:
7066 number = fvalue_get_uinteger(finfo->value);
7067
7068 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7069 char tmp[ITEM_LABEL_LENGTH240];
7070 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7071
7072 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7072, "fmtfunc"))))
;
7073 fmtfunc(tmp, number);
7074
7075 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
7076
7077 } else if (hfinfo->strings) {
7078 number_out = hf_try_val_to_str(number, hfinfo);
7079
7080 if (!number_out) {
7081 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7082 }
7083
7084 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7085
7086 } else {
7087 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7088
7089 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7090 }
7091
7092 break;
7093
7094 /* XXX - make these just FT_NUMBER? */
7095 case FT_INT8:
7096 case FT_INT16:
7097 case FT_INT24:
7098 case FT_INT32:
7099 case FT_UINT8:
7100 case FT_UINT16:
7101 case FT_UINT24:
7102 case FT_UINT32:
7103 case FT_FRAMENUM:
7104 hf_str_val = NULL((void*)0);
7105 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
))
?
7106 (uint32_t) fvalue_get_sinteger(finfo->value) :
7107 fvalue_get_uinteger(finfo->value);
7108
7109 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7110 char tmp[ITEM_LABEL_LENGTH240];
7111 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7112
7113 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7113, "fmtfunc"))))
;
7114 fmtfunc(tmp, number);
7115
7116 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
7117
7118 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7119 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7120 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7121 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7122 hf_str_val = hf_try_val_to_str(number, hfinfo);
7123 label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7124 } else {
7125 number_out = hf_try_val_to_str(number, hfinfo);
7126
7127 if (!number_out) {
7128 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7129 }
7130
7131 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7132 }
7133 } else {
7134 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7135
7136 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7137 }
7138
7139 break;
7140
7141 case FT_INT40:
7142 case FT_INT48:
7143 case FT_INT56:
7144 case FT_INT64:
7145 case FT_UINT40:
7146 case FT_UINT48:
7147 case FT_UINT56:
7148 case FT_UINT64:
7149 hf_str_val = NULL((void*)0);
7150 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
))
?
7151 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7152 fvalue_get_uinteger64(finfo->value);
7153
7154 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7155 char tmp[ITEM_LABEL_LENGTH240];
7156 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7157
7158 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7158, "fmtfunc64"
))))
;
7159 fmtfunc64(tmp, number64);
7160
7161 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
7162 } else if (hfinfo->strings) {
7163 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7164 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7165 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7166 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7167 label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7168 } else {
7169 number_out = hf_try_val64_to_str(number64, hfinfo);
7170
7171 if (!number_out)
7172 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7173
7174 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7175 }
7176 } else {
7177 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7178
7179 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7180 }
7181
7182 break;
7183
7184 case FT_EUI64:
7185 tmp_str = eui64_to_str(NULL((void*)0), fvalue_get_uinteger64(finfo->value));
7186 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7187 wmem_free(NULL((void*)0), tmp_str);
7188 break;
7189
7190 case FT_IPv4:
7191 ipv4 = fvalue_get_ipv4(finfo->value);
7192 //XXX: Should we ignore the mask?
7193 set_address_ipv4(&addr, ipv4);
7194 tmp_str = address_to_display(NULL((void*)0), &addr);
7195 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7196 wmem_free(NULL((void*)0), tmp_str);
7197 free_address(&addr);
7198 break;
7199
7200 case FT_IPv6:
7201 ipv6 = fvalue_get_ipv6(finfo->value);
7202 set_address_ipv6(&addr, ipv6);
7203 tmp_str = address_to_display(NULL((void*)0), &addr);
7204 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7205 wmem_free(NULL((void*)0), tmp_str);
7206 free_address(&addr);
7207 break;
7208
7209 case FT_FCWWN:
7210 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7211 tmp_str = address_to_display(NULL((void*)0), &addr);
7212 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7213 wmem_free(NULL((void*)0), tmp_str);
7214 break;
7215
7216 case FT_ETHER:
7217 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7218 tmp_str = address_to_display(NULL((void*)0), &addr);
7219 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7220 wmem_free(NULL((void*)0), tmp_str);
7221 break;
7222
7223 case FT_GUID:
7224 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7225 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7226 wmem_free(NULL((void*)0), tmp_str);
7227 break;
7228
7229 case FT_REL_OID:
7230 bytes = fvalue_get_bytes_data(finfo->value);
7231 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7232 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7233 wmem_free(NULL((void*)0), tmp_str);
7234 break;
7235
7236 case FT_OID:
7237 bytes = fvalue_get_bytes_data(finfo->value);
7238 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7239 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7240 wmem_free(NULL((void*)0), tmp_str);
7241 break;
7242
7243 case FT_SYSTEM_ID:
7244 bytes = fvalue_get_bytes_data(finfo->value);
7245 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7246 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7247 wmem_free(NULL((void*)0), tmp_str);
7248 break;
7249
7250 case FT_FLOAT:
7251 case FT_DOUBLE:
7252 label_len = (int)fill_display_label_float(finfo, display_label_str);
7253 break;
7254
7255 case FT_STRING:
7256 case FT_STRINGZ:
7257 case FT_UINT_STRING:
7258 case FT_STRINGZPAD:
7259 case FT_STRINGZTRUNC:
7260 str = fvalue_get_string(finfo->value);
7261 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7262 if (label_len >= label_str_size) {
7263 /* Truncation occurred. Get the real length
7264 * copied (not including '\0') */
7265 label_len = label_str_size ? label_str_size - 1 : 0;
7266 }
7267 break;
7268
7269 default:
7270 /* First try ftype string representation */
7271 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7272 if (!tmp_str) {
7273 /* Default to show as bytes */
7274 bytes = fvalue_get_bytes_data(finfo->value);
7275 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7276 }
7277 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7278 wmem_free(NULL((void*)0), tmp_str);
7279 break;
7280 }
7281 return label_len;
7282}
7283
7284/* -------------------------- */
7285/* Sets the text for a custom column from proto fields.
7286 *
7287 * @param[out] result The "resolved" column text (human readable, uses strings)
7288 * @param[out] expr The "unresolved" column text (values, display repr)
7289 * @return The filter (abbrev) for the field (XXX: Only the first if multifield)
7290 */
7291const char *
7292proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7293 char *result, char *expr, const int size)
7294{
7295 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7296 GPtrArray *finfos;
7297 field_info *finfo = NULL((void*)0);
7298 header_field_info* hfinfo;
7299 const char *abbrev = NULL((void*)0);
7300
7301 const char *hf_str_val;
7302 char *str;
7303 col_custom_t *field_idx;
7304 int field_id;
7305 int ii = 0;
7306
7307 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7307, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7308 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7309 field_id = field_idx->field_id;
7310 if (field_id == 0) {
7311 GPtrArray *fvals = NULL((void*)0);
7312 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7313 if (fvals != NULL((void*)0)) {
7314
7315 // XXX - Handling occurrences is unusual when more
7316 // than one field is involved, e.g. there's four
7317 // results for tcp.port + tcp.port. We may really
7318 // want to apply it to the operands, not the output.
7319 // Note that occurrences are not quite the same as
7320 // the layer operator (should the grammar support
7321 // both?)
7322 /* Calculate single index or set outer boundaries */
7323 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7324 if (occurrence < 0) {
7325 i = occurrence + len;
7326 last = i;
7327 } else if (occurrence > 0) {
7328 i = occurrence - 1;
7329 last = i;
7330 } else {
7331 i = 0;
7332 last = len - 1;
7333 }
7334 if (i < 0 || i >= len) {
7335 g_ptr_array_unref(fvals);
7336 continue;
7337 }
7338 for (; i <= last; i++) {
7339 /* XXX - We could have a "resolved" result
7340 * for types where the value depends only
7341 * on the type, e.g. FT_IPv4, and not on
7342 * hfinfo->strings. Supporting the latter
7343 * requires knowing which hfinfo matched
7344 * if there are multiple with the same
7345 * abbreviation. In any case, we need to
7346 * know the expected return type of the
7347 * field expression.
7348 */
7349 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7350 if (offset_r && (offset_r < (size - 1)))
7351 result[offset_r++] = ',';
7352 if (offset_e && (offset_e < (size - 1)))
7353 expr[offset_e++] = ',';
7354 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
7355 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
7356 g_free(str);
7357 }
7358 g_ptr_array_unref(fvals);
7359 } else if (passed) {
7360 // XXX - Occurrence doesn't make sense for a test
7361 // output, it should be applied to the operands.
7362 if (offset_r && (offset_r < (size - 1)))
7363 result[offset_r++] = ',';
7364 if (offset_e && (offset_e < (size - 1)))
7365 expr[offset_e++] = ',';
7366 /* Prevent multiple check marks */
7367 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7368 offset_r += protoo_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7369 } else {
7370 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7371 }
7372 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7373 offset_e += protoo_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7374 } else {
7375 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7376 }
7377 }
7378 continue;
7379 }
7380 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", 7380
, __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", 7380,
"(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", 7380,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7381
7382 /* do we need to rewind ? */
7383 if (!hfinfo)
7384 return "";
7385
7386 if (occurrence < 0) {
7387 /* Search other direction */
7388 while (hfinfo->same_name_prev_id != -1) {
7389 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", 7389
, __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", 7389, "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", 7389,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7390 }
7391 }
7392
7393 prev_len = 0; /* Reset handled occurrences */
7394
7395 while (hfinfo) {
7396 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7397
7398 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7399 if (occurrence < 0) {
7400 hfinfo = hfinfo->same_name_next;
7401 } else {
7402 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7403 }
7404 continue;
7405 }
7406
7407 /* Are there enough occurrences of the field? */
7408 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7409 if (occurrence < 0) {
7410 hfinfo = hfinfo->same_name_next;
7411 } else {
7412 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7413 }
7414 prev_len += len;
7415 continue;
7416 }
7417
7418 /* Calculate single index or set outer boundaries */
7419 if (occurrence < 0) {
7420 i = occurrence + len + prev_len;
7421 last = i;
7422 } else if (occurrence > 0) {
7423 i = occurrence - 1 - prev_len;
7424 last = i;
7425 } else {
7426 i = 0;
7427 last = len - 1;
7428 }
7429
7430 prev_len += len; /* Count handled occurrences */
7431
7432 while (i <= last) {
7433 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7434
7435 if (offset_r && (offset_r < (size - 1)))
7436 result[offset_r++] = ',';
7437
7438 if (display_details) {
7439 char representation[ITEM_LABEL_LENGTH240];
7440 size_t offset = 0;
7441
7442 if (finfo->rep && finfo->rep->value_len) {
7443 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7444 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7445 } else {
7446 proto_item_fill_label(finfo, representation, &offset);
7447 }
7448 offset_r += protoo_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7449 } else {
7450 switch (hfinfo->type) {
7451
7452 case FT_NONE:
7453 case FT_PROTOCOL:
7454 /* Prevent multiple check marks */
7455 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7456 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7457 } else {
7458 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7459 }
7460 break;
7461
7462 default:
7463 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7464 break;
7465 }
7466 }
7467
7468 if (offset_e && (offset_e < (size - 1)))
7469 expr[offset_e++] = ',';
7470
7471 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
))
)) {
7472 /* Integer types with BASE_NONE never get the numeric value. */
7473 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7474 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7475 } 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
)
) {
7476 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7477 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7478 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7479 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7480 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7481 }
7482 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7483 offset_e = (int)strlen(expr);
7484 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7485 /* Prevent multiple check marks */
7486 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7487 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7488 } else {
7489 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7490 }
7491 } else {
7492 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7493 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
7494 wmem_free(NULL((void*)0), str);
7495 }
7496 i++;
7497 }
7498
7499 /* XXX: Why is only the first abbreviation returned for a multifield
7500 * custom column? */
7501 if (!abbrev) {
7502 /* Store abbrev for return value */
7503 abbrev = hfinfo->abbrev;
7504 }
7505
7506 if (occurrence == 0) {
7507 /* Fetch next hfinfo with same name (abbrev) */
7508 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7509 } else {
7510 hfinfo = NULL((void*)0);
7511 }
7512 }
7513 }
7514
7515 if (offset_r >= (size - 1)) {
7516 mark_truncated(result, 0, size, NULL((void*)0));
7517 }
7518 if (offset_e >= (size - 1)) {
7519 mark_truncated(expr, 0, size, NULL((void*)0));
7520 }
7521 return abbrev ? abbrev : "";
7522}
7523
7524char *
7525proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7526{
7527 int len, prev_len, last, i;
7528 GPtrArray *finfos;
7529 field_info *finfo = NULL((void*)0);
7530 header_field_info* hfinfo;
7531
7532 char *filter = NULL((void*)0);
7533 GPtrArray *filter_array;
7534
7535 col_custom_t *col_custom;
7536 int field_id;
7537
7538 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7538, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7539 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7540 for (GSList *iter = field_ids; iter; iter = iter->next) {
7541 col_custom = (col_custom_t*)iter->data;
7542 field_id = col_custom->field_id;
7543 if (field_id == 0) {
7544 GPtrArray *fvals = NULL((void*)0);
7545 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7546 if (fvals != NULL((void*)0)) {
7547 // XXX - Handling occurrences is unusual when more
7548 // than one field is involved, e.g. there's four
7549 // results for tcp.port + tcp.port. We really
7550 // want to apply it to the operands, not the output.
7551 /* Calculate single index or set outer boundaries */
7552 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7553 if (occurrence < 0) {
7554 i = occurrence + len;
7555 last = i;
7556 } else if (occurrence > 0) {
7557 i = occurrence - 1;
7558 last = i;
7559 } else {
7560 i = 0;
7561 last = len - 1;
7562 }
7563 if (i < 0 || i >= len) {
7564 g_ptr_array_unref(fvals);
7565 continue;
7566 }
7567 for (; i <= last; i++) {
7568 /* XXX - Should multiple values for one
7569 * field use set membership to reduce
7570 * verbosity, here and below? */
7571 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7572 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7573 wmem_free(NULL((void*)0), str);
7574 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7575 g_ptr_array_add(filter_array, filter);
7576 }
7577 }
7578 g_ptr_array_unref(fvals);
7579 } else if (passed) {
7580 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7581 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7582 g_ptr_array_add(filter_array, filter);
7583 }
7584 } else {
7585 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7586 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7587 g_ptr_array_add(filter_array, filter);
7588 }
7589 }
7590 continue;
7591 }
7592
7593 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", 7593
, __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", 7593,
"(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", 7593,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7594
7595 /* do we need to rewind ? */
7596 if (!hfinfo)
7597 return NULL((void*)0);
7598
7599 if (occurrence < 0) {
7600 /* Search other direction */
7601 while (hfinfo->same_name_prev_id != -1) {
7602 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", 7602
, __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", 7602, "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", 7602,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7603 }
7604 }
7605
7606 prev_len = 0; /* Reset handled occurrences */
7607
7608 while (hfinfo) {
7609 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7610
7611 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7612 if (occurrence < 0) {
7613 hfinfo = hfinfo->same_name_next;
7614 } else {
7615 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7616 }
7617 continue;
7618 }
7619
7620 /* Are there enough occurrences of the field? */
7621 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7622 if (occurrence < 0) {
7623 hfinfo = hfinfo->same_name_next;
7624 } else {
7625 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7626 }
7627 prev_len += len;
7628 continue;
7629 }
7630
7631 /* Calculate single index or set outer boundaries */
7632 if (occurrence < 0) {
7633 i = occurrence + len + prev_len;
7634 last = i;
7635 } else if (occurrence > 0) {
7636 i = occurrence - 1 - prev_len;
7637 last = i;
7638 } else {
7639 i = 0;
7640 last = len - 1;
7641 }
7642
7643 prev_len += len; /* Count handled occurrences */
7644
7645 while (i <= last) {
7646 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7647
7648 filter = proto_construct_match_selected_string(finfo, edt);
7649 if (filter) {
7650 /* Only add the same expression once (especially for FT_PROTOCOL).
7651 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7652 */
7653 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7654 g_ptr_array_add(filter_array, filter);
7655 }
7656 }
7657 i++;
7658 }
7659
7660 if (occurrence == 0) {
7661 /* Fetch next hfinfo with same name (abbrev) */
7662 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7663 } else {
7664 hfinfo = NULL((void*)0);
7665 }
7666 }
7667 }
7668
7669 g_ptr_array_add(filter_array, NULL((void*)0));
7670
7671 /* XXX: Should this be || or && ? */
7672 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7673
7674 g_ptr_array_free(filter_array, true1);
7675
7676 return output;
7677}
7678
7679/* Set text of proto_item after having already been created. */
7680void
7681proto_item_set_text(proto_item *pi, const char *format, ...)
7682{
7683 field_info *fi = NULL((void*)0);
7684 va_list ap;
7685
7686 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7687
7688 fi = PITEM_FINFO(pi)((pi)->finfo);
7689 if (fi == NULL((void*)0))
7690 return;
7691
7692 if (fi->rep) {
7693 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7694 fi->rep = NULL((void*)0);
7695 }
7696
7697 va_start(ap, format)__builtin_va_start(ap, format);
7698 proto_tree_set_representation(pi, format, ap);
7699 va_end(ap)__builtin_va_end(ap);
7700}
7701
7702/* Append to text of proto_item after having already been created. */
7703void
7704proto_item_append_text(proto_item *pi, const char *format, ...)
7705{
7706 field_info *fi = NULL((void*)0);
7707 size_t curlen;
7708 char *str;
7709 va_list ap;
7710
7711 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7712
7713 fi = PITEM_FINFO(pi)((pi)->finfo);
7714 if (fi == NULL((void*)0)) {
7715 return;
7716 }
7717
7718 if (!proto_item_is_hidden(pi)) {
7719 /*
7720 * If we don't already have a representation,
7721 * generate the default representation.
7722 */
7723 if (fi->rep == NULL((void*)0)) {
7724 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;
;
7725 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7726 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7727 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7728 (strncmp(format, ": ", 2) == 0)) {
7729 fi->rep->value_pos += 2;
7730 }
7731 }
7732 if (fi->rep) {
7733 curlen = strlen(fi->rep->representation);
7734 /* curlen doesn't include the \0 byte.
7735 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7736 * the representation has already been truncated (of an up
7737 * to 4 byte UTF-8 character) or is just at the maximum length
7738 * unless we search for " [truncated]" (which may not be
7739 * at the start.)
7740 * It's safer to do nothing.
7741 */
7742 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7743 va_start(ap, format)__builtin_va_start(ap, format);
7744 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7745 va_end(ap)__builtin_va_end(ap);
7746 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"
, 7746, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7747 /* Keep fi->rep->value_pos */
7748 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7749 if (curlen >= ITEM_LABEL_LENGTH240) {
7750 /* Uh oh, we don't have enough room. Tell the user
7751 * that the field is truncated.
7752 */
7753 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7754 }
7755 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7756 }
7757 }
7758 }
7759}
7760
7761/* Prepend to text of proto_item after having already been created. */
7762void
7763proto_item_prepend_text(proto_item *pi, const char *format, ...)
7764{
7765 field_info *fi = NULL((void*)0);
7766 size_t pos;
7767 char representation[ITEM_LABEL_LENGTH240];
7768 char *str;
7769 va_list ap;
7770
7771 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7772
7773 fi = PITEM_FINFO(pi)((pi)->finfo);
7774 if (fi == NULL((void*)0)) {
7775 return;
7776 }
7777
7778 if (!proto_item_is_hidden(pi)) {
7779 /*
7780 * If we don't already have a representation,
7781 * generate the default representation.
7782 */
7783 if (fi->rep == NULL((void*)0)) {
7784 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;
;
7785 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7786 } else
7787 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7788
7789 va_start(ap, format)__builtin_va_start(ap, format);
7790 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7791 va_end(ap)__builtin_va_end(ap);
7792 WS_UTF_8_CHECK(str, -1)do { const char *__uni_endptr; if (1 && (str) != ((void
*)0) && !g_utf8_validate(str, -1, &__uni_endptr))
{ do { if (1) { ws_log_utf8_full("UTF-8", LOG_LEVEL_DEBUG, "epan/proto.c"
, 7792, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7793 fi->rep->value_pos += strlen(str);
7794 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7795 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7796 /* XXX: As above, if the old representation is close to the label
7797 * length, it might already be marked as truncated. */
7798 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7799 /* Uh oh, we don't have enough room. Tell the user
7800 * that the field is truncated.
7801 */
7802 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7803 }
7804 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7805 }
7806}
7807
7808static void
7809finfo_set_len(field_info *fi, const int length)
7810{
7811 int length_remaining;
7812
7813 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", 7813,
"length >= 0", fi->hfinfo->abbrev))))
;
7814 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7815 if (length > length_remaining)
7816 fi->length = length_remaining;
7817 else
7818 fi->length = length;
7819
7820 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7821 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7822 fvalue_set_protocol_length(fi->value, fi->length);
7823 }
7824
7825 /*
7826 * You cannot just make the "len" field of a GByteArray
7827 * larger, if there's no data to back that length;
7828 * you can only make it smaller.
7829 */
7830 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7831 GBytes *bytes = fvalue_get_bytes(fi->value);
7832 size_t size;
7833 const void *data = g_bytes_get_data(bytes, &size);
7834 if ((size_t)fi->length <= size) {
7835 fvalue_set_bytes_data(fi->value, data, fi->length);
7836 }
7837 g_bytes_unref(bytes);
7838 }
7839}
7840
7841void
7842proto_item_set_len(proto_item *pi, const int length)
7843{
7844 field_info *fi;
7845
7846 if (pi == NULL((void*)0))
7847 return;
7848
7849 fi = PITEM_FINFO(pi)((pi)->finfo);
7850 if (fi == NULL((void*)0))
7851 return;
7852
7853 finfo_set_len(fi, length);
7854}
7855
7856/*
7857 * Sets the length of the item based on its start and on the specified
7858 * offset, which is the offset past the end of the item; as the start
7859 * in the item is relative to the beginning of the data source tvbuff,
7860 * we need to pass in a tvbuff - the end offset is relative to the beginning
7861 * of that tvbuff.
7862 */
7863void
7864proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7865{
7866 field_info *fi;
7867 int length;
7868
7869 if (pi == NULL((void*)0))
7870 return;
7871
7872 fi = PITEM_FINFO(pi)((pi)->finfo);
7873 if (fi == NULL((void*)0))
7874 return;
7875
7876 end += tvb_raw_offset(tvb);
7877 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7877, "end >= fi->start"
))))
;
7878 length = end - fi->start;
7879
7880 finfo_set_len(fi, length);
7881}
7882
7883int
7884proto_item_get_len(const proto_item *pi)
7885{
7886 field_info *fi;
7887
7888 if (!pi)
7889 return -1;
7890 fi = PITEM_FINFO(pi)((pi)->finfo);
7891 return fi ? fi->length : -1;
7892}
7893
7894void
7895proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7896 if (!ti) {
7897 return;
7898 }
7899 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)
;
7900 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)
;
7901}
7902
7903char *
7904proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7905{
7906 field_info *fi;
7907
7908 if (!pi)
7909 return wmem_strdup(scope, "");
7910 fi = PITEM_FINFO(pi)((pi)->finfo);
7911 if (!fi)
7912 return wmem_strdup(scope, "");
7913 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7913, "fi->hfinfo != ((void*)0)"
))))
;
7914 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7915}
7916
7917proto_tree *
7918proto_tree_create_root(packet_info *pinfo)
7919{
7920 proto_node *pnode;
7921
7922 /* Initialize the proto_node */
7923 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
7924 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
7925 pnode->parent = NULL((void*)0);
7926 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
7927 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
7928
7929 /* Make sure we can access pinfo everywhere */
7930 pnode->tree_data->pinfo = pinfo;
7931
7932 /* Don't initialize the tree_data_t. Wait until we know we need it */
7933 pnode->tree_data->interesting_hfids = NULL((void*)0);
7934
7935 /* Set the default to false so it's easier to
7936 * find errors; if we expect to see the protocol tree
7937 * but for some reason the default 'visible' is not
7938 * changed, then we'll find out very quickly. */
7939 pnode->tree_data->visible = false0;
7940
7941 /* Make sure that we fake protocols (if possible) */
7942 pnode->tree_data->fake_protocols = true1;
7943
7944 /* Keep track of the number of children */
7945 pnode->tree_data->count = 0;
7946
7947 return (proto_tree *)pnode;
7948}
7949
7950
7951/* "prime" a proto_tree with a single hfid that a dfilter
7952 * is interested in. */
7953void
7954proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
7955{
7956 header_field_info *hfinfo;
7957
7958 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", 7958, __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", 7958, "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", 7958, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
7959 /* this field is referenced by a filter so increase the refcount.
7960 also increase the refcount for the parent, i.e the protocol.
7961 Don't increase the refcount if we're already printing the
7962 type, as that is a superset of direct reference.
7963 */
7964 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
7965 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
7966 }
7967 /* only increase the refcount if there is a parent.
7968 if this is a protocol and not a field then parent will be -1
7969 and there is no parent to add any refcounting for.
7970 */
7971 if (hfinfo->parent != -1) {
7972 header_field_info *parent_hfinfo;
7973 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", 7973
, __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", 7973,
"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", 7973,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
7974
7975 /* Mark parent as indirectly referenced unless it is already directly
7976 * referenced, i.e. the user has specified the parent in a filter.
7977 */
7978 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
7979 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
7980 }
7981}
7982
7983/* "prime" a proto_tree with a single hfid that a dfilter
7984 * is interested in. */
7985void
7986proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
7987{
7988 header_field_info *hfinfo;
7989
7990 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", 7990, __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", 7990, "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", 7990, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
7991 /* this field is referenced by an (output) filter so increase the refcount.
7992 also increase the refcount for the parent, i.e the protocol.
7993 */
7994 hfinfo->ref_type = HF_REF_TYPE_PRINT;
7995 /* only increase the refcount if there is a parent.
7996 if this is a protocol and not a field then parent will be -1
7997 and there is no parent to add any refcounting for.
7998 */
7999 if (hfinfo->parent != -1) {
8000 header_field_info *parent_hfinfo;
8001 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", 8001
, __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", 8001,
"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", 8001,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8002
8003 /* Mark parent as indirectly referenced unless it is already directly
8004 * referenced, i.e. the user has specified the parent in a filter.
8005 */
8006 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8007 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8008 }
8009}
8010
8011proto_tree *
8012proto_item_add_subtree(proto_item *pi, const int idx) {
8013 field_info *fi;
8014
8015 if (!pi)
8016 return NULL((void*)0);
8017
8018 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", 8018, "idx >= 0 && idx < num_tree_types"
))))
;
8019
8020 fi = PITEM_FINFO(pi)((pi)->finfo);
8021 if (!fi)
8022 return (proto_tree *)pi;
8023
8024 fi->tree_type = idx;
8025
8026 return (proto_tree *)pi;
8027}
8028
8029proto_tree *
8030proto_item_get_subtree(proto_item *pi) {
8031 field_info *fi;
8032
8033 if (!pi)
8034 return NULL((void*)0);
8035 fi = PITEM_FINFO(pi)((pi)->finfo);
8036 if ( (fi) && (fi->tree_type == -1) )
8037 return NULL((void*)0);
8038 return (proto_tree *)pi;
8039}
8040
8041proto_item *
8042proto_item_get_parent(const proto_item *ti) {
8043 if (!ti)
8044 return NULL((void*)0);
8045 return ti->parent;
8046}
8047
8048proto_item *
8049proto_item_get_parent_nth(proto_item *ti, int gen) {
8050 if (!ti)
8051 return NULL((void*)0);
8052 while (gen--) {
8053 ti = ti->parent;
8054 if (!ti)
8055 return NULL((void*)0);
8056 }
8057 return ti;
8058}
8059
8060
8061proto_item *
8062proto_tree_get_parent(proto_tree *tree) {
8063 if (!tree)
8064 return NULL((void*)0);
8065 return (proto_item *)tree;
8066}
8067
8068proto_tree *
8069proto_tree_get_parent_tree(proto_tree *tree) {
8070 if (!tree)
8071 return NULL((void*)0);
8072
8073 /* we're the root tree, there's no parent
8074 return ourselves so the caller has at least a tree to attach to */
8075 if (!tree->parent)
8076 return tree;
8077
8078 return (proto_tree *)tree->parent;
8079}
8080
8081proto_tree *
8082proto_tree_get_root(proto_tree *tree) {
8083 if (!tree)
8084 return NULL((void*)0);
8085 while (tree->parent) {
8086 tree = tree->parent;
8087 }
8088 return tree;
8089}
8090
8091void
8092proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8093 proto_item *item_to_move)
8094{
8095 /* This function doesn't generate any values. It only reorganizes the prococol tree
8096 * so we can bail out immediately if it isn't visible. */
8097 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8098 return;
8099
8100 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", 8100, "item_to_move->parent == tree"
))))
;
8101 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", 8101, "fixed_item->parent == tree"
))))
;
8102
8103 /*** cut item_to_move out ***/
8104
8105 /* is item_to_move the first? */
8106 if (tree->first_child == item_to_move) {
8107 /* simply change first child to next */
8108 tree->first_child = item_to_move->next;
8109
8110 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", 8110, "tree->last_child != item_to_move"
))))
;
8111 } else {
8112 proto_item *curr_item;
8113 /* find previous and change it's next */
8114 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8115 if (curr_item->next == item_to_move) {
8116 break;
8117 }
8118 }
8119
8120 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8120, "curr_item"
))))
;
8121
8122 curr_item->next = item_to_move->next;
8123
8124 /* fix last_child if required */
8125 if (tree->last_child == item_to_move) {
8126 tree->last_child = curr_item;
8127 }
8128 }
8129
8130 /*** insert to_move after fixed ***/
8131 item_to_move->next = fixed_item->next;
8132 fixed_item->next = item_to_move;
8133 if (tree->last_child == fixed_item) {
8134 tree->last_child = item_to_move;
8135 }
8136}
8137
8138void
8139proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8140 const int length)
8141{
8142 field_info *fi;
8143
8144 if (tree == NULL((void*)0))
8145 return;
8146
8147 fi = PTREE_FINFO(tree)((tree)->finfo);
8148 if (fi == NULL((void*)0))
8149 return;
8150
8151 start += tvb_raw_offset(tvb);
8152 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8152, "start >= 0"
))))
;
8153 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8153, "length >= 0"
))))
;
8154
8155 fi->appendix_start = start;
8156 fi->appendix_length = length;
8157}
8158
8159static void
8160check_protocol_filter_name_or_fail(const char *filter_name)
8161{
8162 /* Require at least two characters. */
8163 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8164 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)
;
8165 }
8166
8167 if (proto_check_field_name(filter_name) != '\0') {
8168 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)
8169 " 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)
8170 " 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)
;
8171 }
8172
8173 /* Check that it doesn't match some very common numeric forms. */
8174 if (filter_name[0] == '0' &&
8175 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8176 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8177 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])
8178 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])
;
8179 }
8180
8181 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8182
8183 /* Check that it contains at least one letter. */
8184 bool_Bool have_letter = false0;
8185 for (const char *s = filter_name; *s != '\0'; s++) {
8186 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8187 have_letter = true1;
8188 break;
8189 }
8190 }
8191 if (!have_letter) {
8192 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)
8193 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8194 }
8195
8196 /* Check for reserved keywords. */
8197 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8198 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)
8199 " 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)
;
8200 }
8201}
8202
8203int
8204proto_register_protocol(const char *name, const char *short_name,
8205 const char *filter_name)
8206{
8207 protocol_t *protocol;
8208 header_field_info *hfinfo;
8209
8210 /*
8211 * Make sure there's not already a protocol with any of those
8212 * names. Crash if there is, as that's an error in the code
8213 * or an inappropriate plugin.
8214 * This situation has to be fixed to not register more than one
8215 * protocol with the same name.
8216 */
8217
8218 if (g_hash_table_lookup(proto_names, name)) {
8219 /* ws_error will terminate the program */
8220 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)
8221 " 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)
;
8222 }
8223
8224 if (g_hash_table_lookup(proto_short_names, short_name)) {
8225 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)
8226 " 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)
;
8227 }
8228
8229 check_protocol_filter_name_or_fail(filter_name);
8230
8231 if (g_hash_table_lookup(proto_filter_names, filter_name)) {
8232 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)
8233 " 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)
;
8234 }
8235
8236 /*
8237 * Add this protocol to the list of known protocols;
8238 * the list is sorted by protocol short name.
8239 */
8240 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8241 protocol->name = name;
8242 protocol->short_name = short_name;
8243 protocol->filter_name = filter_name;
8244 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8245 protocol->is_enabled = true1; /* protocol is enabled by default */
8246 protocol->enabled_by_default = true1; /* see previous comment */
8247 protocol->can_toggle = true1;
8248 protocol->parent_proto_id = -1;
8249 protocol->heur_list = NULL((void*)0);
8250
8251 /* List will be sorted later by name, when all protocols completed registering */
8252 protocols = g_list_prepend(protocols, protocol);
8253 g_hash_table_insert(proto_names, (void *)name, protocol);
8254 g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol);
8255 g_hash_table_insert(proto_short_names, (void *)short_name, protocol);
8256
8257 /* Here we allocate a new header_field_info struct */
8258 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8259 hfinfo->name = name;
8260 hfinfo->abbrev = filter_name;
8261 hfinfo->type = FT_PROTOCOL;
8262 hfinfo->display = BASE_NONE;
8263 hfinfo->strings = protocol;
8264 hfinfo->bitmask = 0;
8265 hfinfo->ref_type = HF_REF_TYPE_NONE;
8266 hfinfo->blurb = NULL((void*)0);
8267 hfinfo->parent = -1; /* This field differentiates protos and fields */
8268
8269 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8270 return protocol->proto_id;
8271}
8272
8273int
8274proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8275{
8276 protocol_t *protocol;
8277 header_field_info *hfinfo;
8278
8279 /*
8280 * Helper protocols don't need the strict rules as a "regular" protocol
8281 * Just register it in a list and make a hf_ field from it
8282 */
8283 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8284 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)
;
8285 }
8286
8287 if (parent_proto <= 0) {
8288 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)
8289 " 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)
;
8290 }
8291
8292 check_protocol_filter_name_or_fail(filter_name);
8293
8294 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8295 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8296 protocol->name = name;
8297 protocol->short_name = short_name;
8298 protocol->filter_name = filter_name;
8299 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8300
8301 /* Enabling and toggling is really determined by parent protocol,
8302 but provide default values here */
8303 protocol->is_enabled = true1;
8304 protocol->enabled_by_default = true1;
8305 protocol->can_toggle = true1;
8306
8307 protocol->parent_proto_id = parent_proto;
8308 protocol->heur_list = NULL((void*)0);
8309
8310 /* List will be sorted later by name, when all protocols completed registering */
8311 protocols = g_list_prepend(protocols, protocol);
8312
8313 /* Here we allocate a new header_field_info struct */
8314 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8315 hfinfo->name = name;
8316 hfinfo->abbrev = filter_name;
8317 hfinfo->type = field_type;
8318 hfinfo->display = BASE_NONE;
8319 if (field_type == FT_BYTES) {
8320 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8321 }
8322 hfinfo->strings = protocol;
8323 hfinfo->bitmask = 0;
8324 hfinfo->ref_type = HF_REF_TYPE_NONE;
8325 hfinfo->blurb = NULL((void*)0);
8326 hfinfo->parent = -1; /* This field differentiates protos and fields */
8327
8328 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8329 return protocol->proto_id;
8330}
8331
8332bool_Bool
8333proto_deregister_protocol(const char *short_name)
8334{
8335 protocol_t *protocol;
8336 header_field_info *hfinfo;
8337 int proto_id;
8338 unsigned i;
8339
8340 proto_id = proto_get_id_by_short_name(short_name);
8341 protocol = find_protocol_by_id(proto_id);
8342 if (protocol == NULL((void*)0))
8343 return false0;
8344
8345 g_hash_table_remove(proto_names, protocol->name);
8346 g_hash_table_remove(proto_short_names, (void *)short_name);
8347 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8348
8349 if (protocol->fields) {
8350 for (i = 0; i < protocol->fields->len; i++) {
8351 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8352 hfinfo_remove_from_gpa_name_map(hfinfo);
8353 expert_deregister_expertinfo(hfinfo->abbrev);
8354 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8355 }
8356 g_ptr_array_free(protocol->fields, true1);
8357 protocol->fields = NULL((void*)0);
8358 }
8359
8360 g_list_free(protocol->heur_list);
8361
8362 /* Remove this protocol from the list of known protocols */
8363 protocols = g_list_remove(protocols, protocol);
8364
8365 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8366 g_hash_table_steal(gpa_name_map, protocol->filter_name);
8367
8368 g_free(last_field_name);
8369 last_field_name = NULL((void*)0);
8370
8371 return true1;
8372}
8373
8374void
8375proto_register_alias(const int proto_id, const char *alias_name)
8376{
8377 protocol_t *protocol;
8378
8379 protocol = find_protocol_by_id(proto_id);
8380 if (alias_name && protocol) {
8381 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8382 }
8383}
8384
8385/*
8386 * Routines to use to iterate over the protocols.
8387 * The argument passed to the iterator routines is an opaque cookie to
8388 * their callers; it's the GList pointer for the current element in
8389 * the list.
8390 * The ID of the protocol is returned, or -1 if there is no protocol.
8391 */
8392int
8393proto_get_first_protocol(void **cookie)
8394{
8395 protocol_t *protocol;
8396
8397 if (protocols == NULL((void*)0))
8398 return -1;
8399 *cookie = protocols;
8400 protocol = (protocol_t *)protocols->data;
8401 return protocol->proto_id;
8402}
8403
8404int
8405proto_get_data_protocol(void *cookie)
8406{
8407 GList *list_item = (GList *)cookie;
8408
8409 protocol_t *protocol = (protocol_t *)list_item->data;
8410 return protocol->proto_id;
8411}
8412
8413int
8414proto_get_next_protocol(void **cookie)
8415{
8416 GList *list_item = (GList *)*cookie;
8417 protocol_t *protocol;
8418
8419 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8420 if (list_item == NULL((void*)0))
8421 return -1;
8422 *cookie = list_item;
8423 protocol = (protocol_t *)list_item->data;
8424 return protocol->proto_id;
8425}
8426
8427header_field_info *
8428proto_get_first_protocol_field(const int proto_id, void **cookie)
8429{
8430 protocol_t *protocol = find_protocol_by_id(proto_id);
8431
8432 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8433 return NULL((void*)0);
8434
8435 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8436 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8437}
8438
8439header_field_info *
8440proto_get_next_protocol_field(const int proto_id, void **cookie)
8441{
8442 protocol_t *protocol = find_protocol_by_id(proto_id);
8443 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8444
8445 i++;
8446
8447 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8448 return NULL((void*)0);
8449
8450 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8451 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8452}
8453
8454protocol_t *
8455find_protocol_by_id(const int proto_id)
8456{
8457 header_field_info *hfinfo;
8458
8459 if (proto_id <= 0)
8460 return NULL((void*)0);
8461
8462 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", 8462, __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", 8462,
"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", 8462, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8463 if (hfinfo->type != FT_PROTOCOL) {
8464 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", 8464, "hfinfo->display & 0x00004000"
))))
;
8465 }
8466 return (protocol_t *)hfinfo->strings;
8467}
8468
8469int
8470proto_get_id(const protocol_t *protocol)
8471{
8472 return protocol->proto_id;
8473}
8474
8475bool_Bool
8476proto_name_already_registered(const char *name)
8477{
8478 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8478, "name", "No name present"))))
;
8479
8480 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8481 return true1;
8482 return false0;
8483}
8484
8485int
8486proto_get_id_by_filter_name(const char *filter_name)
8487{
8488 const protocol_t *protocol = NULL((void*)0);
8489
8490 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", 8490,
"filter_name", "No filter name present"))))
;
8491
8492 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8493
8494 if (protocol == NULL((void*)0))
8495 return -1;
8496 return protocol->proto_id;
8497}
8498
8499int
8500proto_get_id_by_short_name(const char *short_name)
8501{
8502 const protocol_t *protocol = NULL((void*)0);
8503
8504 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", 8504,
"short_name", "No short name present"))))
;
8505
8506 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8507
8508 if (protocol == NULL((void*)0))
8509 return -1;
8510 return protocol->proto_id;
8511}
8512
8513const char *
8514proto_get_protocol_name(const int proto_id)
8515{
8516 protocol_t *protocol;
8517
8518 protocol = find_protocol_by_id(proto_id);
8519
8520 if (protocol == NULL((void*)0))
8521 return NULL((void*)0);
8522 return protocol->name;
8523}
8524
8525const char *
8526proto_get_protocol_short_name(const protocol_t *protocol)
8527{
8528 if (protocol == NULL((void*)0))
8529 return "(none)";
8530 return protocol->short_name;
8531}
8532
8533const char *
8534proto_get_protocol_long_name(const protocol_t *protocol)
8535{
8536 if (protocol == NULL((void*)0))
8537 return "(none)";
8538 return protocol->name;
8539}
8540
8541const char *
8542proto_get_protocol_filter_name(const int proto_id)
8543{
8544 protocol_t *protocol;
8545
8546 protocol = find_protocol_by_id(proto_id);
8547 if (protocol == NULL((void*)0))
8548 return "(none)";
8549 return protocol->filter_name;
8550}
8551
8552void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8553{
8554 heur_dtbl_entry_t* heuristic_dissector;
8555
8556 if (protocol == NULL((void*)0))
8557 return;
8558
8559 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8560 if (heuristic_dissector != NULL((void*)0))
8561 {
8562 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8563 }
8564}
8565
8566void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8567{
8568 if (protocol == NULL((void*)0))
8569 return;
8570
8571 g_list_foreach(protocol->heur_list, func, user_data);
8572}
8573
8574void
8575proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8576 bool_Bool *is_tcp, bool_Bool *is_udp,
8577 bool_Bool *is_sctp, bool_Bool *is_tls,
8578 bool_Bool *is_rtp,
8579 bool_Bool *is_lte_rlc)
8580{
8581 wmem_list_frame_t *protos = wmem_list_head(layers);
8582 int proto_id;
8583 const char *proto_name;
8584
8585 /* Walk the list of a available protocols in the packet and
8586 attempt to find "major" ones. */
8587 /* It might make more sense to assemble and return a bitfield. */
8588 while (protos != NULL((void*)0))
8589 {
8590 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8591 proto_name = proto_get_protocol_filter_name(proto_id);
8592
8593 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8594 (!strcmp(proto_name, "ipv6")))) {
8595 *is_ip = true1;
8596 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8597 *is_tcp = true1;
8598 } else if (is_udp && !strcmp(proto_name, "udp")) {
8599 *is_udp = true1;
8600 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8601 *is_sctp = true1;
8602 } else if (is_tls && !strcmp(proto_name, "tls")) {
8603 *is_tls = true1;
8604 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8605 *is_rtp = true1;
8606 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8607 *is_lte_rlc = true1;
8608 }
8609
8610 protos = wmem_list_frame_next(protos);
8611 }
8612}
8613
8614bool_Bool
8615proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8616{
8617 wmem_list_frame_t *protos = wmem_list_head(layers);
8618 int proto_id;
8619 const char *name;
8620
8621 /* Walk the list of a available protocols in the packet and
8622 attempt to find the specified protocol. */
8623 while (protos != NULL((void*)0))
8624 {
8625 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8626 name = proto_get_protocol_filter_name(proto_id);
8627
8628 if (!strcmp(name, proto_name))
8629 {
8630 return true1;
8631 }
8632
8633 protos = wmem_list_frame_next(protos);
8634 }
8635
8636 return false0;
8637}
8638
8639char *
8640proto_list_layers(const packet_info *pinfo)
8641{
8642 wmem_strbuf_t *buf;
8643 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8644
8645 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8646
8647 /* Walk the list of layers in the packet and
8648 return a string of all entries. */
8649 while (layers != NULL((void*)0))
8650 {
8651 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8652
8653 layers = wmem_list_frame_next(layers);
8654 if (layers != NULL((void*)0)) {
8655 wmem_strbuf_append_c(buf, ':');
8656 }
8657 }
8658
8659 return wmem_strbuf_finalize(buf);
8660}
8661
8662bool_Bool
8663proto_is_pino(const protocol_t *protocol)
8664{
8665 return (protocol->parent_proto_id != -1);
8666}
8667
8668bool_Bool
8669// NOLINTNEXTLINE(misc-no-recursion)
8670proto_is_protocol_enabled(const protocol_t *protocol)
8671{
8672 if (protocol == NULL((void*)0))
8673 return false0;
8674
8675 //parent protocol determines enable/disable for helper dissectors
8676 if (proto_is_pino(protocol))
8677 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8678
8679 return protocol->is_enabled;
8680}
8681
8682bool_Bool
8683// NOLINTNEXTLINE(misc-no-recursion)
8684proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8685{
8686 //parent protocol determines enable/disable for helper dissectors
8687 if (proto_is_pino(protocol))
8688 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8689
8690 return protocol->enabled_by_default;
8691}
8692
8693bool_Bool
8694// NOLINTNEXTLINE(misc-no-recursion)
8695proto_can_toggle_protocol(const int proto_id)
8696{
8697 protocol_t *protocol;
8698
8699 protocol = find_protocol_by_id(proto_id);
8700 //parent protocol determines toggling for helper dissectors
8701 if (proto_is_pino(protocol))
8702 return proto_can_toggle_protocol(protocol->parent_proto_id);
8703
8704 return protocol->can_toggle;
8705}
8706
8707void
8708proto_disable_by_default(const int proto_id)
8709{
8710 protocol_t *protocol;
8711
8712 protocol = find_protocol_by_id(proto_id);
8713 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8713, "protocol->can_toggle"
))))
;
8714 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", 8714, "proto_is_pino(protocol) == 0"
))))
;
8715 protocol->is_enabled = false0;
8716 protocol->enabled_by_default = false0;
8717}
8718
8719void
8720proto_set_decoding(const int proto_id, const bool_Bool enabled)
8721{
8722 protocol_t *protocol;
8723
8724 protocol = find_protocol_by_id(proto_id);
8725 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8725, "protocol->can_toggle"
))))
;
8726 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", 8726, "proto_is_pino(protocol) == 0"
))))
;
8727 protocol->is_enabled = enabled;
8728}
8729
8730void
8731proto_disable_all(void)
8732{
8733 /* This doesn't explicitly disable heuristic protocols,
8734 * but the heuristic doesn't get called if the parent
8735 * protocol isn't enabled.
8736 */
8737 protocol_t *protocol;
8738 GList *list_item = protocols;
8739
8740 if (protocols == NULL((void*)0))
8741 return;
8742
8743 while (list_item) {
8744 protocol = (protocol_t *)list_item->data;
8745 if (protocol->can_toggle) {
8746 protocol->is_enabled = false0;
8747 }
8748 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8749 }
8750}
8751
8752static void
8753heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8754{
8755 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8756
8757 heur->enabled = heur->enabled_by_default;
8758}
8759
8760void
8761proto_reenable_all(void)
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 = protocol->enabled_by_default;
8773 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8774 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8775 }
8776}
8777
8778void
8779proto_set_cant_toggle(const int proto_id)
8780{
8781 protocol_t *protocol;
8782
8783 protocol = find_protocol_by_id(proto_id);
8784 protocol->can_toggle = false0;
8785}
8786
8787static int
8788proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8789{
8790 if (proto != NULL((void*)0)) {
8791 g_ptr_array_add(proto->fields, hfi);
8792 }
8793
8794 return proto_register_field_init(hfi, parent);
8795}
8796
8797/* for use with static arrays only, since we don't allocate our own copies
8798of the header_field_info struct contained within the hf_register_info struct */
8799void
8800proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8801{
8802 hf_register_info *ptr = hf;
8803 protocol_t *proto;
8804 int i;
8805
8806 proto = find_protocol_by_id(parent);
8807
8808 if (proto->fields == NULL((void*)0)) {
8809 proto->fields = g_ptr_array_sized_new(num_records);
8810 }
8811
8812 for (i = 0; i < num_records; i++, ptr++) {
8813 /*
8814 * Make sure we haven't registered this yet.
8815 * Most fields have variables associated with them
8816 * that are initialized to -1; some have array elements,
8817 * or possibly uninitialized variables, so we also allow
8818 * 0 (which is unlikely to be the field ID we get back
8819 * from "proto_register_field_init()").
8820 */
8821 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8822 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8823 "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)
8824 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8825 return;
8826 }
8827
8828 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8829 }
8830}
8831
8832/* deregister already registered fields */
8833void
8834proto_deregister_field (const int parent, int hf_id)
8835{
8836 header_field_info *hfi;
8837 protocol_t *proto;
8838 unsigned i;
8839
8840 g_free(last_field_name);
8841 last_field_name = NULL((void*)0);
8842
8843 if (hf_id == -1 || hf_id == 0)
8844 return;
8845
8846 proto = find_protocol_by_id (parent);
8847 if (!proto || proto->fields == NULL((void*)0)) {
8848 return;
8849 }
8850
8851 for (i = 0; i < proto->fields->len; i++) {
8852 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8853 if (hfi->id == hf_id) {
8854 /* Found the hf_id in this protocol */
8855 g_hash_table_steal(gpa_name_map, hfi->abbrev);
8856 g_ptr_array_remove_index_fast(proto->fields, i);
8857 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8858 return;
8859 }
8860 }
8861}
8862
8863void
8864proto_add_deregistered_data (void *data)
8865{
8866 g_ptr_array_add(deregistered_data, data);
8867}
8868
8869void
8870proto_add_deregistered_slice (size_t block_size, void *mem_block)
8871{
8872 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
)))
;
8873
8874 slice_data->block_size = block_size;
8875 slice_data->mem_block = mem_block;
8876
8877 g_ptr_array_add(deregistered_slice, slice_data);
8878}
8879
8880void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8881{
8882 if (field_strings == NULL((void*)0)) {
8883 return;
8884 }
8885
8886 switch (field_type) {
8887 case FT_FRAMENUM:
8888 /* This is just an integer represented as a pointer */
8889 break;
8890 case FT_PROTOCOL: {
8891 protocol_t *protocol = (protocol_t *)field_strings;
8892 g_free((char *)protocol->short_name);
8893 break;
8894 }
8895 case FT_BOOLEAN: {
8896 true_false_string *tf = (true_false_string *)field_strings;
8897 g_free((char *)tf->true_string);
8898 g_free((char *)tf->false_string);
8899 break;
8900 }
8901 case FT_UINT40:
8902 case FT_INT40:
8903 case FT_UINT48:
8904 case FT_INT48:
8905 case FT_UINT56:
8906 case FT_INT56:
8907 case FT_UINT64:
8908 case FT_INT64: {
8909 if (field_display & BASE_UNIT_STRING0x00001000) {
8910 unit_name_string *unit = (unit_name_string *)field_strings;
8911 g_free((char *)unit->singular);
8912 g_free((char *)unit->plural);
8913 } else if (field_display & BASE_RANGE_STRING0x00000100) {
8914 range_string *rs = (range_string *)field_strings;
8915 while (rs->strptr) {
8916 g_free((char *)rs->strptr);
8917 rs++;
8918 }
8919 } else if (field_display & BASE_EXT_STRING0x00000200) {
8920 val64_string_ext *vse = (val64_string_ext *)field_strings;
8921 val64_string *vs = (val64_string *)vse->_vs_p;
8922 while (vs->strptr) {
8923 g_free((char *)vs->strptr);
8924 vs++;
8925 }
8926 val64_string_ext_free(vse);
8927 field_strings = NULL((void*)0);
8928 } else if (field_display == BASE_CUSTOM) {
8929 /* this will be a pointer to a function, don't free that */
8930 field_strings = NULL((void*)0);
8931 } else {
8932 val64_string *vs64 = (val64_string *)field_strings;
8933 while (vs64->strptr) {
8934 g_free((char *)vs64->strptr);
8935 vs64++;
8936 }
8937 }
8938 break;
8939 }
8940 case FT_CHAR:
8941 case FT_UINT8:
8942 case FT_INT8:
8943 case FT_UINT16:
8944 case FT_INT16:
8945 case FT_UINT24:
8946 case FT_INT24:
8947 case FT_UINT32:
8948 case FT_INT32:
8949 case FT_FLOAT:
8950 case FT_DOUBLE: {
8951 if (field_display & BASE_UNIT_STRING0x00001000) {
8952 unit_name_string *unit = (unit_name_string *)field_strings;
8953 g_free((char *)unit->singular);
8954 g_free((char *)unit->plural);
8955 } else if (field_display & BASE_RANGE_STRING0x00000100) {
8956 range_string *rs = (range_string *)field_strings;
8957 while (rs->strptr) {
8958 g_free((char *)rs->strptr);
8959 rs++;
8960 }
8961 } else if (field_display & BASE_EXT_STRING0x00000200) {
8962 value_string_ext *vse = (value_string_ext *)field_strings;
8963 value_string *vs = (value_string *)vse->_vs_p;
8964 while (vs->strptr) {
8965 g_free((char *)vs->strptr);
8966 vs++;
8967 }
8968 value_string_ext_free(vse);
8969 field_strings = NULL((void*)0);
8970 } else if (field_display == BASE_CUSTOM) {
8971 /* this will be a pointer to a function, don't free that */
8972 field_strings = NULL((void*)0);
8973 } else {
8974 value_string *vs = (value_string *)field_strings;
8975 while (vs->strptr) {
8976 g_free((char *)vs->strptr);
8977 vs++;
8978 }
8979 }
8980 break;
8981 default:
8982 break;
8983 }
8984 }
8985
8986 if (field_type != FT_FRAMENUM) {
8987 g_free((void *)field_strings);
8988 }
8989}
8990
8991static void
8992free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
8993{
8994 header_field_info *hfi = (header_field_info *) data;
8995 int hf_id = hfi->id;
8996
8997 g_free((char *)hfi->name);
8998 g_free((char *)hfi->abbrev);
8999 g_free((char *)hfi->blurb);
9000
9001 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9002
9003 if (hfi->parent == -1)
9004 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)
;
9005
9006 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9007}
9008
9009static void
9010free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9011{
9012 g_free (data);
9013}
9014
9015static void
9016free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9017{
9018 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9019
9020 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9021 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)
;
9022}
9023
9024/* free deregistered fields and data */
9025void
9026proto_free_deregistered_fields (void)
9027{
9028 expert_free_deregistered_expertinfos();
9029
9030 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9031 g_ptr_array_free(deregistered_fields, true1);
9032 deregistered_fields = g_ptr_array_new();
9033
9034 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9035 g_ptr_array_free(deregistered_data, true1);
9036 deregistered_data = g_ptr_array_new();
9037
9038 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9039 g_ptr_array_free(deregistered_slice, true1);
9040 deregistered_slice = g_ptr_array_new();
9041}
9042
9043static const value_string hf_display[] = {
9044 { BASE_NONE, "BASE_NONE" },
9045 { BASE_DEC, "BASE_DEC" },
9046 { BASE_HEX, "BASE_HEX" },
9047 { BASE_OCT, "BASE_OCT" },
9048 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9049 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9050 { BASE_CUSTOM, "BASE_CUSTOM" },
9051 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9052 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9053 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9054 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9055 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9056 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9057 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9058 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9059 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9060 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9061 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9062 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9063 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9064 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9065 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9066 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9067 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9068 { BASE_PT_UDP, "BASE_PT_UDP" },
9069 { BASE_PT_TCP, "BASE_PT_TCP" },
9070 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9071 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9072 { BASE_OUI, "BASE_OUI" },
9073 { 0, NULL((void*)0) } };
9074
9075const char* proto_field_display_to_string(int field_display)
9076{
9077 return val_to_str_const(field_display, hf_display, "Unknown");
9078}
9079
9080static inline port_type
9081display_to_port_type(field_display_e e)
9082{
9083 switch (e) {
9084 case BASE_PT_UDP:
9085 return PT_UDP;
9086 case BASE_PT_TCP:
9087 return PT_TCP;
9088 case BASE_PT_DCCP:
9089 return PT_DCCP;
9090 case BASE_PT_SCTP:
9091 return PT_SCTP;
9092 default:
9093 break;
9094 }
9095 return PT_NONE;
9096}
9097
9098/* temporary function containing assert part for easier profiling */
9099static void
9100tmp_fld_check_assert(header_field_info *hfinfo)
9101{
9102 char* tmp_str;
9103
9104 /* The field must have a name (with length > 0) */
9105 if (!hfinfo->name || !hfinfo->name[0]) {
9106 if (hfinfo->abbrev)
9107 /* Try to identify the field */
9108 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)
9109 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9110 else
9111 /* Hum, no luck */
9112 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)"
)
;
9113 }
9114
9115 /* fields with an empty string for an abbreviation aren't filterable */
9116 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9117 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)
;
9118
9119 /* These types of fields are allowed to have value_strings,
9120 * true_false_strings or a protocol_t struct
9121 */
9122 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9123 switch (hfinfo->type) {
9124
9125 /*
9126 * These types are allowed to support display value_strings,
9127 * value64_strings, the extended versions of the previous
9128 * two, range strings, or unit strings.
9129 */
9130 case FT_CHAR:
9131 case FT_UINT8:
9132 case FT_UINT16:
9133 case FT_UINT24:
9134 case FT_UINT32:
9135 case FT_UINT40:
9136 case FT_UINT48:
9137 case FT_UINT56:
9138 case FT_UINT64:
9139 case FT_INT8:
9140 case FT_INT16:
9141 case FT_INT24:
9142 case FT_INT32:
9143 case FT_INT40:
9144 case FT_INT48:
9145 case FT_INT56:
9146 case FT_INT64:
9147 case FT_BOOLEAN:
9148 case FT_PROTOCOL:
9149 break;
9150
9151 /*
9152 * This is allowed to have a value of type
9153 * enum ft_framenum_type to indicate what relationship
9154 * the frame in question has to the frame in which
9155 * the field is put.
9156 */
9157 case FT_FRAMENUM:
9158 break;
9159
9160 /*
9161 * These types are allowed to support only unit strings.
9162 */
9163 case FT_FLOAT:
9164 case FT_DOUBLE:
9165 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9166 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))
9167 " (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))
9168 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))
;
9169 }
9170 break;
9171
9172 /*
9173 * This type is only allowed to support a string if it's
9174 * a protocol (for pinos).
9175 */
9176 case FT_BYTES:
9177 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9178 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))
9179 " (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))
9180 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))
;
9181 }
9182 break;
9183
9184 default:
9185 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))
9186 " (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))
9187 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))
;
9188 }
9189 }
9190
9191 /* TODO: This check may slow down startup, and output quite a few warnings.
9192 It would be good to be able to enable this (and possibly other checks?)
9193 in non-release builds. */
9194#ifdef ENABLE_CHECK_FILTER
9195 /* Check for duplicate value_string values.
9196 There are lots that have the same value *and* string, so for now only
9197 report those that have same value but different string. */
9198 if ((hfinfo->strings != NULL((void*)0)) &&
9199 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9200 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9201 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9202 (
9203 (hfinfo->type == FT_CHAR) ||
9204 (hfinfo->type == FT_UINT8) ||
9205 (hfinfo->type == FT_UINT16) ||
9206 (hfinfo->type == FT_UINT24) ||
9207 (hfinfo->type == FT_UINT32) ||
9208 (hfinfo->type == FT_INT8) ||
9209 (hfinfo->type == FT_INT16) ||
9210 (hfinfo->type == FT_INT24) ||
9211 (hfinfo->type == FT_INT32) )) {
9212
9213 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9214 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9215 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9216 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9217 } else {
9218 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9219 CHECK_HF_VALUE(value_string, "u", start_values);
9220 }
9221 } else {
9222 const value_string *start_values = (const value_string*)hfinfo->strings;
9223 CHECK_HF_VALUE(value_string, "u", start_values);
9224 }
9225 }
9226
9227 if (hfinfo->type == FT_BOOLEAN) {
9228 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9229 if (tfs) {
9230 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9231 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"
, 9233, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9232 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9233, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9233 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9233, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9234 }
9235 }
9236 }
9237
9238 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9239 const range_string *rs = (const range_string*)(hfinfo->strings);
9240 if (rs) {
9241 const range_string *this_it = rs;
9242
9243 do {
9244 if (this_it->value_max < this_it->value_min) {
9245 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"
, 9249, __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)
9246 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9249, __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)
9247 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9249, __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)
9248 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9249, __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)
9249 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9249, __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)
;
9250 ++this_it;
9251 continue;
9252 }
9253
9254 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9255 /* Not OK if this one is completely hidden by an earlier one! */
9256 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9257 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"
, 9263, __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)
9258 "(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"
, 9263, __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)
9259 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9263, __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)
9260 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9263, __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)
9261 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9263, __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)
9262 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9263, __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)
9263 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9263, __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)
;
9264 }
9265 }
9266 ++this_it;
9267 } while (this_it->strptr);
9268 }
9269 }
9270#endif
9271
9272 switch (hfinfo->type) {
9273
9274 case FT_CHAR:
9275 /* Require the char type to have BASE_HEX, BASE_OCT,
9276 * BASE_CUSTOM, or BASE_NONE as its base.
9277 *
9278 * If the display value is BASE_NONE and there is a
9279 * strings conversion then the dissector writer is
9280 * telling us that the field's numerical value is
9281 * meaningless; we'll avoid showing the value to the
9282 * user.
9283 */
9284 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9285 case BASE_HEX:
9286 case BASE_OCT:
9287 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9288 break;
9289 case BASE_NONE:
9290 if (hfinfo->strings == NULL((void*)0))
9291 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
))
9292 " 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
))
9293 " 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
))
9294 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
))
9295 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
))
;
9296 break;
9297 default:
9298 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9299 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)
9300 " 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)
9301 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)
9302 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)
;
9303 //wmem_free(NULL, tmp_str);
9304 }
9305 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9306 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
))
9307 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
))
9308 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
))
;
9309 }
9310 break;
9311 case FT_INT8:
9312 case FT_INT16:
9313 case FT_INT24:
9314 case FT_INT32:
9315 case FT_INT40:
9316 case FT_INT48:
9317 case FT_INT56:
9318 case FT_INT64:
9319 /* Hexadecimal and octal are, in printf() and everywhere
9320 * else, unsigned so don't allow dissectors to register a
9321 * signed field to be displayed unsigned. (Else how would
9322 * we display negative values?)
9323 */
9324 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9325 case BASE_HEX:
9326 case BASE_OCT:
9327 case BASE_DEC_HEX:
9328 case BASE_HEX_DEC:
9329 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9330 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)
9331 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)
9332 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)
;
9333 //wmem_free(NULL, tmp_str);
9334 }
9335 /* FALL THROUGH */
9336 case FT_UINT8:
9337 case FT_UINT16:
9338 case FT_UINT24:
9339 case FT_UINT32:
9340 case FT_UINT40:
9341 case FT_UINT48:
9342 case FT_UINT56:
9343 case FT_UINT64:
9344 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
))
) {
9345 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9346 if (hfinfo->type != FT_UINT16) {
9347 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))
9348 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))
9349 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))
;
9350 }
9351 if (hfinfo->strings != NULL((void*)0)) {
9352 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)
9353 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)
9354 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)
;
9355 }
9356 if (hfinfo->bitmask != 0) {
9357 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)
9358 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)
9359 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)
;
9360 }
9361 wmem_free(NULL((void*)0), tmp_str);
9362 break;
9363 }
9364
9365 if (hfinfo->display == BASE_OUI) {
9366 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9367 if (hfinfo->type != FT_UINT24) {
9368 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))
9369 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))
9370 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))
;
9371 }
9372 if (hfinfo->strings != NULL((void*)0)) {
9373 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)
9374 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)
9375 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)
;
9376 }
9377 if (hfinfo->bitmask != 0) {
9378 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)
9379 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)
9380 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)
;
9381 }
9382 wmem_free(NULL((void*)0), tmp_str);
9383 break;
9384 }
9385
9386 /* Require integral types (other than frame number,
9387 * which is always displayed in decimal) to have a
9388 * number base.
9389 *
9390 * If the display value is BASE_NONE and there is a
9391 * strings conversion then the dissector writer is
9392 * telling us that the field's numerical value is
9393 * meaningless; we'll avoid showing the value to the
9394 * user.
9395 */
9396 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9397 case BASE_DEC:
9398 case BASE_HEX:
9399 case BASE_OCT:
9400 case BASE_DEC_HEX:
9401 case BASE_HEX_DEC:
9402 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9403 break;
9404 case BASE_NONE:
9405 if (hfinfo->strings == NULL((void*)0)) {
9406 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
))
9407 " 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
))
9408 " 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
))
9409 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
))
9410 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
))
;
9411 }
9412 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9413 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
))
9414 " 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
))
9415 " 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
))
9416 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
))
9417 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
))
;
9418 }
9419 break;
9420
9421 default:
9422 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9423 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)
9424 " 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)
9425 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)
9426 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)
;
9427 //wmem_free(NULL, tmp_str);
9428 }
9429 break;
9430 case FT_BYTES:
9431 case FT_UINT_BYTES:
9432 /* Require bytes to have a "display type" that could
9433 * add a character between displayed bytes.
9434 */
9435 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9436 case BASE_NONE:
9437 case SEP_DOT:
9438 case SEP_DASH:
9439 case SEP_COLON:
9440 case SEP_SPACE:
9441 break;
9442 default:
9443 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9444 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)
9445 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)
;
9446 //wmem_free(NULL, tmp_str);
9447 }
9448 if (hfinfo->bitmask != 0)
9449 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
))
9450 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
))
9451 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
))
;
9452 //allowed to support string if its a protocol (for pinos)
9453 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9454 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
))
9455 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
))
9456 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
))
;
9457 break;
9458
9459 case FT_PROTOCOL:
9460 case FT_FRAMENUM:
9461 if (hfinfo->display != BASE_NONE) {
9462 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9463 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)
9464 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)
9465 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)
;
9466 //wmem_free(NULL, tmp_str);
9467 }
9468 if (hfinfo->bitmask != 0)
9469 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
))
9470 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
))
9471 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
))
;
9472 break;
9473
9474 case FT_BOOLEAN:
9475 break;
9476
9477 case FT_ABSOLUTE_TIME:
9478 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9479 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9480 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)
9481 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)
;
9482 //wmem_free(NULL, tmp_str);
9483 }
9484 if (hfinfo->bitmask != 0)
9485 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
))
9486 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
))
9487 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
))
;
9488 break;
9489
9490 case FT_STRING:
9491 case FT_STRINGZ:
9492 case FT_UINT_STRING:
9493 case FT_STRINGZPAD:
9494 case FT_STRINGZTRUNC:
9495 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9496 case BASE_NONE:
9497 case BASE_STR_WSP:
9498 break;
9499
9500 default:
9501 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9502 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)
9503 " 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)
9504 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)
9505 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)
;
9506 //wmem_free(NULL, tmp_str);
9507 }
9508
9509 if (hfinfo->bitmask != 0)
9510 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
))
9511 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
))
9512 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
))
;
9513 if (hfinfo->strings != NULL((void*)0))
9514 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
))
9515 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
))
9516 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
))
;
9517 break;
9518
9519 case FT_IPv4:
9520 switch (hfinfo->display) {
9521 case BASE_NONE:
9522 case BASE_NETMASK:
9523 break;
9524
9525 default:
9526 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9527 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)
9528 " 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)
9529 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)
9530 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)
;
9531 //wmem_free(NULL, tmp_str);
9532 break;
9533 }
9534 break;
9535 case FT_FLOAT:
9536 case FT_DOUBLE:
9537 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9538 case BASE_NONE:
9539 case BASE_DEC:
9540 case BASE_HEX:
9541 case BASE_EXP:
9542 case BASE_CUSTOM:
9543 break;
9544 default:
9545 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9546 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)
9547 " 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)
9548 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)
9549 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)
;
9550 //wmem_free(NULL, tmp_str);
9551 }
9552 if (hfinfo->bitmask != 0)
9553 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
))
9554 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
))
9555 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
))
;
9556 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9557 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
))
9558 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
))
9559 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
))
;
9560 break;
9561 default:
9562 if (hfinfo->display != BASE_NONE) {
9563 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9564 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)
9565 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)
9566 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)
9567 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)
;
9568 //wmem_free(NULL, tmp_str);
9569 }
9570 if (hfinfo->bitmask != 0)
9571 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
))
9572 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
))
9573 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
))
;
9574 if (hfinfo->strings != NULL((void*)0))
9575 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
))
9576 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
))
9577 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
))
;
9578 break;
9579 }
9580}
9581
9582#ifdef ENABLE_CHECK_FILTER
9583static enum ftenum
9584_ftype_common(enum ftenum type)
9585{
9586 switch (type) {
9587 case FT_INT8:
9588 case FT_INT16:
9589 case FT_INT24:
9590 case FT_INT32:
9591 return FT_INT32;
9592
9593 case FT_CHAR:
9594 case FT_UINT8:
9595 case FT_UINT16:
9596 case FT_UINT24:
9597 case FT_UINT32:
9598 case FT_IPXNET:
9599 case FT_FRAMENUM:
9600 return FT_UINT32;
9601
9602 case FT_UINT64:
9603 case FT_EUI64:
9604 return FT_UINT64;
9605
9606 case FT_STRING:
9607 case FT_STRINGZ:
9608 case FT_UINT_STRING:
9609 return FT_STRING;
9610
9611 case FT_FLOAT:
9612 case FT_DOUBLE:
9613 return FT_DOUBLE;
9614
9615 case FT_BYTES:
9616 case FT_UINT_BYTES:
9617 case FT_ETHER:
9618 case FT_OID:
9619 return FT_BYTES;
9620
9621 case FT_ABSOLUTE_TIME:
9622 case FT_RELATIVE_TIME:
9623 return FT_ABSOLUTE_TIME;
9624
9625 default:
9626 return type;
9627 }
9628}
9629#endif
9630
9631static void
9632register_type_length_mismatch(void)
9633{
9634 static ei_register_info ei[] = {
9635 { &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)}}
}},
9636 { &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)}}
}},
9637 };
9638
9639 expert_module_t* expert_type_length_mismatch;
9640
9641 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9642
9643 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9644 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9645
9646 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9647 disabling them makes no sense. */
9648 proto_set_cant_toggle(proto_type_length_mismatch);
9649}
9650
9651static void
9652register_byte_array_string_decodinws_error(void)
9653{
9654 static ei_register_info ei[] = {
9655 { &ei_byte_array_string_decoding_failed_error,
9656 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9657 "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)}}
9658 }
9659 },
9660 };
9661
9662 expert_module_t* expert_byte_array_string_decoding_error;
9663
9664 proto_byte_array_string_decoding_error =
9665 proto_register_protocol("Byte Array-String Decoding Error",
9666 "Byte Array-string decoding error",
9667 "_ws.byte_array_string.decoding_error");
9668
9669 expert_byte_array_string_decoding_error =
9670 expert_register_protocol(proto_byte_array_string_decoding_error);
9671 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9672
9673 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9674 disabling them makes no sense. */
9675 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9676}
9677
9678static void
9679register_date_time_string_decodinws_error(void)
9680{
9681 static ei_register_info ei[] = {
9682 { &ei_date_time_string_decoding_failed_error,
9683 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9684 "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)}}
9685 }
9686 },
9687 };
9688
9689 expert_module_t* expert_date_time_string_decoding_error;
9690
9691 proto_date_time_string_decoding_error =
9692 proto_register_protocol("Date and Time-String Decoding Error",
9693 "Date and Time-string decoding error",
9694 "_ws.date_time_string.decoding_error");
9695
9696 expert_date_time_string_decoding_error =
9697 expert_register_protocol(proto_date_time_string_decoding_error);
9698 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9699
9700 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9701 disabling them makes no sense. */
9702 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9703}
9704
9705static void
9706register_string_errors(void)
9707{
9708 static ei_register_info ei[] = {
9709 { &ei_string_trailing_characters,
9710 { "_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)}}
}
9711 },
9712 };
9713
9714 expert_module_t* expert_string_errors;
9715
9716 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9717
9718 expert_string_errors = expert_register_protocol(proto_string_errors);
9719 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9720
9721 /* "String Errors" isn't really a protocol, it's an error indication;
9722 disabling them makes no sense. */
9723 proto_set_cant_toggle(proto_string_errors);
9724}
9725
9726#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
9727static int
9728proto_register_field_init(header_field_info *hfinfo, const int parent)
9729{
9730
9731 tmp_fld_check_assert(hfinfo);
9732
9733 hfinfo->parent = parent;
9734 hfinfo->same_name_next = NULL((void*)0);
9735 hfinfo->same_name_prev_id = -1;
9736
9737 /* if we always add and never delete, then id == len - 1 is correct */
9738 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9739 if (!gpa_hfinfo.hfi) {
9740 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9741 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9742 /* The entry with index 0 is not used. */
9743 gpa_hfinfo.hfi[0] = NULL((void*)0);
9744 gpa_hfinfo.len = 1;
9745 } else {
9746 gpa_hfinfo.allocated_len += 1000;
9747 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9748 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9749 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9750 }
9751 }
9752 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9753 gpa_hfinfo.len++;
9754 hfinfo->id = gpa_hfinfo.len - 1;
9755
9756 /* if we have real names, enter this field in the name tree */
9757 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
9758
9759 header_field_info *same_name_next_hfinfo;
9760 unsigned char c;
9761
9762 /* Check that the filter name (abbreviation) is legal;
9763 * it must contain only alphanumerics, '-', "_", and ".". */
9764 c = proto_check_field_name(hfinfo->abbrev);
9765 if (c) {
9766 if (c == '.') {
9767 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)
;
9768 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9769 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)
;
9770 } else {
9771 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)
;
9772 }
9773 }
9774
9775 /* We allow multiple hfinfo's to be registered under the same
9776 * abbreviation. This was done for X.25, as, depending
9777 * on whether it's modulo-8 or modulo-128 operation,
9778 * some bitfield fields may be in different bits of
9779 * a byte, and we want to be able to refer to that field
9780 * with one name regardless of whether the packets
9781 * are modulo-8 or modulo-128 packets. */
9782
9783 same_name_hfinfo = NULL((void*)0);
9784
9785 g_hash_table_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9786 /* GLIB 2.x - if it is already present
9787 * the previous hfinfo with the same name is saved
9788 * to same_name_hfinfo by value destroy callback */
9789 if (same_name_hfinfo) {
9790 /* There's already a field with this name.
9791 * Put the current field *before* that field
9792 * in the list of fields with this name, Thus,
9793 * we end up with an effectively
9794 * doubly-linked-list of same-named hfinfo's,
9795 * with the head of the list (stored in the
9796 * hash) being the last seen hfinfo.
9797 */
9798 same_name_next_hfinfo =
9799 same_name_hfinfo->same_name_next;
9800
9801 hfinfo->same_name_next = same_name_next_hfinfo;
9802 if (same_name_next_hfinfo)
9803 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9804
9805 same_name_hfinfo->same_name_next = hfinfo;
9806 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9807#ifdef ENABLE_CHECK_FILTER
9808 while (same_name_hfinfo) {
9809 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
9810 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"
, 9810, __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)
;
9811 same_name_hfinfo = same_name_hfinfo->same_name_next;
9812 }
9813#endif
9814 }
9815 }
9816
9817 return hfinfo->id;
9818}
9819
9820void
9821proto_register_subtree_array(int * const *indices, const int num_indices)
9822{
9823 int i;
9824 int *const *ptr = indices;
9825
9826 /*
9827 * If we've already allocated the array of tree types, expand
9828 * it; this lets plugins such as mate add tree types after
9829 * the initial startup. (If we haven't already allocated it,
9830 * we don't allocate it; on the first pass, we just assign
9831 * ett values and keep track of how many we've assigned, and
9832 * when we're finished registering all dissectors we allocate
9833 * the array, so that we do only one allocation rather than
9834 * wasting CPU time and memory by growing the array for each
9835 * dissector that registers ett values.)
9836 */
9837 if (tree_is_expanded != NULL((void*)0)) {
9838 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9839
9840 /* set new items to 0 */
9841 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9842 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9843 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9844 }
9845
9846 /*
9847 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9848 * returning the indices through the pointers in the array whose
9849 * first element is pointed to by "indices", and update
9850 * "num_tree_types" appropriately.
9851 */
9852 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9853 if (**ptr != -1 && **ptr != 0) {
9854 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.")
9855 " 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.")
9856 " 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.")
9857 " 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.")
;
9858 }
9859 **ptr = num_tree_types;
9860 }
9861}
9862
9863static void
9864mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
9865{
9866 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "]";
9867 const size_t trunc_len = sizeof(trunc_str)-1;
9868 char *last_char;
9869
9870 /* ..... field_name: dataaaaaaaaaaaaa
9871 * |
9872 * ^^^^^ name_pos
9873 *
9874 * ..... field_name […]: dataaaaaaaaaaaaa
9875 *
9876 * name_pos==0 means that we have only data or only a field_name
9877 */
9878
9879 if (name_pos < size - trunc_len) {
9880 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
9881 memcpy(label_str + name_pos, trunc_str, trunc_len);
9882
9883 /* in general, label_str is UTF-8
9884 we can truncate it only at the beginning of a new character
9885 we go backwards from the byte right after our buffer and
9886 find the next starting byte of a UTF-8 character, this is
9887 where we cut
9888 there's no need to use g_utf8_find_prev_char(), the search
9889 will always succeed since we copied trunc_str into the
9890 buffer */
9891 /* g_utf8_prev_char does not deference the memory address
9892 * passed in (until after decrementing it, so it is perfectly
9893 * legal to pass in a pointer one past the last element.
9894 */
9895 last_char = g_utf8_prev_char(label_str + size);
9896 *last_char = '\0';
9897
9898 if (value_pos && *value_pos > 0) {
9899 if (name_pos == 0) {
9900 *value_pos += trunc_len;
9901 } else {
9902 /* Move one back to include trunc_str in the value. */
9903 *value_pos -= 1;
9904 }
9905 }
9906 } else if (name_pos < size)
9907 (void) g_strlcpy(label_str + name_pos, trunc_str, size - name_pos);
9908}
9909
9910static void
9911label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
9912{
9913 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
9914}
9915
9916static size_t
9917label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
9918{
9919 size_t name_pos;
9920
9921 /* "%s: %s", hfinfo->name, text */
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 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
9929 }
9930
9931 if (pos >= ITEM_LABEL_LENGTH240) {
9932 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9933 label_mark_truncated(label_str, name_pos, value_pos);
9934 }
9935
9936 return pos;
9937}
9938
9939static size_t
9940label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
9941{
9942 size_t name_pos;
9943
9944 /* "%s: %s (%s)", hfinfo->name, text, descr */
9945 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
9946 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
9947 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
9948 if (value_pos) {
9949 *value_pos = pos;
9950 }
9951 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9952 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
9953 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
9954 } else {
9955 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
9956 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
9957 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
9958 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
9959 }
9960 }
9961
9962 if (pos >= ITEM_LABEL_LENGTH240) {
9963 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9964 label_mark_truncated(label_str, name_pos, value_pos);
9965 }
9966
9967 return pos;
9968}
9969
9970void
9971proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
9972{
9973 const header_field_info *hfinfo;
9974 const char *str;
9975 const uint8_t *bytes;
9976 uint32_t integer;
9977 uint64_t integer64;
9978 const ipv4_addr_and_mask *ipv4;
9979 const ipv6_addr_and_prefix *ipv6;
9980 const e_guid_t *guid;
9981 char *name;
9982 address addr;
9983 char *addr_str;
9984 char *tmp;
9985
9986 if (!label_str) {
9987 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9987, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
9988 return;
9989 }
9990
9991 label_str[0]= '\0';
9992
9993 if (!fi) {
9994 return;
9995 }
9996
9997 hfinfo = fi->hfinfo;
9998
9999 switch (hfinfo->type) {
10000 case FT_NONE:
10001 case FT_PROTOCOL:
10002 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10003 if (value_pos) {
10004 *value_pos = strlen(hfinfo->name);
10005 }
10006 break;
10007
10008 case FT_BOOLEAN:
10009 fill_label_boolean(fi, label_str, value_pos);
10010 break;
10011
10012 case FT_BYTES:
10013 case FT_UINT_BYTES:
10014 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10015 fvalue_get_bytes_data(fi->value),
10016 (unsigned)fvalue_length2(fi->value));
10017 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10018 wmem_free(NULL((void*)0), tmp);
10019 break;
10020
10021 case FT_CHAR:
10022 if (hfinfo->bitmask) {
10023 fill_label_bitfield_char(fi, label_str, value_pos);
10024 } else {
10025 fill_label_char(fi, label_str, value_pos);
10026 }
10027 break;
10028
10029 /* Four types of integers to take care of:
10030 * Bitfield, with val_string
10031 * Bitfield, w/o val_string
10032 * Non-bitfield, with val_string
10033 * Non-bitfield, w/o val_string
10034 */
10035 case FT_UINT8:
10036 case FT_UINT16:
10037 case FT_UINT24:
10038 case FT_UINT32:
10039 if (hfinfo->bitmask) {
10040 fill_label_bitfield(fi, label_str, value_pos, false0);
10041 } else {
10042 fill_label_number(fi, label_str, value_pos, false0);
10043 }
10044 break;
10045
10046 case FT_FRAMENUM:
10047 fill_label_number(fi, label_str, value_pos, false0);
10048 break;
10049
10050 case FT_UINT40:
10051 case FT_UINT48:
10052 case FT_UINT56:
10053 case FT_UINT64:
10054 if (hfinfo->bitmask) {
10055 fill_label_bitfield64(fi, label_str, value_pos, false0);
10056 } else {
10057 fill_label_number64(fi, label_str, value_pos, false0);
10058 }
10059 break;
10060
10061 case FT_INT8:
10062 case FT_INT16:
10063 case FT_INT24:
10064 case FT_INT32:
10065 if (hfinfo->bitmask) {
10066 fill_label_bitfield(fi, label_str, value_pos, true1);
10067 } else {
10068 fill_label_number(fi, label_str, value_pos, true1);
10069 }
10070 break;
10071
10072 case FT_INT40:
10073 case FT_INT48:
10074 case FT_INT56:
10075 case FT_INT64:
10076 if (hfinfo->bitmask) {
10077 fill_label_bitfield64(fi, label_str, value_pos, true1);
10078 } else {
10079 fill_label_number64(fi, label_str, value_pos, true1);
10080 }
10081 break;
10082
10083 case FT_FLOAT:
10084 case FT_DOUBLE:
10085 fill_label_float(fi, label_str, value_pos);
10086 break;
10087
10088 case FT_ABSOLUTE_TIME:
10089 {
10090 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10091 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10092 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10093 }
10094 tmp = abs_time_to_str_ex(NULL((void*)0), fvalue_get_time(fi->value), hfinfo->display, flags);
10095 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10096 wmem_free(NULL((void*)0), tmp);
10097 break;
10098 }
10099 case FT_RELATIVE_TIME:
10100 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10101 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10102 wmem_free(NULL((void*)0), tmp);
10103 break;
10104
10105 case FT_IPXNET:
10106 integer = fvalue_get_uinteger(fi->value);
10107 tmp = get_ipxnet_name(NULL((void*)0), integer);
10108 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10109 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10110 wmem_free(NULL((void*)0), tmp);
10111 wmem_free(NULL((void*)0), addr_str);
10112 break;
10113
10114 case FT_VINES:
10115 addr.type = AT_VINES;
10116 addr.len = VINES_ADDR_LEN6;
10117 addr.data = fvalue_get_bytes_data(fi->value);
10118
10119 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10120 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10121 wmem_free(NULL((void*)0), addr_str);
10122 break;
10123
10124 case FT_ETHER:
10125 bytes = fvalue_get_bytes_data(fi->value);
10126
10127 addr.type = AT_ETHER;
10128 addr.len = 6;
10129 addr.data = bytes;
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 break;
10135
10136 case FT_IPv4:
10137 ipv4 = fvalue_get_ipv4(fi->value);
10138 set_address_ipv4(&addr, ipv4);
10139
10140 if (hfinfo->display == BASE_NETMASK) {
10141 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10142 } else {
10143 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10144 }
10145 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10146 wmem_free(NULL((void*)0), addr_str);
10147 free_address(&addr);
10148 break;
10149
10150 case FT_IPv6:
10151 ipv6 = fvalue_get_ipv6(fi->value);
10152 set_address_ipv6(&addr, ipv6);
10153
10154 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10155 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10156 wmem_free(NULL((void*)0), addr_str);
10157 free_address(&addr);
10158 break;
10159
10160 case FT_FCWWN:
10161 bytes = fvalue_get_bytes_data(fi->value);
10162 addr.type = AT_FCWWN;
10163 addr.len = FCWWN_ADDR_LEN8;
10164 addr.data = bytes;
10165
10166 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10167 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10168 wmem_free(NULL((void*)0), addr_str);
10169 break;
10170
10171 case FT_GUID:
10172 guid = fvalue_get_guid(fi->value);
10173 tmp = guid_to_str(NULL((void*)0), guid);
10174 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10175 wmem_free(NULL((void*)0), tmp);
10176 break;
10177
10178 case FT_OID:
10179 bytes = fvalue_get_bytes_data(fi->value);
10180 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10181 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10182 if (name) {
10183 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10184 wmem_free(NULL((void*)0), name);
10185 } else {
10186 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10187 }
10188 wmem_free(NULL((void*)0), tmp);
10189 break;
10190
10191 case FT_REL_OID:
10192 bytes = fvalue_get_bytes_data(fi->value);
10193 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10194 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10195 if (name) {
10196 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10197 wmem_free(NULL((void*)0), name);
10198 } else {
10199 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10200 }
10201 wmem_free(NULL((void*)0), tmp);
10202 break;
10203
10204 case FT_SYSTEM_ID:
10205 bytes = fvalue_get_bytes_data(fi->value);
10206 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10207 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10208 wmem_free(NULL((void*)0), tmp);
10209 break;
10210
10211 case FT_EUI64:
10212 integer64 = fvalue_get_uinteger64(fi->value);
10213 addr_str = eui64_to_str(NULL((void*)0), integer64);
10214 tmp = (char*)eui64_to_display(NULL((void*)0), integer64);
10215 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10216 wmem_free(NULL((void*)0), tmp);
10217 wmem_free(NULL((void*)0), addr_str);
10218 break;
10219 case FT_STRING:
10220 case FT_STRINGZ:
10221 case FT_UINT_STRING:
10222 case FT_STRINGZPAD:
10223 case FT_STRINGZTRUNC:
10224 case FT_AX25:
10225 str = fvalue_get_string(fi->value);
10226 label_fill(label_str, 0, hfinfo, str, value_pos);
10227 break;
10228
10229 case FT_IEEE_11073_SFLOAT:
10230 case FT_IEEE_11073_FLOAT:
10231 tmp = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, hfinfo->display);
10232 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10233 wmem_free(NULL((void*)0), tmp);
10234 break;
10235
10236 default:
10237 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
))
10238 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
))
10239 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
))
10240 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
))
;
10241 break;
10242 }
10243}
10244
10245static void
10246fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10247{
10248 char *p;
10249 int bitfield_byte_length = 0, bitwidth;
10250 uint64_t unshifted_value;
10251 uint64_t value;
10252
10253 const header_field_info *hfinfo = fi->hfinfo;
10254
10255 value = fvalue_get_uinteger64(fi->value);
10256 if (hfinfo->bitmask) {
10257 /* Figure out the bit width */
10258 bitwidth = hfinfo_container_bitwidth(hfinfo);
10259
10260 /* Un-shift bits */
10261 unshifted_value = value;
10262 unshifted_value <<= hfinfo_bitshift(hfinfo);
10263
10264 /* Create the bitfield first */
10265 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10266 bitfield_byte_length = (int) (p - label_str);
10267 }
10268
10269 /* Fill in the textual info */
10270 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10271}
10272
10273static const char *
10274hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10275{
10276 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10277 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10278
10279 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10280 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10281 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10282 else
10283 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10284 }
10285
10286 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10287 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10288
10289 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10290 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10291
10292 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10293}
10294
10295static const char *
10296hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10297{
10298 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10299 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10300 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10301 else
10302 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10303 }
10304
10305 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10306 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10307
10308 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10309 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10310
10311 /* If this is reached somebody registered a 64-bit field with a 32-bit
10312 * value-string, which isn't right. */
10313 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)
10314 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10315
10316 /* This is necessary to squelch MSVC errors; is there
10317 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10318 never returns? */
10319 return NULL((void*)0);
10320}
10321
10322static const char *
10323hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10324{
10325 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10326 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10327
10328 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)
;
10329
10330 /* This is necessary to squelch MSVC errors; is there
10331 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10332 never returns? */
10333 return NULL((void*)0);
10334}
10335
10336static const char *
10337hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10338{
10339 const char *str = hf_try_val_to_str(value, hfinfo);
10340
10341 return (str) ? str : unknown_str;
10342}
10343
10344static const char *
10345hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10346{
10347 const char *str = hf_try_val64_to_str(value, hfinfo);
10348
10349 return (str) ? str : unknown_str;
10350}
10351
10352/* Fills data for bitfield chars with val_strings */
10353static void
10354fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10355{
10356 char *p;
10357 int bitfield_byte_length, bitwidth;
10358 uint32_t unshifted_value;
10359 uint32_t value;
10360
10361 char buf[32];
10362 const char *out;
10363
10364 const header_field_info *hfinfo = fi->hfinfo;
10365
10366 /* Figure out the bit width */
10367 bitwidth = hfinfo_container_bitwidth(hfinfo);
10368
10369 /* Un-shift bits */
10370 value = fvalue_get_uinteger(fi->value);
10371
10372 unshifted_value = value;
10373 if (hfinfo->bitmask) {
10374 unshifted_value <<= hfinfo_bitshift(hfinfo);
10375 }
10376
10377 /* Create the bitfield first */
10378 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10379 bitfield_byte_length = (int) (p - label_str);
10380
10381 /* Fill in the textual info using stored (shifted) value */
10382 if (hfinfo->display == BASE_CUSTOM) {
10383 char tmp[ITEM_LABEL_LENGTH240];
10384 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10385
10386 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10386, "fmtfunc"))))
;
10387 fmtfunc(tmp, value);
10388 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10389 }
10390 else if (hfinfo->strings) {
10391 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10392
10393 out = hfinfo_char_vals_format(hfinfo, buf, value);
10394 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10395 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10396 else
10397 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10398 }
10399 else {
10400 out = hfinfo_char_value_format(hfinfo, buf, value);
10401
10402 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10403 }
10404}
10405
10406/* Fills data for bitfield ints with val_strings */
10407static void
10408fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10409{
10410 char *p;
10411 int bitfield_byte_length, bitwidth;
10412 uint32_t value, unshifted_value;
10413 char buf[NUMBER_LABEL_LENGTH80];
10414 const char *out;
10415
10416 const header_field_info *hfinfo = fi->hfinfo;
10417
10418 /* Figure out the bit width */
10419 if (fi->flags & FI_VARINT0x00004000)
10420 bitwidth = fi->length*8;
10421 else
10422 bitwidth = hfinfo_container_bitwidth(hfinfo);
10423
10424 /* Un-shift bits */
10425 if (is_signed)
10426 value = fvalue_get_sinteger(fi->value);
10427 else
10428 value = fvalue_get_uinteger(fi->value);
10429
10430 unshifted_value = value;
10431 if (hfinfo->bitmask) {
10432 unshifted_value <<= hfinfo_bitshift(hfinfo);
10433 }
10434
10435 /* Create the bitfield first */
10436 if (fi->flags & FI_VARINT0x00004000)
10437 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10438 else
10439 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10440 bitfield_byte_length = (int) (p - label_str);
10441
10442 /* Fill in the textual info using stored (shifted) value */
10443 if (hfinfo->display == BASE_CUSTOM) {
10444 char tmp[ITEM_LABEL_LENGTH240];
10445 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10446
10447 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10447, "fmtfunc"))))
;
10448 fmtfunc(tmp, value);
10449 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10450 }
10451 else if (hfinfo->strings) {
10452 const char *val_str = hf_try_val_to_str(value, hfinfo);
10453
10454 out = hfinfo_number_vals_format(hfinfo, buf, value);
10455 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10456 /*
10457 * Unique values only display value_string string
10458 * if there is a match. Otherwise it's just a number
10459 */
10460 if (val_str) {
10461 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10462 } else {
10463 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10464 }
10465 } else {
10466 if (val_str == NULL((void*)0))
10467 val_str = "Unknown";
10468
10469 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10470 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10471 else
10472 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10473 }
10474 }
10475 else {
10476 out = hfinfo_number_value_format(hfinfo, buf, value);
10477
10478 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10479 }
10480}
10481
10482static void
10483fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10484{
10485 char *p;
10486 int bitfield_byte_length, bitwidth;
10487 uint64_t value, unshifted_value;
10488 char buf[NUMBER_LABEL_LENGTH80];
10489 const char *out;
10490
10491 const header_field_info *hfinfo = fi->hfinfo;
10492
10493 /* Figure out the bit width */
10494 if (fi->flags & FI_VARINT0x00004000)
10495 bitwidth = fi->length*8;
10496 else
10497 bitwidth = hfinfo_container_bitwidth(hfinfo);
10498
10499 /* Un-shift bits */
10500 if (is_signed)
10501 value = fvalue_get_sinteger64(fi->value);
10502 else
10503 value = fvalue_get_uinteger64(fi->value);
10504
10505 unshifted_value = value;
10506 if (hfinfo->bitmask) {
10507 unshifted_value <<= hfinfo_bitshift(hfinfo);
10508 }
10509
10510 /* Create the bitfield first */
10511 if (fi->flags & FI_VARINT0x00004000)
10512 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10513 else
10514 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10515 bitfield_byte_length = (int) (p - label_str);
10516
10517 /* Fill in the textual info using stored (shifted) value */
10518 if (hfinfo->display == BASE_CUSTOM) {
10519 char tmp[ITEM_LABEL_LENGTH240];
10520 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10521
10522 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10522, "fmtfunc64"
))))
;
10523 fmtfunc64(tmp, value);
10524 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10525 }
10526 else if (hfinfo->strings) {
10527 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10528
10529 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10530 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10531 /*
10532 * Unique values only display value_string string
10533 * if there is a match. Otherwise it's just a number
10534 */
10535 if (val_str) {
10536 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10537 } else {
10538 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10539 }
10540 } else {
10541 if (val_str == NULL((void*)0))
10542 val_str = "Unknown";
10543
10544 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10545 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10546 else
10547 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10548 }
10549 }
10550 else {
10551 out = hfinfo_number_value_format64(hfinfo, buf, value);
10552
10553 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10554 }
10555}
10556
10557static void
10558fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10559{
10560 const header_field_info *hfinfo = fi->hfinfo;
10561 uint32_t value;
10562
10563 char buf[32];
10564 const char *out;
10565
10566 value = fvalue_get_uinteger(fi->value);
10567
10568 /* Fill in the textual info */
10569 if (hfinfo->display == BASE_CUSTOM) {
10570 char tmp[ITEM_LABEL_LENGTH240];
10571 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10572
10573 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10573, "fmtfunc"))))
;
10574 fmtfunc(tmp, value);
10575 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10576 }
10577 else if (hfinfo->strings) {
10578 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10579
10580 out = hfinfo_char_vals_format(hfinfo, buf, value);
10581 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10582 }
10583 else {
10584 out = hfinfo_char_value_format(hfinfo, buf, value);
10585
10586 label_fill(label_str, 0, hfinfo, out, value_pos);
10587 }
10588}
10589
10590static void
10591fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10592{
10593 const header_field_info *hfinfo = fi->hfinfo;
10594 uint32_t value;
10595
10596 char buf[NUMBER_LABEL_LENGTH80];
10597 const char *out;
10598
10599 if (is_signed)
10600 value = fvalue_get_sinteger(fi->value);
10601 else
10602 value = fvalue_get_uinteger(fi->value);
10603
10604 /* Fill in the textual info */
10605 if (hfinfo->display == BASE_CUSTOM) {
10606 char tmp[ITEM_LABEL_LENGTH240];
10607 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10608
10609 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10609, "fmtfunc"))))
;
10610 fmtfunc(tmp, value);
10611 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10612 }
10613 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10614 /*
10615 * It makes no sense to have a value-string table for a
10616 * frame-number field - they're just integers giving
10617 * the ordinal frame number.
10618 */
10619 const char *val_str = hf_try_val_to_str(value, hfinfo);
10620
10621 out = hfinfo_number_vals_format(hfinfo, buf, value);
10622 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10623 /*
10624 * Unique values only display value_string string
10625 * if there is a match. Otherwise it's just a number
10626 */
10627 if (val_str) {
10628 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10629 } else {
10630 label_fill(label_str, 0, hfinfo, out, value_pos);
10631 }
10632 } else {
10633 if (val_str == NULL((void*)0))
10634 val_str = "Unknown";
10635
10636 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10637 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10638 else
10639 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10640 }
10641 }
10642 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
))
) {
10643 char tmp[ITEM_LABEL_LENGTH240];
10644
10645 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10646 display_to_port_type((field_display_e)hfinfo->display), value);
10647 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10648 }
10649 else {
10650 out = hfinfo_number_value_format(hfinfo, buf, value);
10651
10652 label_fill(label_str, 0, hfinfo, out, value_pos);
10653 }
10654}
10655
10656static void
10657fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10658{
10659 const header_field_info *hfinfo = fi->hfinfo;
10660 uint64_t value;
10661
10662 char buf[NUMBER_LABEL_LENGTH80];
10663 const char *out;
10664
10665 if (is_signed)
10666 value = fvalue_get_sinteger64(fi->value);
10667 else
10668 value = fvalue_get_uinteger64(fi->value);
10669
10670 /* Fill in the textual info */
10671 if (hfinfo->display == BASE_CUSTOM) {
10672 char tmp[ITEM_LABEL_LENGTH240];
10673 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10674
10675 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10675, "fmtfunc64"
))))
;
10676 fmtfunc64(tmp, value);
10677 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10678 }
10679 else if (hfinfo->strings) {
10680 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10681
10682 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10683 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10684 /*
10685 * Unique values only display value_string string
10686 * if there is a match. Otherwise it's just a number
10687 */
10688 if (val_str) {
10689 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10690 } else {
10691 label_fill(label_str, 0, hfinfo, out, value_pos);
10692 }
10693 } else {
10694 if (val_str == NULL((void*)0))
10695 val_str = "Unknown";
10696
10697 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10698 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10699 else
10700 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10701 }
10702 }
10703 else {
10704 out = hfinfo_number_value_format64(hfinfo, buf, value);
10705
10706 label_fill(label_str, 0, hfinfo, out, value_pos);
10707 }
10708}
10709
10710static size_t
10711fill_display_label_float(const field_info *fi, char *label_str)
10712{
10713 int display;
10714 int digits;
10715 int n;
10716 double value;
10717
10718 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10719 value = fvalue_get_floating(fi->value);
10720
10721 if (display == BASE_CUSTOM) {
10722 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10723 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10723, "fmtfunc"))))
;
10724 fmtfunc(label_str, value);
10725 return strlen(label_str);
10726 }
10727
10728 switch (display) {
10729 case BASE_NONE:
10730 if (fi->hfinfo->type == FT_FLOAT)
10731 digits = FLT_DIG6;
10732 else
10733 digits = DBL_DIG15;
10734
10735 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%.*g", digits, value);
10736 break;
10737 case BASE_DEC:
10738 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%f", value);
10739 break;
10740 case BASE_HEX:
10741 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%a", value);
10742 break;
10743 case BASE_EXP:
10744 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%e", value);
10745 break;
10746 default:
10747 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10747
, __func__, "assertion \"not reached\" failed")
;
10748 }
10749 if (n < 0) {
10750 return 0; /* error */
10751 }
10752 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10753 const char *hf_str_val;
10754 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10755 n += protoo_strlcpy(label_str + n, hf_str_val, ITEM_LABEL_LENGTH240 - n);
10756 }
10757 if (n > ITEM_LABEL_LENGTH240) {
10758 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10758, __func__, "label length too small"); } } while (0)
;
10759 return strlen(label_str);
10760 }
10761
10762 return n;
10763}
10764
10765void
10766fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10767{
10768 char tmp[ITEM_LABEL_LENGTH240];
10769
10770 fill_display_label_float(fi, tmp);
10771 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10772}
10773
10774int
10775hfinfo_bitshift(const header_field_info *hfinfo)
10776{
10777 return ws_ctz(hfinfo->bitmask);
10778}
10779
10780
10781static int
10782hfinfo_bitoffset(const header_field_info *hfinfo)
10783{
10784 if (!hfinfo->bitmask) {
10785 return 0;
10786 }
10787
10788 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10789 * as the first bit */
10790 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10791}
10792
10793static int
10794hfinfo_mask_bitwidth(const header_field_info *hfinfo)
10795{
10796 if (!hfinfo->bitmask) {
10797 return 0;
10798 }
10799
10800 /* ilog2 = first set bit, ctz = last set bit */
10801 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
10802}
10803
10804static int
10805hfinfo_type_bitwidth(enum ftenum type)
10806{
10807 int bitwidth = 0;
10808
10809 switch (type) {
10810 case FT_CHAR:
10811 case FT_UINT8:
10812 case FT_INT8:
10813 bitwidth = 8;
10814 break;
10815 case FT_UINT16:
10816 case FT_INT16:
10817 bitwidth = 16;
10818 break;
10819 case FT_UINT24:
10820 case FT_INT24:
10821 bitwidth = 24;
10822 break;
10823 case FT_UINT32:
10824 case FT_INT32:
10825 bitwidth = 32;
10826 break;
10827 case FT_UINT40:
10828 case FT_INT40:
10829 bitwidth = 40;
10830 break;
10831 case FT_UINT48:
10832 case FT_INT48:
10833 bitwidth = 48;
10834 break;
10835 case FT_UINT56:
10836 case FT_INT56:
10837 bitwidth = 56;
10838 break;
10839 case FT_UINT64:
10840 case FT_INT64:
10841 bitwidth = 64;
10842 break;
10843 default:
10844 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 10844))
;
10845 ;
10846 }
10847 return bitwidth;
10848}
10849
10850
10851static int
10852hfinfo_container_bitwidth(const header_field_info *hfinfo)
10853{
10854 if (!hfinfo->bitmask) {
10855 return 0;
10856 }
10857
10858 if (hfinfo->type == FT_BOOLEAN) {
10859 return hfinfo->display; /* hacky? :) */
10860 }
10861
10862 return hfinfo_type_bitwidth(hfinfo->type);
10863}
10864
10865static int
10866hfinfo_hex_digits(const header_field_info *hfinfo)
10867{
10868 int bitwidth;
10869
10870 /* If we have a bitmask, hfinfo->type is the width of the container, so not
10871 * appropriate to determine the number of hex digits for the field.
10872 * So instead, we compute it from the bitmask.
10873 */
10874 if (hfinfo->bitmask != 0) {
10875 bitwidth = hfinfo_mask_bitwidth(hfinfo);
10876 } else {
10877 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
10878 }
10879
10880 /* Divide by 4, rounding up, to get number of hex digits. */
10881 return (bitwidth + 3) / 4;
10882}
10883
10884const char *
10885hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
10886{
10887 char *ptr = &buf[6];
10888 static const char hex_digits[16] =
10889 { '0', '1', '2', '3', '4', '5', '6', '7',
10890 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
10891
10892 *ptr = '\0';
10893 *(--ptr) = '\'';
10894 /* Properly format value */
10895 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
10896 /*
10897 * Printable, so just show the character, and, if it needs
10898 * to be escaped, escape it.
10899 */
10900 *(--ptr) = value;
10901 if (value == '\\' || value == '\'')
10902 *(--ptr) = '\\';
10903 } else {
10904 /*
10905 * Non-printable; show it as an escape sequence.
10906 */
10907 switch (value) {
10908
10909 case '\0':
10910 /*
10911 * Show a NUL with only one digit.
10912 */
10913 *(--ptr) = '0';
10914 break;
10915
10916 case '\a':
10917 *(--ptr) = 'a';
10918 break;
10919
10920 case '\b':
10921 *(--ptr) = 'b';
10922 break;
10923
10924 case '\f':
10925 *(--ptr) = 'f';
10926 break;
10927
10928 case '\n':
10929 *(--ptr) = 'n';
10930 break;
10931
10932 case '\r':
10933 *(--ptr) = 'r';
10934 break;
10935
10936 case '\t':
10937 *(--ptr) = 't';
10938 break;
10939
10940 case '\v':
10941 *(--ptr) = 'v';
10942 break;
10943
10944 default:
10945 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
10946
10947 case BASE_OCT:
10948 *(--ptr) = (value & 0x7) + '0';
10949 value >>= 3;
10950 *(--ptr) = (value & 0x7) + '0';
10951 value >>= 3;
10952 *(--ptr) = (value & 0x7) + '0';
10953 break;
10954
10955 case BASE_HEX:
10956 *(--ptr) = hex_digits[value & 0x0F];
10957 value >>= 4;
10958 *(--ptr) = hex_digits[value & 0x0F];
10959 *(--ptr) = 'x';
10960 break;
10961
10962 default:
10963 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
10964 }
10965 }
10966 *(--ptr) = '\\';
10967 }
10968 *(--ptr) = '\'';
10969 return ptr;
10970}
10971
10972static const char *
10973hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
10974{
10975 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
10976 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
))
;
10977
10978 *ptr = '\0';
10979 /* Properly format value */
10980 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
10981 case BASE_DEC:
10982 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
10983
10984 case BASE_DEC_HEX:
10985 *(--ptr) = ')';
10986 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10987 *(--ptr) = '(';
10988 *(--ptr) = ' ';
10989 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
10990 return ptr;
10991
10992 case BASE_OCT:
10993 return oct_to_str_back(ptr, value);
10994
10995 case BASE_HEX:
10996 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10997
10998 case BASE_HEX_DEC:
10999 *(--ptr) = ')';
11000 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11001 *(--ptr) = '(';
11002 *(--ptr) = ' ';
11003 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11004 return ptr;
11005
11006 case BASE_PT_UDP:
11007 case BASE_PT_TCP:
11008 case BASE_PT_DCCP:
11009 case BASE_PT_SCTP:
11010 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11011 display_to_port_type((field_display_e)display), value);
11012 return buf;
11013 case BASE_OUI:
11014 {
11015 uint8_t p_oui[3];
11016 const char *manuf_name;
11017
11018 p_oui[0] = value >> 16 & 0xFF;
11019 p_oui[1] = value >> 8 & 0xFF;
11020 p_oui[2] = value & 0xFF;
11021
11022 /* Attempt an OUI lookup. */
11023 manuf_name = uint_get_manuf_name_if_known(value);
11024 if (manuf_name == NULL((void*)0)) {
11025 /* Could not find an OUI. */
11026 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11027 }
11028 else {
11029 /* Found an address string. */
11030 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11031 }
11032 return buf;
11033 }
11034
11035 default:
11036 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11037 }
11038 return ptr;
11039}
11040
11041static const char *
11042hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11043{
11044 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11045 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
))
;
11046
11047 *ptr = '\0';
11048 /* Properly format value */
11049 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11050 case BASE_DEC:
11051 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11052
11053 case BASE_DEC_HEX:
11054 *(--ptr) = ')';
11055 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11056 *(--ptr) = '(';
11057 *(--ptr) = ' ';
11058 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11059 return ptr;
11060
11061 case BASE_OCT:
11062 return oct64_to_str_back(ptr, value);
11063
11064 case BASE_HEX:
11065 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11066
11067 case BASE_HEX_DEC:
11068 *(--ptr) = ')';
11069 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11070 *(--ptr) = '(';
11071 *(--ptr) = ' ';
11072 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11073 return ptr;
11074
11075 default:
11076 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11077 }
11078
11079 return ptr;
11080}
11081
11082static const char *
11083hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11084{
11085 int display = hfinfo->display;
11086
11087 if (hfinfo->type == FT_FRAMENUM) {
11088 /*
11089 * Frame numbers are always displayed in decimal.
11090 */
11091 display = BASE_DEC;
11092 }
11093
11094 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11095}
11096
11097static const char *
11098hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11099{
11100 int display = hfinfo->display;
11101
11102 if (hfinfo->type == FT_FRAMENUM) {
11103 /*
11104 * Frame numbers are always displayed in decimal.
11105 */
11106 display = BASE_DEC;
11107 }
11108
11109 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11110}
11111
11112static const char *
11113hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11114{
11115 /* Get the underlying BASE_ value */
11116 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11117
11118 return hfinfo_char_value_format_display(display, buf, value);
11119}
11120
11121static const char *
11122hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11123{
11124 /* Get the underlying BASE_ value */
11125 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11126
11127 if (hfinfo->type == FT_FRAMENUM) {
11128 /*
11129 * Frame numbers are always displayed in decimal.
11130 */
11131 display = BASE_DEC;
11132 }
11133
11134 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11135 display = BASE_DEC;
11136 } else if (display == BASE_OUI) {
11137 display = BASE_HEX;
11138 }
11139
11140 switch (display) {
11141 case BASE_NONE:
11142 /* case BASE_DEC: */
11143 case BASE_DEC_HEX:
11144 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11145 case BASE_CUSTOM:
11146 display = BASE_DEC;
11147 break;
11148
11149 /* case BASE_HEX: */
11150 case BASE_HEX_DEC:
11151 display = BASE_HEX;
11152 break;
11153 }
11154
11155 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11156}
11157
11158static const char *
11159hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11160{
11161 /* Get the underlying BASE_ value */
11162 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11163
11164 if (hfinfo->type == FT_FRAMENUM) {
11165 /*
11166 * Frame numbers are always displayed in decimal.
11167 */
11168 display = BASE_DEC;
11169 }
11170
11171 switch (display) {
11172 case BASE_NONE:
11173 /* case BASE_DEC: */
11174 case BASE_DEC_HEX:
11175 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11176 case BASE_CUSTOM:
11177 display = BASE_DEC;
11178 break;
11179
11180 /* case BASE_HEX: */
11181 case BASE_HEX_DEC:
11182 display = BASE_HEX;
11183 break;
11184 }
11185
11186 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11187}
11188
11189static const char *
11190hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11191{
11192 /* Get the underlying BASE_ value */
11193 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11194
11195 return hfinfo_char_value_format_display(display, buf, value);
11196}
11197
11198static const char *
11199hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11200{
11201 /* Get the underlying BASE_ value */
11202 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11203
11204 if (display == BASE_NONE)
11205 return NULL((void*)0);
11206
11207 if (display == BASE_DEC_HEX)
11208 display = BASE_DEC;
11209 if (display == BASE_HEX_DEC)
11210 display = BASE_HEX;
11211
11212 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11213}
11214
11215static const char *
11216hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11217{
11218 /* Get the underlying BASE_ value */
11219 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11220
11221 if (display == BASE_NONE)
11222 return NULL((void*)0);
11223
11224 if (display == BASE_DEC_HEX)
11225 display = BASE_DEC;
11226 if (display == BASE_HEX_DEC)
11227 display = BASE_HEX;
11228
11229 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11230}
11231
11232const char *
11233proto_registrar_get_name(const int n)
11234{
11235 header_field_info *hfinfo;
11236
11237 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", 11237
, __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", 11237
, "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", 11237, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11238 return hfinfo->name;
11239}
11240
11241const char *
11242proto_registrar_get_abbrev(const int n)
11243{
11244 header_field_info *hfinfo;
11245
11246 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", 11246
, __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", 11246
, "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", 11246, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11247 return hfinfo->abbrev;
11248}
11249
11250enum ftenum
11251proto_registrar_get_ftype(const int n)
11252{
11253 header_field_info *hfinfo;
11254
11255 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", 11255
, __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", 11255
, "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", 11255, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11256 return hfinfo->type;
11257}
11258
11259int
11260proto_registrar_get_parent(const int n)
11261{
11262 header_field_info *hfinfo;
11263
11264 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", 11264
, __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", 11264
, "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", 11264, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11265 return hfinfo->parent;
11266}
11267
11268bool_Bool
11269proto_registrar_is_protocol(const int n)
11270{
11271 header_field_info *hfinfo;
11272
11273 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", 11273
, __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", 11273
, "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", 11273, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11274 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11275}
11276
11277/* Returns length of field in packet (not necessarily the length
11278 * in our internal representation, as in the case of IPv4).
11279 * 0 means undeterminable at time of registration
11280 * -1 means the field is not registered. */
11281int
11282proto_registrar_get_length(const int n)
11283{
11284 header_field_info *hfinfo;
11285
11286 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", 11286
, __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", 11286
, "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", 11286, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11287 return ftype_wire_size(hfinfo->type);
11288}
11289
11290/* Looks for a protocol or a field in a proto_tree. Returns true if
11291 * it exists anywhere, or false if it exists nowhere. */
11292bool_Bool
11293proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11294{
11295 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11296
11297 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11298 return true1;
11299 }
11300 else {
11301 return false0;
11302 }
11303}
11304
11305/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11306 * This only works if the hfindex was "primed" before the dissection
11307 * took place, as we just pass back the already-created GPtrArray*.
11308 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11309 * handles that. */
11310GPtrArray *
11311proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11312{
11313 if (!tree)
11314 return NULL((void*)0);
11315
11316 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11317 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11318 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11319 else
11320 return NULL((void*)0);
11321}
11322
11323bool_Bool
11324proto_tracking_interesting_fields(const proto_tree *tree)
11325{
11326 GHashTable *interesting_hfids;
11327
11328 if (!tree)
11329 return false0;
11330
11331 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11332
11333 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11334}
11335
11336/* Helper struct for proto_find_info() and proto_all_finfos() */
11337typedef struct {
11338 GPtrArray *array;
11339 int id;
11340} ffdata_t;
11341
11342/* Helper function for proto_find_info() */
11343static bool_Bool
11344find_finfo(proto_node *node, void * data)
11345{
11346 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11347 if (fi && fi->hfinfo) {
11348 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11349 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11350 }
11351 }
11352
11353 /* Don't stop traversing. */
11354 return false0;
11355}
11356
11357/* Helper function for proto_find_first_info() */
11358static bool_Bool
11359find_first_finfo(proto_node *node, void *data)
11360{
11361 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11362 if (fi && fi->hfinfo) {
11363 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11364 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11365
11366 /* Stop traversing. */
11367 return true1;
11368 }
11369 }
11370
11371 /* Continue traversing. */
11372 return false0;
11373}
11374
11375/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11376* This works on any proto_tree, primed or unprimed, but actually searches
11377* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11378* The caller does need to free the returned GPtrArray with
11379* g_ptr_array_free(<array>, true).
11380*/
11381GPtrArray *
11382proto_find_finfo(proto_tree *tree, const int id)
11383{
11384 ffdata_t ffdata;
11385
11386 ffdata.array = g_ptr_array_new();
11387 ffdata.id = id;
11388
11389 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11390
11391 return ffdata.array;
11392}
11393
11394/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11395* This works on any proto_tree, primed or unprimed, but actually searches
11396* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11397* The caller does need to free the returned GPtrArray with
11398* g_ptr_array_free(<array>, true).
11399*/
11400GPtrArray *
11401proto_find_first_finfo(proto_tree *tree, const int id)
11402{
11403 ffdata_t ffdata;
11404
11405 ffdata.array = g_ptr_array_new();
11406 ffdata.id = id;
11407
11408 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11409
11410 return ffdata.array;
11411}
11412
11413/* Helper function for proto_all_finfos() */
11414static bool_Bool
11415every_finfo(proto_node *node, void * data)
11416{
11417 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11418 if (fi && fi->hfinfo) {
11419 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11420 }
11421
11422 /* Don't stop traversing. */
11423 return false0;
11424}
11425
11426/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11427 * The caller does need to free the returned GPtrArray with
11428 * g_ptr_array_free(<array>, true).
11429 */
11430GPtrArray *
11431proto_all_finfos(proto_tree *tree)
11432{
11433 ffdata_t ffdata;
11434
11435 /* Pre allocate enough space to hold all fields in most cases */
11436 ffdata.array = g_ptr_array_sized_new(512);
11437 ffdata.id = 0;
11438
11439 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11440
11441 return ffdata.array;
11442}
11443
11444
11445typedef struct {
11446 unsigned offset;
11447 field_info *finfo;
11448 tvbuff_t *tvb;
11449} offset_search_t;
11450
11451static bool_Bool
11452check_for_offset(proto_node *node, void * data)
11453{
11454 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11455 offset_search_t *offsearch = (offset_search_t *)data;
11456
11457 /* !fi == the top most container node which holds nothing */
11458 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11459 if (offsearch->offset >= (unsigned) fi->start &&
11460 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11461
11462 offsearch->finfo = fi;
11463 return false0; /* keep traversing */
11464 }
11465 }
11466 return false0; /* keep traversing */
11467}
11468
11469/* Search a proto_tree backwards (from leaves to root) looking for the field
11470 * whose start/length occupies 'offset' */
11471/* XXX - I couldn't find an easy way to search backwards, so I search
11472 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11473 * the one I want to return to the user. This algorithm is inefficient
11474 * and could be re-done, but I'd have to handle all the children and
11475 * siblings of each node myself. When I have more time I'll do that.
11476 * (yeah right) */
11477field_info *
11478proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11479{
11480 offset_search_t offsearch;
11481
11482 offsearch.offset = offset;
11483 offsearch.finfo = NULL((void*)0);
11484 offsearch.tvb = tvb;
11485
11486 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11487
11488 return offsearch.finfo;
11489}
11490
11491typedef struct {
11492 int length;
11493 char *buf;
11494} decoded_data_t;
11495
11496static bool_Bool
11497check_for_undecoded(proto_node *node, void * data)
11498{
11499 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11500 decoded_data_t* decoded = (decoded_data_t*)data;
11501 int i;
11502 unsigned byte;
11503 unsigned bit;
11504
11505 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11506 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11507 byte = i / 8;
11508 bit = i % 8;
11509 decoded->buf[byte] |= (1 << bit);
11510 }
11511 }
11512
11513 return false0;
11514}
11515
11516char*
11517proto_find_undecoded_data(proto_tree *tree, unsigned length)
11518{
11519 decoded_data_t decoded;
11520 decoded.length = length;
11521 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11522
11523 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11524 return decoded.buf;
11525}
11526
11527/* Dumps the protocols in the registration database to stdout. An independent
11528 * program can take this output and format it into nice tables or HTML or
11529 * whatever.
11530 *
11531 * There is one record per line. The fields are tab-delimited.
11532 *
11533 * Field 1 = protocol name
11534 * Field 2 = protocol short name
11535 * Field 3 = protocol filter name
11536 * Field 4 = protocol enabled
11537 * Field 5 = protocol enabled by default
11538 * Field 6 = protocol can toggle
11539 */
11540void
11541proto_registrar_dump_protocols(void)
11542{
11543 protocol_t *protocol;
11544 int i;
11545 void *cookie = NULL((void*)0);
11546
11547
11548 i = proto_get_first_protocol(&cookie);
11549 while (i != -1) {
11550 protocol = find_protocol_by_id(i);
11551 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11552 protocol->name,
11553 protocol->short_name,
11554 protocol->filter_name,
11555 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11556 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11557 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11558 i = proto_get_next_protocol(&cookie);
11559 }
11560}
11561
11562/* Dumps the value_strings, extended value string headers, range_strings
11563 * or true/false strings for fields that have them.
11564 * There is one record per line. Fields are tab-delimited.
11565 * There are four types of records: Value String, Extended Value String Header,
11566 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11567 * the type of record.
11568 *
11569 * Note that a record will be generated only if the value_string,... is referenced
11570 * in a registered hfinfo entry.
11571 *
11572 *
11573 * Value Strings
11574 * -------------
11575 * Field 1 = 'V'
11576 * Field 2 = Field abbreviation to which this value string corresponds
11577 * Field 3 = Integer value
11578 * Field 4 = String
11579 *
11580 * Extended Value String Headers
11581 * -----------------------------
11582 * Field 1 = 'E'
11583 * Field 2 = Field abbreviation to which this extended value string header corresponds
11584 * Field 3 = Extended Value String "Name"
11585 * Field 4 = Number of entries in the associated value_string array
11586 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11587 *
11588 * Range Strings
11589 * -------------
11590 * Field 1 = 'R'
11591 * Field 2 = Field abbreviation to which this range string corresponds
11592 * Field 3 = Integer value: lower bound
11593 * Field 4 = Integer value: upper bound
11594 * Field 5 = String
11595 *
11596 * True/False Strings
11597 * ------------------
11598 * Field 1 = 'T'
11599 * Field 2 = Field abbreviation to which this true/false string corresponds
11600 * Field 3 = True String
11601 * Field 4 = False String
11602 */
11603void
11604proto_registrar_dump_values(void)
11605{
11606 header_field_info *hfinfo;
11607 int i, len, vi;
11608 const value_string *vals;
11609 const val64_string *vals64;
11610 const range_string *range;
11611 const true_false_string *tfs;
11612 const unit_name_string *units;
11613
11614 len = gpa_hfinfo.len;
11615 for (i = 0; i < len ; i++) {
11616 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11617 continue; /* This is a deregistered protocol or field */
11618
11619 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", 11619
, __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", 11619
, "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", 11619, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11620
11621 if (hfinfo->id == hf_text_only) {
11622 continue;
11623 }
11624
11625 /* ignore protocols */
11626 if (proto_registrar_is_protocol(i)) {
11627 continue;
11628 }
11629 /* process header fields */
11630#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11631 /*
11632 * If this field isn't at the head of the list of
11633 * fields with this name, skip this field - all
11634 * fields with the same name are really just versions
11635 * of the same field stored in different bits, and
11636 * should have the same type/radix/value list, and
11637 * just differ in their bit masks. (If a field isn't
11638 * a bitfield, but can be, say, 1 or 2 bytes long,
11639 * it can just be made FT_UINT16, meaning the
11640 * *maximum* length is 2 bytes, and be used
11641 * for all lengths.)
11642 */
11643 if (hfinfo->same_name_prev_id != -1)
11644 continue;
11645#endif
11646 vals = NULL((void*)0);
11647 vals64 = NULL((void*)0);
11648 range = NULL((void*)0);
11649 tfs = NULL((void*)0);
11650 units = NULL((void*)0);
11651
11652 if (hfinfo->strings != NULL((void*)0)) {
11653 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11654 (hfinfo->type == FT_CHAR ||
11655 hfinfo->type == FT_UINT8 ||
11656 hfinfo->type == FT_UINT16 ||
11657 hfinfo->type == FT_UINT24 ||
11658 hfinfo->type == FT_UINT32 ||
11659 hfinfo->type == FT_UINT40 ||
11660 hfinfo->type == FT_UINT48 ||
11661 hfinfo->type == FT_UINT56 ||
11662 hfinfo->type == FT_UINT64 ||
11663 hfinfo->type == FT_INT8 ||
11664 hfinfo->type == FT_INT16 ||
11665 hfinfo->type == FT_INT24 ||
11666 hfinfo->type == FT_INT32 ||
11667 hfinfo->type == FT_INT40 ||
11668 hfinfo->type == FT_INT48 ||
11669 hfinfo->type == FT_INT56 ||
11670 hfinfo->type == FT_INT64 ||
11671 hfinfo->type == FT_FLOAT ||
11672 hfinfo->type == FT_DOUBLE)) {
11673
11674 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11675 range = (const range_string *)hfinfo->strings;
11676 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11677 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11678 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11679 } else {
11680 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11681 }
11682 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11683 vals64 = (const val64_string *)hfinfo->strings;
11684 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11685 units = (const unit_name_string *)hfinfo->strings;
11686 } else {
11687 vals = (const value_string *)hfinfo->strings;
11688 }
11689 }
11690 else if (hfinfo->type == FT_BOOLEAN) {
11691 tfs = (const struct true_false_string *)hfinfo->strings;
11692 }
11693 }
11694
11695 /* Print value strings? */
11696 if (vals) {
11697 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11698 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11699 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11700 if (!val64_string_ext_validate(vse_p)) {
11701 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11701, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11702 continue;
11703 }
11704 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11705 printf("E\t%s\t%u\t%s\t%s\n",
11706 hfinfo->abbrev,
11707 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11708 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11709 val64_string_ext_match_type_str(vse_p));
11710 } else {
11711 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11712 if (!value_string_ext_validate(vse_p)) {
11713 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11713, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11714 continue;
11715 }
11716 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11717 printf("E\t%s\t%u\t%s\t%s\n",
11718 hfinfo->abbrev,
11719 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11720 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11721 value_string_ext_match_type_str(vse_p));
11722 }
11723 }
11724 vi = 0;
11725 while (vals[vi].strptr) {
11726 /* Print in the proper base */
11727 if (hfinfo->type == FT_CHAR) {
11728 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11729 printf("V\t%s\t'%c'\t%s\n",
11730 hfinfo->abbrev,
11731 vals[vi].value,
11732 vals[vi].strptr);
11733 } else {
11734 if (hfinfo->display == BASE_HEX) {
11735 printf("V\t%s\t'\\x%02x'\t%s\n",
11736 hfinfo->abbrev,
11737 vals[vi].value,
11738 vals[vi].strptr);
11739 }
11740 else {
11741 printf("V\t%s\t'\\%03o'\t%s\n",
11742 hfinfo->abbrev,
11743 vals[vi].value,
11744 vals[vi].strptr);
11745 }
11746 }
11747 } else {
11748 if (hfinfo->display == BASE_HEX) {
11749 printf("V\t%s\t0x%x\t%s\n",
11750 hfinfo->abbrev,
11751 vals[vi].value,
11752 vals[vi].strptr);
11753 }
11754 else {
11755 printf("V\t%s\t%u\t%s\n",
11756 hfinfo->abbrev,
11757 vals[vi].value,
11758 vals[vi].strptr);
11759 }
11760 }
11761 vi++;
11762 }
11763 }
11764 else if (vals64) {
11765 vi = 0;
11766 while (vals64[vi].strptr) {
11767 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11768 hfinfo->abbrev,
11769 vals64[vi].value,
11770 vals64[vi].strptr);
11771 vi++;
11772 }
11773 }
11774
11775 /* print range strings? */
11776 else if (range) {
11777 vi = 0;
11778 while (range[vi].strptr) {
11779 /* Print in the proper base */
11780 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11781 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11782 hfinfo->abbrev,
11783 range[vi].value_min,
11784 range[vi].value_max,
11785 range[vi].strptr);
11786 }
11787 else {
11788 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11789 hfinfo->abbrev,
11790 range[vi].value_min,
11791 range[vi].value_max,
11792 range[vi].strptr);
11793 }
11794 vi++;
11795 }
11796 }
11797
11798 /* Print true/false strings? */
11799 else if (tfs) {
11800 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11801 tfs->true_string, tfs->false_string);
11802 }
11803 /* Print unit strings? */
11804 else if (units) {
11805 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11806 units->singular, units->plural ? units->plural : "(no plural)");
11807 }
11808 }
11809}
11810
11811/* Prints the number of registered fields.
11812 * Useful for determining an appropriate value for
11813 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
11814 *
11815 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
11816 * the number of fields, true otherwise.
11817 */
11818bool_Bool
11819proto_registrar_dump_fieldcount(void)
11820{
11821 uint32_t i;
11822 header_field_info *hfinfo;
11823 uint32_t deregistered_count = 0;
11824 uint32_t same_name_count = 0;
11825 uint32_t protocol_count = 0;
11826
11827 for (i = 0; i < gpa_hfinfo.len; i++) {
11828 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
11829 deregistered_count++;
11830 continue; /* This is a deregistered protocol or header field */
11831 }
11832
11833 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", 11833
, __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", 11833
, "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", 11833, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11834
11835 if (proto_registrar_is_protocol(i))
11836 protocol_count++;
11837
11838 if (hfinfo->same_name_prev_id != -1)
11839 same_name_count++;
11840 }
11841
11842 printf("There are %u header fields registered, of which:\n"
11843 "\t%u are deregistered\n"
11844 "\t%u are protocols\n"
11845 "\t%u have the same name as another field\n\n",
11846 gpa_hfinfo.len, deregistered_count, protocol_count,
11847 same_name_count);
11848
11849 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
11850 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
11851 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
11852 "\n");
11853
11854 printf("The header field table consumes %u KiB of memory.\n",
11855 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
11856 printf("The fields themselves consume %u KiB of memory.\n",
11857 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
11858
11859 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
11860}
11861
11862static void
11863elastic_add_base_mapping(json_dumper *dumper)
11864{
11865 json_dumper_set_member_name(dumper, "settings");
11866 json_dumper_begin_object(dumper);
11867 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
11868 json_dumper_value_anyf(dumper, "%d", 1000000);
11869 json_dumper_end_object(dumper);
11870}
11871
11872static char*
11873ws_type_to_elastic(unsigned type _U___attribute__((unused)))
11874{
11875 switch(type) {
11876 case FT_UINT16:
11877 case FT_INT16:
11878 case FT_INT32:
11879 case FT_UINT24:
11880 case FT_INT24:
11881 return "integer";
11882 case FT_INT8:
11883 case FT_UINT8:
11884 return "short";
11885 case FT_FRAMENUM:
11886 case FT_UINT32:
11887 case FT_UINT40:
11888 case FT_UINT48:
11889 case FT_UINT56:
11890 case FT_UINT64: // Actually it's not handled by 'long' elastic type.
11891 case FT_INT48:
11892 case FT_INT64:
11893 return "long";
11894 case FT_FLOAT:
11895 case FT_DOUBLE:
11896 return "float";
11897 case FT_IPv6:
11898 case FT_IPv4:
11899 return "ip";
11900 case FT_ABSOLUTE_TIME:
11901 case FT_RELATIVE_TIME:
11902 return "date";
11903 case FT_BYTES:
11904 case FT_UINT_BYTES:
11905 return "byte";
11906 case FT_BOOLEAN:
11907 return "boolean";
11908 default:
11909 return NULL((void*)0);
11910 }
11911}
11912
11913static char*
11914dot_to_underscore(char* str)
11915{
11916 unsigned i;
11917 for (i = 0; i < strlen(str); i++) {
11918 if (str[i] == '.')
11919 str[i] = '_';
11920 }
11921 return str;
11922}
11923
11924/* Dumps a mapping file for ElasticSearch
11925 */
11926void
11927proto_registrar_dump_elastic(const char* filter)
11928{
11929 header_field_info *hfinfo;
11930 header_field_info *parent_hfinfo;
11931 unsigned i;
11932 bool_Bool open_object = true1;
11933 const char* prev_proto = NULL((void*)0);
11934 char* str;
11935 char** protos = NULL((void*)0);
11936 char* proto;
11937 bool_Bool found;
11938 unsigned j;
11939 char* type;
11940 char* prev_item = NULL((void*)0);
11941
11942 /* We have filtering protocols. Extract them. */
11943 if (filter) {
11944 protos = g_strsplit(filter, ",", -1);
11945 }
11946
11947 /*
11948 * To help tracking down the json tree, objects have been appended with a comment:
11949 * n.label -> where n is the indentation level and label the name of the object
11950 */
11951
11952 json_dumper dumper = {
11953 .output_file = stdoutstdout,
11954 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
11955 };
11956 json_dumper_begin_object(&dumper); // 1.root
11957 elastic_add_base_mapping(&dumper);
11958
11959 json_dumper_set_member_name(&dumper, "mappings");
11960 json_dumper_begin_object(&dumper); // 2.mappings
11961 json_dumper_set_member_name(&dumper, "dynamic");
11962 json_dumper_value_anyf(&dumper, "false");
11963
11964 json_dumper_set_member_name(&dumper, "properties");
11965 json_dumper_begin_object(&dumper); // 3.properties
11966 json_dumper_set_member_name(&dumper, "timestamp");
11967 json_dumper_begin_object(&dumper); // 4.timestamp
11968 json_dumper_set_member_name(&dumper, "type");
11969 json_dumper_value_string(&dumper, "date");
11970 json_dumper_end_object(&dumper); // 4.timestamp
11971
11972 json_dumper_set_member_name(&dumper, "layers");
11973 json_dumper_begin_object(&dumper); // 4.layers
11974 json_dumper_set_member_name(&dumper, "properties");
11975 json_dumper_begin_object(&dumper); // 5.properties
11976
11977 for (i = 0; i < gpa_hfinfo.len; i++) {
11978 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11979 continue; /* This is a deregistered protocol or header field */
11980
11981 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", 11981
, __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", 11981
, "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", 11981, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11982
11983 /*
11984 * Skip the pseudo-field for "proto_tree_add_text()" since
11985 * we don't want it in the list of filterable protocols.
11986 */
11987 if (hfinfo->id == hf_text_only)
11988 continue;
11989
11990 if (!proto_registrar_is_protocol(i)) {
11991 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", 11991
, __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", 11991
, "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", 11991
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
11992
11993 /*
11994 * Skip the field if filter protocols have been set and this one's
11995 * parent is not listed.
11996 */
11997 if (protos) {
11998 found = false0;
11999 j = 0;
12000 proto = protos[0];
12001 while(proto) {
12002 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12003 found = true1;
12004 break;
12005 }
12006 j++;
12007 proto = protos[j];
12008 }
12009 if (!found)
12010 continue;
12011 }
12012
12013 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12014 json_dumper_end_object(&dumper); // 7.properties
12015 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12016 open_object = true1;
12017 }
12018
12019 prev_proto = parent_hfinfo->abbrev;
12020
12021 if (open_object) {
12022 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12023 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12024 json_dumper_set_member_name(&dumper, "properties");
12025 json_dumper_begin_object(&dumper); // 7.properties
12026 open_object = false0;
12027 }
12028 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12029 type = ws_type_to_elastic(hfinfo->type);
12030 /* when type is NULL, we have the default mapping: string */
12031 if (type) {
12032 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12033 dot_to_underscore(str);
12034 if (g_strcmp0(prev_item, str)) {
12035 json_dumper_set_member_name(&dumper, str);
12036 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12037 json_dumper_set_member_name(&dumper, "type");
12038 json_dumper_value_string(&dumper, type);
12039 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12040 }
12041 g_free(prev_item);
12042 prev_item = str;
12043 }
12044 }
12045 }
12046 g_free(prev_item);
12047
12048 if (prev_proto) {
12049 json_dumper_end_object(&dumper); // 7.properties
12050 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12051 }
12052
12053 json_dumper_end_object(&dumper); // 5.properties
12054 json_dumper_end_object(&dumper); // 4.layers
12055 json_dumper_end_object(&dumper); // 3.properties
12056 json_dumper_end_object(&dumper); // 2.mappings
12057 json_dumper_end_object(&dumper); // 1.root
12058 bool_Bool ret = json_dumper_finish(&dumper);
12059 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12059, "ret"))))
;
12060
12061 g_strfreev(protos);
12062}
12063
12064/* Dumps the contents of the registration database to stdout. An independent
12065 * program can take this output and format it into nice tables or HTML or
12066 * whatever.
12067 *
12068 * There is one record per line. Each record is either a protocol or a header
12069 * field, differentiated by the first field. The fields are tab-delimited.
12070 *
12071 * Protocols
12072 * ---------
12073 * Field 1 = 'P'
12074 * Field 2 = descriptive protocol name
12075 * Field 3 = protocol abbreviation
12076 *
12077 * Header Fields
12078 * -------------
12079 * Field 1 = 'F'
12080 * Field 2 = descriptive field name
12081 * Field 3 = field abbreviation
12082 * Field 4 = type ( textual representation of the ftenum type )
12083 * Field 5 = parent protocol abbreviation
12084 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12085 * Field 7 = bitmask: format: hex: 0x....
12086 * Field 8 = blurb describing field
12087 */
12088void
12089proto_registrar_dump_fields(void)
12090{
12091 header_field_info *hfinfo, *parent_hfinfo;
12092 int i, len;
12093 const char *enum_name;
12094 const char *base_name;
12095 const char *blurb;
12096 char width[5];
12097
12098 len = gpa_hfinfo.len;
12099 for (i = 0; i < len ; i++) {
12100 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12101 continue; /* This is a deregistered protocol or header field */
12102
12103 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", 12103
, __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", 12103
, "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", 12103, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12104
12105 /*
12106 * Skip the pseudo-field for "proto_tree_add_text()" since
12107 * we don't want it in the list of filterable fields.
12108 */
12109 if (hfinfo->id == hf_text_only)
12110 continue;
12111
12112 /* format for protocols */
12113 if (proto_registrar_is_protocol(i)) {
12114 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12115 }
12116 /* format for header fields */
12117 else {
12118 /*
12119 * If this field isn't at the head of the list of
12120 * fields with this name, skip this field - all
12121 * fields with the same name are really just versions
12122 * of the same field stored in different bits, and
12123 * should have the same type/radix/value list, and
12124 * just differ in their bit masks. (If a field isn't
12125 * a bitfield, but can be, say, 1 or 2 bytes long,
12126 * it can just be made FT_UINT16, meaning the
12127 * *maximum* length is 2 bytes, and be used
12128 * for all lengths.)
12129 */
12130 if (hfinfo->same_name_prev_id != -1)
12131 continue;
12132
12133 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", 12133
, __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", 12133
, "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", 12133
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12134
12135 enum_name = ftype_name(hfinfo->type);
12136 base_name = "";
12137
12138 if (hfinfo->type == FT_CHAR ||
12139 hfinfo->type == FT_UINT8 ||
12140 hfinfo->type == FT_UINT16 ||
12141 hfinfo->type == FT_UINT24 ||
12142 hfinfo->type == FT_UINT32 ||
12143 hfinfo->type == FT_UINT40 ||
12144 hfinfo->type == FT_UINT48 ||
12145 hfinfo->type == FT_UINT56 ||
12146 hfinfo->type == FT_UINT64 ||
12147 hfinfo->type == FT_INT8 ||
12148 hfinfo->type == FT_INT16 ||
12149 hfinfo->type == FT_INT24 ||
12150 hfinfo->type == FT_INT32 ||
12151 hfinfo->type == FT_INT40 ||
12152 hfinfo->type == FT_INT48 ||
12153 hfinfo->type == FT_INT56 ||
12154 hfinfo->type == FT_INT64) {
12155
12156 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12157 case BASE_NONE:
12158 case BASE_DEC:
12159 case BASE_HEX:
12160 case BASE_OCT:
12161 case BASE_DEC_HEX:
12162 case BASE_HEX_DEC:
12163 case BASE_CUSTOM:
12164 case BASE_PT_UDP:
12165 case BASE_PT_TCP:
12166 case BASE_PT_DCCP:
12167 case BASE_PT_SCTP:
12168 case BASE_OUI:
12169 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12170 break;
12171 default:
12172 base_name = "????";
12173 break;
12174 }
12175 } else if (hfinfo->type == FT_BOOLEAN) {
12176 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12177 snprintf(width, sizeof(width), "%d", hfinfo->display);
12178 base_name = width;
12179 }
12180
12181 blurb = hfinfo->blurb;
12182 if (blurb == NULL((void*)0))
12183 blurb = "";
12184 else if (strlen(blurb) == 0)
12185 blurb = "\"\"";
12186
12187 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12188 hfinfo->name, hfinfo->abbrev, enum_name,
12189 parent_hfinfo->abbrev, base_name,
12190 hfinfo->bitmask, blurb);
12191 }
12192 }
12193}
12194
12195/* Dumps all abbreviated field and protocol completions of the given string to
12196 * stdout. An independent program may use this for command-line tab completion
12197 * of fields.
12198 */
12199bool_Bool
12200proto_registrar_dump_field_completions(const char *prefix)
12201{
12202 header_field_info *hfinfo;
12203 int i, len;
12204 size_t prefix_len;
12205 bool_Bool matched = false0;
12206
12207 prefix_len = strlen(prefix);
12208 len = gpa_hfinfo.len;
12209 for (i = 0; i < len ; i++) {
12210 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12211 continue; /* This is a deregistered protocol or header field */
12212
12213 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", 12213
, __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", 12213
, "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", 12213, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12214
12215 /*
12216 * Skip the pseudo-field for "proto_tree_add_text()" since
12217 * we don't want it in the list of filterable fields.
12218 */
12219 if (hfinfo->id == hf_text_only)
12220 continue;
12221
12222 /* format for protocols */
12223 if (proto_registrar_is_protocol(i)) {
12224 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12225 matched = true1;
12226 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12227 }
12228 }
12229 /* format for header fields */
12230 else {
12231 /*
12232 * If this field isn't at the head of the list of
12233 * fields with this name, skip this field - all
12234 * fields with the same name are really just versions
12235 * of the same field stored in different bits, and
12236 * should have the same type/radix/value list, and
12237 * just differ in their bit masks. (If a field isn't
12238 * a bitfield, but can be, say, 1 or 2 bytes long,
12239 * it can just be made FT_UINT16, meaning the
12240 * *maximum* length is 2 bytes, and be used
12241 * for all lengths.)
12242 */
12243 if (hfinfo->same_name_prev_id != -1)
12244 continue;
12245
12246 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12247 matched = true1;
12248 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12249 }
12250 }
12251 }
12252 return matched;
12253}
12254
12255/* Dumps field types and descriptive names to stdout. An independent
12256 * program can take this output and format it into nice tables or HTML or
12257 * whatever.
12258 *
12259 * There is one record per line. The fields are tab-delimited.
12260 *
12261 * Field 1 = field type name, e.g. FT_UINT8
12262 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12263 */
12264void
12265proto_registrar_dump_ftypes(void)
12266{
12267 int fte;
12268
12269 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12270 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12271 }
12272}
12273
12274/* This function indicates whether it's possible to construct a
12275 * "match selected" display filter string for the specified field,
12276 * returns an indication of whether it's possible, and, if it's
12277 * possible and "filter" is non-null, constructs the filter and
12278 * sets "*filter" to point to it.
12279 * You do not need to [g_]free() this string since it will be automatically
12280 * freed once the next packet is dissected.
12281 */
12282static bool_Bool
12283construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12284 char **filter)
12285{
12286 const header_field_info *hfinfo;
12287 char *ptr;
12288 int buf_len;
12289 int i;
12290 int start, length, length_remaining;
12291 uint8_t c;
12292
12293 if (!finfo)
12294 return false0;
12295
12296 hfinfo = finfo->hfinfo;
12297 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12297, "hfinfo"))))
;
12298
12299 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12300 * then "the numeric value ... is not used when preparing
12301 * filters for the field in question." If it's any other
12302 * base, we'll generate the filter normally (which will
12303 * be numeric, even though the human-readable string does
12304 * work for filtering.)
12305 *
12306 * XXX - It might be nice to use fvalue_to_string_repr() in
12307 * "proto_item_fill_label()" as well, although, there, you'd
12308 * have to deal with the base *and* with resolved values for
12309 * addresses.
12310 *
12311 * Perhaps in addition to taking the repr type (DISPLAY
12312 * or DFILTER) and the display (base), fvalue_to_string_repr()
12313 * should have the the "strings" values in the header_field_info
12314 * structure for the field as a parameter, so it can have
12315 * if the field is Boolean or an enumerated integer type,
12316 * the tables used to generate human-readable values.
12317 */
12318 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12319 const char *str = NULL((void*)0);
12320
12321 switch (hfinfo->type) {
12322
12323 case FT_INT8:
12324 case FT_INT16:
12325 case FT_INT24:
12326 case FT_INT32:
12327 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12328 break;
12329
12330 case FT_CHAR:
12331 case FT_UINT8:
12332 case FT_UINT16:
12333 case FT_UINT24:
12334 case FT_UINT32:
12335 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12336 break;
12337
12338 default:
12339 break;
12340 }
12341
12342 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12343 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12344 return true1;
12345 }
12346 }
12347
12348 switch (hfinfo->type) {
12349
12350 case FT_PROTOCOL:
12351 if (filter != NULL((void*)0))
12352 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12353 break;
12354
12355 case FT_NONE:
12356 /*
12357 * If the length is 0, just match the name of the
12358 * field.
12359 *
12360 * (Also check for negative values, just in case,
12361 * as we'll cast it to an unsigned value later.)
12362 */
12363 length = finfo->length;
12364 if (length == 0) {
12365 if (filter != NULL((void*)0))
12366 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12367 break;
12368 }
12369 if (length < 0)
12370 return false0;
12371
12372 /*
12373 * This doesn't have a value, so we'd match
12374 * on the raw bytes at this address.
12375 *
12376 * Should we be allowed to access to the raw bytes?
12377 * If "edt" is NULL, the answer is "no".
12378 */
12379 if (edt == NULL((void*)0))
12380 return false0;
12381
12382 /*
12383 * Is this field part of the raw frame tvbuff?
12384 * If not, we can't use "frame[N:M]" to match
12385 * it.
12386 *
12387 * XXX - should this be frame-relative, or
12388 * protocol-relative?
12389 *
12390 * XXX - does this fallback for non-registered
12391 * fields even make sense?
12392 */
12393 if (finfo->ds_tvb != edt->tvb)
12394 return false0; /* you lose */
12395
12396 /*
12397 * Don't go past the end of that tvbuff.
12398 */
12399 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12400 if (length > length_remaining)
12401 length = length_remaining;
12402 if (length <= 0)
12403 return false0;
12404
12405 if (filter != NULL((void*)0)) {
12406 start = finfo->start;
12407 buf_len = 32 + length * 3;
12408 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12409 ptr = *filter;
12410
12411 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12412 "frame[%d:%d] == ", finfo->start, length);
12413 for (i=0; i<length; i++) {
12414 c = tvb_get_uint8(finfo->ds_tvb, start);
12415 start++;
12416 if (i == 0 ) {
12417 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12418 }
12419 else {
12420 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12421 }
12422 }
12423 }
12424 break;
12425
12426 /* By default, use the fvalue's "to_string_repr" method. */
12427 default:
12428 if (filter != NULL((void*)0)) {
12429 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12430 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12431 wmem_free(NULL((void*)0), str);
12432 }
12433 break;
12434 }
12435
12436 return true1;
12437}
12438
12439/*
12440 * Returns true if we can do a "match selected" on the field, false
12441 * otherwise.
12442 */
12443bool_Bool
12444proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12445{
12446 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12447}
12448
12449/* This function attempts to construct a "match selected" display filter
12450 * string for the specified field; if it can do so, it returns a pointer
12451 * to the string, otherwise it returns NULL.
12452 *
12453 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12454 */
12455char *
12456proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12457{
12458 char *filter = NULL((void*)0);
12459
12460 if (!construct_match_selected_string(finfo, edt, &filter))
12461 {
12462 wmem_free(NULL((void*)0), filter);
12463 return NULL((void*)0);
12464 }
12465 return filter;
12466}
12467
12468/* This function is common code for all proto_tree_add_bitmask... functions.
12469 */
12470
12471static bool_Bool
12472proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12473 const int len, const int ett, int * const *fields,
12474 const int flags, bool_Bool first,
12475 bool_Bool use_parent_tree,
12476 proto_tree* tree, uint64_t value)
12477{
12478 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12479 uint64_t bitmask = 0;
12480 uint64_t tmpval;
12481 header_field_info *hf;
12482 uint32_t integer32;
12483 int bit_offset;
12484 int no_of_bits;
12485
12486 if (!*fields)
12487 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"
)
;
12488
12489 if (len < 0 || len > 8)
12490 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12491 /**
12492 * packet-frame.c uses len=0 since the value is taken from the packet
12493 * metadata, not the packet bytes. In that case, assume that all bits
12494 * in the provided value are valid.
12495 */
12496 if (len > 0) {
12497 available_bits >>= (8 - (unsigned)len)*8;
12498 }
12499
12500 if (use_parent_tree == false0)
12501 tree = proto_item_add_subtree(item, ett);
12502
12503 while (*fields) {
12504 uint64_t present_bits;
12505 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", 12505, __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", 12505
, "**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", 12505, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12506 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", 12506
, "hf->bitmask != 0", hf->abbrev))))
;
12507
12508 bitmask |= hf->bitmask;
12509
12510 /* Skip fields that aren't fully present */
12511 present_bits = available_bits & hf->bitmask;
12512 if (present_bits != hf->bitmask) {
12513 fields++;
12514 continue;
12515 }
12516
12517 switch (hf->type) {
12518 case FT_CHAR:
12519 case FT_UINT8:
12520 case FT_UINT16:
12521 case FT_UINT24:
12522 case FT_UINT32:
12523 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12524 break;
12525
12526 case FT_INT8:
12527 case FT_INT16:
12528 case FT_INT24:
12529 case FT_INT32:
12530 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12531 break;
12532
12533 case FT_UINT40:
12534 case FT_UINT48:
12535 case FT_UINT56:
12536 case FT_UINT64:
12537 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12538 break;
12539
12540 case FT_INT40:
12541 case FT_INT48:
12542 case FT_INT56:
12543 case FT_INT64:
12544 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12545 break;
12546
12547 case FT_BOOLEAN:
12548 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12549 break;
12550
12551 default:
12552 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))
12553 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))
12554 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))
12555 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))
;
12556 break;
12557 }
12558 if (flags & BMT_NO_APPEND0x01) {
12559 fields++;
12560 continue;
12561 }
12562 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12563
12564 /* XXX: README.developer and the comments have always defined
12565 * BMT_NO_INT as "only boolean flags are added to the title /
12566 * don't add non-boolean (integral) fields", but the
12567 * implementation has always added BASE_CUSTOM and fields with
12568 * value_strings, though not fields with unit_strings.
12569 * Possibly this is because some dissectors use a FT_UINT8
12570 * with a value_string for fields that should be a FT_BOOLEAN.
12571 */
12572 switch (hf->type) {
12573 case FT_CHAR:
12574 if (hf->display == BASE_CUSTOM) {
12575 char lbl[ITEM_LABEL_LENGTH240];
12576 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12577
12578 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12578, "fmtfunc"))))
;
12579 fmtfunc(lbl, (uint32_t) tmpval);
12580 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12581 hf->name, lbl);
12582 first = false0;
12583 }
12584 else if (hf->strings) {
12585 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12586 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12587 first = false0;
12588 }
12589 else if (!(flags & BMT_NO_INT0x02)) {
12590 char buf[32];
12591 const char *out;
12592
12593 if (!first) {
12594 proto_item_append_text(item, ", ");
12595 }
12596
12597 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12598 proto_item_append_text(item, "%s: %s", hf->name, out);
12599 first = false0;
12600 }
12601
12602 break;
12603
12604 case FT_UINT8:
12605 case FT_UINT16:
12606 case FT_UINT24:
12607 case FT_UINT32:
12608 if (hf->display == BASE_CUSTOM) {
12609 char lbl[ITEM_LABEL_LENGTH240];
12610 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12611
12612 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12612, "fmtfunc"))))
;
12613 fmtfunc(lbl, (uint32_t) tmpval);
12614 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12615 hf->name, lbl);
12616 first = false0;
12617 }
12618 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12619 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12620 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12621 first = false0;
12622 }
12623 else if (!(flags & BMT_NO_INT0x02)) {
12624 char buf[NUMBER_LABEL_LENGTH80];
12625 const char *out = NULL((void*)0);
12626
12627 if (!first) {
12628 proto_item_append_text(item, ", ");
12629 }
12630
12631 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12632 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12633 }
12634 if (out == NULL((void*)0)) {
12635 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12636 }
12637 proto_item_append_text(item, "%s: %s", hf->name, out);
12638 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12639 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12640 }
12641 first = false0;
12642 }
12643
12644 break;
12645
12646 case FT_INT8:
12647 case FT_INT16:
12648 case FT_INT24:
12649 case FT_INT32:
12650 integer32 = (uint32_t) tmpval;
12651 if (hf->bitmask) {
12652 no_of_bits = ws_count_ones(hf->bitmask);
12653 integer32 = ws_sign_ext32(integer32, no_of_bits);
12654 }
12655 if (hf->display == BASE_CUSTOM) {
12656 char lbl[ITEM_LABEL_LENGTH240];
12657 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12658
12659 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12659, "fmtfunc"))))
;
12660 fmtfunc(lbl, (int32_t) integer32);
12661 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12662 hf->name, lbl);
12663 first = false0;
12664 }
12665 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12666 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12667 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12668 first = false0;
12669 }
12670 else if (!(flags & BMT_NO_INT0x02)) {
12671 char buf[NUMBER_LABEL_LENGTH80];
12672 const char *out = NULL((void*)0);
12673
12674 if (!first) {
12675 proto_item_append_text(item, ", ");
12676 }
12677
12678 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12679 out = hf_try_val_to_str((int32_t) integer32, hf);
12680 }
12681 if (out == NULL((void*)0)) {
12682 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12683 }
12684 proto_item_append_text(item, "%s: %s", hf->name, out);
12685 if (hf->display & BASE_UNIT_STRING0x00001000) {
12686 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12687 }
12688 first = false0;
12689 }
12690
12691 break;
12692
12693 case FT_UINT40:
12694 case FT_UINT48:
12695 case FT_UINT56:
12696 case FT_UINT64:
12697 if (hf->display == BASE_CUSTOM) {
12698 char lbl[ITEM_LABEL_LENGTH240];
12699 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12700
12701 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12701, "fmtfunc"))))
;
12702 fmtfunc(lbl, tmpval);
12703 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12704 hf->name, lbl);
12705 first = false0;
12706 }
12707 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12708 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12709 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12710 first = false0;
12711 }
12712 else if (!(flags & BMT_NO_INT0x02)) {
12713 char buf[NUMBER_LABEL_LENGTH80];
12714 const char *out = NULL((void*)0);
12715
12716 if (!first) {
12717 proto_item_append_text(item, ", ");
12718 }
12719
12720 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12721 out = hf_try_val64_to_str(tmpval, hf);
12722 }
12723 if (out == NULL((void*)0)) {
12724 out = hfinfo_number_value_format64(hf, buf, tmpval);
12725 }
12726 proto_item_append_text(item, "%s: %s", hf->name, out);
12727 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12728 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12729 }
12730 first = false0;
12731 }
12732
12733 break;
12734
12735 case FT_INT40:
12736 case FT_INT48:
12737 case FT_INT56:
12738 case FT_INT64:
12739 if (hf->bitmask) {
12740 no_of_bits = ws_count_ones(hf->bitmask);
12741 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12742 }
12743 if (hf->display == BASE_CUSTOM) {
12744 char lbl[ITEM_LABEL_LENGTH240];
12745 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12746
12747 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12747, "fmtfunc"))))
;
12748 fmtfunc(lbl, (int64_t) tmpval);
12749 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12750 hf->name, lbl);
12751 first = false0;
12752 }
12753 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12754 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12755 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12756 first = false0;
12757 }
12758 else if (!(flags & BMT_NO_INT0x02)) {
12759 char buf[NUMBER_LABEL_LENGTH80];
12760 const char *out = NULL((void*)0);
12761
12762 if (!first) {
12763 proto_item_append_text(item, ", ");
12764 }
12765
12766 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12767 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12768 }
12769 if (out == NULL((void*)0)) {
12770 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12771 }
12772 proto_item_append_text(item, "%s: %s", hf->name, out);
12773 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12774 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12775 }
12776 first = false0;
12777 }
12778
12779 break;
12780
12781 case FT_BOOLEAN:
12782 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12783 /* If we have true/false strings, emit full - otherwise messages
12784 might look weird */
12785 const struct true_false_string *tfs =
12786 (const struct true_false_string *)hf->strings;
12787
12788 if (tmpval) {
12789 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12790 hf->name, tfs->true_string);
12791 first = false0;
12792 } else if (!(flags & BMT_NO_FALSE0x04)) {
12793 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12794 hf->name, tfs->false_string);
12795 first = false0;
12796 }
12797 } else if (hf->bitmask & value) {
12798 /* If the flag is set, show the name */
12799 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12800 first = false0;
12801 }
12802 break;
12803 default:
12804 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))
12805 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))
12806 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))
12807 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))
;
12808 break;
12809 }
12810
12811 fields++;
12812 }
12813
12814 /* XXX: We don't pass the hfi into this function. Perhaps we should,
12815 * but then again most dissectors don't set the bitmask field for
12816 * the higher level bitmask hfi, so calculate the bitmask from the
12817 * fields present. */
12818 if (item) {
12819 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
12820 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
12821 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)
;
12822 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)
;
12823 }
12824 return first;
12825}
12826
12827/* This function will dissect a sequence of bytes that describe a
12828 * bitmask and supply the value of that sequence through a pointer.
12829 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12830 * to be dissected.
12831 * This field will form an expansion under which the individual fields of the
12832 * bitmask is dissected and displayed.
12833 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12834 *
12835 * fields is an array of pointers to int that lists all the fields of the
12836 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12837 * or another integer of the same type/size as hf_hdr with a mask specified.
12838 * This array is terminated by a NULL entry.
12839 *
12840 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12841 * FT_integer fields that have a value_string attached will have the
12842 * matched string displayed on the expansion line.
12843 */
12844proto_item *
12845proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
12846 const unsigned offset, const int hf_hdr,
12847 const int ett, int * const *fields,
12848 const unsigned encoding, uint64_t *retval)
12849{
12850 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);
12851}
12852
12853/* This function will dissect a sequence of bytes that describe a
12854 * bitmask.
12855 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12856 * to be dissected.
12857 * This field will form an expansion under which the individual fields of the
12858 * bitmask is dissected and displayed.
12859 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12860 *
12861 * fields is an array of pointers to int that lists all the fields of the
12862 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12863 * or another integer of the same type/size as hf_hdr with a mask specified.
12864 * This array is terminated by a NULL entry.
12865 *
12866 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12867 * FT_integer fields that have a value_string attached will have the
12868 * matched string displayed on the expansion line.
12869 */
12870proto_item *
12871proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
12872 const unsigned offset, const int hf_hdr,
12873 const int ett, int * const *fields,
12874 const unsigned encoding)
12875{
12876 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
12877}
12878
12879/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12880 * what data is appended to the header.
12881 */
12882proto_item *
12883proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12884 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
12885 uint64_t *retval)
12886{
12887 proto_item *item = NULL((void*)0);
12888 header_field_info *hf;
12889 int len;
12890 uint64_t value;
12891
12892 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", 12892, __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", 12892
, "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", 12892, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12893 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", 12893, (hf)->abbrev)))
;
12894 len = ftype_wire_size(hf->type);
12895 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12896
12897 if (parent_tree) {
12898 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12899 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12900 flags, false0, false0, NULL((void*)0), value);
12901 }
12902
12903 *retval = value;
12904 if (hf->bitmask) {
12905 /* Mask out irrelevant portions */
12906 *retval &= hf->bitmask;
12907 /* Shift bits */
12908 *retval >>= hfinfo_bitshift(hf);
12909 }
12910
12911 return item;
12912}
12913
12914/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12915 * what data is appended to the header.
12916 */
12917proto_item *
12918proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12919 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
12920{
12921 proto_item *item = NULL((void*)0);
12922 header_field_info *hf;
12923 int len;
12924 uint64_t value;
12925
12926 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", 12926, __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", 12926
, "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", 12926, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12927 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", 12927, (hf)->abbrev)))
;
12928
12929 if (parent_tree) {
12930 len = ftype_wire_size(hf->type);
12931 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12932 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12933 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12934 flags, false0, false0, NULL((void*)0), value);
12935 }
12936
12937 return item;
12938}
12939
12940/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
12941 can't be retrieved directly from tvb) */
12942proto_item *
12943proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12944 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
12945{
12946 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
12947 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
12948}
12949
12950/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
12951WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
12952proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12953 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
12954{
12955 proto_item *item = NULL((void*)0);
12956 header_field_info *hf;
12957 int len;
12958
12959 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", 12959, __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", 12959
, "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", 12959, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12960 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", 12960, (hf)->abbrev)))
;
12961 /* the proto_tree_add_uint/_uint64() calls below
12962 will fail if tvb==NULL and len!=0 */
12963 len = tvb ? ftype_wire_size(hf->type) : 0;
12964
12965 if (parent_tree) {
12966 if (len <= 4)
12967 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
12968 else
12969 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
12970
12971 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12972 flags, false0, false0, NULL((void*)0), value);
12973 }
12974
12975 return item;
12976}
12977
12978/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
12979void
12980proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
12981 const int len, int * const *fields, const unsigned encoding)
12982{
12983 uint64_t value;
12984
12985 if (tree) {
12986 value = get_uint64_value(tree, tvb, offset, len, encoding);
12987 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
12988 BMT_NO_APPEND0x01, false0, true1, tree, value);
12989 }
12990}
12991
12992WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
12993proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
12994 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
12995{
12996 uint64_t value;
12997
12998 value = get_uint64_value(tree, tvb, offset, len, encoding);
12999 if (tree) {
13000 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13001 BMT_NO_APPEND0x01, false0, true1, tree, value);
13002 }
13003 if (retval) {
13004 *retval = value;
13005 }
13006}
13007
13008WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13009proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13010 const int len, int * const *fields, const uint64_t value)
13011{
13012 if (tree) {
13013 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13014 BMT_NO_APPEND0x01, false0, true1, tree, value);
13015 }
13016}
13017
13018
13019/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13020 * This is intended to support bitmask fields whose lengths can vary, perhaps
13021 * as the underlying standard evolves over time.
13022 * With this API there is the possibility of being called to display more or
13023 * less data than the dissector was coded to support.
13024 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13025 * Thus when presented with "too much" or "too little" data, MSbits will be
13026 * ignored or MSfields sacrificed.
13027 *
13028 * Only fields for which all defined bits are available are displayed.
13029 */
13030proto_item *
13031proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13032 const unsigned offset, const unsigned len, const int hf_hdr,
13033 const int ett, int * const *fields, struct expert_field* exp,
13034 const unsigned encoding)
13035{
13036 proto_item *item = NULL((void*)0);
13037 header_field_info *hf;
13038 unsigned decodable_len;
13039 unsigned decodable_offset;
13040 uint32_t decodable_value;
13041 uint64_t value;
13042
13043 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", 13043, __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", 13043
, "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", 13043, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13044 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", 13044, (hf)->abbrev)))
;
13045
13046 decodable_offset = offset;
13047 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13048
13049 /* If we are ftype_wire_size-limited,
13050 * make sure we decode as many LSBs as possible.
13051 */
13052 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13053 decodable_offset += (len - decodable_len);
13054 }
13055
13056 if (parent_tree) {
13057 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13058 decodable_len, encoding);
13059
13060 /* The root item covers all the bytes even if we can't decode them all */
13061 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13062 decodable_value);
13063 }
13064
13065 if (decodable_len < len) {
13066 /* Dissector likely requires updating for new protocol revision */
13067 expert_add_info_format(NULL((void*)0), item, exp,
13068 "Only least-significant %d of %d bytes decoded",
13069 decodable_len, len);
13070 }
13071
13072 if (item) {
13073 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13074 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13075 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13076 }
13077
13078 return item;
13079}
13080
13081/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13082proto_item *
13083proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13084 const unsigned offset, const unsigned len,
13085 const char *name, const char *fallback,
13086 const int ett, int * const *fields,
13087 const unsigned encoding, const int flags)
13088{
13089 proto_item *item = NULL((void*)0);
13090 uint64_t value;
13091
13092 if (parent_tree) {
13093 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13094 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13095 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13096 flags, true1, false0, NULL((void*)0), value) && fallback) {
13097 /* Still at first item - append 'fallback' text if any */
13098 proto_item_append_text(item, "%s", fallback);
13099 }
13100 }
13101
13102 return item;
13103}
13104
13105proto_item *
13106proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13107 const unsigned bit_offset, const int no_of_bits,
13108 const unsigned encoding)
13109{
13110 header_field_info *hfinfo;
13111 int octet_length;
13112 int octet_offset;
13113
13114 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", 13114, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13114
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13114, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13115
13116 if (no_of_bits < 0) {
13117 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13118 }
13119 octet_length = (no_of_bits + 7) >> 3;
13120 octet_offset = bit_offset >> 3;
13121 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13122
13123 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13124 * but only after doing a bunch more work (which we can, in the common
13125 * case, shortcut here).
13126 */
13127 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13128 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", 13128
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13128, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13128, "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", 13128, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13129
13130 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13131}
13132
13133/*
13134 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13135 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13136 * Offset should be given in bits from the start of the tvb.
13137 */
13138
13139static proto_item *
13140_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13141 const unsigned bit_offset, const int no_of_bits,
13142 uint64_t *return_value, const unsigned encoding)
13143{
13144 int offset;
13145 unsigned length;
13146 uint8_t tot_no_bits;
13147 char *bf_str;
13148 char lbl_str[ITEM_LABEL_LENGTH240];
13149 uint64_t value = 0;
13150 uint8_t *bytes = NULL((void*)0);
13151 size_t bytes_length = 0;
13152
13153 proto_item *pi;
13154 header_field_info *hf_field;
13155
13156 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13157 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", 13157, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13157
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13157, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13158
13159 if (hf_field->bitmask != 0) {
13160 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)
13161 " 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)
13162 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)
;
13163 }
13164
13165 if (no_of_bits < 0) {
13166 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13167 } else if (no_of_bits == 0) {
13168 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)
13169 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)
;
13170 }
13171
13172 /* Byte align offset */
13173 offset = bit_offset>>3;
13174
13175 /*
13176 * Calculate the number of octets used to hold the bits
13177 */
13178 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13179 length = (tot_no_bits + 7) >> 3;
13180
13181 if (no_of_bits < 65) {
13182 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13183 } else if (hf_field->type != FT_BYTES) {
13184 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)
13185 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)
;
13186 return NULL((void*)0);
13187 }
13188
13189 /* Sign extend for signed types */
13190 switch (hf_field->type) {
13191 case FT_INT8:
13192 case FT_INT16:
13193 case FT_INT24:
13194 case FT_INT32:
13195 case FT_INT40:
13196 case FT_INT48:
13197 case FT_INT56:
13198 case FT_INT64:
13199 value = ws_sign_ext64(value, no_of_bits);
13200 break;
13201
13202 default:
13203 break;
13204 }
13205
13206 if (return_value) {
13207 *return_value = value;
13208 }
13209
13210 /* Coast clear. Try and fake it */
13211 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13212 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", 13212
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13212, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13212, "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", 13212, __func__, "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); } } }
;
13213
13214 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13215
13216 switch (hf_field->type) {
13217 case FT_BOOLEAN:
13218 /* Boolean field */
13219 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13220 "%s = %s: %s",
13221 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13222 break;
13223
13224 case FT_CHAR:
13225 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13226 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13227 break;
13228
13229 case FT_UINT8:
13230 case FT_UINT16:
13231 case FT_UINT24:
13232 case FT_UINT32:
13233 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13234 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13235 break;
13236
13237 case FT_INT8:
13238 case FT_INT16:
13239 case FT_INT24:
13240 case FT_INT32:
13241 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13242 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13243 break;
13244
13245 case FT_UINT40:
13246 case FT_UINT48:
13247 case FT_UINT56:
13248 case FT_UINT64:
13249 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13250 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13251 break;
13252
13253 case FT_INT40:
13254 case FT_INT48:
13255 case FT_INT56:
13256 case FT_INT64:
13257 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13258 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13259 break;
13260
13261 case FT_BYTES:
13262 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13263 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13264 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13265 proto_item_set_text(pi, "%s", lbl_str);
13266 return pi;
13267
13268 /* TODO: should handle FT_UINT_BYTES ? */
13269
13270 default:
13271 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))
13272 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))
13273 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))
13274 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))
;
13275 return NULL((void*)0);
13276 }
13277
13278 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13279 return pi;
13280}
13281
13282proto_item *
13283proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13284 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13285 uint64_t *return_value)
13286{
13287 proto_item *pi;
13288 int no_of_bits;
13289 int octet_offset;
13290 unsigned mask_initial_bit_offset;
13291 unsigned mask_greatest_bit_offset;
13292 unsigned octet_length;
13293 uint8_t i;
13294 char bf_str[256];
13295 char lbl_str[ITEM_LABEL_LENGTH240];
13296 uint64_t value;
13297 uint64_t composite_bitmask;
13298 uint64_t composite_bitmap;
13299
13300 header_field_info *hf_field;
13301
13302 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13303 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", 13303, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13303
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13303, "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
13304
13305 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13306 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)
13307 " 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)
13308 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)
;
13309 }
13310
13311 mask_initial_bit_offset = bit_offset % 8;
13312
13313 no_of_bits = 0;
13314 value = 0;
13315 i = 0;
13316 mask_greatest_bit_offset = 0;
13317 composite_bitmask = 0;
13318 composite_bitmap = 0;
13319
13320 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
13321 uint64_t crumb_mask, crumb_value;
13322 uint8_t crumb_end_bit_offset;
13323
13324 crumb_value = tvb_get_bits64(tvb,
13325 bit_offset + crumb_spec[i].crumb_bit_offset,
13326 crumb_spec[i].crumb_bit_length,
13327 ENC_BIG_ENDIAN0x00000000);
13328 value += crumb_value;
13329 no_of_bits += crumb_spec[i].crumb_bit_length;
13330 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", 13330
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13331
13332 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13333 octet containing the initial offset.
13334 If the mask is beyond 32 bits, then give up on bit map display.
13335 This could be improved in future, probably showing a table
13336 of 32 or 64 bits per row */
13337 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13338 crumb_end_bit_offset = mask_initial_bit_offset
13339 + crumb_spec[i].crumb_bit_offset
13340 + crumb_spec[i].crumb_bit_length;
13341 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'
13342
13343 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13344 mask_greatest_bit_offset = crumb_end_bit_offset;
13345 }
13346 /* Currently the bitmap of the crumbs are only shown if
13347 * smaller than 32 bits. Do not bother calculating the
13348 * mask if it is larger than that. */
13349 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13350 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'
13351 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13352 }
13353 }
13354 /* Shift left for the next segment */
13355 value <<= crumb_spec[++i].crumb_bit_length;
13356 }
13357
13358 /* Sign extend for signed types */
13359 switch (hf_field->type) {
13360 case FT_INT8:
13361 case FT_INT16:
13362 case FT_INT24:
13363 case FT_INT32:
13364 case FT_INT40:
13365 case FT_INT48:
13366 case FT_INT56:
13367 case FT_INT64:
13368 value = ws_sign_ext64(value, no_of_bits);
13369 break;
13370 default:
13371 break;
13372 }
13373
13374 if (return_value) {
13375 *return_value = value;
13376 }
13377
13378 /* Coast clear. Try and fake it */
13379 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13380 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", 13380
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13380, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13380, "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", 13380, __func__, "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); } } }
;
13381
13382 /* initialise the format string */
13383 bf_str[0] = '\0';
13384
13385 octet_offset = bit_offset >> 3;
13386
13387 /* Round up mask length to nearest octet */
13388 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13389 mask_greatest_bit_offset = octet_length << 3;
13390
13391 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13392 It would be a useful enhancement to eliminate this restriction. */
13393 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13394 other_decode_bitfield_value(bf_str,
13395 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13396 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13397 mask_greatest_bit_offset);
13398 } else {
13399 /* If the bitmask is too large, try to describe its contents. */
13400 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13401 }
13402
13403 switch (hf_field->type) {
13404 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13405 /* Boolean field */
13406 return proto_tree_add_boolean_format(tree, hfindex,
13407 tvb, octet_offset, octet_length, value,
13408 "%s = %s: %s",
13409 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13410 break;
13411
13412 case FT_CHAR:
13413 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13414 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13415 break;
13416
13417 case FT_UINT8:
13418 case FT_UINT16:
13419 case FT_UINT24:
13420 case FT_UINT32:
13421 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13422 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13423 break;
13424
13425 case FT_INT8:
13426 case FT_INT16:
13427 case FT_INT24:
13428 case FT_INT32:
13429 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13430 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13431 break;
13432
13433 case FT_UINT40:
13434 case FT_UINT48:
13435 case FT_UINT56:
13436 case FT_UINT64:
13437 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13438 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13439 break;
13440
13441 case FT_INT40:
13442 case FT_INT48:
13443 case FT_INT56:
13444 case FT_INT64:
13445 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13446 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13447 break;
13448
13449 default:
13450 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))
13451 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))
13452 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))
13453 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))
;
13454 return NULL((void*)0);
13455 }
13456 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13457 return pi;
13458}
13459
13460void
13461proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13462 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13463{
13464 header_field_info *hfinfo;
13465 int start = bit_offset >> 3;
13466 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13467
13468 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13469 * so that we can use the tree's memory scope in calculating the string */
13470 if (length == -1) {
13471 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13472 } else {
13473 tvb_ensure_bytes_exist(tvb, start, length);
13474 }
13475 if (!tree) return;
13476
13477 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", 13477, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13477
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13477, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13478 proto_tree_add_text_internal(tree, tvb, start, length,
13479 "%s crumb %d of %s (decoded above)",
13480 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13481 tvb_get_bits(tvb,
13482 bit_offset,
13483 crumb_spec[crumb_index].crumb_bit_length,
13484 ENC_BIG_ENDIAN0x00000000),
13485 ENC_BIG_ENDIAN0x00000000),
13486 crumb_index,
13487 hfinfo->name);
13488}
13489
13490proto_item *
13491proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13492 const unsigned bit_offset, const int no_of_bits,
13493 uint64_t *return_value, const unsigned encoding)
13494{
13495 proto_item *item;
13496
13497 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13498 bit_offset, no_of_bits,
13499 return_value, encoding))) {
13500 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)
;
13501 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)
;
13502 }
13503 return item;
13504}
13505
13506static proto_item *
13507_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13508 tvbuff_t *tvb, const unsigned bit_offset,
13509 const int no_of_bits, void *value_ptr,
13510 const unsigned encoding, char *value_str)
13511{
13512 int offset;
13513 unsigned length;
13514 uint8_t tot_no_bits;
13515 char *str;
13516 uint64_t value = 0;
13517 header_field_info *hf_field;
13518
13519 /* We do not have to return a value, try to fake it as soon as possible */
13520 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13521 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", 13521
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13521, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13521, "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", 13521, __func__, "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); } } }
;
13522
13523 if (hf_field->bitmask != 0) {
13524 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)
13525 " 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)
13526 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)
;
13527 }
13528
13529 if (no_of_bits < 0) {
13530 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13531 } else if (no_of_bits == 0) {
13532 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)
13533 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)
;
13534 }
13535
13536 /* Byte align offset */
13537 offset = bit_offset>>3;
13538
13539 /*
13540 * Calculate the number of octets used to hold the bits
13541 */
13542 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13543 length = tot_no_bits>>3;
13544 /* If we are using part of the next octet, increase length by 1 */
13545 if (tot_no_bits & 0x07)
13546 length++;
13547
13548 if (no_of_bits < 65) {
13549 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13550 } else {
13551 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)
13552 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)
;
13553 return NULL((void*)0);
13554 }
13555
13556 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13557
13558 (void) g_strlcat(str, " = ", 256+64);
13559 (void) g_strlcat(str, hf_field->name, 256+64);
13560
13561 /*
13562 * This function does not receive an actual value but a dimensionless pointer to that value.
13563 * For this reason, the type of the header field is examined in order to determine
13564 * what kind of value we should read from this address.
13565 * The caller of this function must make sure that for the specific header field type the address of
13566 * a compatible value is provided.
13567 */
13568 switch (hf_field->type) {
13569 case FT_BOOLEAN:
13570 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13571 "%s: %s", str, value_str);
13572 break;
13573
13574 case FT_CHAR:
13575 case FT_UINT8:
13576 case FT_UINT16:
13577 case FT_UINT24:
13578 case FT_UINT32:
13579 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13580 "%s: %s", str, value_str);
13581 break;
13582
13583 case FT_UINT40:
13584 case FT_UINT48:
13585 case FT_UINT56:
13586 case FT_UINT64:
13587 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13588 "%s: %s", str, value_str);
13589 break;
13590
13591 case FT_INT8:
13592 case FT_INT16:
13593 case FT_INT24:
13594 case FT_INT32:
13595 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13596 "%s: %s", str, value_str);
13597 break;
13598
13599 case FT_INT40:
13600 case FT_INT48:
13601 case FT_INT56:
13602 case FT_INT64:
13603 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13604 "%s: %s", str, value_str);
13605 break;
13606
13607 case FT_FLOAT:
13608 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13609 "%s: %s", str, value_str);
13610 break;
13611
13612 default:
13613 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))
13614 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))
13615 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))
13616 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))
;
13617 return NULL((void*)0);
13618 }
13619}
13620
13621static proto_item *
13622proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13623 tvbuff_t *tvb, const unsigned bit_offset,
13624 const int no_of_bits, void *value_ptr,
13625 const unsigned encoding, char *value_str)
13626{
13627 proto_item *item;
13628
13629 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13630 tvb, bit_offset, no_of_bits,
13631 value_ptr, encoding, value_str))) {
13632 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)
;
13633 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)
;
13634 }
13635 return item;
13636}
13637
13638#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);
\
13639 va_start(ap, format)__builtin_va_start(ap, format); \
13640 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13641 va_end(ap)__builtin_va_end(ap);
13642
13643proto_item *
13644proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13645 tvbuff_t *tvb, const unsigned bit_offset,
13646 const int no_of_bits, uint32_t value,
13647 const unsigned encoding,
13648 const char *format, ...)
13649{
13650 va_list ap;
13651 char *dst;
13652 header_field_info *hf_field;
13653
13654 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13655
13656 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", 13656
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13656, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13656, "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", 13656, __func__, "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); } } }
;
13657
13658 switch (hf_field->type) {
13659 case FT_UINT8:
13660 case FT_UINT16:
13661 case FT_UINT24:
13662 case FT_UINT32:
13663 break;
13664
13665 default:
13666 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)
13667 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)
;
13668 return NULL((void*)0);
13669 }
13670
13671 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);
;
13672
13673 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13674}
13675
13676proto_item *
13677proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13678 tvbuff_t *tvb, const unsigned bit_offset,
13679 const int no_of_bits, uint64_t value,
13680 const unsigned encoding,
13681 const char *format, ...)
13682{
13683 va_list ap;
13684 char *dst;
13685 header_field_info *hf_field;
13686
13687 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13688
13689 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", 13689
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13689, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13689, "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", 13689, __func__, "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); } } }
;
13690
13691 switch (hf_field->type) {
13692 case FT_UINT40:
13693 case FT_UINT48:
13694 case FT_UINT56:
13695 case FT_UINT64:
13696 break;
13697
13698 default:
13699 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)
13700 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)
;
13701 return NULL((void*)0);
13702 }
13703
13704 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);
;
13705
13706 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13707}
13708
13709proto_item *
13710proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13711 tvbuff_t *tvb, const unsigned bit_offset,
13712 const int no_of_bits, float value,
13713 const unsigned encoding,
13714 const char *format, ...)
13715{
13716 va_list ap;
13717 char *dst;
13718 header_field_info *hf_field;
13719
13720 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13721
13722 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", 13722
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13722, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13722, "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", 13722, __func__, "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); } } }
;
13723
13724 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",
13724, ((hf_field))->abbrev))))
;
13725
13726 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);
;
13727
13728 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13729}
13730
13731proto_item *
13732proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13733 tvbuff_t *tvb, const unsigned bit_offset,
13734 const int no_of_bits, int32_t value,
13735 const unsigned encoding,
13736 const char *format, ...)
13737{
13738 va_list ap;
13739 char *dst;
13740 header_field_info *hf_field;
13741
13742 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13743
13744 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", 13744
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13744, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13744, "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", 13744, __func__, "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); } } }
;
13745
13746 switch (hf_field->type) {
13747 case FT_INT8:
13748 case FT_INT16:
13749 case FT_INT24:
13750 case FT_INT32:
13751 break;
13752
13753 default:
13754 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)
13755 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)
;
13756 return NULL((void*)0);
13757 }
13758
13759 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);
;
13760
13761 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13762}
13763
13764proto_item *
13765proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13766 tvbuff_t *tvb, const unsigned bit_offset,
13767 const int no_of_bits, int64_t value,
13768 const unsigned encoding,
13769 const char *format, ...)
13770{
13771 va_list ap;
13772 char *dst;
13773 header_field_info *hf_field;
13774
13775 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13776
13777 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", 13777
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13777, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13777, "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", 13777, __func__, "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); } } }
;
13778
13779 switch (hf_field->type) {
13780 case FT_INT40:
13781 case FT_INT48:
13782 case FT_INT56:
13783 case FT_INT64:
13784 break;
13785
13786 default:
13787 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)
13788 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)
;
13789 return NULL((void*)0);
13790 }
13791
13792 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);
;
13793
13794 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13795}
13796
13797proto_item *
13798proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13799 tvbuff_t *tvb, const unsigned bit_offset,
13800 const int no_of_bits, uint64_t value,
13801 const unsigned encoding,
13802 const char *format, ...)
13803{
13804 va_list ap;
13805 char *dst;
13806 header_field_info *hf_field;
13807
13808 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13809
13810 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", 13810
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13810, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13810, "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", 13810, __func__, "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); } } }
;
13811
13812 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"
, 13812, ((hf_field))->abbrev))))
;
13813
13814 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);
;
13815
13816 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13817}
13818
13819proto_item *
13820proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13821 const unsigned bit_offset, const int no_of_chars)
13822{
13823 proto_item *pi;
13824 header_field_info *hfinfo;
13825 int byte_length;
13826 int byte_offset;
13827 char *string;
13828
13829 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13830
13831 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", 13831
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13831, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13831, "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", 13831, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13832
13833 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"
, 13833, ((hfinfo))->abbrev))))
;
13834
13835 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13836 byte_offset = bit_offset >> 3;
13837
13838 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13839
13840 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13841 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13841, "byte_length >= 0"
))))
;
13842 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13843
13844 return pi;
13845}
13846
13847proto_item *
13848proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13849 const unsigned bit_offset, const int no_of_chars)
13850{
13851 proto_item *pi;
13852 header_field_info *hfinfo;
13853 int byte_length;
13854 int byte_offset;
13855 char *string;
13856
13857 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13858
13859 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", 13859
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13859, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13859, "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", 13859, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
13860
13861 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"
, 13861, ((hfinfo))->abbrev))))
;
13862
13863 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13864 byte_offset = bit_offset >> 3;
13865
13866 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13867
13868 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13869 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13869, "byte_length >= 0"
))))
;
13870 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13871
13872 return pi;
13873}
13874
13875const value_string proto_checksum_vals[] = {
13876 { PROTO_CHECKSUM_E_BAD, "Bad" },
13877 { PROTO_CHECKSUM_E_GOOD, "Good" },
13878 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
13879 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
13880 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
13881
13882 { 0, NULL((void*)0) }
13883};
13884
13885proto_item *
13886proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13887 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
13888 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
13889{
13890 header_field_info *hfinfo;
13891 uint32_t checksum;
13892 uint32_t len;
13893 proto_item* ti = NULL((void*)0);
13894 proto_item* ti2;
13895 bool_Bool incorrect_checksum = true1;
13896
13897 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", 13897, __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", 13897
, "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", 13897, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
13898
13899 switch (hfinfo->type) {
13900 case FT_UINT8:
13901 len = 1;
13902 break;
13903 case FT_UINT16:
13904 len = 2;
13905 break;
13906 case FT_UINT24:
13907 len = 3;
13908 break;
13909 case FT_UINT32:
13910 len = 4;
13911 break;
13912 default:
13913 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)
13914 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
13915 }
13916
13917 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
13918 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
13919 proto_item_set_generated(ti);
13920 if (hf_checksum_status != -1) {
13921 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
13922 proto_item_set_generated(ti2);
13923 }
13924 return ti;
13925 }
13926
13927 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
13928 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
13929 proto_item_set_generated(ti);
13930 } else {
13931 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
13932 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
13933 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
13934 if (computed_checksum == 0) {
13935 proto_item_append_text(ti, " [correct]");
13936 if (hf_checksum_status != -1) {
13937 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13938 proto_item_set_generated(ti2);
13939 }
13940 incorrect_checksum = false0;
13941 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
13942 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
13943 }
13944 } else {
13945 if (checksum == computed_checksum) {
13946 proto_item_append_text(ti, " [correct]");
13947 if (hf_checksum_status != -1) {
13948 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13949 proto_item_set_generated(ti2);
13950 }
13951 incorrect_checksum = false0;
13952 }
13953 }
13954
13955 if (incorrect_checksum) {
13956 if (hf_checksum_status != -1) {
13957 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
13958 proto_item_set_generated(ti2);
13959 }
13960 if (flags & PROTO_CHECKSUM_ZERO0x08) {
13961 proto_item_append_text(ti, " [incorrect]");
13962 if (bad_checksum_expert != NULL((void*)0))
13963 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
13964 } else {
13965 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
13966 if (bad_checksum_expert != NULL((void*)0))
13967 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);
13968 }
13969 }
13970 } else {
13971 if (hf_checksum_status != -1) {
13972 proto_item_append_text(ti, " [unverified]");
13973 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
13974 proto_item_set_generated(ti2);
13975 }
13976 }
13977 }
13978
13979 return ti;
13980}
13981
13982proto_item *
13983proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13984 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
13985 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
13986{
13987 header_field_info *hfinfo;
13988 uint8_t *checksum = NULL((void*)0);
13989 proto_item* ti = NULL((void*)0);
13990 proto_item* ti2;
13991 bool_Bool incorrect_checksum = true1;
13992
13993 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", 13993, __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", 13993
, "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", 13993, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
13994
13995 if (hfinfo->type != FT_BYTES) {
13996 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)
13997 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
13998 }
13999
14000 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14001 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14002 proto_item_set_generated(ti);
14003 if (hf_checksum_status != -1) {
14004 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14005 proto_item_set_generated(ti2);
14006 }
14007 return ti;
14008 }
14009
14010 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14011 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14012 proto_item_set_generated(ti);
14013 } else {
14014 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
))))))
;
14015 tvb_memcpy(tvb, checksum, offset, checksum_len);
14016 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14017 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14018 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14019 if (computed_checksum == 0) {
14020 proto_item_append_text(ti, " [correct]");
14021 if (hf_checksum_status != -1) {
14022 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14023 proto_item_set_generated(ti2);
14024 }
14025 incorrect_checksum = false0;
14026 }
14027 } else {
14028 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14029 proto_item_append_text(ti, " [correct]");
14030 if (hf_checksum_status != -1) {
14031 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14032 proto_item_set_generated(ti2);
14033 }
14034 incorrect_checksum = false0;
14035 }
14036 }
14037
14038 if (incorrect_checksum) {
14039 if (hf_checksum_status != -1) {
14040 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14041 proto_item_set_generated(ti2);
14042 }
14043 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14044 proto_item_append_text(ti, " [incorrect]");
14045 if (bad_checksum_expert != NULL((void*)0))
14046 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14047 } else {
14048 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14049 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))))))
;
14050 for (size_t counter = 0; counter < checksum_len; ++counter) {
14051 snprintf(
14052 /* On ecah iteration inserts two characters */
14053 (char*)&computed_checksum_str[counter << 1],
14054 computed_checksum_str_len - (counter << 1),
14055 "%02x",
14056 computed_checksum[counter]);
14057 }
14058 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14059 if (bad_checksum_expert != NULL((void*)0))
14060 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14061 }
14062 }
14063 } else {
14064 if (hf_checksum_status != -1) {
14065 proto_item_append_text(ti, " [unverified]");
14066 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14067 proto_item_set_generated(ti2);
14068 }
14069 }
14070 }
14071
14072 return ti;
14073}
14074
14075unsigned char
14076proto_check_field_name(const char *field_name)
14077{
14078 return module_check_valid_name(field_name, false0);
14079}
14080
14081unsigned char
14082proto_check_field_name_lower(const char *field_name)
14083{
14084 return module_check_valid_name(field_name, true1);
14085}
14086
14087bool_Bool
14088tree_expanded(int tree_type)
14089{
14090 if (tree_type <= 0) {
14091 return false0;
14092 }
14093 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", 14093, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14094 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14095}
14096
14097void
14098tree_expanded_set(int tree_type, bool_Bool value)
14099{
14100 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", 14100, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14101
14102 if (value)
14103 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14104 else
14105 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14106}
14107
14108/*
14109 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14110 *
14111 * Local variables:
14112 * c-basic-offset: 8
14113 * tab-width: 8
14114 * indent-tabs-mode: t
14115 * End:
14116 *
14117 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14118 * :indentSize=8:tabSize=8:noTabs=false:
14119 */