Bug Summary

File:builds/wireshark/wireshark/epan/proto.c
Warning:line 13327, column 39
The result of left shift is undefined because the right operand '64' is not smaller than 64, the capacity of 'uint64_t'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name proto.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-18/lib/clang/18 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/libxml2 -isystem /usr/include/lua5.4 -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-truncation -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -dwarf-debug-flags /usr/lib/llvm-18/bin/clang -### --analyze -x c -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/libxml2 -isystem /usr/include/lua5.4 -fvisibility=hidden -fexcess-precision=fast -fstrict-flex-arrays=3 -fstack-clash-protection -fcf-protection=full -D _GLIBCXX_ASSERTIONS -fstack-protector-strong -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fexceptions -Wno-format-truncation -Wno-format-nonliteral -fdiagnostics-color=always -Wno-pointer-sign -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -std=gnu11 -fPIC /builds/wireshark/wireshark/epan/proto.c -o /builds/wireshark/wireshark/sbout/2025-01-04-100244-3868-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-01-04-100244-3868-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/pint.h>
31#include <wsutil/wslog.h>
32#include <wsutil/ws_assert.h>
33#include <wsutil/unicode-utils.h>
34#include <wsutil/dtoa.h>
35
36#include <ftypes/ftypes.h>
37
38#include "packet.h"
39#include "exceptions.h"
40#include "ptvcursor.h"
41#include "strutil.h"
42#include "addr_resolv.h"
43#include "address_types.h"
44#include "oids.h"
45#include "proto.h"
46#include "epan_dissect.h"
47#include "dfilter/dfilter.h"
48#include "tvbuff.h"
49#include <epan/wmem_scopes.h>
50#include "charsets.h"
51#include "column-info.h"
52#include "to_str.h"
53#include "osi-utils.h"
54#include "expert.h"
55#include "show_exception.h"
56#include "in_cksum.h"
57#include "register-int.h"
58
59#include <wsutil/crash_info.h>
60#include <wsutil/epochs.h>
61
62/* Ptvcursor limits */
63#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
64#define SUBTREE_MAX_LEVELS256 256
65
66typedef struct __subtree_lvl {
67 int cursor_offset;
68 proto_item *it;
69 proto_tree *tree;
70} subtree_lvl;
71
72struct ptvcursor {
73 wmem_allocator_t *scope;
74 subtree_lvl *pushed_tree;
75 uint8_t pushed_tree_index;
76 uint8_t pushed_tree_max;
77 proto_tree *tree;
78 tvbuff_t *tvb;
79 int offset;
80};
81
82#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
83
84/** See inlined comments.
85 @param tree the tree to append this item to
86 @param free_block a code block to call to free resources if this returns
87 @return NULL if 'tree' is null */
88#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
89 if (!tree) { \
90 free_block; \
91 return NULL((void*)0); \
92 }
93
94/** See inlined comments.
95 @param tree the tree to append this item to
96 @param free_block a code block to call to free resources if this returns
97 @return NULL if 'tree' is null */
98#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
99 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
100
101/** See inlined comments.
102 @param length the length of this item
103 @param cleanup_block a code block to call to free resources if this returns
104 @return NULL if 'length' is lower -1 or equal 0 */
105#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
106 if (length < -1 || length == 0 ) { \
107 cleanup_block; \
108 return NULL((void*)0); \
109 }
110
111/** See inlined comments.
112 @param length the length of this item
113 @return NULL if 'length' is lower -1 or equal 0 */
114#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
115 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
116
117/** See inlined comments.
118 @param tree the tree to append this item to
119 @param hfindex field index
120 @param hfinfo header_field
121 @param free_block a code block to call to free resources if this returns
122 @return the header field matching 'hfinfo' */
123#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", 123
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 123, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 123, "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", 123, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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
); } } }
\
124 /* If the tree is not visible and this item is not referenced \
125 we don't have to do much work at all but we should still \
126 return a node so that referenced field items below this node \
127 (think proto_item_add_subtree()) will still have somewhere \
128 to attach to or else filtering will not work (they would be \
129 ignored since tree would be NULL). \
130 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
131 because that means we can change its length or repr, and we \
132 don't want to do so with calls intended for this faked new \
133 item, so this item needs a new (hidden) child node. \
134 We fake FT_PROTOCOL unless some clients have requested us \
135 not to do so. \
136 */ \
137 PTREE_DATA(tree)((tree)->tree_data)->count++; \
138 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", 138, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 138, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 138, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
139 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
140 free_block; \
141 if (wireshark_abort_on_too_many_items) \
142 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", 143
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
143 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 143
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
144 /* Let the exception handler add items to the tree */ \
145 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
146 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)))
147 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)))
148 "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)))
149 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)))
; \
150 } \
151 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
152 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
153 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
154 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
155 && (hfinfo->type != FT_PROTOCOL || \
156 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
157 free_block; \
158 /* return fake node with no field info */\
159 return proto_tree_add_fake_node(tree, hfinfo); \
160 } \
161 } \
162 }
163
164/** See inlined comments.
165 @param tree the tree to append this item to
166 @param hfindex field index
167 @param hfinfo header_field
168 @return the header field matching 'hfinfo' */
169#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", 169
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 169, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 169, "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", 169, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
\
170 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", 170
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 170, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 170, "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", 170, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
171
172
173/** See inlined comments.
174 @param pi the created protocol item we're about to return */
175#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 175, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
\
176 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 176, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
177 if (!PITEM_FINFO(pi)((pi)->finfo)) \
178 return pi; \
179 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
180 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
181 /* If the tree (GUI) or item isn't visible it's pointless for \
182 * us to generate the protocol item's string representation */ \
183 return pi; \
184 }
185/* Same as above but returning void */
186#define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
\
187 if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
188 return; \
189 if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
190 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
191 /* If the tree (GUI) or item isn't visible it's pointless for \
192 * us to generate the protocol item's string representation */ \
193 return; \
194 }
195/* Similar to above, but allows a NULL tree */
196#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; }
\
197 if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
198 PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
199 /* If the tree (GUI) or item isn't visible it's pointless for \
200 * us to generate the protocol item's string representation */ \
201 return pi; \
202 }
203
204#ifdef ENABLE_CHECK_FILTER
205#define CHECK_HF_VALUE(type, spec, start_values) \
206{ \
207 const type *current; \
208 int n, m; \
209 current = start_values; \
210 for (n=0; current; n++, current++) { \
211 /* Drop out if we reached the end. */ \
212 if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
213 break; \
214 } \
215 /* Check value against all previous */ \
216 for (m=0; m < n; m++) { \
217 /* There are lots of duplicates with the same string, \
218 so only report if different... */ \
219 if ((start_values[m].value == current->value) && \
220 (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
221 ws_warning("Field '%s' (%s) has a conflicting entry in its" \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 224, __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 " value_string: %" spec " is at indices %u (%s) and %u (%s)", \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 224, __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 hfinfo->name, hfinfo->abbrev, \do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 224, __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)
224 current->value, m, start_values[m].strptr, n, current->strptr)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 224, __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)
; \
225 } \
226 } \
227 } \
228}
229#endif
230
231/* The longest NUMBER-like field label we have is for BASE_OUI, which
232 * can have up to 64 bytes for the manufacturer name if resolved plus
233 * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
234 */
235#define NUMBER_LABEL_LENGTH80 80
236
237static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
238static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
239static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
240static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
241static int hfinfo_bitoffset(const header_field_info *hfinfo);
242static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
243static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
244
245#define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
246 ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
247
248static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
249static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
250#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)
251
252static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
253static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
254static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
256static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
257static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
258static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
259
260static size_t fill_display_label_float(const field_info *fi, char *label_str);
261static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
262
263static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
264static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
265static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
266static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
267static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
268static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
269static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
270static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
271static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
272static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
273
274static void proto_cleanup_base(void);
275
276static proto_item *
277proto_tree_add_node(proto_tree *tree, field_info *fi);
278
279static proto_item *
280proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
281
282static void
283get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
284 int *item_length, const unsigned encoding);
285
286static int
287get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
288 int length, unsigned item_length, const int encoding);
289
290static field_info *
291new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
292 const int start, const int item_length);
293
294static proto_item *
295proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
296 int start, int *length);
297
298static void
299proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
300static void
301proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
302
303static void
304proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
305static void
306proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
307static void
308proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
309static void
310proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
311static void
312proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
313static void
314proto_tree_set_string(field_info *fi, const char* value);
315static void
316proto_tree_set_ax25(field_info *fi, const uint8_t* value);
317static void
318proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
319static void
320proto_tree_set_vines(field_info *fi, const uint8_t* value);
321static void
322proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
323static void
324proto_tree_set_ether(field_info *fi, const uint8_t* value);
325static void
326proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
327static void
328proto_tree_set_ipxnet(field_info *fi, uint32_t value);
329static void
330proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
331static void
332proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
333static void
334proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
335static void
336proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
337static void
338proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
339static void
340proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
341static void
342proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
343static void
344proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
345static void
346proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
347static void
348proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
349static void
350proto_tree_set_boolean(field_info *fi, uint64_t value);
351static void
352proto_tree_set_float(field_info *fi, float value);
353static void
354proto_tree_set_double(field_info *fi, double value);
355static void
356proto_tree_set_uint(field_info *fi, uint32_t value);
357static void
358proto_tree_set_int(field_info *fi, int32_t value);
359static void
360proto_tree_set_uint64(field_info *fi, uint64_t value);
361static void
362proto_tree_set_int64(field_info *fi, int64_t value);
363static void
364proto_tree_set_eui64(field_info *fi, const uint64_t value);
365static void
366proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
367
368/* Handle type length mismatch (now filterable) expert info */
369static int proto_type_length_mismatch;
370static expert_field ei_type_length_mismatch_error;
371static expert_field ei_type_length_mismatch_warn;
372static void register_type_length_mismatch(void);
373
374/* Handle byte array string decoding errors with expert info */
375static int proto_byte_array_string_decoding_error;
376static expert_field ei_byte_array_string_decoding_failed_error;
377static void register_byte_array_string_decodinws_error(void);
378
379/* Handle date and time string decoding errors with expert info */
380static int proto_date_time_string_decoding_error;
381static expert_field ei_date_time_string_decoding_failed_error;
382static void register_date_time_string_decodinws_error(void);
383
384/* Handle string errors expert info */
385static int proto_string_errors;
386static expert_field ei_string_trailing_characters;
387static void register_string_errors(void);
388
389static int proto_register_field_init(header_field_info *hfinfo, const int parent);
390
391/* special-case header field used within proto.c */
392static header_field_info hfi_text_only =
393 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
394int hf_text_only;
395
396/* Structure for information about a protocol */
397struct _protocol {
398 const char *name; /* long description */
399 const char *short_name; /* short description */
400 const char *filter_name; /* name of this protocol in filters */
401 GPtrArray *fields; /* fields for this protocol */
402 int proto_id; /* field ID for this protocol */
403 bool_Bool is_enabled; /* true if protocol is enabled */
404 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
405 bool_Bool can_toggle; /* true if is_enabled can be changed */
406 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
407 For dissectors that need a protocol name so they
408 can be added to a dissector table, but use the
409 parent_proto_id for things like enable/disable */
410 GList *heur_list; /* Heuristic dissectors associated with this protocol */
411};
412
413/* List of all protocols */
414static GList *protocols;
415
416/* Structure stored for deregistered g_slice */
417struct g_slice_data {
418 size_t block_size;
419 void *mem_block;
420};
421
422/* Deregistered fields */
423static GPtrArray *deregistered_fields;
424static GPtrArray *deregistered_data;
425static GPtrArray *deregistered_slice;
426
427/* indexed by prefix, contains initializers */
428static GHashTable* prefixes;
429
430/* Contains information about a field when a dissector calls
431 * proto_tree_add_item. */
432#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)))
433#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
434
435/* Contains the space for proto_nodes. */
436#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
437 node->first_child = NULL((void*)0); \
438 node->last_child = NULL((void*)0); \
439 node->next = NULL((void*)0);
440
441#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
442 wmem_free(pool, node)
443
444/* String space for protocol and field items for the GUI */
445#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;
\
446 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
447 il->value_pos = 0; \
448 il->value_len = 0;
449#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
450 wmem_free(pool, il);
451
452#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", 452, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 452, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 452, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
453 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
454 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 454
, __func__, "Unregistered hf! index=%d", hfindex)
; \
455 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", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
456 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", 456, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
457 hfinfo = gpa_hfinfo.hfi[hfindex];
458
459/* List which stores protocols and fields that have been registered */
460typedef struct _gpa_hfinfo_t {
461 uint32_t len;
462 uint32_t allocated_len;
463 header_field_info **hfi;
464} gpa_hfinfo_t;
465
466static gpa_hfinfo_t gpa_hfinfo;
467
468/* Hash table of abbreviations and IDs */
469static GHashTable *gpa_name_map;
470static header_field_info *same_name_hfinfo;
471
472/* Hash table protocol aliases. const char * -> const char * */
473static GHashTable *gpa_protocol_aliases;
474
475/*
476 * We're called repeatedly with the same field name when sorting a column.
477 * Cache our last gpa_name_map hit for faster lookups.
478 */
479static char *last_field_name;
480static header_field_info *last_hfinfo;
481
482static void save_same_name_hfinfo(void *data)
483{
484 same_name_hfinfo = (header_field_info*)data;
485}
486
487/* Points to the first element of an array of bits, indexed by
488 a subtree item type; that array element is true if subtrees of
489 an item of that type are to be expanded. */
490static uint32_t *tree_is_expanded;
491
492/* Number of elements in that array. The entry with index 0 is not used. */
493int num_tree_types = 1;
494
495/* Name hashtables for fast detection of duplicate names */
496static GHashTable* proto_names;
497static GHashTable* proto_short_names;
498static GHashTable* proto_filter_names;
499
500static const char *reserved_filter_names[] = {
501 /* Display filter keywords. */
502 "eq",
503 "ne",
504 "all_eq",
505 "any_eq",
506 "all_ne",
507 "any_ne",
508 "gt",
509 "ge",
510 "lt",
511 "le",
512 "bitand",
513 "bitwise_and",
514 "contains",
515 "matches",
516 "not",
517 "and",
518 "or",
519 "xor",
520 "in",
521 "any",
522 "all",
523 "true",
524 "false",
525 "nan",
526 "inf",
527 "infinity",
528 NULL((void*)0)
529};
530
531static GHashTable *proto_reserved_filter_names;
532
533static int
534proto_compare_name(const void *p1_arg, const void *p2_arg)
535{
536 const protocol_t *p1 = (const protocol_t *)p1_arg;
537 const protocol_t *p2 = (const protocol_t *)p2_arg;
538
539 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
540}
541
542static GSList *dissector_plugins;
543
544#ifdef HAVE_PLUGINS1
545void
546proto_register_plugin(const proto_plugin *plug)
547{
548 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
549}
550#else /* HAVE_PLUGINS */
551void
552proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
553{
554 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 554, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
555}
556#endif /* HAVE_PLUGINS */
557
558static void
559call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
560{
561 proto_plugin *plug = (proto_plugin *)data;
562
563 if (plug->register_protoinfo) {
564 plug->register_protoinfo();
565 }
566}
567
568static void
569call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
570{
571 proto_plugin *plug = (proto_plugin *)data;
572
573 if (plug->register_handoff) {
574 plug->register_handoff();
575 }
576}
577
578/* initialize data structures and register protocols and fields */
579void
580proto_init(GSList *register_all_plugin_protocols_list,
581 GSList *register_all_plugin_handoffs_list,
582 register_cb cb,
583 void *client_data)
584{
585 proto_cleanup_base();
586
587 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
588 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
589 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
590
591 proto_reserved_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
592 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
593 /* GHashTable has no key destructor so the cast is safe. */
594 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
595 }
596
597 gpa_hfinfo.len = 0;
598 gpa_hfinfo.allocated_len = 0;
599 gpa_hfinfo.hfi = NULL((void*)0);
600 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL((void*)0), save_same_name_hfinfo);
601 gpa_protocol_aliases = g_hash_table_new(g_str_hash, g_str_equal);
602 deregistered_fields = g_ptr_array_new();
603 deregistered_data = g_ptr_array_new();
604 deregistered_slice = g_ptr_array_new();
605
606 /* Initialize the ftype subsystem */
607 ftypes_initialize();
608
609 /* Initialize the address type subsystem */
610 address_types_initialize();
611
612 /* Register one special-case FT_TEXT_ONLY field for use when
613 converting wireshark to new-style proto_tree. These fields
614 are merely strings on the GUI tree; they are not filterable */
615 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
616
617 /* Register the pseudo-protocols used for exceptions. */
618 register_show_exception();
619 register_type_length_mismatch();
620 register_byte_array_string_decodinws_error();
621 register_date_time_string_decodinws_error();
622 register_string_errors();
623 ftypes_register_pseudofields();
624 col_register_protocol();
625
626 /* Have each built-in dissector register its protocols, fields,
627 dissector tables, and dissectors to be called through a
628 handle, and do whatever one-time initialization it needs to
629 do. */
630 register_all_protocols(cb, client_data);
631
632 /* Now call the registration routines for all epan plugins. */
633 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
634 ((void (*)(register_cb, void *))l->data)(cb, client_data);
635 }
636
637 /* Now call the registration routines for all dissector plugins. */
638 if (cb)
639 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
640 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
641
642 /* Now call the "handoff registration" routines of all built-in
643 dissectors; those routines register the dissector in other
644 dissectors' handoff tables, and fetch any dissector handles
645 they need. */
646 register_all_protocol_handoffs(cb, client_data);
647
648 /* Now do the same with epan plugins. */
649 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
650 ((void (*)(register_cb, void *))l->data)(cb, client_data);
651 }
652
653 /* Now do the same with dissector plugins. */
654 if (cb)
655 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
656 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
657
658 /* sort the protocols by protocol name */
659 protocols = g_list_sort(protocols, proto_compare_name);
660
661 /* sort the dissector handles in dissector tables (for -G reports
662 * and -d error messages. The GUI sorts the handles itself.) */
663 packet_all_tables_sort_handles();
664
665 /* We've assigned all the subtree type values; allocate the array
666 for them, and zero it out. */
667 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
)))
;
668}
669
670static void
671proto_cleanup_base(void)
672{
673 protocol_t *protocol;
674 header_field_info *hfinfo;
675
676 /* Free the abbrev/ID hash table */
677 if (gpa_name_map) {
678 g_hash_table_destroy(gpa_name_map);
679 gpa_name_map = NULL((void*)0);
680 }
681 if (gpa_protocol_aliases) {
682 g_hash_table_destroy(gpa_protocol_aliases);
683 gpa_protocol_aliases = NULL((void*)0);
684 }
685 g_free(last_field_name);
686 last_field_name = NULL((void*)0);
687
688 while (protocols) {
689 protocol = (protocol_t *)protocols->data;
690 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", 690
, __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", 690, "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", 690, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
691 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", 691, "protocol->proto_id == hfinfo->id"
))))
;
692
693 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)
;
694 if (protocol->parent_proto_id != -1) {
695 // pino protocol
696 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 696, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
697 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"
, 697, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
698 } else {
699 if (protocol->fields) {
700 g_ptr_array_free(protocol->fields, true1);
701 }
702 g_list_free(protocol->heur_list);
703 }
704 protocols = g_list_remove(protocols, protocol);
705 g_free(protocol);
706 }
707
708 if (proto_names) {
709 g_hash_table_destroy(proto_names);
710 proto_names = NULL((void*)0);
711 }
712
713 if (proto_short_names) {
714 g_hash_table_destroy(proto_short_names);
715 proto_short_names = NULL((void*)0);
716 }
717
718 if (proto_filter_names) {
719 g_hash_table_destroy(proto_filter_names);
720 proto_filter_names = NULL((void*)0);
721 }
722
723 if (proto_reserved_filter_names) {
724 g_hash_table_destroy(proto_reserved_filter_names);
725 proto_reserved_filter_names = NULL((void*)0);
726 }
727
728 if (gpa_hfinfo.allocated_len) {
729 gpa_hfinfo.len = 0;
730 gpa_hfinfo.allocated_len = 0;
731 g_free(gpa_hfinfo.hfi);
732 gpa_hfinfo.hfi = NULL((void*)0);
733 }
734
735 if (deregistered_fields) {
736 g_ptr_array_free(deregistered_fields, true1);
737 deregistered_fields = NULL((void*)0);
738 }
739
740 if (deregistered_data) {
741 g_ptr_array_free(deregistered_data, true1);
742 deregistered_data = NULL((void*)0);
743 }
744
745 if (deregistered_slice) {
746 g_ptr_array_free(deregistered_slice, true1);
747 deregistered_slice = NULL((void*)0);
748 }
749
750 g_free(tree_is_expanded);
751 tree_is_expanded = NULL((void*)0);
752
753 if (prefixes)
754 g_hash_table_destroy(prefixes);
755}
756
757void
758proto_cleanup(void)
759{
760 proto_free_deregistered_fields();
761 proto_cleanup_base();
762
763 g_slist_free(dissector_plugins);
764 dissector_plugins = NULL((void*)0);
765}
766
767static bool_Bool
768// NOLINTNEXTLINE(misc-no-recursion)
769proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
770 void *data)
771{
772 proto_node *pnode = tree;
773 proto_node *child;
774 proto_node *current;
775
776 if (func(pnode, data))
777 return true1;
778
779 child = pnode->first_child;
780 while (child != NULL((void*)0)) {
781 /*
782 * The routine we call might modify the child, e.g. by
783 * freeing it, so we get the child's successor before
784 * calling that routine.
785 */
786 current = child;
787 child = current->next;
788 // We recurse here, but we're limited by prefs.gui_max_tree_depth
789 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
790 return true1;
791 }
792
793 return false0;
794}
795
796void
797proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
798 void *data)
799{
800 proto_node *node = tree;
801 proto_node *current;
802
803 if (!node)
804 return;
805
806 node = node->first_child;
807 while (node != NULL((void*)0)) {
808 current = node;
809 node = current->next;
810 func((proto_tree *)current, data);
811 }
812}
813
814static void
815free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
816{
817 GPtrArray *ptrs = (GPtrArray *)value;
818 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
819 header_field_info *hfinfo;
820
821 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", 821, __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", 821, "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", 821, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
822 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
823 /* when a field is referenced by a filter this also
824 affects the refcount for the parent protocol so we need
825 to adjust the refcount for the parent as well
826 */
827 if (hfinfo->parent != -1) {
828 header_field_info *parent_hfinfo;
829 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", 829
, __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", 829, "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", 829, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
830 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
831 }
832 hfinfo->ref_type = HF_REF_TYPE_NONE;
833 }
834
835 g_ptr_array_free(ptrs, true1);
836}
837
838static void
839proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
840{
841 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
842
843 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
844
845 if (finfo) {
846 fvalue_free(finfo->value);
847 finfo->value = NULL((void*)0);
848 }
849}
850
851void
852proto_tree_reset(proto_tree *tree)
853{
854 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
855
856 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
857
858 /* free tree data */
859 if (tree_data->interesting_hfids) {
860 /* Free all the GPtrArray's in the interesting_hfids hash. */
861 g_hash_table_foreach(tree_data->interesting_hfids,
862 free_GPtrArray_value, NULL((void*)0));
863
864 /* And then remove all values. */
865 g_hash_table_remove_all(tree_data->interesting_hfids);
866 }
867
868 /* Reset track of the number of children */
869 tree_data->count = 0;
870
871 /* Reset our loop checks */
872 tree_data->max_start = 0;
873 tree_data->start_idle_count = 0;
874
875 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
876}
877
878/* frees the resources that the dissection a proto_tree uses */
879void
880proto_tree_free(proto_tree *tree)
881{
882 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
883
884 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
885
886 /* free tree data */
887 if (tree_data->interesting_hfids) {
888 /* Free all the GPtrArray's in the interesting_hfids hash. */
889 g_hash_table_foreach(tree_data->interesting_hfids,
890 free_GPtrArray_value, NULL((void*)0));
891
892 /* And then destroy the hash. */
893 g_hash_table_destroy(tree_data->interesting_hfids);
894 }
895
896 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)
;
897
898 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
899}
900
901/* Is the parsing being done for a visible proto_tree or an invisible one?
902 * By setting this correctly, the proto_tree creation is sped up by not
903 * having to call vsnprintf and copy strings around.
904 */
905bool_Bool
906proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
907{
908 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
909
910 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
911
912 return old_visible;
913}
914
915void
916proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
917{
918 if (tree)
919 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
920}
921
922/* Assume dissector set only its protocol fields.
923 This function is called by dissectors and allows the speeding up of filtering
924 in wireshark; if this function returns false it is safe to reset tree to NULL
925 and thus skip calling most of the expensive proto_tree_add_...()
926 functions.
927 If the tree is visible we implicitly assume the field is referenced.
928*/
929bool_Bool
930proto_field_is_referenced(proto_tree *tree, int proto_id)
931{
932 register header_field_info *hfinfo;
933
934
935 if (!tree)
936 return false0;
937
938 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
939 return true1;
940
941 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", 941, __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", 941, "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", 941, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
942 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
943 return true1;
944
945 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
946 return true1;
947
948 return false0;
949}
950
951
952/* Finds a record in the hfinfo array by id. */
953header_field_info *
954proto_registrar_get_nth(unsigned hfindex)
955{
956 register header_field_info *hfinfo;
957
958 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", 958, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 958, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 958, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
959 return hfinfo;
960}
961
962
963/* Prefix initialization
964 * this allows for a dissector to register a display filter name prefix
965 * so that it can delay the initialization of the hf array as long as
966 * possible.
967 */
968
969/* compute a hash for the part before the dot of a display filter */
970static unsigned
971prefix_hash (const void *key) {
972 /* end the string at the dot and compute its hash */
973 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
974 char* c = copy;
975 unsigned tmp;
976
977 for (; *c; c++) {
978 if (*c == '.') {
979 *c = 0;
980 break;
981 }
982 }
983
984 tmp = g_str_hash(copy);
985 g_free(copy);
986 return tmp;
987}
988
989/* are both strings equal up to the end or the dot? */
990static gboolean
991prefix_equal (const void *ap, const void *bp) {
992 const char* a = (const char *)ap;
993 const char* b = (const char *)bp;
994
995 do {
996 char ac = *a++;
997 char bc = *b++;
998
999 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1000
1001 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1002 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1003
1004 if (ac != bc) return FALSE(0);
1005 } while (1);
1006
1007 return FALSE(0);
1008}
1009
1010/* Register a new prefix for "delayed" initialization of field arrays */
1011void
1012proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1013 if (! prefixes ) {
1014 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1015 }
1016
1017 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1018}
1019
1020/* helper to call all prefix initializers */
1021static gboolean
1022initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1023 ((prefix_initializer_t)v)((const char *)k);
1024 return TRUE(!(0));
1025}
1026
1027/** Initialize every remaining uninitialized prefix. */
1028void
1029proto_initialize_all_prefixes(void) {
1030 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1031}
1032
1033/* Finds a record in the hfinfo array by name.
1034 * If it fails to find it in the already registered fields,
1035 * it tries to find and call an initializer in the prefixes
1036 * table and if so it looks again.
1037 */
1038
1039header_field_info *
1040proto_registrar_get_byname(const char *field_name)
1041{
1042 header_field_info *hfinfo;
1043 prefix_initializer_t pi;
1044
1045 if (!field_name)
1046 return NULL((void*)0);
1047
1048 if (g_strcmp0(field_name, last_field_name) == 0) {
1049 return last_hfinfo;
1050 }
1051
1052 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1053
1054 if (hfinfo) {
1055 g_free(last_field_name);
1056 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1057 last_hfinfo = hfinfo;
1058 return hfinfo;
1059 }
1060
1061 if (!prefixes)
1062 return NULL((void*)0);
1063
1064 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1065 pi(field_name);
1066 g_hash_table_remove(prefixes, field_name);
1067 } else {
1068 return NULL((void*)0);
1069 }
1070
1071 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1072
1073 if (hfinfo) {
1074 g_free(last_field_name);
1075 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1076 last_hfinfo = hfinfo;
1077 }
1078 return hfinfo;
1079}
1080
1081header_field_info*
1082proto_registrar_get_byalias(const char *alias_name)
1083{
1084 if (!alias_name) {
1085 return NULL((void*)0);
1086 }
1087
1088 /* Find our aliased protocol. */
1089 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1090 char *dot = strchr(an_copy, '.');
1091 if (dot) {
1092 *dot = '\0';
1093 }
1094 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1095 if (!proto_pfx) {
1096 g_free(an_copy);
1097 return NULL((void*)0);
1098 }
1099
1100 /* Construct our aliased field and look it up. */
1101 GString *filter_name = g_string_new(proto_pfx);
1102 if (dot) {
1103 g_string_append_printf(filter_name, ".%s", dot+1);
1104 }
1105 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1106 g_free(an_copy);
1107 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)))))
;
1108
1109 return hfinfo;
1110}
1111
1112int
1113proto_registrar_get_id_byname(const char *field_name)
1114{
1115 header_field_info *hfinfo;
1116
1117 hfinfo = proto_registrar_get_byname(field_name);
1118
1119 if (!hfinfo)
1120 return -1;
1121
1122 return hfinfo->id;
1123}
1124
1125static int
1126label_strcat_flags(const header_field_info *hfinfo)
1127{
1128 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1129 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1130
1131 return 0;
1132}
1133
1134static char *
1135format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1136 const uint8_t *bytes, unsigned length, size_t max_str_len)
1137{
1138 char *str = NULL((void*)0);
1139 const uint8_t *p;
1140 bool_Bool is_printable;
1141
1142 if (bytes) {
1143 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1144 /*
1145 * If all bytes are valid and printable UTF-8, show the
1146 * bytes as a string - in quotes to indicate that it's
1147 * a string.
1148 */
1149 if (isprint_utf8_string(bytes, length)) {
1150 str = wmem_strdup_printf(scope, "\"%.*s\"",
1151 (int)length, bytes);
1152 return str;
1153 }
1154 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1155 /*
1156 * Check whether all bytes are printable.
1157 */
1158 is_printable = true1;
1159 for (p = bytes; p < bytes+length; p++) {
1160 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1161 /* Not printable. */
1162 is_printable = false0;
1163 break;
1164 }
1165 }
1166
1167 /*
1168 * If all bytes are printable ASCII, show the bytes
1169 * as a string - in quotes to indicate that it's
1170 * a string.
1171 */
1172 if (is_printable) {
1173 str = wmem_strdup_printf(scope, "\"%.*s\"",
1174 (int)length, bytes);
1175 return str;
1176 }
1177 }
1178
1179 /*
1180 * Either it's not printable ASCII, or we don't care whether
1181 * it's printable ASCII; show it as hex bytes.
1182 */
1183 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1184 case SEP_DOT:
1185 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1186 break;
1187 case SEP_DASH:
1188 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1189 break;
1190 case SEP_COLON:
1191 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1192 break;
1193 case SEP_SPACE:
1194 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1195 break;
1196 case BASE_NONE:
1197 default:
1198 if (prefs.display_byte_fields_with_spaces) {
1199 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1200 } else {
1201 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1202 }
1203 break;
1204 }
1205 }
1206 else {
1207 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1208 str = wmem_strdup(scope, "<none>");
1209 } else {
1210 str = wmem_strdup(scope, "<MISSING>");
1211 }
1212 }
1213 return str;
1214}
1215
1216static char *
1217format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1218 const uint8_t *bytes, unsigned length)
1219{
1220 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1221}
1222
1223static void
1224ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1225{
1226 subtree_lvl *pushed_tree;
1227
1228 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"
, 1228, "ptvc->pushed_tree_max <= 256-8"))))
;
1229 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1230
1231 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1232 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1232, "pushed_tree != ((void*)0)"
))))
;
1233 ptvc->pushed_tree = pushed_tree;
1234}
1235
1236static void
1237ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1238{
1239 ptvc->pushed_tree = NULL((void*)0);
1240 ptvc->pushed_tree_max = 0;
1241 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", 1241, "ptvc->pushed_tree_index == 0"
))))
;
1242 ptvc->pushed_tree_index = 0;
1243}
1244
1245/* Allocates an initializes a ptvcursor_t with 3 variables:
1246 * proto_tree, tvbuff, and offset. */
1247ptvcursor_t *
1248ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1249{
1250 ptvcursor_t *ptvc;
1251
1252 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1253 ptvc->scope = scope;
1254 ptvc->tree = tree;
1255 ptvc->tvb = tvb;
1256 ptvc->offset = offset;
1257 ptvc->pushed_tree = NULL((void*)0);
1258 ptvc->pushed_tree_max = 0;
1259 ptvc->pushed_tree_index = 0;
1260 return ptvc;
1261}
1262
1263
1264/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1265void
1266ptvcursor_free(ptvcursor_t *ptvc)
1267{
1268 ptvcursor_free_subtree_levels(ptvc);
1269 /*g_free(ptvc);*/
1270}
1271
1272/* Returns tvbuff. */
1273tvbuff_t *
1274ptvcursor_tvbuff(ptvcursor_t *ptvc)
1275{
1276 return ptvc->tvb;
1277}
1278
1279/* Returns current offset. */
1280int
1281ptvcursor_current_offset(ptvcursor_t *ptvc)
1282{
1283 return ptvc->offset;
1284}
1285
1286proto_tree *
1287ptvcursor_tree(ptvcursor_t *ptvc)
1288{
1289 if (!ptvc)
1290 return NULL((void*)0);
1291
1292 return ptvc->tree;
1293}
1294
1295void
1296ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1297{
1298 ptvc->tree = tree;
1299}
1300
1301/* creates a subtree, sets it as the working tree and pushes the old working tree */
1302proto_tree *
1303ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1304{
1305 subtree_lvl *subtree;
1306 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1307 ptvcursor_new_subtree_levels(ptvc);
1308
1309 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1310 subtree->tree = ptvc->tree;
1311 subtree->it= NULL((void*)0);
1312 ptvc->pushed_tree_index++;
1313 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1314}
1315
1316/* pops a subtree */
1317void
1318ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1319{
1320 subtree_lvl *subtree;
1321
1322 if (ptvc->pushed_tree_index <= 0)
1323 return;
1324
1325 ptvc->pushed_tree_index--;
1326 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1327 if (subtree->it != NULL((void*)0))
1328 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1329
1330 ptvc->tree = subtree->tree;
1331}
1332
1333/* saves the current tvb offset and the item in the current subtree level */
1334static void
1335ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1336{
1337 subtree_lvl *subtree;
1338
1339 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", 1339, "ptvc->pushed_tree_index > 0"
))))
;
1340
1341 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1342 subtree->it = it;
1343 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1344}
1345
1346/* Creates a subtree and adds it to the cursor as the working tree but does not
1347 * save the old working tree */
1348proto_tree *
1349ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1350{
1351 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1352 return ptvc->tree;
1353}
1354
1355static proto_tree *
1356ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1357{
1358 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1359 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1360 ptvcursor_subtree_set_item(ptvc, it);
1361 return ptvcursor_tree(ptvc);
1362}
1363
1364/* Add an item to the tree and create a subtree
1365 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1366 * In this case, when the subtree will be closed, the parent item length will
1367 * be equal to the advancement of the cursor since the creation of the subtree.
1368 */
1369proto_tree *
1370ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1371 const unsigned encoding, int ett_subtree)
1372{
1373 proto_item *it;
1374
1375 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1376 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1377}
1378
1379static proto_item *
1380proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1381
1382/* Add a text node to the tree and create a subtree
1383 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1384 * In this case, when the subtree will be closed, the item length will be equal
1385 * to the advancement of the cursor since the creation of the subtree.
1386 */
1387proto_tree *
1388ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1389 int ett_subtree, const char *format, ...)
1390{
1391 proto_item *pi;
1392 va_list ap;
1393 header_field_info *hfinfo;
1394 proto_tree *tree;
1395
1396 tree = ptvcursor_tree(ptvc);
1397
1398 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1399
1400 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", 1400
, __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", 1400, "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", 1400, "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", 1400, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1401
1402 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1403 ptvcursor_current_offset(ptvc), length);
1404
1405 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1405, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1406
1407 va_start(ap, format)__builtin_va_start(ap, format);
1408 proto_tree_set_representation(pi, format, ap);
1409 va_end(ap)__builtin_va_end(ap);
1410
1411 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1412}
1413
1414/* Add a text-only node, leaving it to our caller to fill the text in */
1415static proto_item *
1416proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1417{
1418 proto_item *pi;
1419
1420 if (tree == NULL((void*)0))
1421 return NULL((void*)0);
1422
1423 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1424
1425 return pi;
1426}
1427
1428/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1429proto_item *
1430proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1431 const char *format, ...)
1432{
1433 proto_item *pi;
1434 va_list ap;
1435 header_field_info *hfinfo;
1436
1437 if (length == -1) {
1438 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1439 } else {
1440 tvb_ensure_bytes_exist(tvb, start, length);
1441 }
1442
1443 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1444
1445 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", 1445
, __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", 1445, "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", 1445, "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", 1445, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1446
1447 pi = proto_tree_add_text_node(tree, tvb, start, length);
1448
1449 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1449, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1450
1451 va_start(ap, format)__builtin_va_start(ap, format);
1452 proto_tree_set_representation(pi, format, ap);
1453 va_end(ap)__builtin_va_end(ap);
1454
1455 return pi;
1456}
1457
1458/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1459proto_item *
1460proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1461 int length, const char *format, va_list ap)
1462{
1463 proto_item *pi;
1464 header_field_info *hfinfo;
1465
1466 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1467 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1468 * the length to be what's in the tvbuff if length is -1, and the
1469 * minimum of length and what's in the tvbuff if not.
1470 */
1471
1472 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1473
1474 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", 1474
, __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", 1474, "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", 1474, "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", 1474, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1475
1476 pi = proto_tree_add_text_node(tree, tvb, start, length);
1477
1478 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1478, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1479
1480 proto_tree_set_representation(pi, format, ap);
1481
1482 return pi;
1483}
1484
1485/* Add a text-only node that creates a subtree underneath.
1486 */
1487proto_tree *
1488proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1489{
1490 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1491}
1492
1493/* Add a text-only node that creates a subtree underneath.
1494 */
1495proto_tree *
1496proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1497{
1498 proto_tree *pt;
1499 proto_item *pi;
1500 va_list ap;
1501
1502 va_start(ap, format)__builtin_va_start(ap, format);
1503 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1504 va_end(ap)__builtin_va_end(ap);
1505
1506 if (tree_item != NULL((void*)0))
1507 *tree_item = pi;
1508
1509 pt = proto_item_add_subtree(pi, idx);
1510
1511 return pt;
1512}
1513
1514/* Add a text-only node for debugging purposes. The caller doesn't need
1515 * to worry about tvbuff, start, or length. Debug message gets sent to
1516 * STDOUT, too */
1517proto_item *
1518proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1519{
1520 proto_item *pi;
1521 va_list ap;
1522
1523 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1524
1525 if (pi) {
1526 va_start(ap, format)__builtin_va_start(ap, format);
1527 proto_tree_set_representation(pi, format, ap);
1528 va_end(ap)__builtin_va_end(ap);
1529 }
1530 va_start(ap, format)__builtin_va_start(ap, format);
1531 vprintf(format, ap);
1532 va_end(ap)__builtin_va_end(ap);
1533 printf("\n");
1534
1535 return pi;
1536}
1537
1538proto_item *
1539proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1540{
1541 proto_item *pi;
1542 header_field_info *hfinfo;
1543
1544 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1545
1546 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", 1546
, __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", 1546, "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", 1546, "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", 1546, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1547
1548 pi = proto_tree_add_text_node(tree, tvb, start, length);
1549
1550 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1550, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1551
1552 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1553
1554 return pi;
1555}
1556
1557proto_item *
1558proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1559{
1560 proto_item *pi;
1561 header_field_info *hfinfo;
1562 char *str;
1563
1564 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1565
1566 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", 1566
, __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", 1566, "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", 1566, "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", 1566, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
1567
1568 pi = proto_tree_add_text_node(tree, tvb, start, length);
1569
1570 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1570, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
1571
1572 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1573 proto_item_set_text(pi, "%s", str);
1574 wmem_free(NULL((void*)0), str);
1575
1576 return pi;
1577}
1578
1579void proto_report_dissector_bug(const char *format, ...)
1580{
1581 va_list args;
1582
1583 if (wireshark_abort_on_dissector_bug) {
1584 /*
1585 * Try to have the error message show up in the crash
1586 * information.
1587 */
1588 va_start(args, format)__builtin_va_start(args, format);
1589 ws_vadd_crash_info(format, args);
1590 va_end(args)__builtin_va_end(args);
1591
1592 /*
1593 * Print the error message.
1594 */
1595 va_start(args, format)__builtin_va_start(args, format);
1596 vfprintf(stderrstderr, format, args);
1597 va_end(args)__builtin_va_end(args);
1598 putc('\n', stderrstderr);
1599
1600 /*
1601 * And crash.
1602 */
1603 abort();
1604 } else {
1605 va_start(args, format)__builtin_va_start(args, format);
1606 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1607 va_end(args)__builtin_va_end(args);
1608 }
1609}
1610
1611/* We could probably get away with changing is_error to a minimum length value. */
1612static void
1613report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1614{
1615 if (is_error) {
1616 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1617 } else {
1618 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1619 }
1620
1621 if (is_error) {
1622 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1623 }
1624}
1625
1626static uint32_t
1627get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1628{
1629 uint32_t value;
1630 bool_Bool length_error;
1631
1632 switch (length) {
1633
1634 case 1:
1635 value = tvb_get_uint8(tvb, offset);
1636 if (encoding & ENC_ZIGBEE0x40000000) {
1637 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1638 value = 0;
1639 }
1640 }
1641 break;
1642
1643 case 2:
1644 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1645 : tvb_get_ntohs(tvb, offset);
1646 if (encoding & ENC_ZIGBEE0x40000000) {
1647 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1648 value = 0;
1649 }
1650 }
1651 break;
1652
1653 case 3:
1654 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1655 : tvb_get_ntoh24(tvb, offset);
1656 break;
1657
1658 case 4:
1659 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1660 : tvb_get_ntohl(tvb, offset);
1661 break;
1662
1663 default:
1664 if (length < 1) {
1665 length_error = true1;
1666 value = 0;
1667 } else {
1668 length_error = false0;
1669 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1670 : tvb_get_ntohl(tvb, offset);
1671 }
1672 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1673 break;
1674 }
1675 return value;
1676}
1677
1678static inline uint64_t
1679get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1680{
1681 uint64_t value;
1682
1683 value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1684
1685 if (length < 1 || length > 8) {
1686 report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1687 }
1688
1689 return value;
1690}
1691
1692static int32_t
1693get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1694{
1695 int32_t value;
1696 bool_Bool length_error;
1697
1698 switch (length) {
1699
1700 case 1:
1701 value = tvb_get_int8(tvb, offset);
1702 break;
1703
1704 case 2:
1705 value = encoding ? tvb_get_letohis(tvb, offset)
1706 : tvb_get_ntohis(tvb, offset);
1707 break;
1708
1709 case 3:
1710 value = encoding ? tvb_get_letohi24(tvb, offset)
1711 : tvb_get_ntohi24(tvb, offset);
1712 break;
1713
1714 case 4:
1715 value = encoding ? tvb_get_letohil(tvb, offset)
1716 : tvb_get_ntohil(tvb, offset);
1717 break;
1718
1719 default:
1720 if (length < 1) {
1721 length_error = true1;
1722 value = 0;
1723 } else {
1724 length_error = false0;
1725 value = encoding ? tvb_get_letohil(tvb, offset)
1726 : tvb_get_ntohil(tvb, offset);
1727 }
1728 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1729 break;
1730 }
1731 return value;
1732}
1733
1734/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1735 * be cast-able as a int64_t. This is weird, but what the code has always done.
1736 */
1737static inline uint64_t
1738get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1739{
1740 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1741
1742 switch (length) {
1743 case 7:
1744 value = ws_sign_ext64(value, 56);
1745 break;
1746 case 6:
1747 value = ws_sign_ext64(value, 48);
1748 break;
1749 case 5:
1750 value = ws_sign_ext64(value, 40);
1751 break;
1752 case 4:
1753 value = ws_sign_ext64(value, 32);
1754 break;
1755 case 3:
1756 value = ws_sign_ext64(value, 24);
1757 break;
1758 case 2:
1759 value = ws_sign_ext64(value, 16);
1760 break;
1761 case 1:
1762 value = ws_sign_ext64(value, 8);
1763 break;
1764 }
1765
1766 return value;
1767}
1768
1769/* For FT_STRING */
1770static inline const uint8_t *
1771get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1772 int length, int *ret_length, const unsigned encoding)
1773{
1774 if (length == -1) {
1775 length = tvb_ensure_captured_length_remaining(tvb, start);
1776 }
1777 *ret_length = length;
1778 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1779}
1780
1781/* For FT_STRINGZ */
1782static inline const uint8_t *
1783get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1784 int start, int length, int *ret_length, const unsigned encoding)
1785{
1786 const uint8_t *value;
1787
1788 if (length < -1) {
1789 report_type_length_mismatch(tree, "a string", length, true1);
1790 }
1791 if (length == -1) {
1792 /* This can throw an exception */
1793 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1794 } else {
1795 /* In this case, length signifies the length of the string.
1796 *
1797 * This could either be a null-padded string, which doesn't
1798 * necessarily have a '\0' at the end, or a null-terminated
1799 * string, with a trailing '\0'. (Yes, there are cases
1800 * where you have a string that's both counted and null-
1801 * terminated.)
1802 *
1803 * In the first case, we must allocate a buffer of length
1804 * "length+1", to make room for a trailing '\0'.
1805 *
1806 * In the second case, we don't assume that there is a
1807 * trailing '\0' there, as the packet might be malformed.
1808 * (XXX - should we throw an exception if there's no
1809 * trailing '\0'?) Therefore, we allocate a buffer of
1810 * length "length+1", and put in a trailing '\0', just to
1811 * be safe.
1812 *
1813 * (XXX - this would change if we made string values counted
1814 * rather than null-terminated.)
1815 */
1816 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1817 }
1818 *ret_length = length;
1819 return value;
1820}
1821
1822/* For FT_UINT_STRING */
1823static inline const uint8_t *
1824get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1825 tvbuff_t *tvb, int start, int length, int *ret_length,
1826 const unsigned encoding)
1827{
1828 uint32_t n;
1829 const uint8_t *value;
1830
1831 /* I believe it's ok if this is called with a NULL tree */
1832 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1833 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1834 length += n;
1835 *ret_length = length;
1836 return value;
1837}
1838
1839/* For FT_STRINGZPAD */
1840static inline const uint8_t *
1841get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1842 int length, int *ret_length, const unsigned encoding)
1843{
1844 /*
1845 * XXX - currently, string values are null-
1846 * terminated, so a "zero-padded" string
1847 * isn't special. If we represent string
1848 * values as something that includes a counted
1849 * array of bytes, we'll need to strip the
1850 * trailing NULs.
1851 */
1852 if (length == -1) {
1853 length = tvb_ensure_captured_length_remaining(tvb, start);
1854 }
1855 *ret_length = length;
1856 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1857}
1858
1859/* For FT_STRINGZTRUNC */
1860static inline const uint8_t *
1861get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1862 int length, int *ret_length, const unsigned encoding)
1863{
1864 /*
1865 * XXX - currently, string values are null-
1866 * terminated, so a "zero-truncated" string
1867 * isn't special. If we represent string
1868 * values as something that includes a counted
1869 * array of bytes, we'll need to strip everything
1870 * starting with the terminating NUL.
1871 */
1872 if (length == -1) {
1873 length = tvb_ensure_captured_length_remaining(tvb, start);
1874 }
1875 *ret_length = length;
1876 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1877}
1878
1879/*
1880 * Deltas between the epochs for various non-UN*X time stamp formats and
1881 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1882 * stamp format.
1883 */
1884
1885/*
1886 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1887 * XXX - if it's OK if this is unsigned, can we just use
1888 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1889 */
1890#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1891
1892/*
1893 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1894 */
1895#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1896
1897/* this can be called when there is no tree, so tree may be null */
1898static void
1899get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1900 const int length, const unsigned encoding, nstime_t *time_stamp,
1901 const bool_Bool is_relative)
1902{
1903 uint32_t tmpsecs;
1904 uint64_t tmp64secs;
1905 uint64_t todusecs;
1906
1907 switch (encoding) {
1908
1909 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1910 /*
1911 * If the length is 16, 8-byte seconds, followed
1912 * by 8-byte fractional time in nanoseconds,
1913 * both big-endian.
1914 *
1915 * If the length is 12, 8-byte seconds, followed
1916 * by 4-byte fractional time in nanoseconds,
1917 * both big-endian.
1918 *
1919 * If the length is 8, 4-byte seconds, followed
1920 * by 4-byte fractional time in nanoseconds,
1921 * both big-endian.
1922 *
1923 * For absolute times, the seconds are seconds
1924 * since the UN*X epoch.
1925 */
1926 if (length == 16) {
1927 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1928 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1929 } else if (length == 12) {
1930 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1931 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1932 } else if (length == 8) {
1933 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1934 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1935 } else if (length == 4) {
1936 /*
1937 * Backwards compatibility.
1938 * ENC_TIME_SECS_NSECS is 0; using
1939 * ENC_BIG_ENDIAN by itself with a 4-byte
1940 * time-in-seconds value was done in the
1941 * past.
1942 */
1943 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1944 time_stamp->nsecs = 0;
1945 } else {
1946 time_stamp->secs = 0;
1947 time_stamp->nsecs = 0;
1948 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1949 }
1950 break;
1951
1952 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
1953 /*
1954 * If the length is 16, 8-byte seconds, followed
1955 * by 8-byte fractional time in nanoseconds,
1956 * both little-endian.
1957 *
1958 * If the length is 12, 8-byte seconds, followed
1959 * by 4-byte fractional time in nanoseconds,
1960 * both little-endian.
1961 *
1962 * If the length is 8, 4-byte seconds, followed
1963 * by 4-byte fractional time in nanoseconds,
1964 * both little-endian.
1965 *
1966 * For absolute times, the seconds are seconds
1967 * since the UN*X epoch.
1968 */
1969 if (length == 16) {
1970 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1971 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
1972 } else if (length == 12) {
1973 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
1974 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
1975 } else if (length == 8) {
1976 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1977 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
1978 } else if (length == 4) {
1979 /*
1980 * Backwards compatibility.
1981 * ENC_TIME_SECS_NSECS is 0; using
1982 * ENC_LITTLE_ENDIAN by itself with a 4-byte
1983 * time-in-seconds value was done in the
1984 * past.
1985 */
1986 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
1987 time_stamp->nsecs = 0;
1988 } else {
1989 time_stamp->secs = 0;
1990 time_stamp->nsecs = 0;
1991 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1992 }
1993 break;
1994
1995 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
1996 /*
1997 * NTP time stamp, big-endian.
1998 * Only supported for absolute times.
1999 */
2000 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2000, "!is_relative"
))))
;
2001
2002 /* We need a temporary variable here so the unsigned math
2003 * works correctly (for years > 2036 according to RFC 2030
2004 * chapter 3).
2005 *
2006 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2007 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2008 * If bit 0 is not set, the time is in the range 2036-2104 and
2009 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2010 */
2011 tmpsecs = tvb_get_ntohl(tvb, start);
2012 if ((tmpsecs & 0x80000000) != 0)
2013 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2014 else
2015 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2016
2017 if (length == 8) {
2018 tmp64secs = tvb_get_ntoh64(tvb, start);
2019 if (tmp64secs == 0) {
2020 //This is "NULL" time
2021 time_stamp->secs = 0;
2022 time_stamp->nsecs = 0;
2023 } else {
2024 /*
2025 * Convert 1/2^32s of a second to
2026 * nanoseconds.
2027 */
2028 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2029 }
2030 } else if (length == 4) {
2031 /*
2032 * Backwards compatibility.
2033 */
2034 if (tmpsecs == 0) {
2035 //This is "NULL" time
2036 time_stamp->secs = 0;
2037 }
2038 time_stamp->nsecs = 0;
2039 } else {
2040 time_stamp->secs = 0;
2041 time_stamp->nsecs = 0;
2042 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2043 }
2044 break;
2045
2046 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2047 /*
2048 * NTP time stamp, little-endian.
2049 * Only supported for absolute times.
2050 *
2051 * NTP doesn't use this, because it's an Internet format
2052 * and hence big-endian. Any implementation must decide
2053 * whether the NTP timestamp is a 64-bit unsigned fixed
2054 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2055 * with a 32-bit unsigned seconds field followed by a
2056 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2057 * the previous two).
2058 *
2059 * XXX: We do the latter, but no dissector uses this format.
2060 * OTOH, ERF timestamps do the former, so perhaps we
2061 * should switch the interpretation so that packet-erf.c
2062 * could use this directly?
2063 */
2064 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2064, "!is_relative"
))))
;
2065
2066 /* We need a temporary variable here so the unsigned math
2067 * works correctly (for years > 2036 according to RFC 2030
2068 * chapter 3).
2069 *
2070 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2071 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2072 * If bit 0 is not set, the time is in the range 2036-2104 and
2073 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2074 */
2075 tmpsecs = tvb_get_letohl(tvb, start);
2076 if ((tmpsecs & 0x80000000) != 0)
2077 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2078 else
2079 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2080
2081 if (length == 8) {
2082 tmp64secs = tvb_get_letoh64(tvb, start);
2083 if (tmp64secs == 0) {
2084 //This is "NULL" time
2085 time_stamp->secs = 0;
2086 time_stamp->nsecs = 0;
2087 } else {
2088 /*
2089 * Convert 1/2^32s of a second to
2090 * nanoseconds.
2091 */
2092 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2093 }
2094 } else if (length == 4) {
2095 /*
2096 * Backwards compatibility.
2097 */
2098 if (tmpsecs == 0) {
2099 //This is "NULL" time
2100 time_stamp->secs = 0;
2101 }
2102 time_stamp->nsecs = 0;
2103 } else {
2104 time_stamp->secs = 0;
2105 time_stamp->nsecs = 0;
2106 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2107 }
2108 break;
2109
2110 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2111 /*
2112 * S/3x0 and z/Architecture TOD clock time stamp,
2113 * big-endian. The epoch is January 1, 1900,
2114 * 00:00:00 (proleptic?) UTC.
2115 *
2116 * Only supported for absolute times.
2117 */
2118 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2118, "!is_relative"
))))
;
2119 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2119, "length == 8"
))))
;
2120
2121 if (length == 8) {
2122 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2123 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2124 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2125 } else {
2126 time_stamp->secs = 0;
2127 time_stamp->nsecs = 0;
2128 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2129 }
2130 break;
2131
2132 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2133 /*
2134 * S/3x0 and z/Architecture TOD clock time stamp,
2135 * little-endian. The epoch is January 1, 1900,
2136 * 00:00:00 (proleptic?) UTC.
2137 *
2138 * Only supported for absolute times.
2139 */
2140 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2140, "!is_relative"
))))
;
2141
2142 if (length == 8) {
2143 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2144 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2145 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2146 } else {
2147 time_stamp->secs = 0;
2148 time_stamp->nsecs = 0;
2149 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2150 }
2151 break;
2152
2153 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2154 /*
2155 * Time stamp using the same seconds/fraction format
2156 * as NTP, but with the origin of the time stamp being
2157 * the UNIX epoch rather than the NTP epoch; big-
2158 * endian.
2159 *
2160 * Only supported for absolute times.
2161 */
2162 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2162, "!is_relative"
))))
;
2163
2164 if (length == 8) {
2165 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2166 /*
2167 * Convert 1/2^32s of a second to nanoseconds.
2168 */
2169 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2170 } else {
2171 time_stamp->secs = 0;
2172 time_stamp->nsecs = 0;
2173 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2174 }
2175 break;
2176
2177 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2178 /*
2179 * Time stamp using the same seconds/fraction format
2180 * as NTP, but with the origin of the time stamp being
2181 * the UNIX epoch rather than the NTP epoch; little-
2182 * endian.
2183 *
2184 * Only supported for absolute times.
2185 *
2186 * The RTPS specification explicitly supports Little
2187 * Endian encoding. In one place, it states that its
2188 * Time_t representation "is the one defined by ...
2189 * RFC 1305", but in another explicitly defines it as
2190 * a struct consisting of an 32 bit unsigned seconds
2191 * field and a 32 bit unsigned fraction field, not a 64
2192 * bit fixed point, so we do that here.
2193 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2194 */
2195 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2195, "!is_relative"
))))
;
2196
2197 if (length == 8) {
2198 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2199 /*
2200 * Convert 1/2^32s of a second to nanoseconds.
2201 */
2202 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2203 } else {
2204 time_stamp->secs = 0;
2205 time_stamp->nsecs = 0;
2206 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2207 }
2208 break;
2209
2210 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2211 /*
2212 * MIP6 time stamp, big-endian.
2213 * A 64-bit unsigned integer field containing a timestamp. The
2214 * value indicates the number of seconds since January 1, 1970,
2215 * 00:00 UTC, by using a fixed point format. In this format, the
2216 * integer number of seconds is contained in the first 48 bits of
2217 * the field, and the remaining 16 bits indicate the number of
2218 * 1/65536 fractions of a second.
2219
2220 * Only supported for absolute times.
2221 */
2222 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2222, "!is_relative"
))))
;
2223
2224 if (length == 8) {
2225 /* We need a temporary variable here so the casting and fractions
2226 * of a second work correctly.
2227 */
2228 tmp64secs = tvb_get_ntoh48(tvb, start);
2229 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2230 tmpsecs <<= 16;
2231
2232 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2233 //This is "NULL" time
2234 time_stamp->secs = 0;
2235 time_stamp->nsecs = 0;
2236 } else {
2237 time_stamp->secs = (time_t)tmp64secs;
2238 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2239 }
2240 } else {
2241 time_stamp->secs = 0;
2242 time_stamp->nsecs = 0;
2243 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2244 }
2245 break;
2246
2247 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2248 /*
2249 * If the length is 16, 8-byte seconds, followed
2250 * by 8-byte fractional time in microseconds,
2251 * both big-endian.
2252 *
2253 * If the length is 12, 8-byte seconds, followed
2254 * by 4-byte fractional time in microseconds,
2255 * both big-endian.
2256 *
2257 * If the length is 8, 4-byte seconds, followed
2258 * by 4-byte fractional time in microseconds,
2259 * both big-endian.
2260 *
2261 * For absolute times, the seconds are seconds
2262 * since the UN*X epoch.
2263 */
2264 if (length == 16) {
2265 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2266 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2267 } else if (length == 12) {
2268 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2269 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2270 } else if (length == 8) {
2271 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2272 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2273 } else {
2274 time_stamp->secs = 0;
2275 time_stamp->nsecs = 0;
2276 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2277 }
2278 break;
2279
2280 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2281 /*
2282 * If the length is 16, 8-byte seconds, followed
2283 * by 8-byte fractional time in microseconds,
2284 * both little-endian.
2285 *
2286 * If the length is 12, 8-byte seconds, followed
2287 * by 4-byte fractional time in microseconds,
2288 * both little-endian.
2289 *
2290 * If the length is 8, 4-byte seconds, followed
2291 * by 4-byte fractional time in microseconds,
2292 * both little-endian.
2293 *
2294 * For absolute times, the seconds are seconds
2295 * since the UN*X epoch.
2296 */
2297 if (length == 16) {
2298 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2299 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2300 } else if (length == 12) {
2301 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2302 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2303 } else if (length == 8) {
2304 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2305 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2306 } else {
2307 time_stamp->secs = 0;
2308 time_stamp->nsecs = 0;
2309 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2310 }
2311 break;
2312
2313 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2314 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2315 /*
2316 * Seconds, 1 to 8 bytes.
2317 * For absolute times, it's seconds since the
2318 * UN*X epoch.
2319 */
2320 if (length >= 1 && length <= 8) {
2321 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2322 time_stamp->nsecs = 0;
2323 } else {
2324 time_stamp->secs = 0;
2325 time_stamp->nsecs = 0;
2326 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2327 }
2328 break;
2329
2330 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2331 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2332 /*
2333 * Milliseconds, 1 to 8 bytes.
2334 * For absolute times, it's milliseconds since the
2335 * UN*X epoch.
2336 */
2337 if (length >= 1 && length <= 8) {
2338 uint64_t msecs;
2339
2340 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2341 time_stamp->secs = (time_t)(msecs / 1000);
2342 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2343 } else {
2344 time_stamp->secs = 0;
2345 time_stamp->nsecs = 0;
2346 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2347 }
2348 break;
2349
2350 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2351 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2352 /*
2353 * Microseconds, 1 to 8 bytes.
2354 * For absolute times, it's microseconds since the
2355 * UN*X epoch.
2356 */
2357 if (length >= 1 && length <= 8) {
2358 uint64_t usecs;
2359
2360 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2361 time_stamp->secs = (time_t)(usecs / 1000000);
2362 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2363 } else {
2364 time_stamp->secs = 0;
2365 time_stamp->nsecs = 0;
2366 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2367 }
2368 break;
2369
2370 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2371 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2372 /*
2373 * nanoseconds, 1 to 8 bytes.
2374 * For absolute times, it's nanoseconds since the
2375 * UN*X epoch.
2376 */
2377
2378 if (length >= 1 && length <= 8) {
2379 uint64_t nsecs;
2380
2381 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2382 time_stamp->secs = (time_t)(nsecs / 1000000000);
2383 time_stamp->nsecs = (int)(nsecs % 1000000000);
2384 } else {
2385 time_stamp->secs = 0;
2386 time_stamp->nsecs = 0;
2387 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2388 }
2389 break;
2390
2391 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2392 /*
2393 * 1/64ths of a second since the UN*X epoch,
2394 * big-endian.
2395 *
2396 * Only supported for absolute times.
2397 */
2398 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2398, "!is_relative"
))))
;
2399
2400 if (length == 8) {
2401 /*
2402 * The upper 48 bits are seconds since the
2403 * UN*X epoch.
2404 */
2405 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2406 /*
2407 * The lower 16 bits are 1/2^16s of a second;
2408 * convert them to nanoseconds.
2409 *
2410 * XXX - this may give the impression of higher
2411 * precision than you actually get.
2412 */
2413 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2414 } else {
2415 time_stamp->secs = 0;
2416 time_stamp->nsecs = 0;
2417 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2418 }
2419 break;
2420
2421 case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2422 /*
2423 * 1/64ths of a second since the UN*X epoch,
2424 * little-endian.
2425 *
2426 * Only supported for absolute times.
2427 */
2428 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2428, "!is_relative"
))))
;
2429
2430 if (length == 8) {
2431 /*
2432 * XXX - this is assuming that, if anybody
2433 * were ever to use this format - RFC 3971
2434 * doesn't, because that's an Internet
2435 * protocol, and those use network byte
2436 * order, i.e. big-endian - they'd treat it
2437 * as a 64-bit count of 1/2^16s of a second,
2438 * putting the upper 48 bits at the end.
2439 *
2440 * The lower 48 bits are seconds since the
2441 * UN*X epoch.
2442 */
2443 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2444 /*
2445 * The upper 16 bits are 1/2^16s of a second;
2446 * convert them to nanoseconds.
2447 *
2448 * XXX - this may give the impression of higher
2449 * precision than you actually get.
2450 */
2451 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2452 } else {
2453 time_stamp->secs = 0;
2454 time_stamp->nsecs = 0;
2455 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2456 }
2457 break;
2458
2459 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2460 /*
2461 * NTP time stamp, with 1-second resolution (i.e.,
2462 * seconds since the NTP epoch), big-endian.
2463 * Only supported for absolute times.
2464 */
2465 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2465, "!is_relative"
))))
;
2466
2467 if (length == 4) {
2468 /*
2469 * We need a temporary variable here so the unsigned math
2470 * works correctly (for years > 2036 according to RFC 2030
2471 * chapter 3).
2472 *
2473 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2474 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2475 * If bit 0 is not set, the time is in the range 2036-2104 and
2476 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2477 */
2478 tmpsecs = tvb_get_ntohl(tvb, start);
2479 if ((tmpsecs & 0x80000000) != 0)
2480 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2481 else
2482 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2483 time_stamp->nsecs = 0;
2484 } else {
2485 time_stamp->secs = 0;
2486 time_stamp->nsecs = 0;
2487 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2488 }
2489 break;
2490
2491 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2492 /*
2493 * NTP time stamp, with 1-second resolution (i.e.,
2494 * seconds since the NTP epoch), little-endian.
2495 * Only supported for absolute times.
2496 */
2497 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2497, "!is_relative"
))))
;
2498
2499 /*
2500 * We need a temporary variable here so the unsigned math
2501 * works correctly (for years > 2036 according to RFC 2030
2502 * chapter 3).
2503 *
2504 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2505 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2506 * If bit 0 is not set, the time is in the range 2036-2104 and
2507 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2508 */
2509 if (length == 4) {
2510 tmpsecs = tvb_get_letohl(tvb, start);
2511 if ((tmpsecs & 0x80000000) != 0)
2512 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2513 else
2514 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2515 time_stamp->nsecs = 0;
2516 } else {
2517 time_stamp->secs = 0;
2518 time_stamp->nsecs = 0;
2519 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2520 }
2521 break;
2522
2523 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2524 /*
2525 * Milliseconds, 6 to 8 bytes.
2526 * For absolute times, it's milliseconds since the
2527 * NTP epoch.
2528 *
2529 * ETSI TS 129.274 8.119 defines this as:
2530 * "a 48 bit unsigned integer in network order format
2531 * ...encoded as the number of milliseconds since
2532 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2533 * rounded value of 1000 x the value of the 64-bit
2534 * timestamp (Seconds + (Fraction / (1<<32))) defined
2535 * in clause 6 of IETF RFC 5905."
2536 *
2537 * Taken literally, the part after "i.e." would
2538 * mean that the value rolls over before reaching
2539 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2540 * when the 64 bit timestamp rolls over, and we have
2541 * to pick an NTP Era equivalence class to support
2542 * (such as 1968-01-20 to 2104-02-06).
2543 *
2544 * OTOH, the extra room might be used to store Era
2545 * information instead, in which case times until
2546 * 10819-08-03 can be represented with 6 bytes without
2547 * ambiguity. We handle both implementations, and assume
2548 * that times before 1968-01-20 are not represented.
2549 *
2550 * Only 6 bytes or more makes sense as an absolute
2551 * time. 5 bytes or fewer could express a span of
2552 * less than 35 years, either 1900-1934 or 2036-2070.
2553 */
2554 if (length >= 6 && length <= 8) {
2555 uint64_t msecs;
2556
2557 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2558 tmp64secs = (msecs / 1000);
2559 /*
2560 * Assume that times in the first half of NTP
2561 * Era 0 really represent times in the NTP
2562 * Era 1.
2563 */
2564 if (tmp64secs >= 0x80000000)
2565 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2566 else
2567 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2568 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2569 }
2570 else {
2571 time_stamp->secs = 0;
2572 time_stamp->nsecs = 0;
2573 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2574 }
2575 break;
2576
2577 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2578 /*
2579 * MP4 file time stamps, big-endian.
2580 * Only supported for absolute times.
2581 */
2582 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2582, "!is_relative"
))))
;
2583
2584 if (length == 8) {
2585 tmp64secs = tvb_get_ntoh64(tvb, start);
2586 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2587 time_stamp->nsecs = 0;
2588 } else if (length == 4) {
2589 tmpsecs = tvb_get_ntohl(tvb, start);
2590 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2591 time_stamp->nsecs = 0;
2592 } else {
2593 time_stamp->secs = 0;
2594 time_stamp->nsecs = 0;
2595 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2596 }
2597 break;
2598
2599 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2600 /*
2601 * Zigbee ZCL time stamps, big-endian.
2602 * Only supported for absolute times.
2603 */
2604 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2604, "!is_relative"
))))
;
2605
2606 if (length == 8) {
2607 tmp64secs = tvb_get_ntoh64(tvb, start);
2608 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)));
2609 time_stamp->nsecs = 0;
2610 } else if (length == 4) {
2611 tmpsecs = tvb_get_ntohl(tvb, start);
2612 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)));
2613 time_stamp->nsecs = 0;
2614 } else {
2615 time_stamp->secs = 0;
2616 time_stamp->nsecs = 0;
2617 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2618 }
2619 break;
2620
2621 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2622 /*
2623 * Zigbee ZCL time stamps, little-endian.
2624 * Only supported for absolute times.
2625 */
2626 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2626, "!is_relative"
))))
;
2627
2628 if (length == 8) {
2629 tmp64secs = tvb_get_letoh64(tvb, start);
2630 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)));
2631 time_stamp->nsecs = 0;
2632 } else if (length == 4) {
2633 tmpsecs = tvb_get_letohl(tvb, start);
2634 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)));
2635 time_stamp->nsecs = 0;
2636 } else {
2637 time_stamp->secs = 0;
2638 time_stamp->nsecs = 0;
2639 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2640 }
2641 break;
2642
2643 default:
2644 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2644))
;
2645 break;
2646 }
2647}
2648
2649static void
2650tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2651{
2652 const header_field_info *hfinfo = fi->hfinfo;
2653
2654 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2655 GPtrArray *ptrs = NULL((void*)0);
2656
2657 if (tree_data->interesting_hfids == NULL((void*)0)) {
2658 /* Initialize the hash because we now know that it is needed */
2659 tree_data->interesting_hfids =
2660 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2661 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2662 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2663 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2664 }
2665
2666 if (!ptrs) {
2667 /* First element triggers the creation of pointer array */
2668 ptrs = g_ptr_array_new();
2669 g_hash_table_insert(tree_data->interesting_hfids,
2670 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2671 }
2672
2673 g_ptr_array_add(ptrs, fi);
2674 }
2675}
2676
2677
2678/*
2679 * Validates that field length bytes are available starting from
2680 * start (pos/neg). Throws an exception if they aren't.
2681 */
2682static void
2683test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2684 int start, int length, const unsigned encoding)
2685{
2686 int size = length;
2687
2688 if (!tvb)
2689 return;
2690
2691 if ((hfinfo->type == FT_STRINGZ) ||
2692 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2693 (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
))
))) {
2694 /* If we're fetching until the end of the TVB, only validate
2695 * that the offset is within range.
2696 */
2697 if (length == -1)
2698 size = 0;
2699 }
2700
2701 tvb_ensure_bytes_exist(tvb, start, size);
2702}
2703
2704static void
2705detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2706{
2707 bool_Bool found_stray_character = false0;
2708
2709 if (!string)
2710 return;
2711
2712 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2713 case ENC_ASCII0x00000000:
2714 case ENC_UTF_80x00000002:
2715 for (int i = (int)strlen(string); i < length; i++) {
2716 if (string[i] != '\0') {
2717 found_stray_character = true1;
2718 break;
2719 }
2720 }
2721 break;
2722
2723 default:
2724 break;
2725 }
2726
2727 if (found_stray_character) {
2728 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2729 }
2730}
2731
2732static void
2733free_fvalue_cb(void *data)
2734{
2735 fvalue_t *fv = (fvalue_t*)data;
2736 fvalue_free(fv);
2737}
2738
2739/* Add an item to a proto_tree, using the text label registered to that item;
2740 the item is extracted from the tvbuff handed to it. */
2741static proto_item *
2742proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2743 tvbuff_t *tvb, int start, int length,
2744 unsigned encoding)
2745{
2746 proto_item *pi;
2747 uint32_t value, n;
2748 uint64_t value64;
2749 ws_in4_addr ipv4_value;
2750 float floatval;
2751 double doubleval;
2752 const char *stringval = NULL((void*)0);
2753 nstime_t time_stamp;
2754 bool_Bool length_error;
2755
2756 /* Ensure that the newly created fvalue_t is freed if we throw an
2757 * exception before adding it to the tree. (gcc creates clobbering
2758 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2759 * XXX: Move the new_field_info() call inside here?
2760 */
2761 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))
;
2762
2763 switch (new_fi->hfinfo->type) {
2764 case FT_NONE:
2765 /* no value to set for FT_NONE */
2766 break;
2767
2768 case FT_PROTOCOL:
2769 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2770 break;
2771
2772 case FT_BYTES:
2773 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2774 break;
2775
2776 case FT_UINT_BYTES:
2777 n = get_uint_value(tree, tvb, start, length, encoding);
2778 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2779
2780 /* Instead of calling proto_item_set_len(), since we don't yet
2781 * have a proto_item, we set the field_info's length ourselves. */
2782 new_fi->length = n + length;
2783 break;
2784
2785 case FT_BOOLEAN:
2786 /*
2787 * Map all non-zero values to little-endian for
2788 * backwards compatibility.
2789 */
2790 if (encoding)
2791 encoding = ENC_LITTLE_ENDIAN0x80000000;
2792 proto_tree_set_boolean(new_fi,
2793 get_uint64_value(tree, tvb, start, length, encoding));
2794 break;
2795
2796 case FT_CHAR:
2797 /* XXX - make these just FT_UINT? */
2798 case FT_UINT8:
2799 case FT_UINT16:
2800 case FT_UINT24:
2801 case FT_UINT32:
2802 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2803 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2804 value = (uint32_t)value64;
2805 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2806 new_fi->flags |= FI_VARINT0x00004000;
2807 }
2808 }
2809 else {
2810 /*
2811 * Map all non-zero values to little-endian for
2812 * backwards compatibility.
2813 */
2814 if (encoding)
2815 encoding = ENC_LITTLE_ENDIAN0x80000000;
2816
2817 value = get_uint_value(tree, tvb, start, length, encoding);
2818 }
2819 proto_tree_set_uint(new_fi, value);
2820 break;
2821
2822 case FT_UINT40:
2823 case FT_UINT48:
2824 case FT_UINT56:
2825 case FT_UINT64:
2826 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2827 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2828 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2829 new_fi->flags |= FI_VARINT0x00004000;
2830 }
2831 }
2832 else {
2833 /*
2834 * Map all other non-zero values to little-endian for
2835 * backwards compatibility.
2836 */
2837 if (encoding)
2838 encoding = ENC_LITTLE_ENDIAN0x80000000;
2839
2840 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2841 }
2842 proto_tree_set_uint64(new_fi, value64);
2843 break;
2844
2845 /* XXX - make these just FT_INT? */
2846 case FT_INT8:
2847 case FT_INT16:
2848 case FT_INT24:
2849 case FT_INT32:
2850 /*
2851 * Map all non-zero values to little-endian for
2852 * backwards compatibility.
2853 */
2854 if (encoding)
2855 encoding = ENC_LITTLE_ENDIAN0x80000000;
2856 proto_tree_set_int(new_fi,
2857 get_int_value(tree, tvb, start, length, encoding));
2858 break;
2859
2860 case FT_INT40:
2861 case FT_INT48:
2862 case FT_INT56:
2863 case FT_INT64:
2864 /*
2865 * Map all non-zero values to little-endian for
2866 * backwards compatibility.
2867 */
2868 if (encoding)
2869 encoding = ENC_LITTLE_ENDIAN0x80000000;
2870 proto_tree_set_int64(new_fi,
2871 get_int64_value(tree, tvb, start, length, encoding));
2872 break;
2873
2874 case FT_IPv4:
2875 /*
2876 * Map all non-zero values to little-endian for
2877 * backwards compatibility.
2878 */
2879 if (encoding)
2880 encoding = ENC_LITTLE_ENDIAN0x80000000;
2881 if (length != FT_IPv4_LEN4) {
2882 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2883 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2884 }
2885 ipv4_value = tvb_get_ipv4(tvb, start);
2886 /*
2887 * NOTE: to support code written when
2888 * proto_tree_add_item() took a bool as its
2889 * last argument, with false meaning "big-endian"
2890 * and true meaning "little-endian", we treat any
2891 * non-zero value of "encoding" as meaning
2892 * "little-endian".
2893 */
2894 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);
2895 break;
2896
2897 case FT_IPXNET:
2898 if (length != FT_IPXNET_LEN4) {
2899 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2900 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2901 }
2902 proto_tree_set_ipxnet(new_fi,
2903 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2904 break;
2905
2906 case FT_IPv6:
2907 if (length != FT_IPv6_LEN16) {
2908 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2909 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2910 }
2911 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2912 break;
2913
2914 case FT_FCWWN:
2915 if (length != FT_FCWWN_LEN8) {
2916 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2917 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2918 }
2919 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2920 break;
2921
2922 case FT_AX25:
2923 if (length != 7) {
2924 length_error = length < 7 ? true1 : false0;
2925 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2926 }
2927 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2928 break;
2929
2930 case FT_VINES:
2931 if (length != VINES_ADDR_LEN6) {
2932 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2933 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2934 }
2935 proto_tree_set_vines_tvb(new_fi, tvb, start);
2936 break;
2937
2938 case FT_ETHER:
2939 if (length != FT_ETHER_LEN6) {
2940 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2941 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2942 }
2943 proto_tree_set_ether_tvb(new_fi, tvb, start);
2944 break;
2945
2946 case FT_EUI64:
2947 /*
2948 * Map all non-zero values to little-endian for
2949 * backwards compatibility.
2950 */
2951 if (encoding)
2952 encoding = ENC_LITTLE_ENDIAN0x80000000;
2953 if (length != FT_EUI64_LEN8) {
2954 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
2955 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2956 }
2957 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2958 break;
2959 case FT_GUID:
2960 /*
2961 * Map all non-zero values to little-endian for
2962 * backwards compatibility.
2963 */
2964 if (encoding)
2965 encoding = ENC_LITTLE_ENDIAN0x80000000;
2966 if (length != FT_GUID_LEN16) {
2967 length_error = length < FT_GUID_LEN16 ? true1 : false0;
2968 report_type_length_mismatch(tree, "a GUID", length, length_error);
2969 }
2970 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
2971 break;
2972
2973 case FT_OID:
2974 case FT_REL_OID:
2975 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
2976 break;
2977
2978 case FT_SYSTEM_ID:
2979 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
2980 break;
2981
2982 case FT_FLOAT:
2983 /*
2984 * NOTE: to support code written when
2985 * proto_tree_add_item() took a bool as its
2986 * last argument, with false meaning "big-endian"
2987 * and true meaning "little-endian", we treat any
2988 * non-zero value of "encoding" as meaning
2989 * "little-endian".
2990 *
2991 * At some point in the future, we might
2992 * support non-IEEE-binary floating-point
2993 * formats in the encoding as well
2994 * (IEEE decimal, System/3x0, VAX).
2995 */
2996 if (encoding)
2997 encoding = ENC_LITTLE_ENDIAN0x80000000;
2998 if (length != 4) {
2999 length_error = length < 4 ? true1 : false0;
3000 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3001 }
3002 if (encoding)
3003 floatval = tvb_get_letohieee_float(tvb, start);
3004 else
3005 floatval = tvb_get_ntohieee_float(tvb, start);
3006 proto_tree_set_float(new_fi, floatval);
3007 break;
3008
3009 case FT_DOUBLE:
3010 /*
3011 * NOTE: to support code written when
3012 * proto_tree_add_item() took a bool as its
3013 * last argument, with false meaning "big-endian"
3014 * and true meaning "little-endian", we treat any
3015 * non-zero value of "encoding" as meaning
3016 * "little-endian".
3017 *
3018 * At some point in the future, we might
3019 * support non-IEEE-binary floating-point
3020 * formats in the encoding as well
3021 * (IEEE decimal, System/3x0, VAX).
3022 */
3023 if (encoding == true1)
3024 encoding = ENC_LITTLE_ENDIAN0x80000000;
3025 if (length != 8) {
3026 length_error = length < 8 ? true1 : false0;
3027 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3028 }
3029 if (encoding)
3030 doubleval = tvb_get_letohieee_double(tvb, start);
3031 else
3032 doubleval = tvb_get_ntohieee_double(tvb, start);
3033 proto_tree_set_double(new_fi, doubleval);
3034 break;
3035
3036 case FT_STRING:
3037 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3038 tvb, start, length, &length, encoding);
3039 proto_tree_set_string(new_fi, stringval);
3040
3041 /* Instead of calling proto_item_set_len(), since we
3042 * don't yet have a proto_item, we set the
3043 * field_info's length ourselves.
3044 *
3045 * XXX - our caller can't use that length to
3046 * advance an offset unless they arrange that
3047 * there always be a protocol tree into which
3048 * we're putting this item.
3049 */
3050 new_fi->length = length;
3051 break;
3052
3053 case FT_STRINGZ:
3054 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3055 tree, tvb, start, length, &length, encoding);
3056 proto_tree_set_string(new_fi, stringval);
3057
3058 /* Instead of calling proto_item_set_len(),
3059 * since we don't yet have a proto_item, we
3060 * set the field_info's length ourselves.
3061 *
3062 * XXX - our caller can't use that length to
3063 * advance an offset unless they arrange that
3064 * there always be a protocol tree into which
3065 * we're putting this item.
3066 */
3067 new_fi->length = length;
3068 break;
3069
3070 case FT_UINT_STRING:
3071 /*
3072 * NOTE: to support code written when
3073 * proto_tree_add_item() took a bool as its
3074 * last argument, with false meaning "big-endian"
3075 * and true meaning "little-endian", if the
3076 * encoding value is true, treat that as
3077 * ASCII with a little-endian length.
3078 *
3079 * This won't work for code that passes
3080 * arbitrary non-zero values; that code
3081 * will need to be fixed.
3082 */
3083 if (encoding == true1)
3084 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3085 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3086 tree, tvb, start, length, &length, encoding);
3087 proto_tree_set_string(new_fi, stringval);
3088
3089 /* Instead of calling proto_item_set_len(), since we
3090 * don't yet have a proto_item, we set the
3091 * field_info's length ourselves.
3092 *
3093 * XXX - our caller can't use that length to
3094 * advance an offset unless they arrange that
3095 * there always be a protocol tree into which
3096 * we're putting this item.
3097 */
3098 new_fi->length = length;
3099 break;
3100
3101 case FT_STRINGZPAD:
3102 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3103 tvb, start, length, &length, encoding);
3104 proto_tree_set_string(new_fi, stringval);
3105
3106 /* Instead of calling proto_item_set_len(), since we
3107 * don't yet have a proto_item, we set the
3108 * field_info's length ourselves.
3109 *
3110 * XXX - our caller can't use that length to
3111 * advance an offset unless they arrange that
3112 * there always be a protocol tree into which
3113 * we're putting this item.
3114 */
3115 new_fi->length = length;
3116 break;
3117
3118 case FT_STRINGZTRUNC:
3119 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3120 tvb, start, length, &length, encoding);
3121 proto_tree_set_string(new_fi, stringval);
3122
3123 /* Instead of calling proto_item_set_len(), since we
3124 * don't yet have a proto_item, we set the
3125 * field_info's length ourselves.
3126 *
3127 * XXX - our caller can't use that length to
3128 * advance an offset unless they arrange that
3129 * there always be a protocol tree into which
3130 * we're putting this item.
3131 */
3132 new_fi->length = length;
3133 break;
3134
3135 case FT_ABSOLUTE_TIME:
3136 /*
3137 * Absolute times can be in any of a number of
3138 * formats, and they can be big-endian or
3139 * little-endian.
3140 *
3141 * Historically FT_TIMEs were only timespecs;
3142 * the only question was whether they were stored
3143 * in big- or little-endian format.
3144 *
3145 * For backwards compatibility, we interpret an
3146 * encoding of 1 as meaning "little-endian timespec",
3147 * so that passing true is interpreted as that.
3148 */
3149 if (encoding == true1)
3150 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3151
3152 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3153
3154 proto_tree_set_time(new_fi, &time_stamp);
3155 break;
3156
3157 case FT_RELATIVE_TIME:
3158 /*
3159 * Relative times can be in any of a number of
3160 * formats, and they can be big-endian or
3161 * little-endian.
3162 *
3163 * Historically FT_TIMEs were only timespecs;
3164 * the only question was whether they were stored
3165 * in big- or little-endian format.
3166 *
3167 * For backwards compatibility, we interpret an
3168 * encoding of 1 as meaning "little-endian timespec",
3169 * so that passing true is interpreted as that.
3170 */
3171 if (encoding == true1)
3172 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3173
3174 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3175
3176 proto_tree_set_time(new_fi, &time_stamp);
3177 break;
3178 case FT_IEEE_11073_SFLOAT:
3179 if (encoding)
3180 encoding = ENC_LITTLE_ENDIAN0x80000000;
3181 if (length != 2) {
3182 length_error = length < 2 ? true1 : false0;
3183 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3184 }
3185
3186 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3187
3188 break;
3189 case FT_IEEE_11073_FLOAT:
3190 if (encoding)
3191 encoding = ENC_LITTLE_ENDIAN0x80000000;
3192 if (length != 4) {
3193 length_error = length < 4 ? true1 : false0;
3194 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3195 }
3196
3197 break;
3198 default:
3199 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))
3200 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))
3201 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))
3202 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))
;
3203 break;
3204 }
3205 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)
;
3206
3207 /* Don't add new node to proto_tree until now so that any exceptions
3208 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3209 /* XXX. wouldn't be better to add this item to tree, with some special
3210 * flag (FI_EXCEPTION?) to know which item caused exception? For
3211 * strings and bytes, we would have to set new_fi->value to something
3212 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3213 * could handle NULL values. */
3214 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3215 pi = proto_tree_add_node(tree, new_fi);
3216
3217 switch (new_fi->hfinfo->type) {
3218
3219 case FT_STRING:
3220 /* XXX: trailing stray character detection should be done
3221 * _before_ conversion to UTF-8, because conversion can change
3222 * the length, or else get_string_length should return a value
3223 * for the "length in bytes of the string after conversion
3224 * including internal nulls." (Noting that we do, for other
3225 * reasons, still need the "length in bytes in the field",
3226 * especially for FT_STRINGZ.)
3227 *
3228 * This is true even for ASCII and UTF-8, because
3229 * substituting REPLACEMENT CHARACTERS for illegal characters
3230 * can also do so (and for UTF-8 possibly even make the
3231 * string _shorter_).
3232 */
3233 detect_trailing_stray_characters(encoding, stringval, length, pi);
3234 break;
3235
3236 default:
3237 break;
3238 }
3239
3240 return pi;
3241}
3242
3243proto_item *
3244proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3245 const int start, int length,
3246 const unsigned encoding, int32_t *retval)
3247{
3248 header_field_info *hfinfo;
3249 field_info *new_fi;
3250 int32_t value;
3251
3252 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", 3252, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3252,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3252, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3253
3254 switch (hfinfo->type) {
3255 case FT_INT8:
3256 case FT_INT16:
3257 case FT_INT24:
3258 case FT_INT32:
3259 break;
3260 case FT_INT64:
3261 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)
3262 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3263 default:
3264 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)
3265 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3266 }
3267
3268 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3269 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3270 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3271 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3272 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3273 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3274 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3275
3276 if (encoding & ENC_STRING0x03000000) {
3277 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3278 }
3279 /* I believe it's ok if this is called with a NULL tree */
3280 value = get_int_value(tree, tvb, start, length, encoding);
3281
3282 if (retval) {
3283 int no_of_bits;
3284 *retval = value;
3285 if (hfinfo->bitmask) {
3286 /* Mask out irrelevant portions */
3287 *retval &= (uint32_t)(hfinfo->bitmask);
3288 /* Shift bits */
3289 *retval >>= hfinfo_bitshift(hfinfo);
3290 }
3291 no_of_bits = ws_count_ones(hfinfo->bitmask);
3292 *retval = ws_sign_ext32(*retval, no_of_bits);
3293 }
3294
3295 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3296
3297 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", 3297
, __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", 3297, "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", 3297, "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", 3297, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3298
3299 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3300
3301 proto_tree_set_int(new_fi, value);
3302
3303 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3304
3305 return proto_tree_add_node(tree, new_fi);
3306}
3307
3308proto_item *
3309proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3310 const int start, int length,
3311 const unsigned encoding, uint32_t *retval)
3312{
3313 header_field_info *hfinfo;
3314 field_info *new_fi;
3315 uint32_t value;
3316
3317 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", 3317, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3317,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3317, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3318
3319 switch (hfinfo->type) {
3320 case FT_CHAR:
3321 case FT_UINT8:
3322 case FT_UINT16:
3323 case FT_UINT24:
3324 case FT_UINT32:
3325 break;
3326 default:
3327 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)
3328 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)
;
3329 }
3330
3331 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3332 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3333 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3334 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3335 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3336 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3337 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3338
3339 if (encoding & ENC_STRING0x03000000) {
3340 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3341 }
3342 /* I believe it's ok if this is called with a NULL tree */
3343 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3344 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3345 uint64_t temp64;
3346 tvb_get_varint(tvb, start, length, &temp64, encoding);
3347 value = (uint32_t)temp64;
3348 } else {
3349 value = get_uint_value(tree, tvb, start, length, encoding);
3350 }
3351
3352 if (retval) {
3353 *retval = value;
3354 if (hfinfo->bitmask) {
3355 /* Mask out irrelevant portions */
3356 *retval &= (uint32_t)(hfinfo->bitmask);
3357 /* Shift bits */
3358 *retval >>= hfinfo_bitshift(hfinfo);
3359 }
3360 }
3361
3362 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3363
3364 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", 3364
, __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", 3364, "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", 3364, "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", 3364, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3365
3366 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3367
3368 proto_tree_set_uint(new_fi, value);
3369
3370 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3371 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3372 new_fi->flags |= FI_VARINT0x00004000;
3373 }
3374 return proto_tree_add_node(tree, new_fi);
3375}
3376
3377/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3378 * and returns proto_item* and uint value retreived*/
3379proto_item *
3380ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3381 const unsigned encoding, uint32_t *retval)
3382{
3383 field_info *new_fi;
3384 header_field_info *hfinfo;
3385 int item_length;
3386 int offset;
3387 uint32_t value;
3388
3389 offset = ptvc->offset;
3390 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", 3390, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3390,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3390, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3391
3392 switch (hfinfo->type) {
3393 case FT_CHAR:
3394 case FT_UINT8:
3395 case FT_UINT16:
3396 case FT_UINT24:
3397 case FT_UINT32:
3398 break;
3399 default:
3400 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)
3401 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)
;
3402 }
3403
3404 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3405 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3406
3407 /* I believe it's ok if this is called with a NULL tree */
3408 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3409 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3410
3411 if (retval) {
3412 *retval = value;
3413 if (hfinfo->bitmask) {
3414 /* Mask out irrelevant portions */
3415 *retval &= (uint32_t)(hfinfo->bitmask);
3416 /* Shift bits */
3417 *retval >>= hfinfo_bitshift(hfinfo);
3418 }
3419 }
3420
3421 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3422 item_length, encoding);
3423
3424 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3425
3426 /* Coast clear. Try and fake it */
3427 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", 3427
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3427, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3427, "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", 3427, __func__, "Adding %s would put more than %d 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); } } }
;
3428
3429 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3430
3431 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3432 offset, length, encoding);
3433}
3434
3435/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3436 * and returns proto_item* and int value retreived*/
3437proto_item *
3438ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3439 const unsigned encoding, int32_t *retval)
3440{
3441 field_info *new_fi;
3442 header_field_info *hfinfo;
3443 int item_length;
3444 int offset;
3445 uint32_t value;
3446
3447 offset = ptvc->offset;
3448 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", 3448, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3448,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3448, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3449
3450 switch (hfinfo->type) {
3451 case FT_INT8:
3452 case FT_INT16:
3453 case FT_INT24:
3454 case FT_INT32:
3455 break;
3456 default:
3457 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)
3458 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3459 }
3460
3461 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3462 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3463
3464 /* I believe it's ok if this is called with a NULL tree */
3465 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3466 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3467
3468 if (retval) {
3469 int no_of_bits;
3470 *retval = value;
3471 if (hfinfo->bitmask) {
3472 /* Mask out irrelevant portions */
3473 *retval &= (uint32_t)(hfinfo->bitmask);
3474 /* Shift bits */
3475 *retval >>= hfinfo_bitshift(hfinfo);
3476 }
3477 no_of_bits = ws_count_ones(hfinfo->bitmask);
3478 *retval = ws_sign_ext32(*retval, no_of_bits);
3479 }
3480
3481 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3482 item_length, encoding);
3483
3484 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3485
3486 /* Coast clear. Try and fake it */
3487 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", 3487
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3487, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3487, "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", 3487, __func__, "Adding %s would put more than %d 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); } } }
;
3488
3489 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3490
3491 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3492 offset, length, encoding);
3493}
3494
3495/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3496 * and returns proto_item* and string value retreived */
3497proto_item*
3498ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3499{
3500 header_field_info *hfinfo;
3501 field_info *new_fi;
3502 const uint8_t *value;
3503 int item_length;
3504 int offset;
3505
3506 offset = ptvc->offset;
3507
3508 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", 3508
, __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", 3508, "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", 3508, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3509
3510 switch (hfinfo->type) {
3511 case FT_STRING:
3512 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3513 break;
3514 case FT_STRINGZ:
3515 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3516 break;
3517 case FT_UINT_STRING:
3518 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3519 break;
3520 case FT_STRINGZPAD:
3521 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3522 break;
3523 case FT_STRINGZTRUNC:
3524 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3525 break;
3526 default:
3527 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)
3528 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)
;
3529 }
3530
3531 if (retval)
3532 *retval = value;
3533
3534 ptvc->offset += item_length;
3535
3536 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3537
3538 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", 3538, __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", 3538,
"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", 3538, "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", 3538
, __func__, "Adding %s would put more than %d 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); } } }
;
3539
3540 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3541
3542 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3543 offset, length, encoding);
3544}
3545
3546/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3547 * and returns proto_item* and boolean value retreived */
3548proto_item*
3549ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3550{
3551 header_field_info *hfinfo;
3552 field_info *new_fi;
3553 int item_length;
3554 int offset;
3555 uint64_t value, bitval;
3556
3557 offset = ptvc->offset;
3558 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", 3558, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3558,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3558, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3559
3560 if (hfinfo->type != FT_BOOLEAN) {
3561 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)
3562 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3563 }
3564
3565 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3566 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3567 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3568 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3569 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3570 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3571 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3572
3573 if (encoding & ENC_STRING0x03000000) {
3574 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3575 }
3576
3577 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3578 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3579
3580 /* I believe it's ok if this is called with a NULL tree */
3581 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3582
3583 if (retval) {
3584 bitval = value;
3585 if (hfinfo->bitmask) {
3586 /* Mask out irrelevant portions */
3587 bitval &= hfinfo->bitmask;
3588 }
3589 *retval = (bitval != 0);
3590 }
3591
3592 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3593 item_length, encoding);
3594
3595 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3596
3597 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", 3597, __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", 3597,
"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", 3597, "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", 3597
, __func__, "Adding %s would put more than %d 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); } } }
;
3598
3599 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3600
3601 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3602 offset, length, encoding);
3603}
3604
3605proto_item *
3606proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3607 const int start, int length, const unsigned encoding, uint64_t *retval)
3608{
3609 header_field_info *hfinfo;
3610 field_info *new_fi;
3611 uint64_t value;
3612
3613 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", 3613, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3613,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3613, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3614
3615 switch (hfinfo->type) {
3616 case FT_UINT40:
3617 case FT_UINT48:
3618 case FT_UINT56:
3619 case FT_UINT64:
3620 break;
3621 default:
3622 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)
3623 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3624 }
3625
3626 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3627 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3628 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3629 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3630 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3631 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3632 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3633
3634 if (encoding & ENC_STRING0x03000000) {
3635 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3636 }
3637 /* I believe it's ok if this is called with a NULL tree */
3638 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3639 tvb_get_varint(tvb, start, length, &value, encoding);
3640 } else {
3641 value = get_uint64_value(tree, tvb, start, length, encoding);
3642 }
3643
3644 if (retval) {
3645 *retval = value;
3646 if (hfinfo->bitmask) {
3647 /* Mask out irrelevant portions */
3648 *retval &= hfinfo->bitmask;
3649 /* Shift bits */
3650 *retval >>= hfinfo_bitshift(hfinfo);
3651 }
3652 }
3653
3654 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3655
3656 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", 3656
, __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", 3656, "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", 3656, "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", 3656, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3657
3658 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3659
3660 proto_tree_set_uint64(new_fi, value);
3661
3662 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3663 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3664 new_fi->flags |= FI_VARINT0x00004000;
3665 }
3666
3667 return proto_tree_add_node(tree, new_fi);
3668}
3669
3670proto_item *
3671proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3672 const int start, int length, const unsigned encoding, int64_t *retval)
3673{
3674 header_field_info *hfinfo;
3675 field_info *new_fi;
3676 int64_t value;
3677
3678 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", 3678, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3678,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3678, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3679
3680 switch (hfinfo->type) {
3681 case FT_INT40:
3682 case FT_INT48:
3683 case FT_INT56:
3684 case FT_INT64:
3685 break;
3686 default:
3687 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)
3688 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3689 }
3690
3691 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3692 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3693 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3694 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3695 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3696 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3697 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3698
3699 if (encoding & ENC_STRING0x03000000) {
3700 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3701 }
3702 /* I believe it's ok if this is called with a NULL tree */
3703 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3704 tvb_get_varint(tvb, start, length, &value, encoding);
3705 }
3706 else {
3707 value = get_int64_value(tree, tvb, start, length, encoding);
3708 }
3709
3710 if (retval) {
3711 *retval = value;
3712 }
3713
3714 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3715
3716 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", 3716
, __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", 3716, "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", 3716, "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", 3716, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3717
3718 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3719
3720 proto_tree_set_int64(new_fi, value);
3721
3722 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3723 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3724 new_fi->flags |= FI_VARINT0x00004000;
3725 }
3726
3727 return proto_tree_add_node(tree, new_fi);
3728}
3729
3730proto_item *
3731proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3732 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3733{
3734 header_field_info *hfinfo;
3735 field_info *new_fi;
3736 uint64_t value;
3737
3738 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", 3738, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3738,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3738, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3739
3740 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
))
)) {
3741 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)
3742 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3743 }
3744
3745 /* length validation for native number encoding caught by get_uint64_value() */
3746 /* length has to be -1 or > 0 regardless of encoding */
3747 if (length == 0)
3748 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)
3749 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3750
3751 if (encoding & ENC_STRING0x03000000) {
3752 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3753 }
3754
3755 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3756
3757 if (retval) {
3758 *retval = value;
3759 if (hfinfo->bitmask) {
3760 /* Mask out irrelevant portions */
3761 *retval &= hfinfo->bitmask;
3762 /* Shift bits */
3763 *retval >>= hfinfo_bitshift(hfinfo);
3764 }
3765 }
3766
3767 if (lenretval) {
3768 *lenretval = length;
3769 }
3770
3771 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3772
3773 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", 3773
, __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", 3773, "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", 3773, "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", 3773, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3774
3775 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3776
3777 proto_tree_set_uint64(new_fi, value);
3778
3779 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3780 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3781 new_fi->flags |= FI_VARINT0x00004000;
3782 }
3783
3784 return proto_tree_add_node(tree, new_fi);
3785
3786}
3787
3788proto_item *
3789proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3790 const int start, int length,
3791 const unsigned encoding, bool_Bool *retval)
3792{
3793 header_field_info *hfinfo;
3794 field_info *new_fi;
3795 uint64_t value, bitval;
3796
3797 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", 3797, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3797,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3797, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3798
3799 if (hfinfo->type != FT_BOOLEAN) {
3800 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)
3801 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3802 }
3803
3804 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3805 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3806 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3807 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3808 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3809 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3810 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3811
3812 if (encoding & ENC_STRING0x03000000) {
3813 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3814 }
3815 /* I believe it's ok if this is called with a NULL tree */
3816 value = get_uint64_value(tree, tvb, start, length, encoding);
3817
3818 if (retval) {
3819 bitval = value;
3820 if (hfinfo->bitmask) {
3821 /* Mask out irrelevant portions */
3822 bitval &= hfinfo->bitmask;
3823 }
3824 *retval = (bitval != 0);
3825 }
3826
3827 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3828
3829 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", 3829
, __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", 3829, "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", 3829, "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", 3829, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3830
3831 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3832
3833 proto_tree_set_boolean(new_fi, value);
3834
3835 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3836
3837 return proto_tree_add_node(tree, new_fi);
3838}
3839
3840proto_item *
3841proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3842 const int start, int length,
3843 const unsigned encoding, float *retval)
3844{
3845 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3846 field_info *new_fi;
3847 float value;
3848
3849 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", 3849,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3850
3851 if (hfinfo->type != FT_FLOAT) {
3852 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)
;
3853 }
3854
3855 if (length != 4) {
3856 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3857 }
3858
3859 /* treat any nonzero encoding as little endian for backwards compatibility */
3860 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3861 if (retval) {
3862 *retval = value;
3863 }
3864
3865 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3866
3867 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", 3867
, __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", 3867, "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", 3867, "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", 3867, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3868
3869 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3870 if (encoding) {
3871 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3872 }
3873
3874 proto_tree_set_float(new_fi, value);
3875
3876 return proto_tree_add_node(tree, new_fi);
3877}
3878
3879proto_item *
3880proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3881 const int start, int length,
3882 const unsigned encoding, double *retval)
3883{
3884 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3885 field_info *new_fi;
3886 double value;
3887
3888 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", 3888,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3889
3890 if (hfinfo->type != FT_DOUBLE) {
3891 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)
;
3892 }
3893
3894 if (length != 8) {
3895 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3896 }
3897
3898 /* treat any nonzero encoding as little endian for backwards compatibility */
3899 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3900 if (retval) {
3901 *retval = value;
3902 }
3903
3904 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3905
3906 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", 3906
, __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", 3906, "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", 3906, "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", 3906, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3907
3908 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3909 if (encoding) {
3910 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3911 }
3912
3913 proto_tree_set_double(new_fi, value);
3914
3915 return proto_tree_add_node(tree, new_fi);
3916}
3917
3918proto_item *
3919proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3920 const int start, int length,
3921 const unsigned encoding, ws_in4_addr *retval)
3922{
3923 header_field_info *hfinfo;
3924 field_info *new_fi;
3925 ws_in4_addr value;
3926
3927 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", 3927, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3927,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3927, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3928
3929 switch (hfinfo->type) {
3930 case FT_IPv4:
3931 break;
3932 default:
3933 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)
3934 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3935 }
3936
3937 if (length != FT_IPv4_LEN4)
3938 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)
3939 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3940
3941 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3942 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3943 }
3944
3945 /*
3946 * NOTE: to support code written when proto_tree_add_item() took
3947 * a bool as its last argument, with false meaning "big-endian"
3948 * and true meaning "little-endian", we treat any non-zero value
3949 * of "encoding" as meaning "little-endian".
3950 */
3951 value = tvb_get_ipv4(tvb, start);
3952 if (encoding)
3953 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))))
;
3954
3955 if (retval) {
3956 *retval = value;
3957 }
3958
3959 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3960
3961 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", 3961
, __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", 3961, "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", 3961, "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", 3961, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
3962
3963 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3964
3965 proto_tree_set_ipv4(new_fi, value);
3966
3967 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3968 return proto_tree_add_node(tree, new_fi);
3969}
3970
3971proto_item *
3972proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3973 const int start, int length,
3974 const unsigned encoding, ws_in6_addr *addr)
3975{
3976 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3977 field_info *new_fi;
3978
3979 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", 3979,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3980
3981 switch (hfinfo->type) {
3982 case FT_IPv6:
3983 break;
3984 default:
3985 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)
3986 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
3987 }
3988
3989 if (length != FT_IPv6_LEN16)
3990 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)
3991 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
3992
3993 if (encoding) {
3994 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"
)
;
3995 }
3996
3997 tvb_get_ipv6(tvb, start, addr);
3998
3999 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4000
4001 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", 4001
, __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", 4001, "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", 4001, "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", 4001, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4002
4003 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4004
4005 proto_tree_set_ipv6(new_fi, addr);
4006
4007 return proto_tree_add_node(tree, new_fi);
4008}
4009
4010proto_item *
4011proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4012 const int start, int length, const unsigned encoding, uint8_t *retval) {
4013
4014 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4015 field_info *new_fi;
4016
4017 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", 4017,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4018
4019 switch (hfinfo->type) {
4020 case FT_ETHER:
4021 break;
4022 default:
4023 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)
4024 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4025 }
4026
4027 if (length != FT_ETHER_LEN6)
4028 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)
4029 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4030
4031 if (encoding) {
4032 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"
)
;
4033 }
4034
4035 tvb_memcpy(tvb, retval, start, length);
4036
4037 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4038
4039 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", 4039
, __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", 4039, "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", 4039, "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", 4039, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4040
4041 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4042
4043 proto_tree_set_ether(new_fi, retval);
4044
4045 return proto_tree_add_node(tree, new_fi);
4046}
4047
4048
4049proto_item *
4050proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4051 tvbuff_t *tvb,
4052 const int start, int length,
4053 const unsigned encoding,
4054 wmem_allocator_t *scope,
4055 const uint8_t **retval,
4056 int *lenretval)
4057{
4058 proto_item *pi;
4059 header_field_info *hfinfo;
4060 field_info *new_fi;
4061 const uint8_t *value;
4062
4063 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", 4063, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4063,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4063, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4064
4065 switch (hfinfo->type) {
4066 case FT_STRING:
4067 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4068 break;
4069 case FT_STRINGZ:
4070 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4071 break;
4072 case FT_UINT_STRING:
4073 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4074 break;
4075 case FT_STRINGZPAD:
4076 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4077 break;
4078 case FT_STRINGZTRUNC:
4079 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4080 break;
4081 default:
4082 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)
4083 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)
;
4084 }
4085
4086 if (retval)
4087 *retval = value;
4088
4089 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4090
4091 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", 4091
, __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", 4091, "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", 4091, "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", 4091, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4092
4093 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4094
4095 proto_tree_set_string(new_fi, value);
4096
4097 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4098
4099 pi = proto_tree_add_node(tree, new_fi);
4100
4101 switch (hfinfo->type) {
4102
4103 case FT_STRINGZ:
4104 case FT_STRINGZPAD:
4105 case FT_STRINGZTRUNC:
4106 case FT_UINT_STRING:
4107 break;
4108
4109 case FT_STRING:
4110 detect_trailing_stray_characters(encoding, value, length, pi);
4111 break;
4112
4113 default:
4114 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4114
, __func__, "assertion \"not reached\" failed")
;
4115 }
4116
4117 return pi;
4118}
4119
4120proto_item *
4121proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4122 const int start, int length,
4123 const unsigned encoding, wmem_allocator_t *scope,
4124 const uint8_t **retval)
4125{
4126 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4127 tvb, start, length, encoding, scope, retval, &length);
4128}
4129
4130proto_item *
4131proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4132 tvbuff_t *tvb,
4133 const int start, int length,
4134 const unsigned encoding,
4135 wmem_allocator_t *scope,
4136 char **retval,
4137 int *lenretval)
4138{
4139 proto_item *pi;
4140 header_field_info *hfinfo;
4141 field_info *new_fi;
4142 const uint8_t *value;
4143 uint32_t n = 0;
4144
4145 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", 4145, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4145,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4145, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4146
4147 switch (hfinfo->type) {
4148 case FT_STRING:
4149 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4150 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4151 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4152 break;
4153 case FT_STRINGZ:
4154 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4155 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4156 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4157 break;
4158 case FT_UINT_STRING:
4159 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4160 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4161 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4162 break;
4163 case FT_STRINGZPAD:
4164 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4165 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4166 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4167 break;
4168 case FT_STRINGZTRUNC:
4169 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4170 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4171 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4172 break;
4173 case FT_BYTES:
4174 tvb_ensure_bytes_exist(tvb, start, length);
4175 value = tvb_get_ptr(tvb, start, length);
4176 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4177 *lenretval = length;
4178 break;
4179 case FT_UINT_BYTES:
4180 n = get_uint_value(tree, tvb, start, length, encoding);
4181 tvb_ensure_bytes_exist(tvb, start + length, n);
4182 value = tvb_get_ptr(tvb, start + length, n);
4183 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4184 *lenretval = length + n;
4185 break;
4186 default:
4187 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)
4188 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)
;
4189 }
4190
4191 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4192
4193 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", 4193
, __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", 4193, "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", 4193, "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", 4193, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4194
4195 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4196
4197 switch (hfinfo->type) {
4198
4199 case FT_STRING:
4200 case FT_STRINGZ:
4201 case FT_UINT_STRING:
4202 case FT_STRINGZPAD:
4203 case FT_STRINGZTRUNC:
4204 proto_tree_set_string(new_fi, value);
4205 break;
4206
4207 case FT_BYTES:
4208 proto_tree_set_bytes(new_fi, value, length);
4209 break;
4210
4211 case FT_UINT_BYTES:
4212 proto_tree_set_bytes(new_fi, value, n);
4213 break;
4214
4215 default:
4216 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4216
, __func__, "assertion \"not reached\" failed")
;
4217 }
4218
4219 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4220
4221 pi = proto_tree_add_node(tree, new_fi);
4222
4223 switch (hfinfo->type) {
4224
4225 case FT_STRINGZ:
4226 case FT_STRINGZPAD:
4227 case FT_STRINGZTRUNC:
4228 case FT_UINT_STRING:
4229 break;
4230
4231 case FT_STRING:
4232 detect_trailing_stray_characters(encoding, value, length, pi);
4233 break;
4234
4235 case FT_BYTES:
4236 case FT_UINT_BYTES:
4237 break;
4238
4239 default:
4240 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4240
, __func__, "assertion \"not reached\" failed")
;
4241 }
4242
4243 return pi;
4244}
4245
4246proto_item *
4247proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4248 tvbuff_t *tvb,
4249 const int start, int length,
4250 const unsigned encoding,
4251 wmem_allocator_t *scope,
4252 char **retval)
4253{
4254 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4255 tvb, start, length, encoding, scope, retval, &length);
4256}
4257
4258proto_item *
4259proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4260 tvbuff_t *tvb,
4261 const int start, int length, const unsigned encoding,
4262 wmem_allocator_t *scope, char **retval)
4263{
4264 header_field_info *hfinfo;
4265 field_info *new_fi;
4266 nstime_t time_stamp;
4267 int flags;
4268
4269 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", 4269, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4269,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4269, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4270
4271 switch (hfinfo->type) {
4272 case FT_ABSOLUTE_TIME:
4273 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4274 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4275 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4276 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4277 }
4278 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4279 break;
4280 case FT_RELATIVE_TIME:
4281 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4282 *retval = rel_time_to_secs_str(scope, &time_stamp);
4283 break;
4284 default:
4285 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)
4286 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4287 }
4288
4289 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4290
4291 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", 4291
, __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", 4291, "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", 4291, "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", 4291, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4292
4293 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4294
4295 switch (hfinfo->type) {
4296
4297 case FT_ABSOLUTE_TIME:
4298 case FT_RELATIVE_TIME:
4299 proto_tree_set_time(new_fi, &time_stamp);
4300 break;
4301 default:
4302 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4302
, __func__, "assertion \"not reached\" failed")
;
4303 }
4304
4305 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4306
4307 return proto_tree_add_node(tree, new_fi);
4308}
4309
4310/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4311 and returns proto_item* */
4312proto_item *
4313ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4314 const unsigned encoding)
4315{
4316 field_info *new_fi;
4317 header_field_info *hfinfo;
4318 int item_length;
4319 int offset;
4320
4321 offset = ptvc->offset;
4322 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", 4322, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4322,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4322, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4323 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4324 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4325
4326 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
4327 item_length, encoding);
4328
4329 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4330
4331 /* Coast clear. Try and fake it */
4332 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", 4332
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4332, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4332, "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", 4332, __func__, "Adding %s would put more than %d 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); } } }
;
4333
4334 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4335
4336 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4337 offset, length, encoding);
4338}
4339
4340/* Add an item to a proto_tree, using the text label registered to that item;
4341 the item is extracted from the tvbuff handed to it. */
4342proto_item *
4343proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4344 const int start, int length, const unsigned encoding)
4345{
4346 field_info *new_fi;
4347 int item_length;
4348
4349 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", 4349,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4350
4351 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4352 test_length(hfinfo, tvb, start, item_length, encoding);
4353
4354 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4355
4356 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", 4356
, __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", 4356, "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", 4356, "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", 4356, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4357
4358 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4359
4360 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4361}
4362
4363proto_item *
4364proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4365 const int start, int length, const unsigned encoding)
4366{
4367 register header_field_info *hfinfo;
4368
4369 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", 4369, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4369,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4369, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4370 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4371}
4372
4373/* Add an item to a proto_tree, using the text label registered to that item;
4374 the item is extracted from the tvbuff handed to it.
4375
4376 Return the length of the item through the pointer. */
4377proto_item *
4378proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4379 tvbuff_t *tvb, const int start,
4380 int length, const unsigned encoding,
4381 int *lenretval)
4382{
4383 field_info *new_fi;
4384 int item_length;
4385 proto_item *item;
4386
4387 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", 4387,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4388
4389 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4390 test_length(hfinfo, tvb, start, item_length, encoding);
4391
4392 if (!tree) {
4393 /*
4394 * We need to get the correct item length here.
4395 * That's normally done by proto_tree_new_item(),
4396 * but we won't be calling it.
4397 */
4398 *lenretval = get_full_length(hfinfo, tvb, start, length,
4399 item_length, encoding);
4400 return NULL((void*)0);
4401 }
4402
4403 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", 4410
, __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", 4410, "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", 4410, "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", 4410
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 /*((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", 4410
, __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", 4410, "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", 4410, "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", 4410
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4405 * 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", 4410
, __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", 4410, "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", 4410, "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", 4410
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4406 * 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", 4410
, __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", 4410, "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", 4410, "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", 4410
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4407 */((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", 4410
, __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", 4410, "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", 4410, "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", 4410
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4408 *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", 4410
, __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", 4410, "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", 4410, "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", 4410
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { *lenretval = get_full_length(hfinfo, tvb, start, length
, item_length, encoding); }; return proto_tree_add_fake_node(
tree, hfinfo); } } }
4409 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", 4410
, __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", 4410, "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", 4410, "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", 4410
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4410 })((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", 4410
, __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", 4410, "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", 4410, "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", 4410
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4411
4412 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4413
4414 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4415 *lenretval = new_fi->length;
4416 return item;
4417}
4418
4419proto_item *
4420proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4421 const int start, int length,
4422 const unsigned encoding, int *lenretval)
4423{
4424 register header_field_info *hfinfo;
4425
4426 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", 4426, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4426,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4426, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4427 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4428}
4429
4430/* which FT_ types can use proto_tree_add_bytes_item() */
4431static inline bool_Bool
4432validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4433{
4434 return (type == FT_BYTES ||
4435 type == FT_UINT_BYTES ||
4436 type == FT_OID ||
4437 type == FT_REL_OID ||
4438 type == FT_SYSTEM_ID );
4439}
4440
4441/* Note: this does no validation that the byte array of an FT_OID or
4442 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4443 so I think it's ok to continue not validating it?
4444 */
4445proto_item *
4446proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4447 const int start, int length, const unsigned encoding,
4448 GByteArray *retval, int *endoff, int *err)
4449{
4450 field_info *new_fi;
4451 GByteArray *bytes = retval;
4452 GByteArray *created_bytes = NULL((void*)0);
4453 bool_Bool failed = false0;
4454 uint32_t n = 0;
4455 header_field_info *hfinfo;
4456 bool_Bool generate = (bytes || tree) ? true1 : false0;
4457
4458 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", 4458, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4458,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4458, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4459
4460 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", 4460,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4461
4462 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", 4463, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4463 "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", 4463, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4464
4465 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4466
4467 if (encoding & ENC_STR_NUM0x01000000) {
4468 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"
)
;
4469 }
4470
4471 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4472 if (hfinfo->type == FT_UINT_BYTES) {
4473 /* can't decode FT_UINT_BYTES from strings */
4474 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")
4475 "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")
;
4476 }
4477
4478 unsigned hex_encoding = encoding;
4479 if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4480 /* If none of the separator values are used,
4481 * assume no separator (the common case). */
4482 hex_encoding |= ENC_SEP_NONE0x00010000;
4483#if 0
4484 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")
4485 "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")
;
4486#endif
4487 }
4488
4489 if (!bytes) {
4490 /* caller doesn't care about return value, but we need it to
4491 call tvb_get_string_bytes() and set the tree later */
4492 bytes = created_bytes = g_byte_array_new();
4493 }
4494
4495 /*
4496 * bytes might be NULL after this, but can't add expert
4497 * error until later; if it's NULL, just note that
4498 * it failed.
4499 */
4500 bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4501 if (bytes == NULL((void*)0))
4502 failed = true1;
4503 }
4504 else if (generate) {
4505 tvb_ensure_bytes_exist(tvb, start, length);
4506
4507 if (hfinfo->type == FT_UINT_BYTES) {
4508 n = length; /* n is now the "header" length */
4509 length = get_uint_value(tree, tvb, start, n, encoding);
4510 /* length is now the value's length; only store the value in the array */
4511 tvb_ensure_bytes_exist(tvb, start + n, length);
4512 if (!bytes) {
4513 /* caller doesn't care about return value, but
4514 * we may need it to set the tree later */
4515 bytes = created_bytes = g_byte_array_new();
4516 }
4517 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4518 }
4519 else if (length > 0) {
4520 if (!bytes) {
4521 /* caller doesn't care about return value, but
4522 * we may need it to set the tree later */
4523 bytes = created_bytes = g_byte_array_new();
4524 }
4525 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4526 }
4527
4528 if (endoff)
4529 *endoff = start + n + length;
4530 }
4531
4532 if (err)
4533 *err = failed ? EINVAL22 : 0;
4534
4535 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); }
4536 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4537 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); }
4538 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); }
4539 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); }
4540 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4541 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4542
4543 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", 4549
, __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", 4549, "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", 4549, "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", 4549
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4544 {((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", 4549
, __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", 4549, "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", 4549, "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", 4549
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4545 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", 4549
, __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", 4549, "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", 4549, "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", 4549
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4546 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", 4549
, __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", 4549, "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", 4549, "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", 4549
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4547 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", 4549
, __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", 4549, "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", 4549, "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", 4549
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { { if (created_bytes) g_byte_array_free(created_bytes, 1)
; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node
(tree, hfinfo); } } }
4548 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", 4549
, __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", 4549, "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", 4549, "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", 4549
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
4549 } )((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", 4549
, __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", 4549, "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", 4549, "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", 4549
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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); } } }
;
4550
4551 /* n will be zero except when it's a FT_UINT_BYTES */
4552 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4553
4554 if (encoding & ENC_STRING0x03000000) {
4555 if (failed)
4556 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4557
4558 if (bytes)
4559 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4560 else
4561 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4562
4563 if (created_bytes)
4564 g_byte_array_free(created_bytes, true1);
4565 }
4566 else {
4567 /* n will be zero except when it's a FT_UINT_BYTES */
4568 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4569
4570 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4571 * use the byte array created above in this case.
4572 */
4573 if (created_bytes)
4574 g_byte_array_free(created_bytes, true1);
4575
4576 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4577 (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)
;
4578 }
4579
4580 return proto_tree_add_node(tree, new_fi);
4581}
4582
4583
4584proto_item *
4585proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4586 const int start, int length, const unsigned encoding,
4587 nstime_t *retval, int *endoff, int *err)
4588{
4589 field_info *new_fi;
4590 nstime_t time_stamp;
4591 int saved_err = 0;
4592 header_field_info *hfinfo;
4593
4594 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", 4594, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4594,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4594, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4595
4596 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", 4596,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4597
4598 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4599 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4600 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4601 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4602 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4603 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4604 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4605
4606 nstime_set_zero(&time_stamp);
4607
4608 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4609 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", 4609, ((hfinfo))->abbrev))))
;
4610 /* The only string format that could be a relative time is
4611 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4612 * relative to "now" currently.
4613 */
4614 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4615 saved_err = EINVAL22;
4616 }
4617 else {
4618 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", 4618, ((hfinfo))->abbrev))))
;
4619 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4620
4621 tvb_ensure_bytes_exist(tvb, start, length);
4622 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4623 if (endoff) *endoff = start + length;
4624 }
4625
4626 if (err) *err = saved_err;
4627
4628 if (retval) {
4629 retval->secs = time_stamp.secs;
4630 retval->nsecs = time_stamp.nsecs;
4631 }
4632
4633 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4634
4635 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", 4635
, __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", 4635, "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", 4635, "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", 4635, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4636
4637 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4638
4639 proto_tree_set_time(new_fi, &time_stamp);
4640
4641 if (encoding & ENC_STRING0x03000000) {
4642 if (saved_err)
4643 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4644 }
4645 else {
4646 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4647 (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)
;
4648 }
4649
4650 return proto_tree_add_node(tree, new_fi);
4651}
4652
4653/* Add a FT_NONE to a proto_tree */
4654proto_item *
4655proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4656 const int start, int length, const char *format,
4657 ...)
4658{
4659 proto_item *pi;
4660 va_list ap;
4661 header_field_info *hfinfo;
4662
4663 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4664
4665 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", 4665
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4665, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4665, "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", 4665, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4666
4667 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", 4667
, ((hfinfo))->abbrev))))
;
4668
4669 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4670
4671 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4671, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4672
4673 va_start(ap, format)__builtin_va_start(ap, format);
4674 proto_tree_set_representation(pi, format, ap);
4675 va_end(ap)__builtin_va_end(ap);
4676
4677 /* no value to set for FT_NONE */
4678 return pi;
4679}
4680
4681/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4682 * offset, and returns proto_item* */
4683proto_item *
4684ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4685 const unsigned encoding)
4686{
4687 proto_item *item;
4688
4689 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4690 length, encoding);
4691
4692 return item;
4693}
4694
4695/* Advance the ptvcursor's offset within its tvbuff without
4696 * adding anything to the proto_tree. */
4697void
4698ptvcursor_advance(ptvcursor_t* ptvc, int length)
4699{
4700 ptvc->offset += length;
4701}
4702
4703
4704static void
4705proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4706{
4707 fvalue_set_protocol(fi->value, tvb, field_data, length);
4708}
4709
4710/* Add a FT_PROTOCOL to a proto_tree */
4711proto_item *
4712proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4713 int start, int length, const char *format, ...)
4714{
4715 proto_item *pi;
4716 tvbuff_t *protocol_tvb;
4717 va_list ap;
4718 header_field_info *hfinfo;
4719 char* protocol_rep;
4720
4721 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4722
4723 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", 4723
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4723, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4723, "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", 4723, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4724
4725 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"
, 4725, ((hfinfo))->abbrev))))
;
4726
4727 /*
4728 * This can throw an exception, so do it before we allocate anything.
4729 */
4730 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4731
4732 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4733
4734 va_start(ap, format)__builtin_va_start(ap, format);
4735 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4736 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4737 g_free(protocol_rep);
4738 va_end(ap)__builtin_va_end(ap);
4739
4740 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4740, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4741
4742 va_start(ap, format)__builtin_va_start(ap, format);
4743 proto_tree_set_representation(pi, format, ap);
4744 va_end(ap)__builtin_va_end(ap);
4745
4746 return pi;
4747}
4748
4749/* Add a FT_BYTES to a proto_tree */
4750proto_item *
4751proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4752 int length, const uint8_t *start_ptr)
4753{
4754 proto_item *pi;
4755 header_field_info *hfinfo;
4756 int item_length;
4757
4758 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", 4758, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4758,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4758, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4759 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4760 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4761
4762 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4763
4764 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", 4764
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4764, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4764, "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", 4764, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4765
4766 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",
4766, ((hfinfo))->abbrev))))
;
4767
4768 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4769 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4770
4771 return pi;
4772}
4773
4774/* Add a FT_BYTES to a proto_tree */
4775proto_item *
4776proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4777 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4778{
4779 proto_item *pi;
4780 header_field_info *hfinfo;
4781 int item_length;
4782
4783 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", 4783, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4783,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4783, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4784 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4785 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4786
4787 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4788
4789 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", 4789
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4789, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4789, "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", 4789, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4790
4791 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",
4791, ((hfinfo))->abbrev))))
;
4792
4793 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4794 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4795
4796 return pi;
4797}
4798
4799proto_item *
4800proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4801 int start, int length,
4802 const uint8_t *start_ptr,
4803 const char *format, ...)
4804{
4805 proto_item *pi;
4806 va_list ap;
4807
4808 if (start_ptr == NULL((void*)0))
4809 start_ptr = tvb_get_ptr(tvb, start, length);
4810
4811 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4812
4813 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; }
;
4814
4815 va_start(ap, format)__builtin_va_start(ap, format);
4816 proto_tree_set_representation_value(pi, format, ap);
4817 va_end(ap)__builtin_va_end(ap);
4818
4819 return pi;
4820}
4821
4822proto_item *
4823proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4824 int start, int length, const uint8_t *start_ptr,
4825 const char *format, ...)
4826{
4827 proto_item *pi;
4828 va_list ap;
4829
4830 if (start_ptr == NULL((void*)0))
4831 start_ptr = tvb_get_ptr(tvb, start, length);
4832
4833 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4834
4835 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; }
;
4836
4837 va_start(ap, format)__builtin_va_start(ap, format);
4838 proto_tree_set_representation(pi, format, ap);
4839 va_end(ap)__builtin_va_end(ap);
4840
4841 return pi;
4842}
4843
4844static void
4845proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4846{
4847 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4847, "length >= 0"
))))
;
4848 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", 4848, "start_ptr != ((void*)0) || length == 0"
))))
;
4849
4850 fvalue_set_bytes_data(fi->value, start_ptr, length);
4851}
4852
4853
4854static void
4855proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4856{
4857 tvb_ensure_bytes_exist(tvb, offset, length);
4858 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4859}
4860
4861static void
4862proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4863{
4864 GByteArray *bytes;
4865
4866 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4866, "value != ((void*)0)"
))))
;
4867
4868 bytes = byte_array_dup(value);
4869
4870 fvalue_set_byte_array(fi->value, bytes);
4871}
4872
4873/* Add a FT_*TIME to a proto_tree */
4874proto_item *
4875proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4876 int length, const nstime_t *value_ptr)
4877{
4878 proto_item *pi;
4879 header_field_info *hfinfo;
4880
4881 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4882
4883 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", 4883
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4883, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4883, "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", 4883, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4884
4885 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", 4885, ((hfinfo))->abbrev))))
;
4886
4887 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4888 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4889
4890 return pi;
4891}
4892
4893proto_item *
4894proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4895 int start, int length, nstime_t *value_ptr,
4896 const char *format, ...)
4897{
4898 proto_item *pi;
4899 va_list ap;
4900
4901 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4902 if (pi != tree) {
4903 va_start(ap, format)__builtin_va_start(ap, format);
4904 proto_tree_set_representation_value(pi, format, ap);
4905 va_end(ap)__builtin_va_end(ap);
4906 }
4907
4908 return pi;
4909}
4910
4911proto_item *
4912proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4913 int start, int length, nstime_t *value_ptr,
4914 const char *format, ...)
4915{
4916 proto_item *pi;
4917 va_list ap;
4918
4919 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4920 if (pi != tree) {
4921 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4921, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4922
4923 va_start(ap, format)__builtin_va_start(ap, format);
4924 proto_tree_set_representation(pi, format, ap);
4925 va_end(ap)__builtin_va_end(ap);
4926 }
4927
4928 return pi;
4929}
4930
4931/* Set the FT_*TIME value */
4932static void
4933proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4934{
4935 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4935, "value_ptr != ((void*)0)"
))))
;
4936
4937 fvalue_set_time(fi->value, value_ptr);
4938}
4939
4940/* Add a FT_IPXNET to a proto_tree */
4941proto_item *
4942proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4943 int length, uint32_t value)
4944{
4945 proto_item *pi;
4946 header_field_info *hfinfo;
4947
4948 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4949
4950 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", 4950
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4950, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4950, "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", 4950, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
4951
4952 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"
, 4952, ((hfinfo))->abbrev))))
;
4953
4954 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4955 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
4956
4957 return pi;
4958}
4959
4960proto_item *
4961proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4962 int start, int length, uint32_t value,
4963 const char *format, ...)
4964{
4965 proto_item *pi;
4966 va_list ap;
4967
4968 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4969 if (pi != tree) {
4970 va_start(ap, format)__builtin_va_start(ap, format);
4971 proto_tree_set_representation_value(pi, format, ap);
4972 va_end(ap)__builtin_va_end(ap);
4973 }
4974
4975 return pi;
4976}
4977
4978proto_item *
4979proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4980 int start, int length, uint32_t value,
4981 const char *format, ...)
4982{
4983 proto_item *pi;
4984 va_list ap;
4985
4986 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4987 if (pi != tree) {
4988 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4988, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
4989
4990 va_start(ap, format)__builtin_va_start(ap, format);
4991 proto_tree_set_representation(pi, format, ap);
4992 va_end(ap)__builtin_va_end(ap);
4993 }
4994
4995 return pi;
4996}
4997
4998/* Set the FT_IPXNET value */
4999static void
5000proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5001{
5002 fvalue_set_uinteger(fi->value, value);
5003}
5004
5005/* Add a FT_IPv4 to a proto_tree */
5006proto_item *
5007proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5008 int length, ws_in4_addr value)
5009{
5010 proto_item *pi;
5011 header_field_info *hfinfo;
5012
5013 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5014
5015 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", 5015
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5015, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5015, "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", 5015, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5016
5017 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", 5017
, ((hfinfo))->abbrev))))
;
5018
5019 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5020 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5021
5022 return pi;
5023}
5024
5025proto_item *
5026proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5027 int start, int length, ws_in4_addr value,
5028 const char *format, ...)
5029{
5030 proto_item *pi;
5031 va_list ap;
5032
5033 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5034 if (pi != tree) {
5035 va_start(ap, format)__builtin_va_start(ap, format);
5036 proto_tree_set_representation_value(pi, format, ap);
5037 va_end(ap)__builtin_va_end(ap);
5038 }
5039
5040 return pi;
5041}
5042
5043proto_item *
5044proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5045 int start, int length, ws_in4_addr value,
5046 const char *format, ...)
5047{
5048 proto_item *pi;
5049 va_list ap;
5050
5051 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5052 if (pi != tree) {
5053 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5053, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5054
5055 va_start(ap, format)__builtin_va_start(ap, format);
5056 proto_tree_set_representation(pi, format, ap);
5057 va_end(ap)__builtin_va_end(ap);
5058 }
5059
5060 return pi;
5061}
5062
5063/* Set the FT_IPv4 value */
5064static void
5065proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5066{
5067 ipv4_addr_and_mask ipv4;
5068 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5069 fvalue_set_ipv4(fi->value, &ipv4);
5070}
5071
5072/* Add a FT_IPv6 to a proto_tree */
5073proto_item *
5074proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5075 int length, const ws_in6_addr *value)
5076{
5077 proto_item *pi;
5078 header_field_info *hfinfo;
5079
5080 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5081
5082 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", 5082
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5082, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5082, "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", 5082, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5083
5084 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", 5084
, ((hfinfo))->abbrev))))
;
5085
5086 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5087 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5088
5089 return pi;
5090}
5091
5092proto_item *
5093proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5094 int start, int length,
5095 const ws_in6_addr *value_ptr,
5096 const char *format, ...)
5097{
5098 proto_item *pi;
5099 va_list ap;
5100
5101 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5102 if (pi != tree) {
5103 va_start(ap, format)__builtin_va_start(ap, format);
5104 proto_tree_set_representation_value(pi, format, ap);
5105 va_end(ap)__builtin_va_end(ap);
5106 }
5107
5108 return pi;
5109}
5110
5111proto_item *
5112proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5113 int start, int length,
5114 const ws_in6_addr *value_ptr,
5115 const char *format, ...)
5116{
5117 proto_item *pi;
5118 va_list ap;
5119
5120 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5121 if (pi != tree) {
5122 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5122, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5123
5124 va_start(ap, format)__builtin_va_start(ap, format);
5125 proto_tree_set_representation(pi, format, ap);
5126 va_end(ap)__builtin_va_end(ap);
5127 }
5128
5129 return pi;
5130}
5131
5132/* Set the FT_IPv6 value */
5133static void
5134proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5135{
5136 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5136, "value != ((void*)0)"
))))
;
5137 ipv6_addr_and_prefix ipv6;
5138 ipv6.addr = *value;
5139 ipv6.prefix = 128;
5140 fvalue_set_ipv6(fi->value, &ipv6);
5141}
5142
5143static void
5144proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5145{
5146 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5147}
5148
5149/* Set the FT_FCWWN value */
5150static void
5151proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5152{
5153 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5153, "value_ptr != ((void*)0)"
))))
;
5154 fvalue_set_fcwwn(fi->value, value_ptr);
5155}
5156
5157static void
5158proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5159{
5160 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5161}
5162
5163/* Add a FT_GUID to a proto_tree */
5164proto_item *
5165proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5166 int length, const e_guid_t *value_ptr)
5167{
5168 proto_item *pi;
5169 header_field_info *hfinfo;
5170
5171 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5172
5173 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", 5173
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5173, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5173, "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", 5173, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5174
5175 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", 5175
, ((hfinfo))->abbrev))))
;
5176
5177 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5178 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5179
5180 return pi;
5181}
5182
5183proto_item *
5184proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5185 int start, int length,
5186 const e_guid_t *value_ptr,
5187 const char *format, ...)
5188{
5189 proto_item *pi;
5190 va_list ap;
5191
5192 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5193 if (pi != tree) {
5194 va_start(ap, format)__builtin_va_start(ap, format);
5195 proto_tree_set_representation_value(pi, format, ap);
5196 va_end(ap)__builtin_va_end(ap);
5197 }
5198
5199 return pi;
5200}
5201
5202proto_item *
5203proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5204 int start, int length, const e_guid_t *value_ptr,
5205 const char *format, ...)
5206{
5207 proto_item *pi;
5208 va_list ap;
5209
5210 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5211 if (pi != tree) {
5212 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5212, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5213
5214 va_start(ap, format)__builtin_va_start(ap, format);
5215 proto_tree_set_representation(pi, format, ap);
5216 va_end(ap)__builtin_va_end(ap);
5217 }
5218
5219 return pi;
5220}
5221
5222/* Set the FT_GUID value */
5223static void
5224proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5225{
5226 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5226, "value_ptr != ((void*)0)"
))))
;
5227 fvalue_set_guid(fi->value, value_ptr);
5228}
5229
5230static void
5231proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5232 const unsigned encoding)
5233{
5234 e_guid_t guid;
5235
5236 tvb_get_guid(tvb, start, &guid, encoding);
5237 proto_tree_set_guid(fi, &guid);
5238}
5239
5240/* Add a FT_OID to a proto_tree */
5241proto_item *
5242proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5243 int length, const uint8_t* value_ptr)
5244{
5245 proto_item *pi;
5246 header_field_info *hfinfo;
5247
5248 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5249
5250 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", 5250
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5250, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5250, "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", 5250, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5251
5252 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", 5252
, ((hfinfo))->abbrev))))
;
5253
5254 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5255 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5256
5257 return pi;
5258}
5259
5260proto_item *
5261proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5262 int start, int length,
5263 const uint8_t* value_ptr,
5264 const char *format, ...)
5265{
5266 proto_item *pi;
5267 va_list ap;
5268
5269 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5270 if (pi != tree) {
5271 va_start(ap, format)__builtin_va_start(ap, format);
5272 proto_tree_set_representation_value(pi, format, ap);
5273 va_end(ap)__builtin_va_end(ap);
5274 }
5275
5276 return pi;
5277}
5278
5279proto_item *
5280proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5281 int start, int length, const uint8_t* value_ptr,
5282 const char *format, ...)
5283{
5284 proto_item *pi;
5285 va_list ap;
5286
5287 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5288 if (pi != tree) {
5289 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5289, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5290
5291 va_start(ap, format)__builtin_va_start(ap, format);
5292 proto_tree_set_representation(pi, format, ap);
5293 va_end(ap)__builtin_va_end(ap);
5294 }
5295
5296 return pi;
5297}
5298
5299/* Set the FT_OID value */
5300static void
5301proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5302{
5303 GByteArray *bytes;
5304
5305 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", 5305, "value_ptr != ((void*)0) || length == 0"
))))
;
5306
5307 bytes = g_byte_array_new();
5308 if (length > 0) {
5309 g_byte_array_append(bytes, value_ptr, length);
5310 }
5311 fvalue_set_byte_array(fi->value, bytes);
5312}
5313
5314static void
5315proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5316{
5317 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5318}
5319
5320/* Set the FT_SYSTEM_ID value */
5321static void
5322proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5323{
5324 GByteArray *bytes;
5325
5326 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", 5326, "value_ptr != ((void*)0) || length == 0"
))))
;
5327
5328 bytes = g_byte_array_new();
5329 if (length > 0) {
5330 g_byte_array_append(bytes, value_ptr, length);
5331 }
5332 fvalue_set_byte_array(fi->value, bytes);
5333}
5334
5335static void
5336proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5337{
5338 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5339}
5340
5341/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5342 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5343 * is destroyed. */
5344proto_item *
5345proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5346 int length, const char* value)
5347{
5348 proto_item *pi;
5349 header_field_info *hfinfo;
5350 int item_length;
5351
5352 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", 5352, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5352,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5352, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5353 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5354 /*
5355 * Special case - if the length is 0, skip the test, so that
5356 * we can have an empty string right after the end of the
5357 * packet. (This handles URL-encoded forms where the last field
5358 * has no value so the form ends right after the =.)
5359 */
5360 if (item_length != 0)
5361 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5362
5363 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5364
5365 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", 5365
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5365, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5365, "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", 5365, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5366
5367 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", 5367, ((hfinfo))->abbrev))))
;
5368
5369 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5370 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5370, "length >= 0"
))))
;
5371
5372 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", 5372, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5373 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5374
5375 return pi;
5376}
5377
5378proto_item *
5379proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5380 int start, int length, const char* value,
5381 const char *format,
5382 ...)
5383{
5384 proto_item *pi;
5385 va_list ap;
5386
5387 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5388 if (pi != tree) {
5389 va_start(ap, format)__builtin_va_start(ap, format);
5390 proto_tree_set_representation_value(pi, format, ap);
5391 va_end(ap)__builtin_va_end(ap);
5392 }
5393
5394 return pi;
5395}
5396
5397proto_item *
5398proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5399 int start, int length, const char* value,
5400 const char *format, ...)
5401{
5402 proto_item *pi;
5403 va_list ap;
5404
5405 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5406 if (pi != tree) {
5407 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5407, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5408
5409 va_start(ap, format)__builtin_va_start(ap, format);
5410 proto_tree_set_representation(pi, format, ap);
5411 va_end(ap)__builtin_va_end(ap);
5412 }
5413
5414 return pi;
5415}
5416
5417/* Set the FT_STRING value */
5418static void
5419proto_tree_set_string(field_info *fi, const char* value)
5420{
5421 if (value) {
5422 fvalue_set_string(fi->value, value);
5423 } else {
5424 /*
5425 * XXX - why is a null value for a string field
5426 * considered valid?
5427 */
5428 fvalue_set_string(fi->value, "[ Null ]");
5429 }
5430}
5431
5432/* Set the FT_AX25 value */
5433static void
5434proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5435{
5436 fvalue_set_ax25(fi->value, value);
5437}
5438
5439static void
5440proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5441{
5442 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5443}
5444
5445/* Set the FT_VINES value */
5446static void
5447proto_tree_set_vines(field_info *fi, const uint8_t* value)
5448{
5449 fvalue_set_vines(fi->value, value);
5450}
5451
5452static void
5453proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5454{
5455 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5456}
5457
5458/* Add a FT_ETHER to a proto_tree */
5459proto_item *
5460proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5461 int length, const uint8_t* value)
5462{
5463 proto_item *pi;
5464 header_field_info *hfinfo;
5465
5466 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5467
5468 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", 5468
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5468, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5468, "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", 5468, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5469
5470 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",
5470, ((hfinfo))->abbrev))))
;
5471
5472 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5473 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5474
5475 return pi;
5476}
5477
5478proto_item *
5479proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5480 int start, int length, const uint8_t* value,
5481 const char *format, ...)
5482{
5483 proto_item *pi;
5484 va_list ap;
5485
5486 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5487 if (pi != tree) {
5488 va_start(ap, format)__builtin_va_start(ap, format);
5489 proto_tree_set_representation_value(pi, format, ap);
5490 va_end(ap)__builtin_va_end(ap);
5491 }
5492
5493 return pi;
5494}
5495
5496proto_item *
5497proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5498 int start, int length, const uint8_t* value,
5499 const char *format, ...)
5500{
5501 proto_item *pi;
5502 va_list ap;
5503
5504 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5505 if (pi != tree) {
5506 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5506, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5507
5508 va_start(ap, format)__builtin_va_start(ap, format);
5509 proto_tree_set_representation(pi, format, ap);
5510 va_end(ap)__builtin_va_end(ap);
5511 }
5512
5513 return pi;
5514}
5515
5516/* Set the FT_ETHER value */
5517static void
5518proto_tree_set_ether(field_info *fi, const uint8_t* value)
5519{
5520 fvalue_set_ether(fi->value, value);
5521}
5522
5523static void
5524proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5525{
5526 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5527}
5528
5529/* Add a FT_BOOLEAN to a proto_tree */
5530proto_item *
5531proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5532 int length, uint64_t value)
5533{
5534 proto_item *pi;
5535 header_field_info *hfinfo;
5536
5537 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5538
5539 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", 5539
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5539, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5539, "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", 5539, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5540
5541 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"
, 5541, ((hfinfo))->abbrev))))
;
5542
5543 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5544 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5545
5546 return pi;
5547}
5548
5549proto_item *
5550proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5551 tvbuff_t *tvb, int start, int length,
5552 uint64_t value, const char *format, ...)
5553{
5554 proto_item *pi;
5555 va_list ap;
5556
5557 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5558 if (pi != tree) {
5559 va_start(ap, format)__builtin_va_start(ap, format);
5560 proto_tree_set_representation_value(pi, format, ap);
5561 va_end(ap)__builtin_va_end(ap);
5562 }
5563
5564 return pi;
5565}
5566
5567proto_item *
5568proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5569 int start, int length, uint64_t value,
5570 const char *format, ...)
5571{
5572 proto_item *pi;
5573 va_list ap;
5574
5575 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5576 if (pi != tree) {
5577 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5577, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5578
5579 va_start(ap, format)__builtin_va_start(ap, format);
5580 proto_tree_set_representation(pi, format, ap);
5581 va_end(ap)__builtin_va_end(ap);
5582 }
5583
5584 return pi;
5585}
5586
5587/* Set the FT_BOOLEAN value */
5588static void
5589proto_tree_set_boolean(field_info *fi, uint64_t value)
5590{
5591 proto_tree_set_uint64(fi, value);
5592}
5593
5594/* Generate, into "buf", a string showing the bits of a bitfield.
5595 Return a pointer to the character after that string. */
5596static char *
5597other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5598{
5599 int i = 0;
5600 uint64_t bit;
5601 char *p;
5602
5603 p = buf;
5604
5605 /* This is a devel error. It is safer to stop here. */
5606 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5606, "width >= 1"
))))
;
5607
5608 bit = UINT64_C(1)1UL << (width - 1);
5609 for (;;) {
5610 if (mask & bit) {
5611 /* This bit is part of the field. Show its value. */
5612 if (val & bit)
5613 *p++ = '1';
5614 else
5615 *p++ = '0';
5616 } else {
5617 /* This bit is not part of the field. */
5618 *p++ = '.';
5619 }
5620 bit >>= 1;
5621 i++;
5622 if (i >= width)
5623 break;
5624 if (i % 4 == 0)
5625 *p++ = ' ';
5626 }
5627 *p = '\0';
5628 return p;
5629}
5630
5631static char *
5632decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5633{
5634 char *p;
5635
5636 p = other_decode_bitfield_value(buf, val, mask, width);
5637 p = g_stpcpy(p, " = ");
5638
5639 return p;
5640}
5641
5642static char *
5643other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5644{
5645 int i = 0;
5646 uint64_t bit;
5647 char *p;
5648
5649 p = buf;
5650
5651 /* This is a devel error. It is safer to stop here. */
5652 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5652, "width >= 1"
))))
;
5653
5654 bit = UINT64_C(1)1UL << (width - 1);
5655 for (;;) {
5656 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5657 (mask & bit)) {
5658 /* This bit is part of the field. Show its value. */
5659 if (val & bit)
5660 *p++ = '1';
5661 else
5662 *p++ = '0';
5663 } else {
5664 /* This bit is not part of the field. */
5665 *p++ = '.';
5666 }
5667 bit >>= 1;
5668 i++;
5669 if (i >= width)
5670 break;
5671 if (i % 4 == 0)
5672 *p++ = ' ';
5673 }
5674
5675 *p = '\0';
5676 return p;
5677}
5678
5679static char *
5680decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5681{
5682 char *p;
5683
5684 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5685 p = g_stpcpy(p, " = ");
5686
5687 return p;
5688}
5689
5690/* Add a FT_FLOAT to a proto_tree */
5691proto_item *
5692proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5693 int length, float value)
5694{
5695 proto_item *pi;
5696 header_field_info *hfinfo;
5697
5698 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5699
5700 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", 5700
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5700, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5700, "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", 5700, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5701
5702 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",
5702, ((hfinfo))->abbrev))))
;
5703
5704 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5705 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5706
5707 return pi;
5708}
5709
5710proto_item *
5711proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5712 int start, int length, float value,
5713 const char *format, ...)
5714{
5715 proto_item *pi;
5716 va_list ap;
5717
5718 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5719 if (pi != tree) {
5720 va_start(ap, format)__builtin_va_start(ap, format);
5721 proto_tree_set_representation_value(pi, format, ap);
5722 va_end(ap)__builtin_va_end(ap);
5723 }
5724
5725 return pi;
5726}
5727
5728proto_item *
5729proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5730 int start, int length, float value,
5731 const char *format, ...)
5732{
5733 proto_item *pi;
5734 va_list ap;
5735
5736 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5737 if (pi != tree) {
5738 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5738, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5739
5740 va_start(ap, format)__builtin_va_start(ap, format);
5741 proto_tree_set_representation(pi, format, ap);
5742 va_end(ap)__builtin_va_end(ap);
5743 }
5744
5745 return pi;
5746}
5747
5748/* Set the FT_FLOAT value */
5749static void
5750proto_tree_set_float(field_info *fi, float value)
5751{
5752 fvalue_set_floating(fi->value, value);
5753}
5754
5755/* Add a FT_DOUBLE to a proto_tree */
5756proto_item *
5757proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5758 int length, double value)
5759{
5760 proto_item *pi;
5761 header_field_info *hfinfo;
5762
5763 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5764
5765 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", 5765
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5765, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5765, "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", 5765, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5766
5767 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"
, 5767, ((hfinfo))->abbrev))))
;
5768
5769 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5770 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5771
5772 return pi;
5773}
5774
5775proto_item *
5776proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5777 int start, int length, double value,
5778 const char *format, ...)
5779{
5780 proto_item *pi;
5781 va_list ap;
5782
5783 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5784 if (pi != tree) {
5785 va_start(ap, format)__builtin_va_start(ap, format);
5786 proto_tree_set_representation_value(pi, format, ap);
5787 va_end(ap)__builtin_va_end(ap);
5788 }
5789
5790 return pi;
5791}
5792
5793proto_item *
5794proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5795 int start, int length, double value,
5796 const char *format, ...)
5797{
5798 proto_item *pi;
5799 va_list ap;
5800
5801 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5802 if (pi != tree) {
5803 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5803, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5804
5805 va_start(ap, format)__builtin_va_start(ap, format);
5806 proto_tree_set_representation(pi, format, ap);
5807 va_end(ap)__builtin_va_end(ap);
5808 }
5809
5810 return pi;
5811}
5812
5813/* Set the FT_DOUBLE value */
5814static void
5815proto_tree_set_double(field_info *fi, double value)
5816{
5817 fvalue_set_floating(fi->value, value);
5818}
5819
5820/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5821proto_item *
5822proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5823 int length, uint32_t value)
5824{
5825 proto_item *pi = NULL((void*)0);
5826 header_field_info *hfinfo;
5827
5828 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5829
5830 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", 5830
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5830, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5830, "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", 5830, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5831
5832 switch (hfinfo->type) {
5833 case FT_CHAR:
5834 case FT_UINT8:
5835 case FT_UINT16:
5836 case FT_UINT24:
5837 case FT_UINT32:
5838 case FT_FRAMENUM:
5839 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5840 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5841 break;
5842
5843 default:
5844 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)
5845 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)
;
5846 }
5847
5848 return pi;
5849}
5850
5851proto_item *
5852proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5853 int start, int length, uint32_t value,
5854 const char *format, ...)
5855{
5856 proto_item *pi;
5857 va_list ap;
5858
5859 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5860 if (pi != tree) {
5861 va_start(ap, format)__builtin_va_start(ap, format);
5862 proto_tree_set_representation_value(pi, format, ap);
5863 va_end(ap)__builtin_va_end(ap);
5864 }
5865
5866 return pi;
5867}
5868
5869proto_item *
5870proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5871 int start, int length, uint32_t value,
5872 const char *format, ...)
5873{
5874 proto_item *pi;
5875 va_list ap;
5876
5877 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5878 if (pi != tree) {
5879 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5879, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5880
5881 va_start(ap, format)__builtin_va_start(ap, format);
5882 proto_tree_set_representation(pi, format, ap);
5883 va_end(ap)__builtin_va_end(ap);
5884 }
5885
5886 return pi;
5887}
5888
5889/* Set the FT_UINT{8,16,24,32} value */
5890static void
5891proto_tree_set_uint(field_info *fi, uint32_t value)
5892{
5893 const header_field_info *hfinfo;
5894 uint32_t integer;
5895
5896 hfinfo = fi->hfinfo;
5897 integer = value;
5898
5899 if (hfinfo->bitmask) {
5900 /* Mask out irrelevant portions */
5901 integer &= (uint32_t)(hfinfo->bitmask);
5902
5903 /* Shift bits */
5904 integer >>= hfinfo_bitshift(hfinfo);
5905
5906 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
5907 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)
;
5908 }
5909
5910 fvalue_set_uinteger(fi->value, integer);
5911}
5912
5913/* Add FT_UINT{40,48,56,64} to a proto_tree */
5914proto_item *
5915proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5916 int length, uint64_t value)
5917{
5918 proto_item *pi = NULL((void*)0);
5919 header_field_info *hfinfo;
5920
5921 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5922
5923 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", 5923
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5923, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5923, "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", 5923, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
5924
5925 switch (hfinfo->type) {
5926 case FT_UINT40:
5927 case FT_UINT48:
5928 case FT_UINT56:
5929 case FT_UINT64:
5930 case FT_FRAMENUM:
5931 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5932 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5933 break;
5934
5935 default:
5936 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)
5937 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)
;
5938 }
5939
5940 return pi;
5941}
5942
5943proto_item *
5944proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5945 int start, int length, uint64_t value,
5946 const char *format, ...)
5947{
5948 proto_item *pi;
5949 va_list ap;
5950
5951 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5952 if (pi != tree) {
5953 va_start(ap, format)__builtin_va_start(ap, format);
5954 proto_tree_set_representation_value(pi, format, ap);
5955 va_end(ap)__builtin_va_end(ap);
5956 }
5957
5958 return pi;
5959}
5960
5961proto_item *
5962proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5963 int start, int length, uint64_t value,
5964 const char *format, ...)
5965{
5966 proto_item *pi;
5967 va_list ap;
5968
5969 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5970 if (pi != tree) {
5971 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5971, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
5972
5973 va_start(ap, format)__builtin_va_start(ap, format);
5974 proto_tree_set_representation(pi, format, ap);
5975 va_end(ap)__builtin_va_end(ap);
5976 }
5977
5978 return pi;
5979}
5980
5981/* Set the FT_UINT{40,48,56,64} value */
5982static void
5983proto_tree_set_uint64(field_info *fi, uint64_t value)
5984{
5985 const header_field_info *hfinfo;
5986 uint64_t integer;
5987
5988 hfinfo = fi->hfinfo;
5989 integer = value;
5990
5991 if (hfinfo->bitmask) {
5992 /* Mask out irrelevant portions */
5993 integer &= hfinfo->bitmask;
5994
5995 /* Shift bits */
5996 integer >>= hfinfo_bitshift(hfinfo);
5997
5998 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
5999 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)
;
6000 }
6001
6002 fvalue_set_uinteger64(fi->value, integer);
6003}
6004
6005/* Add FT_INT{8,16,24,32} to a proto_tree */
6006proto_item *
6007proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6008 int length, int32_t value)
6009{
6010 proto_item *pi = NULL((void*)0);
6011 header_field_info *hfinfo;
6012
6013 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6014
6015 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", 6015
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6015, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6015, "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", 6015, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6016
6017 switch (hfinfo->type) {
6018 case FT_INT8:
6019 case FT_INT16:
6020 case FT_INT24:
6021 case FT_INT32:
6022 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6023 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6024 break;
6025
6026 default:
6027 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)
6028 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6029 }
6030
6031 return pi;
6032}
6033
6034proto_item *
6035proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6036 int start, int length, int32_t value,
6037 const char *format, ...)
6038{
6039 proto_item *pi;
6040 va_list ap;
6041
6042 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6043 if (pi != tree) {
6044 va_start(ap, format)__builtin_va_start(ap, format);
6045 proto_tree_set_representation_value(pi, format, ap);
6046 va_end(ap)__builtin_va_end(ap);
6047 }
6048
6049 return pi;
6050}
6051
6052proto_item *
6053proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6054 int start, int length, int32_t value,
6055 const char *format, ...)
6056{
6057 proto_item *pi;
6058 va_list ap;
6059
6060 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6061 if (pi != tree) {
6062 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6062, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6063
6064 va_start(ap, format)__builtin_va_start(ap, format);
6065 proto_tree_set_representation(pi, format, ap);
6066 va_end(ap)__builtin_va_end(ap);
6067 }
6068
6069 return pi;
6070}
6071
6072/* Set the FT_INT{8,16,24,32} value */
6073static void
6074proto_tree_set_int(field_info *fi, int32_t value)
6075{
6076 const header_field_info *hfinfo;
6077 uint32_t integer;
6078 int no_of_bits;
6079
6080 hfinfo = fi->hfinfo;
6081 integer = (uint32_t) value;
6082
6083 if (hfinfo->bitmask) {
6084 /* Mask out irrelevant portions */
6085 integer &= (uint32_t)(hfinfo->bitmask);
6086
6087 /* Shift bits */
6088 integer >>= hfinfo_bitshift(hfinfo);
6089
6090 no_of_bits = ws_count_ones(hfinfo->bitmask);
6091 integer = ws_sign_ext32(integer, no_of_bits);
6092
6093 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
6094 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)
;
6095 }
6096
6097 fvalue_set_sinteger(fi->value, integer);
6098}
6099
6100/* Add FT_INT{40,48,56,64} to a proto_tree */
6101proto_item *
6102proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6103 int length, int64_t value)
6104{
6105 proto_item *pi = NULL((void*)0);
6106 header_field_info *hfinfo;
6107
6108 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6109
6110 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", 6110
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6110, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6110, "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", 6110, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6111
6112 switch (hfinfo->type) {
6113 case FT_INT40:
6114 case FT_INT48:
6115 case FT_INT56:
6116 case FT_INT64:
6117 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6118 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6119 break;
6120
6121 default:
6122 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)
6123 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6124 }
6125
6126 return pi;
6127}
6128
6129proto_item *
6130proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6131 int start, int length, int64_t value,
6132 const char *format, ...)
6133{
6134 proto_item *pi;
6135 va_list ap;
6136
6137 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6138 if (pi != tree) {
6139 va_start(ap, format)__builtin_va_start(ap, format);
6140 proto_tree_set_representation_value(pi, format, ap);
6141 va_end(ap)__builtin_va_end(ap);
6142 }
6143
6144 return pi;
6145}
6146
6147/* Set the FT_INT{40,48,56,64} value */
6148static void
6149proto_tree_set_int64(field_info *fi, int64_t value)
6150{
6151 const header_field_info *hfinfo;
6152 uint64_t integer;
6153 int no_of_bits;
6154
6155 hfinfo = fi->hfinfo;
6156 integer = value;
6157
6158 if (hfinfo->bitmask) {
6159 /* Mask out irrelevant portions */
6160 integer &= hfinfo->bitmask;
6161
6162 /* Shift bits */
6163 integer >>= hfinfo_bitshift(hfinfo);
6164
6165 no_of_bits = ws_count_ones(hfinfo->bitmask);
6166 integer = ws_sign_ext64(integer, no_of_bits);
6167
6168 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
6169 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)
;
6170 }
6171
6172 fvalue_set_sinteger64(fi->value, integer);
6173}
6174
6175proto_item *
6176proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6177 int start, int length, int64_t value,
6178 const char *format, ...)
6179{
6180 proto_item *pi;
6181 va_list ap;
6182
6183 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6184 if (pi != tree) {
6185 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6185, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6186
6187 va_start(ap, format)__builtin_va_start(ap, format);
6188 proto_tree_set_representation(pi, format, ap);
6189 va_end(ap)__builtin_va_end(ap);
6190 }
6191
6192 return pi;
6193}
6194
6195/* Add a FT_EUI64 to a proto_tree */
6196proto_item *
6197proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6198 int length, const uint64_t value)
6199{
6200 proto_item *pi;
6201 header_field_info *hfinfo;
6202
6203 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6204
6205 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", 6205
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6205, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6205, "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", 6205, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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)
; } } }
;
6206
6207 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",
6207, ((hfinfo))->abbrev))))
;
6208
6209 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6210 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6211
6212 return pi;
6213}
6214
6215proto_item *
6216proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6217 int start, int length, const uint64_t value,
6218 const char *format, ...)
6219{
6220 proto_item *pi;
6221 va_list ap;
6222
6223 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6224 if (pi != tree) {
6225 va_start(ap, format)__builtin_va_start(ap, format);
6226 proto_tree_set_representation_value(pi, format, ap);
6227 va_end(ap)__builtin_va_end(ap);
6228 }
6229
6230 return pi;
6231}
6232
6233proto_item *
6234proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6235 int start, int length, const uint64_t value,
6236 const char *format, ...)
6237{
6238 proto_item *pi;
6239 va_list ap;
6240
6241 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6242 if (pi != tree) {
6243 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6243, __func__, "assertion failed: %s", "pi"
); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi)
->tree_data)->visible) && proto_item_is_hidden(
(pi))) { return pi; }
;
6244
6245 va_start(ap, format)__builtin_va_start(ap, format);
6246 proto_tree_set_representation(pi, format, ap);
6247 va_end(ap)__builtin_va_end(ap);
6248 }
6249
6250 return pi;
6251}
6252
6253/* Set the FT_EUI64 value */
6254static void
6255proto_tree_set_eui64(field_info *fi, const uint64_t value)
6256{
6257 uint8_t v[FT_EUI64_LEN8];
6258 phton64(v, value);
6259 fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6260}
6261
6262static void
6263proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6264{
6265 if (encoding)
6266 {
6267 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6268 } else {
6269 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6270 }
6271}
6272
6273proto_item *
6274proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6275 const mac_hf_list_t *list_generic,
6276 int idx, tvbuff_t *tvb,
6277 proto_tree *tree, int offset)
6278{
6279 const uint8_t addr[6];
6280 const char *addr_name = NULL((void*)0);
6281 const char *oui_name = NULL((void*)0);
6282 proto_item *addr_item = NULL((void*)0);
6283 proto_tree *addr_tree = NULL((void*)0);
6284 proto_item *ret_val = NULL((void*)0);
6285
6286 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6287 return NULL((void*)0);
6288 }
6289
6290 /* Resolve what we can of the address */
6291 tvb_memcpy(tvb, (void *)addr, offset, 6);
6292 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6293 addr_name = get_ether_name(addr);
6294 }
6295 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6296 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6297 }
6298
6299 /* Add the item for the specific address type */
6300 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_NA0x00000000);
6301 if (idx >= 0) {
6302 addr_tree = proto_item_add_subtree(ret_val, idx);
6303 }
6304 else {
6305 addr_tree = tree;
6306 }
6307
6308 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6309 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6310 tvb, offset, 6, addr_name);
6311 proto_item_set_generated(addr_item);
6312 proto_item_set_hidden(addr_item);
6313 }
6314
6315 if (list_specific->hf_oui != NULL((void*)0)) {
6316 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_NA0x00000000);
6317 proto_item_set_generated(addr_item);
6318 proto_item_set_hidden(addr_item);
6319
6320 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6321 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6322 proto_item_set_generated(addr_item);
6323 proto_item_set_hidden(addr_item);
6324 }
6325 }
6326
6327 if (list_specific->hf_lg != NULL((void*)0)) {
6328 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6329 }
6330 if (list_specific->hf_ig != NULL((void*)0)) {
6331 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6332 }
6333
6334 /* Were we given a list for generic address fields? If not, stop here */
6335 if (list_generic == NULL((void*)0)) {
6336 return ret_val;
6337 }
6338
6339 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_NA0x00000000);
6340 proto_item_set_hidden(addr_item);
6341
6342 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6343 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6344 tvb, offset, 6, addr_name);
6345 proto_item_set_generated(addr_item);
6346 proto_item_set_hidden(addr_item);
6347 }
6348
6349 if (list_generic->hf_oui != NULL((void*)0)) {
6350 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_NA0x00000000);
6351 proto_item_set_generated(addr_item);
6352 proto_item_set_hidden(addr_item);
6353
6354 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6355 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6356 proto_item_set_generated(addr_item);
6357 proto_item_set_hidden(addr_item);
6358 }
6359 }
6360
6361 if (list_generic->hf_lg != NULL((void*)0)) {
6362 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6363 proto_item_set_hidden(addr_item);
6364 }
6365 if (list_generic->hf_ig != NULL((void*)0)) {
6366 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6367 proto_item_set_hidden(addr_item);
6368 }
6369 return ret_val;
6370}
6371
6372static proto_item *
6373proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6374{
6375 proto_node *pnode, *tnode, *sibling;
6376 field_info *tfi;
6377 unsigned depth = 1;
6378
6379 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6379, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6380
6381 /*
6382 * Restrict our depth. proto_tree_traverse_pre_order and
6383 * proto_tree_traverse_post_order (and possibly others) are recursive
6384 * so we need to be mindful of our stack size.
6385 */
6386 if (tree->first_child == NULL((void*)0)) {
6387 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6388 depth++;
6389 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6390 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__)), 6393)))
6391 "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__)), 6393)))
6392 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__)), 6393)))
6393 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__)), 6393)))
;
6394 }
6395 }
6396 }
6397
6398 /*
6399 * Make sure "tree" is ready to have subtrees under it, by
6400 * checking whether it's been given an ett_ value.
6401 *
6402 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6403 * node of the protocol tree. That node is not displayed,
6404 * so it doesn't need an ett_ value to remember whether it
6405 * was expanded.
6406 */
6407 tnode = tree;
6408 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6409 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6410 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"
, 6411)
6411 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"
, 6411)
;
6412 /* XXX - is it safe to continue here? */
6413 }
6414
6415 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6416 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6417 pnode->parent = tnode;
6418 PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6419 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6420 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6421
6422 if (tnode->last_child != NULL((void*)0)) {
6423 sibling = tnode->last_child;
6424 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6424, "sibling->next == ((void*)0)"
))))
;
6425 sibling->next = pnode;
6426 } else
6427 tnode->first_child = pnode;
6428 tnode->last_child = pnode;
6429
6430 /* We should not be adding a fake node for an interesting field */
6431 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", 6431, __func__, "assertion failed: %s"
, "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT"
); } while (0)
;
6432
6433 /* XXX - Should the proto_item have a header_field_info member, at least
6434 * for faked items, to know what hfi was faked? (Some dissectors look at
6435 * the tree items directly.)
6436 */
6437 return (proto_item *)pnode;
6438}
6439
6440/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6441static proto_item *
6442proto_tree_add_node(proto_tree *tree, field_info *fi)
6443{
6444 proto_node *pnode, *tnode, *sibling;
6445 field_info *tfi;
6446 unsigned depth = 1;
6447
6448 ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6448, __func__, "assertion failed: %s", "tree"
); } while (0)
;
6449
6450 /*
6451 * Restrict our depth. proto_tree_traverse_pre_order and
6452 * proto_tree_traverse_post_order (and possibly others) are recursive
6453 * so we need to be mindful of our stack size.
6454 */
6455 if (tree->first_child == NULL((void*)0)) {
6456 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6457 depth++;
6458 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6459 fvalue_free(fi->value);
6460 fi->value = NULL((void*)0);
6461 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__)), 6464)))
6462 "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__)), 6464)))
6463 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__)), 6464)))
6464 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__)), 6464)))
;
6465 }
6466 }
6467 }
6468
6469 /*
6470 * Make sure "tree" is ready to have subtrees under it, by
6471 * checking whether it's been given an ett_ value.
6472 *
6473 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6474 * node of the protocol tree. That node is not displayed,
6475 * so it doesn't need an ett_ value to remember whether it
6476 * was expanded.
6477 */
6478 tnode = tree;
6479 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6480 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6481 /* Since we are not adding fi to a node, its fvalue won't get
6482 * freed by proto_tree_free_node(), so free it now.
6483 */
6484 fvalue_free(fi->value);
6485 fi->value = NULL((void*)0);
6486 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", 6487)
6487 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", 6487)
;
6488 /* XXX - is it safe to continue here? */
6489 }
6490
6491 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6492 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6493 pnode->parent = tnode;
6494 PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6495 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6496 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6497
6498 if (tnode->last_child != NULL((void*)0)) {
6499 sibling = tnode->last_child;
6500 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6500, "sibling->next == ((void*)0)"
))))
;
6501 sibling->next = pnode;
6502 } else
6503 tnode->first_child = pnode;
6504 tnode->last_child = pnode;
6505
6506 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6507
6508 return (proto_item *)pnode;
6509}
6510
6511
6512/* Generic way to allocate field_info and add to proto_tree.
6513 * Sets *pfi to address of newly-allocated field_info struct */
6514static proto_item *
6515proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6516 int *length)
6517{
6518 proto_item *pi;
6519 field_info *fi;
6520 int item_length;
6521
6522 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6523 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6524 pi = proto_tree_add_node(tree, fi);
6525
6526 return pi;
6527}
6528
6529
6530static void
6531get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6532 int *item_length, const unsigned encoding)
6533{
6534 int length_remaining;
6535
6536 /*
6537 * We only allow a null tvbuff if the item has a zero length,
6538 * i.e. if there's no data backing it.
6539 */
6540 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", 6540, "tvb != ((void*)0) || *length == 0"
))))
;
6541
6542 /*
6543 * XXX - in some protocols, there are 32-bit unsigned length
6544 * fields, so lengths in protocol tree and tvbuff routines
6545 * should really be unsigned. We should have, for those
6546 * field types for which "to the end of the tvbuff" makes sense,
6547 * additional routines that take no length argument and
6548 * add fields that run to the end of the tvbuff.
6549 */
6550 if (*length == -1) {
6551 /*
6552 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6553 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6554 * of -1 means "set the length to what remains in the
6555 * tvbuff".
6556 *
6557 * The assumption is either that
6558 *
6559 * 1) the length of the item can only be determined
6560 * by dissection (typically true of items with
6561 * subitems, which are probably FT_NONE or
6562 * FT_PROTOCOL)
6563 *
6564 * or
6565 *
6566 * 2) if the tvbuff is "short" (either due to a short
6567 * snapshot length or due to lack of reassembly of
6568 * fragments/segments/whatever), we want to display
6569 * what's available in the field (probably FT_BYTES
6570 * or FT_STRING) and then throw an exception later
6571 *
6572 * or
6573 *
6574 * 3) the field is defined to be "what's left in the
6575 * packet"
6576 *
6577 * so we set the length to what remains in the tvbuff so
6578 * that, if we throw an exception while dissecting, it
6579 * has what is probably the right value.
6580 *
6581 * For FT_STRINGZ, it means "the string is null-terminated,
6582 * not null-padded; set the length to the actual length
6583 * of the string", and if the tvbuff if short, we just
6584 * throw an exception.
6585 *
6586 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV, it means "find the end of the string",
6587 * and if the tvbuff if short, we just throw an exception.
6588 *
6589 * It's not valid for any other type of field. For those
6590 * fields, we treat -1 the same way we treat other
6591 * negative values - we assume the length is a Really
6592 * Big Positive Number, and throw a ReportedBoundsError
6593 * exception, under the assumption that the Really Big
6594 * Length would run past the end of the packet.
6595 */
6596 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
))
)) {
6597 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6598 /*
6599 * Leave the length as -1, so our caller knows
6600 * it was -1.
6601 */
6602 *item_length = *length;
6603 return;
6604 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6605 switch (tvb_get_uint8(tvb, start) >> 6)
6606 {
6607 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6608 *item_length = 1;
6609 break;
6610 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6611 *item_length = 2;
6612 break;
6613 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6614 *item_length = 4;
6615 break;
6616 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6617 *item_length = 8;
6618 break;
6619 }
6620 }
6621 }
6622
6623 switch (hfinfo->type) {
6624
6625 case FT_PROTOCOL:
6626 case FT_NONE:
6627 case FT_BYTES:
6628 case FT_STRING:
6629 case FT_STRINGZPAD:
6630 case FT_STRINGZTRUNC:
6631 /*
6632 * We allow FT_PROTOCOLs to be zero-length -
6633 * for example, an ONC RPC NULL procedure has
6634 * neither arguments nor reply, so the
6635 * payload for that protocol is empty.
6636 *
6637 * We also allow the others to be zero-length -
6638 * because that's the way the code has been for a
6639 * long, long time.
6640 *
6641 * However, we want to ensure that the start
6642 * offset is not *past* the byte past the end
6643 * of the tvbuff: we throw an exception in that
6644 * case.
6645 */
6646 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6647 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6647, "*length >= 0"
))))
;
6648 break;
6649
6650 case FT_STRINGZ:
6651 /*
6652 * Leave the length as -1, so our caller knows
6653 * it was -1.
6654 */
6655 break;
6656
6657 default:
6658 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6659 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6659))
;
6660 }
6661 *item_length = *length;
6662 } else {
6663 *item_length = *length;
6664 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6665 /*
6666 * These types are for interior nodes of the
6667 * tree, and don't have data associated with
6668 * them; if the length is negative (XXX - see
6669 * above) or goes past the end of the tvbuff,
6670 * cut it short at the end of the tvbuff.
6671 * That way, if this field is selected in
6672 * Wireshark, we don't highlight stuff past
6673 * the end of the data.
6674 */
6675 /* XXX - what to do, if we don't have a tvb? */
6676 if (tvb) {
6677 length_remaining = tvb_captured_length_remaining(tvb, start);
6678 if (*item_length < 0 ||
6679 (*item_length > 0 &&
6680 (length_remaining < *item_length)))
6681 *item_length = length_remaining;
6682 }
6683 }
6684 if (*item_length < 0) {
6685 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6686 }
6687 }
6688}
6689
6690static int
6691get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6692 int length, unsigned item_length, const int encoding)
6693{
6694 uint32_t n;
6695
6696 /*
6697 * We need to get the correct item length here.
6698 * That's normally done by proto_tree_new_item(),
6699 * but we won't be calling it.
6700 */
6701 switch (hfinfo->type) {
6702
6703 case FT_NONE:
6704 case FT_PROTOCOL:
6705 case FT_BYTES:
6706 /*
6707 * The length is the specified length.
6708 */
6709 break;
6710
6711 case FT_UINT_BYTES:
6712 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6713 item_length += n;
6714 if ((int)item_length < length) {
6715 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6716 }
6717 break;
6718
6719 /* XXX - make these just FT_UINT? */
6720 case FT_UINT8:
6721 case FT_UINT16:
6722 case FT_UINT24:
6723 case FT_UINT32:
6724 case FT_UINT40:
6725 case FT_UINT48:
6726 case FT_UINT56:
6727 case FT_UINT64:
6728 /* XXX - make these just FT_INT? */
6729 case FT_INT8:
6730 case FT_INT16:
6731 case FT_INT24:
6732 case FT_INT32:
6733 case FT_INT40:
6734 case FT_INT48:
6735 case FT_INT56:
6736 case FT_INT64:
6737 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6738 if (length < -1) {
6739 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6740 }
6741 if (length == -1) {
6742 uint64_t dummy;
6743 /* This can throw an exception */
6744 /* XXX - do this without fetching the varint? */
6745 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6746 if (length == 0) {
6747 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6748 }
6749 }
6750 item_length = length;
6751 break;
6752 }
6753
6754 /*
6755 * The length is the specified length.
6756 */
6757 break;
6758
6759 case FT_BOOLEAN:
6760 case FT_CHAR:
6761 case FT_IPv4:
6762 case FT_IPXNET:
6763 case FT_IPv6:
6764 case FT_FCWWN:
6765 case FT_AX25:
6766 case FT_VINES:
6767 case FT_ETHER:
6768 case FT_EUI64:
6769 case FT_GUID:
6770 case FT_OID:
6771 case FT_REL_OID:
6772 case FT_SYSTEM_ID:
6773 case FT_FLOAT:
6774 case FT_DOUBLE:
6775 case FT_STRING:
6776 /*
6777 * The length is the specified length.
6778 */
6779 break;
6780
6781 case FT_STRINGZ:
6782 if (length < -1) {
6783 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6784 }
6785 if (length == -1) {
6786 /* This can throw an exception */
6787 /* XXX - do this without fetching the string? */
6788 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6789 }
6790 item_length = length;
6791 break;
6792
6793 case FT_UINT_STRING:
6794 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6795 item_length += n;
6796 if ((int)item_length < length) {
6797 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6798 }
6799 break;
6800
6801 case FT_STRINGZPAD:
6802 case FT_STRINGZTRUNC:
6803 case FT_ABSOLUTE_TIME:
6804 case FT_RELATIVE_TIME:
6805 case FT_IEEE_11073_SFLOAT:
6806 case FT_IEEE_11073_FLOAT:
6807 /*
6808 * The length is the specified length.
6809 */
6810 break;
6811
6812 default:
6813 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
))
6814 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
))
6815 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
))
6816 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
))
;
6817 break;
6818 }
6819 return item_length;
6820}
6821
6822// This was arbitrarily chosen, but if you're adding 50K items to the tree
6823// without advancing the offset you should probably take a long, hard look
6824// at what you're doing.
6825// We *could* make this a configurable option, but I (Gerald) would like to
6826// avoid adding yet another nerd knob.
6827# define PROTO_TREE_MAX_IDLE50000 50000
6828static field_info *
6829new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6830 const int start, const int item_length)
6831{
6832 field_info *fi;
6833
6834 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6835
6836 fi->hfinfo = hfinfo;
6837 fi->start = start;
6838 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6839 // If our start offset hasn't advanced after adding many items it probably
6840 // means we're in a large or infinite loop.
6841 if (fi->start > 0) {
6842 if (fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6843 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6844 DISSECTOR_ASSERT_HINT(PTREE_DATA(tree)->start_idle_count < PROTO_TREE_MAX_IDLE, fi->hfinfo->abbrev)((void) ((((tree)->tree_data)->start_idle_count < 50000
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6844, "((tree)->tree_data)->start_idle_count < 50000"
, fi->hfinfo->abbrev))))
;
6845 } else {
6846 PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6847 PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6848 }
6849 }
6850 fi->length = item_length;
6851 fi->tree_type = -1;
6852 fi->flags = 0;
6853 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6854 /* If the tree is not visible, set the item hidden, unless we
6855 * need the representation or length and can't fake them.
6856 */
6857 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6858 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6859 }
6860 }
6861 fi->value = fvalue_new(fi->hfinfo->type);
6862 fi->rep = NULL((void*)0);
6863
6864 /* add the data source tvbuff */
6865 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6866
6867 fi->appendix_start = 0;
6868 fi->appendix_length = 0;
6869
6870 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6871 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6872
6873 return fi;
6874}
6875
6876static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6877{
6878 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6879 return 0;
6880 }
6881
6882 /* Search for field name */
6883 char *ptr = strstr(representation, hfinfo->name);
6884 if (!ptr) {
6885 return 0;
6886 }
6887
6888 /* Check if field name ends with the ": " delimiter */
6889 ptr += strlen(hfinfo->name);
6890 if (strncmp(ptr, ": ", 2) == 0) {
6891 ptr += 2;
6892 }
6893
6894 /* Return offset to after field name */
6895 return ptr - representation;
6896}
6897
6898/* If the protocol tree is to be visible, set the representation of a
6899 proto_tree entry with the name of the field for the item and with
6900 the value formatted with the supplied printf-style format and
6901 argument list. */
6902static void
6903proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6904{
6905 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6905, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6906
6907 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6908 * items string representation */
6909 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6910 size_t name_pos, ret = 0;
6911 char *str;
6912 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6913 const header_field_info *hf;
6914
6915 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6915, "fi"))))
;
6916
6917 hf = fi->hfinfo;
6918
6919 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;
;
6920 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))
)) {
6921 uint64_t val;
6922 char *p;
6923
6924 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)
)
6925 val = fvalue_get_uinteger(fi->value);
6926 else
6927 val = fvalue_get_uinteger64(fi->value);
6928
6929 val <<= hfinfo_bitshift(hf);
6930
6931 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6932 ret = (p - fi->rep->representation);
6933 }
6934
6935 /* put in the hf name */
6936 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
6937
6938 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
6939 /* If possible, Put in the value of the string */
6940 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6941 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"
, 6941, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6942 fi->rep->value_pos = ret;
6943 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
6944 if (ret >= ITEM_LABEL_LENGTH240) {
6945 /* Uh oh, we don't have enough room. Tell the user
6946 * that the field is truncated.
6947 */
6948 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6949 }
6950 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6951 }
6952}
6953
6954/* If the protocol tree is to be visible, set the representation of a
6955 proto_tree entry with the representation formatted with the supplied
6956 printf-style format and argument list. */
6957static void
6958proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6959{
6960 size_t ret; /*tmp return value */
6961 char *str;
6962 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6963
6964 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6964, "fi"))))
;
6965
6966 if (!proto_item_is_hidden(pi)) {
6967 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;
;
6968
6969 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6970 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"
, 6970, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6971 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
6972 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
6973 if (ret >= ITEM_LABEL_LENGTH240) {
6974 /* Uh oh, we don't have enough room. Tell the user
6975 * that the field is truncated.
6976 */
6977 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
6978 }
6979 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6980 }
6981}
6982
6983static int
6984protoo_strlcpy(char *dest, const char *src, size_t dest_size)
6985{
6986 if (dest_size == 0) return 0;
6987
6988 size_t res = g_strlcpy(dest, src, dest_size);
6989
6990 /* At most dest_size - 1 characters will be copied
6991 * (unless dest_size is 0). */
6992 if (res >= dest_size)
6993 res = dest_size - 1;
6994 return (int) res;
6995}
6996
6997static header_field_info *
6998hfinfo_same_name_get_prev(const header_field_info *hfinfo)
6999{
7000 header_field_info *dup_hfinfo;
7001
7002 if (hfinfo->same_name_prev_id == -1)
7003 return NULL((void*)0);
7004 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", 7004
, __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", 7004, "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", 7004,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
7005 return dup_hfinfo;
7006}
7007
7008static void
7009hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7010{
7011 g_free(last_field_name);
7012 last_field_name = NULL((void*)0);
7013
7014 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7015 /* No hfinfo with the same name */
7016 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
7017 return;
7018 }
7019
7020 if (hfinfo->same_name_next) {
7021 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7022 }
7023
7024 if (hfinfo->same_name_prev_id != -1) {
7025 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7026 same_name_prev->same_name_next = hfinfo->same_name_next;
7027 if (!hfinfo->same_name_next) {
7028 /* It's always the latest added hfinfo which is stored in gpa_name_map */
7029 g_hash_table_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7030 }
7031 }
7032}
7033
7034int
7035proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7036{
7037 const header_field_info *hfinfo = finfo->hfinfo;
7038 int label_len = 0;
7039 char *tmp_str;
7040 const char *str;
7041 const uint8_t *bytes;
7042 uint32_t number;
7043 uint64_t number64;
7044 const char *hf_str_val;
7045 char number_buf[NUMBER_LABEL_LENGTH80];
7046 const char *number_out;
7047 address addr;
7048 const ipv4_addr_and_mask *ipv4;
7049 const ipv6_addr_and_prefix *ipv6;
7050
7051 switch (hfinfo->type) {
7052
7053 case FT_NONE:
7054 case FT_PROTOCOL:
7055 return protoo_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7056
7057 case FT_UINT_BYTES:
7058 case FT_BYTES:
7059 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7060 hfinfo,
7061 fvalue_get_bytes_data(finfo->value),
7062 (unsigned)fvalue_length2(finfo->value),
7063 label_str_size);
7064 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7065 wmem_free(NULL((void*)0), tmp_str);
7066 break;
7067
7068 case FT_ABSOLUTE_TIME:
7069 {
7070 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7071 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7072 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7073 }
7074 tmp_str = abs_time_to_str_ex(NULL((void*)0), fvalue_get_time(finfo->value), hfinfo->display, flags);
7075 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7076 wmem_free(NULL((void*)0), tmp_str);
7077 break;
7078 }
7079
7080 case FT_RELATIVE_TIME:
7081 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7082 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7083 wmem_free(NULL((void*)0), tmp_str);
7084 break;
7085
7086 case FT_BOOLEAN:
7087 number64 = fvalue_get_uinteger64(finfo->value);
7088 label_len = protoo_strlcpy(display_label_str,
7089 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7090 break;
7091
7092 case FT_CHAR:
7093 number = fvalue_get_uinteger(finfo->value);
7094
7095 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7096 char tmp[ITEM_LABEL_LENGTH240];
7097 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7098
7099 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7099, "fmtfunc"))))
;
7100 fmtfunc(tmp, number);
7101
7102 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
7103
7104 } else if (hfinfo->strings) {
7105 number_out = hf_try_val_to_str(number, hfinfo);
7106
7107 if (!number_out) {
7108 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7109 }
7110
7111 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7112
7113 } else {
7114 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7115
7116 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7117 }
7118
7119 break;
7120
7121 /* XXX - make these just FT_NUMBER? */
7122 case FT_INT8:
7123 case FT_INT16:
7124 case FT_INT24:
7125 case FT_INT32:
7126 case FT_UINT8:
7127 case FT_UINT16:
7128 case FT_UINT24:
7129 case FT_UINT32:
7130 case FT_FRAMENUM:
7131 hf_str_val = NULL((void*)0);
7132 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
))
?
7133 (uint32_t) fvalue_get_sinteger(finfo->value) :
7134 fvalue_get_uinteger(finfo->value);
7135
7136 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7137 char tmp[ITEM_LABEL_LENGTH240];
7138 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7139
7140 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7140, "fmtfunc"))))
;
7141 fmtfunc(tmp, number);
7142
7143 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
7144
7145 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7146 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7147 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7148 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7149 hf_str_val = hf_try_val_to_str(number, hfinfo);
7150 label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7151 } else {
7152 number_out = hf_try_val_to_str(number, hfinfo);
7153
7154 if (!number_out) {
7155 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7156 }
7157
7158 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7159 }
7160 } else {
7161 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7162
7163 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7164 }
7165
7166 break;
7167
7168 case FT_INT40:
7169 case FT_INT48:
7170 case FT_INT56:
7171 case FT_INT64:
7172 case FT_UINT40:
7173 case FT_UINT48:
7174 case FT_UINT56:
7175 case FT_UINT64:
7176 hf_str_val = NULL((void*)0);
7177 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
))
?
7178 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7179 fvalue_get_uinteger64(finfo->value);
7180
7181 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7182 char tmp[ITEM_LABEL_LENGTH240];
7183 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7184
7185 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7185, "fmtfunc64"
))))
;
7186 fmtfunc64(tmp, number64);
7187
7188 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
7189 } else if (hfinfo->strings) {
7190 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7191 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7192 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7193 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7194 label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7195 } else {
7196 number_out = hf_try_val64_to_str(number64, hfinfo);
7197
7198 if (!number_out)
7199 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7200
7201 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7202 }
7203 } else {
7204 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7205
7206 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7207 }
7208
7209 break;
7210
7211 case FT_EUI64:
7212 set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7213 tmp_str = address_to_display(NULL((void*)0), &addr);
7214 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7215 wmem_free(NULL((void*)0), tmp_str);
7216 break;
7217
7218 case FT_IPv4:
7219 ipv4 = fvalue_get_ipv4(finfo->value);
7220 //XXX: Should we ignore the mask?
7221 set_address_ipv4(&addr, ipv4);
7222 tmp_str = address_to_display(NULL((void*)0), &addr);
7223 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7224 wmem_free(NULL((void*)0), tmp_str);
7225 free_address(&addr);
7226 break;
7227
7228 case FT_IPv6:
7229 ipv6 = fvalue_get_ipv6(finfo->value);
7230 set_address_ipv6(&addr, ipv6);
7231 tmp_str = address_to_display(NULL((void*)0), &addr);
7232 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7233 wmem_free(NULL((void*)0), tmp_str);
7234 free_address(&addr);
7235 break;
7236
7237 case FT_FCWWN:
7238 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7239 tmp_str = address_to_display(NULL((void*)0), &addr);
7240 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7241 wmem_free(NULL((void*)0), tmp_str);
7242 break;
7243
7244 case FT_ETHER:
7245 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7246 tmp_str = address_to_display(NULL((void*)0), &addr);
7247 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7248 wmem_free(NULL((void*)0), tmp_str);
7249 break;
7250
7251 case FT_GUID:
7252 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7253 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7254 wmem_free(NULL((void*)0), tmp_str);
7255 break;
7256
7257 case FT_REL_OID:
7258 bytes = fvalue_get_bytes_data(finfo->value);
7259 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7260 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7261 wmem_free(NULL((void*)0), tmp_str);
7262 break;
7263
7264 case FT_OID:
7265 bytes = fvalue_get_bytes_data(finfo->value);
7266 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7267 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7268 wmem_free(NULL((void*)0), tmp_str);
7269 break;
7270
7271 case FT_SYSTEM_ID:
7272 bytes = fvalue_get_bytes_data(finfo->value);
7273 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7274 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7275 wmem_free(NULL((void*)0), tmp_str);
7276 break;
7277
7278 case FT_FLOAT:
7279 case FT_DOUBLE:
7280 label_len = (int)fill_display_label_float(finfo, display_label_str);
7281 break;
7282
7283 case FT_STRING:
7284 case FT_STRINGZ:
7285 case FT_UINT_STRING:
7286 case FT_STRINGZPAD:
7287 case FT_STRINGZTRUNC:
7288 str = fvalue_get_string(finfo->value);
7289 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7290 if (label_len >= label_str_size) {
7291 /* Truncation occurred. Get the real length
7292 * copied (not including '\0') */
7293 label_len = label_str_size ? label_str_size - 1 : 0;
7294 }
7295 break;
7296
7297 default:
7298 /* First try ftype string representation */
7299 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7300 if (!tmp_str) {
7301 /* Default to show as bytes */
7302 bytes = fvalue_get_bytes_data(finfo->value);
7303 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7304 }
7305 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7306 wmem_free(NULL((void*)0), tmp_str);
7307 break;
7308 }
7309 return label_len;
7310}
7311
7312const char *
7313proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7314 char *result, char *expr, const int size)
7315{
7316 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7317 GPtrArray *finfos;
7318 field_info *finfo = NULL((void*)0);
7319 header_field_info* hfinfo;
7320 const char *abbrev = NULL((void*)0);
7321
7322 char *str;
7323 col_custom_t *field_idx;
7324 int field_id;
7325 int ii = 0;
7326
7327 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7327, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7328 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7329 field_id = field_idx->field_id;
7330 if (field_id == 0) {
7331 GPtrArray *fvals = NULL((void*)0);
7332 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7333 if (fvals != NULL((void*)0)) {
7334
7335 // XXX - Handling occurrences is unusual when more
7336 // than one field is involved, e.g. there's four
7337 // results for tcp.port + tcp.port. We may really
7338 // want to apply it to the operands, not the output.
7339 // Note that occurrences are not quite the same as
7340 // the layer operator (should the grammar support
7341 // both?)
7342 /* Calculate single index or set outer boundaries */
7343 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7344 if (occurrence < 0) {
7345 i = occurrence + len;
7346 last = i;
7347 } else if (occurrence > 0) {
7348 i = occurrence - 1;
7349 last = i;
7350 } else {
7351 i = 0;
7352 last = len - 1;
7353 }
7354 if (i < 0 || i >= len) {
7355 g_ptr_array_unref(fvals);
7356 continue;
7357 }
7358 for (; i <= last; i++) {
7359 /* XXX - We could have a "resolved" result
7360 * for types where the value depends only
7361 * on the type, e.g. FT_IPv4, and not on
7362 * hfinfo->strings. Supporting the latter
7363 * requires knowing which hfinfo matched
7364 * if there are multiple with the same
7365 * abbreviation. In any case, we need to
7366 * know the expected return type of the
7367 * field expression.
7368 */
7369 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7370 if (offset_r && (offset_r < (size - 1)))
7371 result[offset_r++] = ',';
7372 if (offset_e && (offset_e < (size - 1)))
7373 expr[offset_e++] = ',';
7374 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
7375 // col_{add,append,set}_* calls ws_label_strcpy
7376 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7377 g_free(str);
7378 }
7379 g_ptr_array_unref(fvals);
7380 } else if (passed) {
7381 // XXX - Occurrence doesn't make sense for a test
7382 // output, it should be applied to the operands.
7383 if (offset_r && (offset_r < (size - 1)))
7384 result[offset_r++] = ',';
7385 if (offset_e && (offset_e < (size - 1)))
7386 expr[offset_e++] = ',';
7387 /* Prevent multiple check marks */
7388 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7389 offset_r += protoo_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7390 } else {
7391 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7392 }
7393 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7394 offset_e += protoo_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7395 } else {
7396 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7397 }
7398 }
7399 continue;
7400 }
7401 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", 7401
, __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", 7401,
"(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", 7401,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7402
7403 /* do we need to rewind ? */
7404 if (!hfinfo)
7405 return "";
7406
7407 if (occurrence < 0) {
7408 /* Search other direction */
7409 while (hfinfo->same_name_prev_id != -1) {
7410 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", 7410
, __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", 7410, "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", 7410,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7411 }
7412 }
7413
7414 prev_len = 0; /* Reset handled occurrences */
7415
7416 while (hfinfo) {
7417 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7418
7419 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7420 if (occurrence < 0) {
7421 hfinfo = hfinfo->same_name_next;
7422 } else {
7423 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7424 }
7425 continue;
7426 }
7427
7428 /* Are there enough occurrences of the field? */
7429 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7430 if (occurrence < 0) {
7431 hfinfo = hfinfo->same_name_next;
7432 } else {
7433 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7434 }
7435 prev_len += len;
7436 continue;
7437 }
7438
7439 /* Calculate single index or set outer boundaries */
7440 if (occurrence < 0) {
7441 i = occurrence + len + prev_len;
7442 last = i;
7443 } else if (occurrence > 0) {
7444 i = occurrence - 1 - prev_len;
7445 last = i;
7446 } else {
7447 i = 0;
7448 last = len - 1;
7449 }
7450
7451 prev_len += len; /* Count handled occurrences */
7452
7453 while (i <= last) {
7454 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7455
7456 if (offset_r && (offset_r < (size - 1)))
7457 result[offset_r++] = ',';
7458
7459 if (display_details) {
7460 char representation[ITEM_LABEL_LENGTH240];
7461 size_t offset = 0;
7462
7463 if (finfo->rep && finfo->rep->value_len) {
7464 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7465 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7466 } else {
7467 proto_item_fill_label(finfo, representation, &offset);
7468 }
7469 offset_r += protoo_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7470 } else {
7471 switch (hfinfo->type) {
7472
7473 case FT_NONE:
7474 case FT_PROTOCOL:
7475 /* Prevent multiple check marks */
7476 if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7477 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7478 } else {
7479 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7480 }
7481 break;
7482
7483 default:
7484 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7485 break;
7486 }
7487 }
7488
7489 if (offset_e && (offset_e < (size - 1)))
7490 expr[offset_e++] = ',';
7491
7492 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
))
)) {
7493 const char *hf_str_val;
7494 /* Integer types with BASE_NONE never get the numeric value. */
7495 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7496 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7497 } else if (FT_IS_UINT32(hfinfo->type)((hfinfo->type) == FT_CHAR || (hfinfo->type) == FT_UINT8
|| (hfinfo->type) == FT_UINT16 || (hfinfo->type) == FT_UINT24
|| (hfinfo->type) == FT_UINT32 || (hfinfo->type) == FT_FRAMENUM
)
) {
7498 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7499 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7500 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7501 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7502 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7503 }
7504 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7505 offset_e = (int)strlen(expr);
7506 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7507 /* Prevent multiple check marks */
7508 if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7509 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7510 } else {
7511 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7512 }
7513 } else {
7514 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7515 // col_{add,append,set}_* calls ws_label_strcpy
7516 offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7517 wmem_free(NULL((void*)0), str);
7518 }
7519 i++;
7520 }
7521
7522 /* XXX: Why is only the first abbreviation returned for a multifield
7523 * custom column? */
7524 if (!abbrev) {
7525 /* Store abbrev for return value */
7526 abbrev = hfinfo->abbrev;
7527 }
7528
7529 if (occurrence == 0) {
7530 /* Fetch next hfinfo with same name (abbrev) */
7531 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7532 } else {
7533 hfinfo = NULL((void*)0);
7534 }
7535 }
7536 }
7537
7538 if (offset_r >= (size - 1)) {
7539 mark_truncated(result, 0, size, NULL((void*)0));
7540 }
7541 if (offset_e >= (size - 1)) {
7542 mark_truncated(expr, 0, size, NULL((void*)0));
7543 }
7544 return abbrev ? abbrev : "";
7545}
7546
7547char *
7548proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7549{
7550 int len, prev_len, last, i;
7551 GPtrArray *finfos;
7552 field_info *finfo = NULL((void*)0);
7553 header_field_info* hfinfo;
7554
7555 char *filter = NULL((void*)0);
7556 GPtrArray *filter_array;
7557
7558 col_custom_t *col_custom;
7559 int field_id;
7560
7561 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7561, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7562 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7563 for (GSList *iter = field_ids; iter; iter = iter->next) {
7564 col_custom = (col_custom_t*)iter->data;
7565 field_id = col_custom->field_id;
7566 if (field_id == 0) {
7567 GPtrArray *fvals = NULL((void*)0);
7568 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7569 if (fvals != NULL((void*)0)) {
7570 // XXX - Handling occurrences is unusual when more
7571 // than one field is involved, e.g. there's four
7572 // results for tcp.port + tcp.port. We really
7573 // want to apply it to the operands, not the output.
7574 /* Calculate single index or set outer boundaries */
7575 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7576 if (occurrence < 0) {
7577 i = occurrence + len;
7578 last = i;
7579 } else if (occurrence > 0) {
7580 i = occurrence - 1;
7581 last = i;
7582 } else {
7583 i = 0;
7584 last = len - 1;
7585 }
7586 if (i < 0 || i >= len) {
7587 g_ptr_array_unref(fvals);
7588 continue;
7589 }
7590 for (; i <= last; i++) {
7591 /* XXX - Should multiple values for one
7592 * field use set membership to reduce
7593 * verbosity, here and below? */
7594 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7595 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7596 wmem_free(NULL((void*)0), str);
7597 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7598 g_ptr_array_add(filter_array, filter);
7599 }
7600 }
7601 g_ptr_array_unref(fvals);
7602 } else if (passed) {
7603 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7604 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7605 g_ptr_array_add(filter_array, filter);
7606 }
7607 } else {
7608 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7609 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7610 g_ptr_array_add(filter_array, filter);
7611 }
7612 }
7613 continue;
7614 }
7615
7616 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", 7616
, __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", 7616,
"(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", 7616,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7617
7618 /* do we need to rewind ? */
7619 if (!hfinfo)
7620 return NULL((void*)0);
7621
7622 if (occurrence < 0) {
7623 /* Search other direction */
7624 while (hfinfo->same_name_prev_id != -1) {
7625 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", 7625
, __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", 7625, "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", 7625,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7626 }
7627 }
7628
7629 prev_len = 0; /* Reset handled occurrences */
7630
7631 while (hfinfo) {
7632 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7633
7634 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7635 if (occurrence < 0) {
7636 hfinfo = hfinfo->same_name_next;
7637 } else {
7638 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7639 }
7640 continue;
7641 }
7642
7643 /* Are there enough occurrences of the field? */
7644 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7645 if (occurrence < 0) {
7646 hfinfo = hfinfo->same_name_next;
7647 } else {
7648 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7649 }
7650 prev_len += len;
7651 continue;
7652 }
7653
7654 /* Calculate single index or set outer boundaries */
7655 if (occurrence < 0) {
7656 i = occurrence + len + prev_len;
7657 last = i;
7658 } else if (occurrence > 0) {
7659 i = occurrence - 1 - prev_len;
7660 last = i;
7661 } else {
7662 i = 0;
7663 last = len - 1;
7664 }
7665
7666 prev_len += len; /* Count handled occurrences */
7667
7668 while (i <= last) {
7669 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7670
7671 filter = proto_construct_match_selected_string(finfo, edt);
7672 if (filter) {
7673 /* Only add the same expression once (especially for FT_PROTOCOL).
7674 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7675 */
7676 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7677 g_ptr_array_add(filter_array, filter);
7678 }
7679 }
7680 i++;
7681 }
7682
7683 if (occurrence == 0) {
7684 /* Fetch next hfinfo with same name (abbrev) */
7685 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7686 } else {
7687 hfinfo = NULL((void*)0);
7688 }
7689 }
7690 }
7691
7692 g_ptr_array_add(filter_array, NULL((void*)0));
7693
7694 /* XXX: Should this be || or && ? */
7695 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7696
7697 g_ptr_array_free(filter_array, true1);
7698
7699 return output;
7700}
7701
7702/* Set text of proto_item after having already been created. */
7703void
7704proto_item_set_text(proto_item *pi, const char *format, ...)
7705{
7706 field_info *fi = NULL((void*)0);
7707 va_list ap;
7708
7709 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7710
7711 fi = PITEM_FINFO(pi)((pi)->finfo);
7712 if (fi == NULL((void*)0))
7713 return;
7714
7715 if (fi->rep) {
7716 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7717 fi->rep = NULL((void*)0);
7718 }
7719
7720 va_start(ap, format)__builtin_va_start(ap, format);
7721 proto_tree_set_representation(pi, format, ap);
7722 va_end(ap)__builtin_va_end(ap);
7723}
7724
7725/* Append to text of proto_item after having already been created. */
7726void
7727proto_item_append_text(proto_item *pi, const char *format, ...)
7728{
7729 field_info *fi = NULL((void*)0);
7730 size_t curlen;
7731 char *str;
7732 va_list ap;
7733
7734 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7735
7736 fi = PITEM_FINFO(pi)((pi)->finfo);
7737 if (fi == NULL((void*)0)) {
7738 return;
7739 }
7740
7741 if (!proto_item_is_hidden(pi)) {
7742 /*
7743 * If we don't already have a representation,
7744 * generate the default representation.
7745 */
7746 if (fi->rep == NULL((void*)0)) {
7747 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;
;
7748 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7749 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7750 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7751 (strncmp(format, ": ", 2) == 0)) {
7752 fi->rep->value_pos += 2;
7753 }
7754 }
7755 if (fi->rep) {
7756 curlen = strlen(fi->rep->representation);
7757 /* curlen doesn't include the \0 byte.
7758 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7759 * the representation has already been truncated (of an up
7760 * to 4 byte UTF-8 character) or is just at the maximum length
7761 * unless we search for " [truncated]" (which may not be
7762 * at the start.)
7763 * It's safer to do nothing.
7764 */
7765 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7766 va_start(ap, format)__builtin_va_start(ap, format);
7767 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7768 va_end(ap)__builtin_va_end(ap);
7769 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"
, 7769, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7770 /* Keep fi->rep->value_pos */
7771 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7772 if (curlen >= ITEM_LABEL_LENGTH240) {
7773 /* Uh oh, we don't have enough room. Tell the user
7774 * that the field is truncated.
7775 */
7776 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7777 }
7778 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7779 }
7780 }
7781 }
7782}
7783
7784/* Prepend to text of proto_item after having already been created. */
7785void
7786proto_item_prepend_text(proto_item *pi, const char *format, ...)
7787{
7788 field_info *fi = NULL((void*)0);
7789 size_t pos;
7790 char representation[ITEM_LABEL_LENGTH240];
7791 char *str;
7792 va_list ap;
7793
7794 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data
)->visible) && proto_item_is_hidden((pi))) { return
; }
;
7795
7796 fi = PITEM_FINFO(pi)((pi)->finfo);
7797 if (fi == NULL((void*)0)) {
7798 return;
7799 }
7800
7801 if (!proto_item_is_hidden(pi)) {
7802 /*
7803 * If we don't already have a representation,
7804 * generate the default representation.
7805 */
7806 if (fi->rep == NULL((void*)0)) {
7807 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;
;
7808 proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7809 } else
7810 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7811
7812 va_start(ap, format)__builtin_va_start(ap, format);
7813 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7814 va_end(ap)__builtin_va_end(ap);
7815 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"
, 7815, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7816 fi->rep->value_pos += strlen(str);
7817 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7818 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7819 /* XXX: As above, if the old representation is close to the label
7820 * length, it might already be marked as truncated. */
7821 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7822 /* Uh oh, we don't have enough room. Tell the user
7823 * that the field is truncated.
7824 */
7825 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7826 }
7827 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7828 }
7829}
7830
7831static void
7832finfo_set_len(field_info *fi, const int length)
7833{
7834 int length_remaining;
7835
7836 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", 7836,
"length >= 0", fi->hfinfo->abbrev))))
;
7837 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7838 if (length > length_remaining)
7839 fi->length = length_remaining;
7840 else
7841 fi->length = length;
7842
7843 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7844 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7845 fvalue_set_protocol_length(fi->value, fi->length);
7846 }
7847
7848 /*
7849 * You cannot just make the "len" field of a GByteArray
7850 * larger, if there's no data to back that length;
7851 * you can only make it smaller.
7852 */
7853 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7854 GBytes *bytes = fvalue_get_bytes(fi->value);
7855 size_t size;
7856 const void *data = g_bytes_get_data(bytes, &size);
7857 if ((size_t)fi->length <= size) {
7858 fvalue_set_bytes_data(fi->value, data, fi->length);
7859 }
7860 g_bytes_unref(bytes);
7861 }
7862}
7863
7864void
7865proto_item_set_len(proto_item *pi, const int length)
7866{
7867 field_info *fi;
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 finfo_set_len(fi, length);
7877}
7878
7879/*
7880 * Sets the length of the item based on its start and on the specified
7881 * offset, which is the offset past the end of the item; as the start
7882 * in the item is relative to the beginning of the data source tvbuff,
7883 * we need to pass in a tvbuff - the end offset is relative to the beginning
7884 * of that tvbuff.
7885 */
7886void
7887proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7888{
7889 field_info *fi;
7890 int length;
7891
7892 if (pi == NULL((void*)0))
7893 return;
7894
7895 fi = PITEM_FINFO(pi)((pi)->finfo);
7896 if (fi == NULL((void*)0))
7897 return;
7898
7899 end += tvb_raw_offset(tvb);
7900 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7900, "end >= fi->start"
))))
;
7901 length = end - fi->start;
7902
7903 finfo_set_len(fi, length);
7904}
7905
7906int
7907proto_item_get_len(const proto_item *pi)
7908{
7909 field_info *fi;
7910
7911 if (!pi)
7912 return -1;
7913 fi = PITEM_FINFO(pi)((pi)->finfo);
7914 return fi ? fi->length : -1;
7915}
7916
7917void
7918proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7919 if (!ti) {
7920 return;
7921 }
7922 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)
;
7923 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)
;
7924}
7925
7926char *
7927proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7928{
7929 field_info *fi;
7930
7931 if (!pi)
7932 return wmem_strdup(scope, "");
7933 fi = PITEM_FINFO(pi)((pi)->finfo);
7934 if (!fi)
7935 return wmem_strdup(scope, "");
7936 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7936, "fi->hfinfo != ((void*)0)"
))))
;
7937 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7938}
7939
7940proto_tree *
7941proto_tree_create_root(packet_info *pinfo)
7942{
7943 proto_node *pnode;
7944
7945 /* Initialize the proto_node */
7946 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
7947 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
7948 pnode->parent = NULL((void*)0);
7949 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
7950 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
7951
7952 /* Make sure we can access pinfo everywhere */
7953 pnode->tree_data->pinfo = pinfo;
7954
7955 /* Don't initialize the tree_data_t. Wait until we know we need it */
7956 pnode->tree_data->interesting_hfids = NULL((void*)0);
7957
7958 /* Set the default to false so it's easier to
7959 * find errors; if we expect to see the protocol tree
7960 * but for some reason the default 'visible' is not
7961 * changed, then we'll find out very quickly. */
7962 pnode->tree_data->visible = false0;
7963
7964 /* Make sure that we fake protocols (if possible) */
7965 pnode->tree_data->fake_protocols = true1;
7966
7967 /* Keep track of the number of children */
7968 pnode->tree_data->count = 0;
7969
7970 /* Initialize our loop checks */
7971 pnode->tree_data->max_start = 0;
7972 pnode->tree_data->start_idle_count = 0;
7973
7974 return (proto_tree *)pnode;
7975}
7976
7977
7978/* "prime" a proto_tree with a single hfid that a dfilter
7979 * is interested in. */
7980void
7981proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
7982{
7983 header_field_info *hfinfo;
7984
7985 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", 7985, __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", 7985, "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", 7985, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
7986 /* this field is referenced by a filter so increase the refcount.
7987 also increase the refcount for the parent, i.e the protocol.
7988 Don't increase the refcount if we're already printing the
7989 type, as that is a superset of direct reference.
7990 */
7991 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
7992 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
7993 }
7994 /* only increase the refcount if there is a parent.
7995 if this is a protocol and not a field then parent will be -1
7996 and there is no parent to add any refcounting for.
7997 */
7998 if (hfinfo->parent != -1) {
7999 header_field_info *parent_hfinfo;
8000 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", 8000
, __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", 8000,
"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", 8000,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8001
8002 /* Mark parent as indirectly referenced unless it is already directly
8003 * referenced, i.e. the user has specified the parent in a filter.
8004 */
8005 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8006 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8007 }
8008}
8009
8010/* "prime" a proto_tree with a single hfid that a dfilter
8011 * is interested in. */
8012void
8013proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8014{
8015 header_field_info *hfinfo;
8016
8017 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", 8017, __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", 8017, "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", 8017, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
8018 /* this field is referenced by an (output) filter so increase the refcount.
8019 also increase the refcount for the parent, i.e the protocol.
8020 */
8021 hfinfo->ref_type = HF_REF_TYPE_PRINT;
8022 /* only increase the refcount if there is a parent.
8023 if this is a protocol and not a field then parent will be -1
8024 and there is no parent to add any refcounting for.
8025 */
8026 if (hfinfo->parent != -1) {
8027 header_field_info *parent_hfinfo;
8028 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", 8028
, __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", 8028,
"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", 8028,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
8029
8030 /* Mark parent as indirectly referenced unless it is already directly
8031 * referenced, i.e. the user has specified the parent in a filter.
8032 */
8033 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8034 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8035 }
8036}
8037
8038proto_tree *
8039proto_item_add_subtree(proto_item *pi, const int idx) {
8040 field_info *fi;
8041
8042 if (!pi)
8043 return NULL((void*)0);
8044
8045 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", 8045, "idx >= 0 && idx < num_tree_types"
))))
;
8046
8047 fi = PITEM_FINFO(pi)((pi)->finfo);
8048 if (!fi)
8049 return (proto_tree *)pi;
8050
8051 fi->tree_type = idx;
8052
8053 return (proto_tree *)pi;
8054}
8055
8056proto_tree *
8057proto_item_get_subtree(proto_item *pi) {
8058 field_info *fi;
8059
8060 if (!pi)
8061 return NULL((void*)0);
8062 fi = PITEM_FINFO(pi)((pi)->finfo);
8063 if ( (fi) && (fi->tree_type == -1) )
8064 return NULL((void*)0);
8065 return (proto_tree *)pi;
8066}
8067
8068proto_item *
8069proto_item_get_parent(const proto_item *ti) {
8070 if (!ti)
8071 return NULL((void*)0);
8072 return ti->parent;
8073}
8074
8075proto_item *
8076proto_item_get_parent_nth(proto_item *ti, int gen) {
8077 if (!ti)
8078 return NULL((void*)0);
8079 while (gen--) {
8080 ti = ti->parent;
8081 if (!ti)
8082 return NULL((void*)0);
8083 }
8084 return ti;
8085}
8086
8087
8088proto_item *
8089proto_tree_get_parent(proto_tree *tree) {
8090 if (!tree)
8091 return NULL((void*)0);
8092 return (proto_item *)tree;
8093}
8094
8095proto_tree *
8096proto_tree_get_parent_tree(proto_tree *tree) {
8097 if (!tree)
8098 return NULL((void*)0);
8099
8100 /* we're the root tree, there's no parent
8101 return ourselves so the caller has at least a tree to attach to */
8102 if (!tree->parent)
8103 return tree;
8104
8105 return (proto_tree *)tree->parent;
8106}
8107
8108proto_tree *
8109proto_tree_get_root(proto_tree *tree) {
8110 if (!tree)
8111 return NULL((void*)0);
8112 while (tree->parent) {
8113 tree = tree->parent;
8114 }
8115 return tree;
8116}
8117
8118void
8119proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8120 proto_item *item_to_move)
8121{
8122 /* This function doesn't generate any values. It only reorganizes the prococol tree
8123 * so we can bail out immediately if it isn't visible. */
8124 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8125 return;
8126
8127 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", 8127, "item_to_move->parent == tree"
))))
;
8128 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", 8128, "fixed_item->parent == tree"
))))
;
8129
8130 /*** cut item_to_move out ***/
8131
8132 /* is item_to_move the first? */
8133 if (tree->first_child == item_to_move) {
8134 /* simply change first child to next */
8135 tree->first_child = item_to_move->next;
8136
8137 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", 8137, "tree->last_child != item_to_move"
))))
;
8138 } else {
8139 proto_item *curr_item;
8140 /* find previous and change it's next */
8141 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8142 if (curr_item->next == item_to_move) {
8143 break;
8144 }
8145 }
8146
8147 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8147, "curr_item"
))))
;
8148
8149 curr_item->next = item_to_move->next;
8150
8151 /* fix last_child if required */
8152 if (tree->last_child == item_to_move) {
8153 tree->last_child = curr_item;
8154 }
8155 }
8156
8157 /*** insert to_move after fixed ***/
8158 item_to_move->next = fixed_item->next;
8159 fixed_item->next = item_to_move;
8160 if (tree->last_child == fixed_item) {
8161 tree->last_child = item_to_move;
8162 }
8163}
8164
8165void
8166proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8167 const int length)
8168{
8169 field_info *fi;
8170
8171 if (tree == NULL((void*)0))
8172 return;
8173
8174 fi = PTREE_FINFO(tree)((tree)->finfo);
8175 if (fi == NULL((void*)0))
8176 return;
8177
8178 start += tvb_raw_offset(tvb);
8179 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8179, "start >= 0"
))))
;
8180 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8180, "length >= 0"
))))
;
8181
8182 fi->appendix_start = start;
8183 fi->appendix_length = length;
8184}
8185
8186static void
8187check_protocol_filter_name_or_fail(const char *filter_name)
8188{
8189 /* Require at least two characters. */
8190 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8191 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)
;
8192 }
8193
8194 if (proto_check_field_name(filter_name) != '\0') {
8195 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)
8196 " 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)
8197 " 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)
;
8198 }
8199
8200 /* Check that it doesn't match some very common numeric forms. */
8201 if (filter_name[0] == '0' &&
8202 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8203 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8204 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])
8205 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])
;
8206 }
8207
8208 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8209
8210 /* Check that it contains at least one letter. */
8211 bool_Bool have_letter = false0;
8212 for (const char *s = filter_name; *s != '\0'; s++) {
8213 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8214 have_letter = true1;
8215 break;
8216 }
8217 }
8218 if (!have_letter) {
8219 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)
8220 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8221 }
8222
8223 /* Check for reserved keywords. */
8224 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8225 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)
8226 " 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)
;
8227 }
8228}
8229
8230int
8231proto_register_protocol(const char *name, const char *short_name,
8232 const char *filter_name)
8233{
8234 protocol_t *protocol;
8235 header_field_info *hfinfo;
8236
8237 /*
8238 * Make sure there's not already a protocol with any of those
8239 * names. Crash if there is, as that's an error in the code
8240 * or an inappropriate plugin.
8241 * This situation has to be fixed to not register more than one
8242 * protocol with the same name.
8243 */
8244
8245 if (g_hash_table_lookup(proto_names, name)) {
8246 /* ws_error will terminate the program */
8247 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)
8248 " 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)
;
8249 }
8250
8251 if (g_hash_table_lookup(proto_short_names, short_name)) {
8252 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)
8253 " 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)
;
8254 }
8255
8256 check_protocol_filter_name_or_fail(filter_name);
8257
8258 if (g_hash_table_lookup(proto_filter_names, filter_name)) {
8259 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)
8260 " 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)
;
8261 }
8262
8263 /*
8264 * Add this protocol to the list of known protocols;
8265 * the list is sorted by protocol short name.
8266 */
8267 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8268 protocol->name = name;
8269 protocol->short_name = short_name;
8270 protocol->filter_name = filter_name;
8271 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8272 protocol->is_enabled = true1; /* protocol is enabled by default */
8273 protocol->enabled_by_default = true1; /* see previous comment */
8274 protocol->can_toggle = true1;
8275 protocol->parent_proto_id = -1;
8276 protocol->heur_list = NULL((void*)0);
8277
8278 /* List will be sorted later by name, when all protocols completed registering */
8279 protocols = g_list_prepend(protocols, protocol);
8280 g_hash_table_insert(proto_names, (void *)name, protocol);
8281 g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol);
8282 g_hash_table_insert(proto_short_names, (void *)short_name, protocol);
8283
8284 /* Here we allocate a new header_field_info struct */
8285 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8286 hfinfo->name = name;
8287 hfinfo->abbrev = filter_name;
8288 hfinfo->type = FT_PROTOCOL;
8289 hfinfo->display = BASE_NONE;
8290 hfinfo->strings = protocol;
8291 hfinfo->bitmask = 0;
8292 hfinfo->ref_type = HF_REF_TYPE_NONE;
8293 hfinfo->blurb = NULL((void*)0);
8294 hfinfo->parent = -1; /* This field differentiates protos and fields */
8295
8296 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8297 return protocol->proto_id;
8298}
8299
8300int
8301proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8302{
8303 protocol_t *protocol;
8304 header_field_info *hfinfo;
8305
8306 /*
8307 * Helper protocols don't need the strict rules as a "regular" protocol
8308 * Just register it in a list and make a hf_ field from it
8309 */
8310 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8311 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)
;
8312 }
8313
8314 if (parent_proto <= 0) {
8315 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)
8316 " 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)
;
8317 }
8318
8319 check_protocol_filter_name_or_fail(filter_name);
8320
8321 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8322 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8323 protocol->name = name;
8324 protocol->short_name = short_name;
8325 protocol->filter_name = filter_name;
8326 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8327
8328 /* Enabling and toggling is really determined by parent protocol,
8329 but provide default values here */
8330 protocol->is_enabled = true1;
8331 protocol->enabled_by_default = true1;
8332 protocol->can_toggle = true1;
8333
8334 protocol->parent_proto_id = parent_proto;
8335 protocol->heur_list = NULL((void*)0);
8336
8337 /* List will be sorted later by name, when all protocols completed registering */
8338 protocols = g_list_prepend(protocols, protocol);
8339
8340 /* Here we allocate a new header_field_info struct */
8341 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8342 hfinfo->name = name;
8343 hfinfo->abbrev = filter_name;
8344 hfinfo->type = field_type;
8345 hfinfo->display = BASE_NONE;
8346 if (field_type == FT_BYTES) {
8347 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8348 }
8349 hfinfo->strings = protocol;
8350 hfinfo->bitmask = 0;
8351 hfinfo->ref_type = HF_REF_TYPE_NONE;
8352 hfinfo->blurb = NULL((void*)0);
8353 hfinfo->parent = -1; /* This field differentiates protos and fields */
8354
8355 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8356 return protocol->proto_id;
8357}
8358
8359bool_Bool
8360proto_deregister_protocol(const char *short_name)
8361{
8362 protocol_t *protocol;
8363 header_field_info *hfinfo;
8364 int proto_id;
8365 unsigned i;
8366
8367 proto_id = proto_get_id_by_short_name(short_name);
8368 protocol = find_protocol_by_id(proto_id);
8369 if (protocol == NULL((void*)0))
8370 return false0;
8371
8372 g_hash_table_remove(proto_names, protocol->name);
8373 g_hash_table_remove(proto_short_names, (void *)short_name);
8374 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8375
8376 if (protocol->fields) {
8377 for (i = 0; i < protocol->fields->len; i++) {
8378 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8379 hfinfo_remove_from_gpa_name_map(hfinfo);
8380 expert_deregister_expertinfo(hfinfo->abbrev);
8381 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8382 }
8383 g_ptr_array_free(protocol->fields, true1);
8384 protocol->fields = NULL((void*)0);
8385 }
8386
8387 g_list_free(protocol->heur_list);
8388
8389 /* Remove this protocol from the list of known protocols */
8390 protocols = g_list_remove(protocols, protocol);
8391
8392 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8393 g_hash_table_steal(gpa_name_map, protocol->filter_name);
8394
8395 g_free(last_field_name);
8396 last_field_name = NULL((void*)0);
8397
8398 return true1;
8399}
8400
8401void
8402proto_register_alias(const int proto_id, const char *alias_name)
8403{
8404 protocol_t *protocol;
8405
8406 protocol = find_protocol_by_id(proto_id);
8407 if (alias_name && protocol) {
8408 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8409 }
8410}
8411
8412/*
8413 * Routines to use to iterate over the protocols.
8414 * The argument passed to the iterator routines is an opaque cookie to
8415 * their callers; it's the GList pointer for the current element in
8416 * the list.
8417 * The ID of the protocol is returned, or -1 if there is no protocol.
8418 */
8419int
8420proto_get_first_protocol(void **cookie)
8421{
8422 protocol_t *protocol;
8423
8424 if (protocols == NULL((void*)0))
8425 return -1;
8426 *cookie = protocols;
8427 protocol = (protocol_t *)protocols->data;
8428 return protocol->proto_id;
8429}
8430
8431int
8432proto_get_data_protocol(void *cookie)
8433{
8434 GList *list_item = (GList *)cookie;
8435
8436 protocol_t *protocol = (protocol_t *)list_item->data;
8437 return protocol->proto_id;
8438}
8439
8440int
8441proto_get_next_protocol(void **cookie)
8442{
8443 GList *list_item = (GList *)*cookie;
8444 protocol_t *protocol;
8445
8446 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8447 if (list_item == NULL((void*)0))
8448 return -1;
8449 *cookie = list_item;
8450 protocol = (protocol_t *)list_item->data;
8451 return protocol->proto_id;
8452}
8453
8454header_field_info *
8455proto_get_first_protocol_field(const int proto_id, void **cookie)
8456{
8457 protocol_t *protocol = find_protocol_by_id(proto_id);
8458
8459 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8460 return NULL((void*)0);
8461
8462 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8463 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8464}
8465
8466header_field_info *
8467proto_get_next_protocol_field(const int proto_id, void **cookie)
8468{
8469 protocol_t *protocol = find_protocol_by_id(proto_id);
8470 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8471
8472 i++;
8473
8474 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8475 return NULL((void*)0);
8476
8477 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8478 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8479}
8480
8481protocol_t *
8482find_protocol_by_id(const int proto_id)
8483{
8484 header_field_info *hfinfo;
8485
8486 if (proto_id <= 0)
8487 return NULL((void*)0);
8488
8489 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", 8489, __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", 8489,
"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", 8489, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8490 if (hfinfo->type != FT_PROTOCOL) {
8491 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", 8491, "hfinfo->display & 0x00004000"
))))
;
8492 }
8493 return (protocol_t *)hfinfo->strings;
8494}
8495
8496int
8497proto_get_id(const protocol_t *protocol)
8498{
8499 return protocol->proto_id;
8500}
8501
8502bool_Bool
8503proto_name_already_registered(const char *name)
8504{
8505 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8505, "name", "No name present"))))
;
8506
8507 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8508 return true1;
8509 return false0;
8510}
8511
8512int
8513proto_get_id_by_filter_name(const char *filter_name)
8514{
8515 const protocol_t *protocol = NULL((void*)0);
8516
8517 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", 8517,
"filter_name", "No filter name present"))))
;
8518
8519 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8520
8521 if (protocol == NULL((void*)0))
8522 return -1;
8523 return protocol->proto_id;
8524}
8525
8526int
8527proto_get_id_by_short_name(const char *short_name)
8528{
8529 const protocol_t *protocol = NULL((void*)0);
8530
8531 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", 8531,
"short_name", "No short name present"))))
;
8532
8533 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8534
8535 if (protocol == NULL((void*)0))
8536 return -1;
8537 return protocol->proto_id;
8538}
8539
8540const char *
8541proto_get_protocol_name(const int proto_id)
8542{
8543 protocol_t *protocol;
8544
8545 protocol = find_protocol_by_id(proto_id);
8546
8547 if (protocol == NULL((void*)0))
8548 return NULL((void*)0);
8549 return protocol->name;
8550}
8551
8552const char *
8553proto_get_protocol_short_name(const protocol_t *protocol)
8554{
8555 if (protocol == NULL((void*)0))
8556 return "(none)";
8557 return protocol->short_name;
8558}
8559
8560const char *
8561proto_get_protocol_long_name(const protocol_t *protocol)
8562{
8563 if (protocol == NULL((void*)0))
8564 return "(none)";
8565 return protocol->name;
8566}
8567
8568const char *
8569proto_get_protocol_filter_name(const int proto_id)
8570{
8571 protocol_t *protocol;
8572
8573 protocol = find_protocol_by_id(proto_id);
8574 if (protocol == NULL((void*)0))
8575 return "(none)";
8576 return protocol->filter_name;
8577}
8578
8579void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8580{
8581 heur_dtbl_entry_t* heuristic_dissector;
8582
8583 if (protocol == NULL((void*)0))
8584 return;
8585
8586 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8587 if (heuristic_dissector != NULL((void*)0))
8588 {
8589 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8590 }
8591}
8592
8593void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8594{
8595 if (protocol == NULL((void*)0))
8596 return;
8597
8598 g_list_foreach(protocol->heur_list, func, user_data);
8599}
8600
8601void
8602proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8603 bool_Bool *is_tcp, bool_Bool *is_udp,
8604 bool_Bool *is_sctp, bool_Bool *is_tls,
8605 bool_Bool *is_rtp,
8606 bool_Bool *is_lte_rlc)
8607{
8608 wmem_list_frame_t *protos = wmem_list_head(layers);
8609 int proto_id;
8610 const char *proto_name;
8611
8612 /* Walk the list of a available protocols in the packet and
8613 attempt to find "major" ones. */
8614 /* It might make more sense to assemble and return a bitfield. */
8615 while (protos != NULL((void*)0))
8616 {
8617 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8618 proto_name = proto_get_protocol_filter_name(proto_id);
8619
8620 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8621 (!strcmp(proto_name, "ipv6")))) {
8622 *is_ip = true1;
8623 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8624 *is_tcp = true1;
8625 } else if (is_udp && !strcmp(proto_name, "udp")) {
8626 *is_udp = true1;
8627 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8628 *is_sctp = true1;
8629 } else if (is_tls && !strcmp(proto_name, "tls")) {
8630 *is_tls = true1;
8631 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8632 *is_rtp = true1;
8633 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8634 *is_lte_rlc = true1;
8635 }
8636
8637 protos = wmem_list_frame_next(protos);
8638 }
8639}
8640
8641bool_Bool
8642proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8643{
8644 wmem_list_frame_t *protos = wmem_list_head(layers);
8645 int proto_id;
8646 const char *name;
8647
8648 /* Walk the list of a available protocols in the packet and
8649 attempt to find the specified protocol. */
8650 while (protos != NULL((void*)0))
8651 {
8652 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8653 name = proto_get_protocol_filter_name(proto_id);
8654
8655 if (!strcmp(name, proto_name))
8656 {
8657 return true1;
8658 }
8659
8660 protos = wmem_list_frame_next(protos);
8661 }
8662
8663 return false0;
8664}
8665
8666char *
8667proto_list_layers(const packet_info *pinfo)
8668{
8669 wmem_strbuf_t *buf;
8670 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8671
8672 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8673
8674 /* Walk the list of layers in the packet and
8675 return a string of all entries. */
8676 while (layers != NULL((void*)0))
8677 {
8678 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8679
8680 layers = wmem_list_frame_next(layers);
8681 if (layers != NULL((void*)0)) {
8682 wmem_strbuf_append_c(buf, ':');
8683 }
8684 }
8685
8686 return wmem_strbuf_finalize(buf);
8687}
8688
8689bool_Bool
8690proto_is_pino(const protocol_t *protocol)
8691{
8692 return (protocol->parent_proto_id != -1);
8693}
8694
8695bool_Bool
8696// NOLINTNEXTLINE(misc-no-recursion)
8697proto_is_protocol_enabled(const protocol_t *protocol)
8698{
8699 if (protocol == NULL((void*)0))
8700 return false0;
8701
8702 //parent protocol determines enable/disable for helper dissectors
8703 if (proto_is_pino(protocol))
8704 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8705
8706 return protocol->is_enabled;
8707}
8708
8709bool_Bool
8710// NOLINTNEXTLINE(misc-no-recursion)
8711proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8712{
8713 //parent protocol determines enable/disable for helper dissectors
8714 if (proto_is_pino(protocol))
8715 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8716
8717 return protocol->enabled_by_default;
8718}
8719
8720bool_Bool
8721// NOLINTNEXTLINE(misc-no-recursion)
8722proto_can_toggle_protocol(const int proto_id)
8723{
8724 protocol_t *protocol;
8725
8726 protocol = find_protocol_by_id(proto_id);
8727 //parent protocol determines toggling for helper dissectors
8728 if (proto_is_pino(protocol))
8729 return proto_can_toggle_protocol(protocol->parent_proto_id);
8730
8731 return protocol->can_toggle;
8732}
8733
8734void
8735proto_disable_by_default(const int proto_id)
8736{
8737 protocol_t *protocol;
8738
8739 protocol = find_protocol_by_id(proto_id);
8740 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8740, "protocol->can_toggle"
))))
;
8741 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", 8741, "proto_is_pino(protocol) == 0"
))))
;
8742 protocol->is_enabled = false0;
8743 protocol->enabled_by_default = false0;
8744}
8745
8746void
8747proto_set_decoding(const int proto_id, const bool_Bool enabled)
8748{
8749 protocol_t *protocol;
8750
8751 protocol = find_protocol_by_id(proto_id);
8752 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8752, "protocol->can_toggle"
))))
;
8753 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", 8753, "proto_is_pino(protocol) == 0"
))))
;
8754 protocol->is_enabled = enabled;
8755}
8756
8757void
8758proto_disable_all(void)
8759{
8760 /* This doesn't explicitly disable heuristic protocols,
8761 * but the heuristic doesn't get called if the parent
8762 * protocol isn't enabled.
8763 */
8764 protocol_t *protocol;
8765 GList *list_item = protocols;
8766
8767 if (protocols == NULL((void*)0))
8768 return;
8769
8770 while (list_item) {
8771 protocol = (protocol_t *)list_item->data;
8772 if (protocol->can_toggle) {
8773 protocol->is_enabled = false0;
8774 }
8775 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8776 }
8777}
8778
8779static void
8780heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8781{
8782 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8783
8784 heur->enabled = heur->enabled_by_default;
8785}
8786
8787void
8788proto_reenable_all(void)
8789{
8790 protocol_t *protocol;
8791 GList *list_item = protocols;
8792
8793 if (protocols == NULL((void*)0))
8794 return;
8795
8796 while (list_item) {
8797 protocol = (protocol_t *)list_item->data;
8798 if (protocol->can_toggle)
8799 protocol->is_enabled = protocol->enabled_by_default;
8800 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8801 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8802 }
8803}
8804
8805void
8806proto_set_cant_toggle(const int proto_id)
8807{
8808 protocol_t *protocol;
8809
8810 protocol = find_protocol_by_id(proto_id);
8811 protocol->can_toggle = false0;
8812}
8813
8814static int
8815proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8816{
8817 if (proto != NULL((void*)0)) {
8818 g_ptr_array_add(proto->fields, hfi);
8819 }
8820
8821 return proto_register_field_init(hfi, parent);
8822}
8823
8824/* for use with static arrays only, since we don't allocate our own copies
8825of the header_field_info struct contained within the hf_register_info struct */
8826void
8827proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8828{
8829 hf_register_info *ptr = hf;
8830 protocol_t *proto;
8831 int i;
8832
8833 proto = find_protocol_by_id(parent);
8834
8835 if (proto->fields == NULL((void*)0)) {
8836 proto->fields = g_ptr_array_sized_new(num_records);
8837 }
8838
8839 for (i = 0; i < num_records; i++, ptr++) {
8840 /*
8841 * Make sure we haven't registered this yet.
8842 * Most fields have variables associated with them
8843 * that are initialized to -1; some have array elements,
8844 * or possibly uninitialized variables, so we also allow
8845 * 0 (which is unlikely to be the field ID we get back
8846 * from "proto_register_field_init()").
8847 */
8848 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8849 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8850 "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)
8851 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8852 return;
8853 }
8854
8855 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8856 }
8857}
8858
8859/* deregister already registered fields */
8860void
8861proto_deregister_field (const int parent, int hf_id)
8862{
8863 header_field_info *hfi;
8864 protocol_t *proto;
8865 unsigned i;
8866
8867 g_free(last_field_name);
8868 last_field_name = NULL((void*)0);
8869
8870 if (hf_id == -1 || hf_id == 0)
8871 return;
8872
8873 proto = find_protocol_by_id (parent);
8874 if (!proto || proto->fields == NULL((void*)0)) {
8875 return;
8876 }
8877
8878 for (i = 0; i < proto->fields->len; i++) {
8879 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8880 if (hfi->id == hf_id) {
8881 /* Found the hf_id in this protocol */
8882 g_hash_table_steal(gpa_name_map, hfi->abbrev);
8883 g_ptr_array_remove_index_fast(proto->fields, i);
8884 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8885 return;
8886 }
8887 }
8888}
8889
8890void
8891proto_add_deregistered_data (void *data)
8892{
8893 g_ptr_array_add(deregistered_data, data);
8894}
8895
8896void
8897proto_add_deregistered_slice (size_t block_size, void *mem_block)
8898{
8899 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
)))
;
8900
8901 slice_data->block_size = block_size;
8902 slice_data->mem_block = mem_block;
8903
8904 g_ptr_array_add(deregistered_slice, slice_data);
8905}
8906
8907void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8908{
8909 if (field_strings == NULL((void*)0)) {
8910 return;
8911 }
8912
8913 switch (field_type) {
8914 case FT_FRAMENUM:
8915 /* This is just an integer represented as a pointer */
8916 break;
8917 case FT_PROTOCOL: {
8918 protocol_t *protocol = (protocol_t *)field_strings;
8919 g_free((char *)protocol->short_name);
8920 break;
8921 }
8922 case FT_BOOLEAN: {
8923 true_false_string *tf = (true_false_string *)field_strings;
8924 g_free((char *)tf->true_string);
8925 g_free((char *)tf->false_string);
8926 break;
8927 }
8928 case FT_UINT40:
8929 case FT_INT40:
8930 case FT_UINT48:
8931 case FT_INT48:
8932 case FT_UINT56:
8933 case FT_INT56:
8934 case FT_UINT64:
8935 case FT_INT64: {
8936 if (field_display & BASE_UNIT_STRING0x00001000) {
8937 unit_name_string *unit = (unit_name_string *)field_strings;
8938 g_free((char *)unit->singular);
8939 g_free((char *)unit->plural);
8940 } else if (field_display & BASE_RANGE_STRING0x00000100) {
8941 range_string *rs = (range_string *)field_strings;
8942 while (rs->strptr) {
8943 g_free((char *)rs->strptr);
8944 rs++;
8945 }
8946 } else if (field_display & BASE_EXT_STRING0x00000200) {
8947 val64_string_ext *vse = (val64_string_ext *)field_strings;
8948 val64_string *vs = (val64_string *)vse->_vs_p;
8949 while (vs->strptr) {
8950 g_free((char *)vs->strptr);
8951 vs++;
8952 }
8953 val64_string_ext_free(vse);
8954 field_strings = NULL((void*)0);
8955 } else if (field_display == BASE_CUSTOM) {
8956 /* this will be a pointer to a function, don't free that */
8957 field_strings = NULL((void*)0);
8958 } else {
8959 val64_string *vs64 = (val64_string *)field_strings;
8960 while (vs64->strptr) {
8961 g_free((char *)vs64->strptr);
8962 vs64++;
8963 }
8964 }
8965 break;
8966 }
8967 case FT_CHAR:
8968 case FT_UINT8:
8969 case FT_INT8:
8970 case FT_UINT16:
8971 case FT_INT16:
8972 case FT_UINT24:
8973 case FT_INT24:
8974 case FT_UINT32:
8975 case FT_INT32:
8976 case FT_FLOAT:
8977 case FT_DOUBLE: {
8978 if (field_display & BASE_UNIT_STRING0x00001000) {
8979 unit_name_string *unit = (unit_name_string *)field_strings;
8980 g_free((char *)unit->singular);
8981 g_free((char *)unit->plural);
8982 } else if (field_display & BASE_RANGE_STRING0x00000100) {
8983 range_string *rs = (range_string *)field_strings;
8984 while (rs->strptr) {
8985 g_free((char *)rs->strptr);
8986 rs++;
8987 }
8988 } else if (field_display & BASE_EXT_STRING0x00000200) {
8989 value_string_ext *vse = (value_string_ext *)field_strings;
8990 value_string *vs = (value_string *)vse->_vs_p;
8991 while (vs->strptr) {
8992 g_free((char *)vs->strptr);
8993 vs++;
8994 }
8995 value_string_ext_free(vse);
8996 field_strings = NULL((void*)0);
8997 } else if (field_display == BASE_CUSTOM) {
8998 /* this will be a pointer to a function, don't free that */
8999 field_strings = NULL((void*)0);
9000 } else {
9001 value_string *vs = (value_string *)field_strings;
9002 while (vs->strptr) {
9003 g_free((char *)vs->strptr);
9004 vs++;
9005 }
9006 }
9007 break;
9008 default:
9009 break;
9010 }
9011 }
9012
9013 if (field_type != FT_FRAMENUM) {
9014 g_free((void *)field_strings);
9015 }
9016}
9017
9018static void
9019free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9020{
9021 header_field_info *hfi = (header_field_info *) data;
9022 int hf_id = hfi->id;
9023
9024 g_free((char *)hfi->name);
9025 g_free((char *)hfi->abbrev);
9026 g_free((char *)hfi->blurb);
9027
9028 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9029
9030 if (hfi->parent == -1)
9031 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)
;
9032
9033 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9034}
9035
9036static void
9037free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9038{
9039 g_free (data);
9040}
9041
9042static void
9043free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9044{
9045 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9046
9047 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9048 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)
;
9049}
9050
9051/* free deregistered fields and data */
9052void
9053proto_free_deregistered_fields (void)
9054{
9055 expert_free_deregistered_expertinfos();
9056
9057 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9058 g_ptr_array_free(deregistered_fields, true1);
9059 deregistered_fields = g_ptr_array_new();
9060
9061 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9062 g_ptr_array_free(deregistered_data, true1);
9063 deregistered_data = g_ptr_array_new();
9064
9065 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9066 g_ptr_array_free(deregistered_slice, true1);
9067 deregistered_slice = g_ptr_array_new();
9068}
9069
9070static const value_string hf_display[] = {
9071 { BASE_NONE, "BASE_NONE" },
9072 { BASE_DEC, "BASE_DEC" },
9073 { BASE_HEX, "BASE_HEX" },
9074 { BASE_OCT, "BASE_OCT" },
9075 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9076 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9077 { BASE_CUSTOM, "BASE_CUSTOM" },
9078 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9079 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9080 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9081 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9082 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9083 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9084 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9085 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9086 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9087 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9088 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9089 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9090 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9091 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9092 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9093 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9094 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9095 { BASE_PT_UDP, "BASE_PT_UDP" },
9096 { BASE_PT_TCP, "BASE_PT_TCP" },
9097 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9098 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9099 { BASE_OUI, "BASE_OUI" },
9100 { 0, NULL((void*)0) } };
9101
9102const char* proto_field_display_to_string(int field_display)
9103{
9104 return val_to_str_const(field_display, hf_display, "Unknown");
9105}
9106
9107static inline port_type
9108display_to_port_type(field_display_e e)
9109{
9110 switch (e) {
9111 case BASE_PT_UDP:
9112 return PT_UDP;
9113 case BASE_PT_TCP:
9114 return PT_TCP;
9115 case BASE_PT_DCCP:
9116 return PT_DCCP;
9117 case BASE_PT_SCTP:
9118 return PT_SCTP;
9119 default:
9120 break;
9121 }
9122 return PT_NONE;
9123}
9124
9125/* temporary function containing assert part for easier profiling */
9126static void
9127tmp_fld_check_assert(header_field_info *hfinfo)
9128{
9129 char* tmp_str;
9130
9131 /* The field must have a name (with length > 0) */
9132 if (!hfinfo->name || !hfinfo->name[0]) {
9133 if (hfinfo->abbrev)
9134 /* Try to identify the field */
9135 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)
9136 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9137 else
9138 /* Hum, no luck */
9139 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)"
)
;
9140 }
9141
9142 /* fields with an empty string for an abbreviation aren't filterable */
9143 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9144 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)
;
9145
9146 /* These types of fields are allowed to have value_strings,
9147 * true_false_strings or a protocol_t struct
9148 */
9149 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9150 switch (hfinfo->type) {
9151
9152 /*
9153 * These types are allowed to support display value_strings,
9154 * value64_strings, the extended versions of the previous
9155 * two, range strings, or unit strings.
9156 */
9157 case FT_CHAR:
9158 case FT_UINT8:
9159 case FT_UINT16:
9160 case FT_UINT24:
9161 case FT_UINT32:
9162 case FT_UINT40:
9163 case FT_UINT48:
9164 case FT_UINT56:
9165 case FT_UINT64:
9166 case FT_INT8:
9167 case FT_INT16:
9168 case FT_INT24:
9169 case FT_INT32:
9170 case FT_INT40:
9171 case FT_INT48:
9172 case FT_INT56:
9173 case FT_INT64:
9174 case FT_BOOLEAN:
9175 case FT_PROTOCOL:
9176 break;
9177
9178 /*
9179 * This is allowed to have a value of type
9180 * enum ft_framenum_type to indicate what relationship
9181 * the frame in question has to the frame in which
9182 * the field is put.
9183 */
9184 case FT_FRAMENUM:
9185 break;
9186
9187 /*
9188 * These types are allowed to support only unit strings.
9189 */
9190 case FT_FLOAT:
9191 case FT_DOUBLE:
9192 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9193 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))
9194 " (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))
9195 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))
;
9196 }
9197 break;
9198
9199 /*
9200 * This type is only allowed to support a string if it's
9201 * a protocol (for pinos).
9202 */
9203 case FT_BYTES:
9204 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9205 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))
9206 " (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))
9207 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))
;
9208 }
9209 break;
9210
9211 default:
9212 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))
9213 " (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))
9214 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))
;
9215 }
9216 }
9217
9218 /* TODO: This check may slow down startup, and output quite a few warnings.
9219 It would be good to be able to enable this (and possibly other checks?)
9220 in non-release builds. */
9221#ifdef ENABLE_CHECK_FILTER
9222 /* Check for duplicate value_string values.
9223 There are lots that have the same value *and* string, so for now only
9224 report those that have same value but different string. */
9225 if ((hfinfo->strings != NULL((void*)0)) &&
9226 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9227 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9228 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9229 (
9230 (hfinfo->type == FT_CHAR) ||
9231 (hfinfo->type == FT_UINT8) ||
9232 (hfinfo->type == FT_UINT16) ||
9233 (hfinfo->type == FT_UINT24) ||
9234 (hfinfo->type == FT_UINT32) ||
9235 (hfinfo->type == FT_INT8) ||
9236 (hfinfo->type == FT_INT16) ||
9237 (hfinfo->type == FT_INT24) ||
9238 (hfinfo->type == FT_INT32) )) {
9239
9240 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9241 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9242 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9243 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9244 } else {
9245 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9246 CHECK_HF_VALUE(value_string, "u", start_values);
9247 }
9248 } else {
9249 const value_string *start_values = (const value_string*)hfinfo->strings;
9250 CHECK_HF_VALUE(value_string, "u", start_values);
9251 }
9252 }
9253
9254 if (hfinfo->type == FT_BOOLEAN) {
9255 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9256 if (tfs) {
9257 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9258 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"
, 9260, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9259 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9260, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9260 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9260, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9261 }
9262 }
9263 }
9264
9265 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9266 const range_string *rs = (const range_string*)(hfinfo->strings);
9267 if (rs) {
9268 const range_string *this_it = rs;
9269
9270 do {
9271 if (this_it->value_max < this_it->value_min) {
9272 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"
, 9276, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9273 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9276, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9274 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9276, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9275 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9276, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%"
"l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x"
")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it
->value_max, this_it->value_max, this_it->value_min,
this_it->value_min); } } while (0)
9276 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9276, __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)
;
9277 ++this_it;
9278 continue;
9279 }
9280
9281 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9282 /* Not OK if this one is completely hidden by an earlier one! */
9283 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9284 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"
, 9290, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9285 "(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"
, 9290, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9286 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9290, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9287 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9290, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9288 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9290, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9289 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9290, __func__, "value_range_string error: %s (%s) hidden by earlier entry "
"(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%"
"l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l"
"u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it
->strptr, prev_it->value_min, prev_it->value_min, prev_it
->value_max, prev_it->value_max, this_it->strptr, this_it
->value_min, this_it->value_min, this_it->value_max,
this_it->value_max); } } while (0)
9290 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9290, __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)
;
9291 }
9292 }
9293 ++this_it;
9294 } while (this_it->strptr);
9295 }
9296 }
9297#endif
9298
9299 switch (hfinfo->type) {
9300
9301 case FT_CHAR:
9302 /* Require the char type to have BASE_HEX, BASE_OCT,
9303 * BASE_CUSTOM, or BASE_NONE as its base.
9304 *
9305 * If the display value is BASE_NONE and there is a
9306 * strings conversion then the dissector writer is
9307 * telling us that the field's numerical value is
9308 * meaningless; we'll avoid showing the value to the
9309 * user.
9310 */
9311 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9312 case BASE_HEX:
9313 case BASE_OCT:
9314 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9315 break;
9316 case BASE_NONE:
9317 if (hfinfo->strings == NULL((void*)0))
9318 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
))
9319 " 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
))
9320 " 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
))
9321 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
))
9322 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
))
;
9323 break;
9324 default:
9325 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9326 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)
9327 " 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)
9328 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)
9329 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)
;
9330 //wmem_free(NULL, tmp_str);
9331 }
9332 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9333 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
))
9334 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
))
9335 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
))
;
9336 }
9337 break;
9338 case FT_INT8:
9339 case FT_INT16:
9340 case FT_INT24:
9341 case FT_INT32:
9342 case FT_INT40:
9343 case FT_INT48:
9344 case FT_INT56:
9345 case FT_INT64:
9346 /* Hexadecimal and octal are, in printf() and everywhere
9347 * else, unsigned so don't allow dissectors to register a
9348 * signed field to be displayed unsigned. (Else how would
9349 * we display negative values?)
9350 */
9351 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9352 case BASE_HEX:
9353 case BASE_OCT:
9354 case BASE_DEC_HEX:
9355 case BASE_HEX_DEC:
9356 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9357 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)
9358 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)
9359 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)
;
9360 //wmem_free(NULL, tmp_str);
9361 }
9362 /* FALL THROUGH */
9363 case FT_UINT8:
9364 case FT_UINT16:
9365 case FT_UINT24:
9366 case FT_UINT32:
9367 case FT_UINT40:
9368 case FT_UINT48:
9369 case FT_UINT56:
9370 case FT_UINT64:
9371 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
))
) {
9372 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9373 if (hfinfo->type != FT_UINT16) {
9374 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))
9375 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))
9376 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))
;
9377 }
9378 if (hfinfo->strings != NULL((void*)0)) {
9379 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)
9380 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)
9381 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)
;
9382 }
9383 if (hfinfo->bitmask != 0) {
9384 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)
9385 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)
9386 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)
;
9387 }
9388 wmem_free(NULL((void*)0), tmp_str);
9389 break;
9390 }
9391
9392 if (hfinfo->display == BASE_OUI) {
9393 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9394 if (hfinfo->type != FT_UINT24) {
9395 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))
9396 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))
9397 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))
;
9398 }
9399 if (hfinfo->strings != NULL((void*)0)) {
9400 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)
9401 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)
9402 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)
;
9403 }
9404 if (hfinfo->bitmask != 0) {
9405 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)
9406 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)
9407 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)
;
9408 }
9409 wmem_free(NULL((void*)0), tmp_str);
9410 break;
9411 }
9412
9413 /* Require integral types (other than frame number,
9414 * which is always displayed in decimal) to have a
9415 * number base.
9416 *
9417 * If the display value is BASE_NONE and there is a
9418 * strings conversion then the dissector writer is
9419 * telling us that the field's numerical value is
9420 * meaningless; we'll avoid showing the value to the
9421 * user.
9422 */
9423 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9424 case BASE_DEC:
9425 case BASE_HEX:
9426 case BASE_OCT:
9427 case BASE_DEC_HEX:
9428 case BASE_HEX_DEC:
9429 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9430 break;
9431 case BASE_NONE:
9432 if (hfinfo->strings == NULL((void*)0)) {
9433 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
))
9434 " 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
))
9435 " 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
))
9436 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
))
9437 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
))
;
9438 }
9439 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9440 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
))
9441 " 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
))
9442 " 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
))
9443 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
))
9444 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
))
;
9445 }
9446 break;
9447
9448 default:
9449 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9450 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)
9451 " 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)
9452 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)
9453 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)
;
9454 //wmem_free(NULL, tmp_str);
9455 }
9456 break;
9457 case FT_BYTES:
9458 case FT_UINT_BYTES:
9459 /* Require bytes to have a "display type" that could
9460 * add a character between displayed bytes.
9461 */
9462 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9463 case BASE_NONE:
9464 case SEP_DOT:
9465 case SEP_DASH:
9466 case SEP_COLON:
9467 case SEP_SPACE:
9468 break;
9469 default:
9470 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9471 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)
9472 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)
;
9473 //wmem_free(NULL, tmp_str);
9474 }
9475 if (hfinfo->bitmask != 0)
9476 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
))
9477 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
))
9478 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
))
;
9479 //allowed to support string if its a protocol (for pinos)
9480 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9481 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
))
9482 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
))
9483 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
))
;
9484 break;
9485
9486 case FT_PROTOCOL:
9487 case FT_FRAMENUM:
9488 if (hfinfo->display != BASE_NONE) {
9489 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9490 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)
9491 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)
9492 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)
;
9493 //wmem_free(NULL, tmp_str);
9494 }
9495 if (hfinfo->bitmask != 0)
9496 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
))
9497 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
))
9498 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
))
;
9499 break;
9500
9501 case FT_BOOLEAN:
9502 break;
9503
9504 case FT_ABSOLUTE_TIME:
9505 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9506 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9507 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)
9508 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)
;
9509 //wmem_free(NULL, tmp_str);
9510 }
9511 if (hfinfo->bitmask != 0)
9512 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
))
9513 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
))
9514 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
))
;
9515 break;
9516
9517 case FT_STRING:
9518 case FT_STRINGZ:
9519 case FT_UINT_STRING:
9520 case FT_STRINGZPAD:
9521 case FT_STRINGZTRUNC:
9522 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9523 case BASE_NONE:
9524 case BASE_STR_WSP:
9525 break;
9526
9527 default:
9528 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9529 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an 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)
9530 " 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)
9531 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)
9532 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)
;
9533 //wmem_free(NULL, tmp_str);
9534 }
9535
9536 if (hfinfo->bitmask != 0)
9537 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
))
9538 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
))
9539 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
))
;
9540 if (hfinfo->strings != NULL((void*)0))
9541 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a strings value",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9542 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9543 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a strings value"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9544 break;
9545
9546 case FT_IPv4:
9547 switch (hfinfo->display) {
9548 case BASE_NONE:
9549 case BASE_NETMASK:
9550 break;
9551
9552 default:
9553 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9554 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)
9555 " 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)
9556 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)
9557 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)
;
9558 //wmem_free(NULL, tmp_str);
9559 break;
9560 }
9561 break;
9562 case FT_FLOAT:
9563 case FT_DOUBLE:
9564 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9565 case BASE_NONE:
9566 case BASE_DEC:
9567 case BASE_HEX:
9568 case BASE_EXP:
9569 case BASE_CUSTOM:
9570 break;
9571 default:
9572 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9573 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)
9574 " 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)
9575 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)
9576 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)
;
9577 //wmem_free(NULL, tmp_str);
9578 }
9579 if (hfinfo->bitmask != 0)
9580 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9581 hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
9582 ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask"
, hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type
))
;
9583 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9584 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
))
9585 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
))
9586 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
))
;
9587 break;
9588 default:
9589 if (hfinfo->display != BASE_NONE) {
9590 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9591 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)
9592 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)
9593 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)
9594 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)
;
9595 //wmem_free(NULL, tmp_str);
9596 }
9597 if (hfinfo->bitmask != 0)
9598 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
))
9599 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
))
9600 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
))
;
9601 if (hfinfo->strings != NULL((void*)0))
9602 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
))
9603 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
))
9604 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
))
;
9605 break;
9606 }
9607}
9608
9609static void
9610register_type_length_mismatch(void)
9611{
9612 static ei_register_info ei[] = {
9613 { &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)}}
}},
9614 { &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)}}
}},
9615 };
9616
9617 expert_module_t* expert_type_length_mismatch;
9618
9619 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9620
9621 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9622 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9623
9624 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9625 disabling them makes no sense. */
9626 proto_set_cant_toggle(proto_type_length_mismatch);
9627}
9628
9629static void
9630register_byte_array_string_decodinws_error(void)
9631{
9632 static ei_register_info ei[] = {
9633 { &ei_byte_array_string_decoding_failed_error,
9634 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9635 "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)}}
9636 }
9637 },
9638 };
9639
9640 expert_module_t* expert_byte_array_string_decoding_error;
9641
9642 proto_byte_array_string_decoding_error =
9643 proto_register_protocol("Byte Array-String Decoding Error",
9644 "Byte Array-string decoding error",
9645 "_ws.byte_array_string.decoding_error");
9646
9647 expert_byte_array_string_decoding_error =
9648 expert_register_protocol(proto_byte_array_string_decoding_error);
9649 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9650
9651 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9652 disabling them makes no sense. */
9653 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9654}
9655
9656static void
9657register_date_time_string_decodinws_error(void)
9658{
9659 static ei_register_info ei[] = {
9660 { &ei_date_time_string_decoding_failed_error,
9661 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9662 "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)}}
9663 }
9664 },
9665 };
9666
9667 expert_module_t* expert_date_time_string_decoding_error;
9668
9669 proto_date_time_string_decoding_error =
9670 proto_register_protocol("Date and Time-String Decoding Error",
9671 "Date and Time-string decoding error",
9672 "_ws.date_time_string.decoding_error");
9673
9674 expert_date_time_string_decoding_error =
9675 expert_register_protocol(proto_date_time_string_decoding_error);
9676 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9677
9678 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9679 disabling them makes no sense. */
9680 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9681}
9682
9683static void
9684register_string_errors(void)
9685{
9686 static ei_register_info ei[] = {
9687 { &ei_string_trailing_characters,
9688 { "_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)}}
}
9689 },
9690 };
9691
9692 expert_module_t* expert_string_errors;
9693
9694 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9695
9696 expert_string_errors = expert_register_protocol(proto_string_errors);
9697 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9698
9699 /* "String Errors" isn't really a protocol, it's an error indication;
9700 disabling them makes no sense. */
9701 proto_set_cant_toggle(proto_string_errors);
9702}
9703
9704#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
9705static int
9706proto_register_field_init(header_field_info *hfinfo, const int parent)
9707{
9708
9709 tmp_fld_check_assert(hfinfo);
9710
9711 hfinfo->parent = parent;
9712 hfinfo->same_name_next = NULL((void*)0);
9713 hfinfo->same_name_prev_id = -1;
9714
9715 /* if we always add and never delete, then id == len - 1 is correct */
9716 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9717 if (!gpa_hfinfo.hfi) {
9718 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9719 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9720 /* The entry with index 0 is not used. */
9721 gpa_hfinfo.hfi[0] = NULL((void*)0);
9722 gpa_hfinfo.len = 1;
9723 } else {
9724 gpa_hfinfo.allocated_len += 1000;
9725 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9726 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9727 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9728 }
9729 }
9730 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9731 gpa_hfinfo.len++;
9732 hfinfo->id = gpa_hfinfo.len - 1;
9733
9734 /* if we have real names, enter this field in the name tree */
9735 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
9736
9737 header_field_info *same_name_next_hfinfo;
9738 unsigned char c;
9739
9740 /* Check that the filter name (abbreviation) is legal;
9741 * it must contain only alphanumerics, '-', "_", and ".". */
9742 c = proto_check_field_name(hfinfo->abbrev);
9743 if (c) {
9744 if (c == '.') {
9745 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)
;
9746 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9747 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)
;
9748 } else {
9749 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)
;
9750 }
9751 }
9752
9753 /* We allow multiple hfinfo's to be registered under the same
9754 * abbreviation. This was done for X.25, as, depending
9755 * on whether it's modulo-8 or modulo-128 operation,
9756 * some bitfield fields may be in different bits of
9757 * a byte, and we want to be able to refer to that field
9758 * with one name regardless of whether the packets
9759 * are modulo-8 or modulo-128 packets. */
9760
9761 same_name_hfinfo = NULL((void*)0);
9762
9763 g_hash_table_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9764 /* GLIB 2.x - if it is already present
9765 * the previous hfinfo with the same name is saved
9766 * to same_name_hfinfo by value destroy callback */
9767 if (same_name_hfinfo) {
9768 /* There's already a field with this name.
9769 * Put the current field *before* that field
9770 * in the list of fields with this name, Thus,
9771 * we end up with an effectively
9772 * doubly-linked-list of same-named hfinfo's,
9773 * with the head of the list (stored in the
9774 * hash) being the last seen hfinfo.
9775 */
9776 same_name_next_hfinfo =
9777 same_name_hfinfo->same_name_next;
9778
9779 hfinfo->same_name_next = same_name_next_hfinfo;
9780 if (same_name_next_hfinfo)
9781 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9782
9783 same_name_hfinfo->same_name_next = hfinfo;
9784 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9785#ifdef ENABLE_CHECK_FILTER
9786 while (same_name_hfinfo) {
9787 if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9788 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"
, 9788, __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)
;
9789 same_name_hfinfo = same_name_hfinfo->same_name_next;
9790 }
9791#endif
9792 }
9793 }
9794
9795 return hfinfo->id;
9796}
9797
9798void
9799proto_register_subtree_array(int * const *indices, const int num_indices)
9800{
9801 int i;
9802 int *const *ptr = indices;
9803
9804 /*
9805 * If we've already allocated the array of tree types, expand
9806 * it; this lets plugins such as mate add tree types after
9807 * the initial startup. (If we haven't already allocated it,
9808 * we don't allocate it; on the first pass, we just assign
9809 * ett values and keep track of how many we've assigned, and
9810 * when we're finished registering all dissectors we allocate
9811 * the array, so that we do only one allocation rather than
9812 * wasting CPU time and memory by growing the array for each
9813 * dissector that registers ett values.)
9814 */
9815 if (tree_is_expanded != NULL((void*)0)) {
9816 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9817
9818 /* set new items to 0 */
9819 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9820 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9821 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9822 }
9823
9824 /*
9825 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9826 * returning the indices through the pointers in the array whose
9827 * first element is pointed to by "indices", and update
9828 * "num_tree_types" appropriately.
9829 */
9830 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9831 if (**ptr != -1 && **ptr != 0) {
9832 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.")
9833 " 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.")
9834 " 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.")
9835 " 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.")
;
9836 }
9837 **ptr = num_tree_types;
9838 }
9839}
9840
9841static void
9842mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
9843{
9844 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "]";
9845 const size_t trunc_len = sizeof(trunc_str)-1;
9846 char *last_char;
9847
9848 /* ..... field_name: dataaaaaaaaaaaaa
9849 * |
9850 * ^^^^^ name_pos
9851 *
9852 * ..... field_name […]: dataaaaaaaaaaaaa
9853 *
9854 * name_pos==0 means that we have only data or only a field_name
9855 */
9856
9857 if (name_pos < size - trunc_len) {
9858 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
9859 memcpy(label_str + name_pos, trunc_str, trunc_len);
9860
9861 /* in general, label_str is UTF-8
9862 we can truncate it only at the beginning of a new character
9863 we go backwards from the byte right after our buffer and
9864 find the next starting byte of a UTF-8 character, this is
9865 where we cut
9866 there's no need to use g_utf8_find_prev_char(), the search
9867 will always succeed since we copied trunc_str into the
9868 buffer */
9869 /* g_utf8_prev_char does not deference the memory address
9870 * passed in (until after decrementing it, so it is perfectly
9871 * legal to pass in a pointer one past the last element.
9872 */
9873 last_char = g_utf8_prev_char(label_str + size);
9874 *last_char = '\0';
9875
9876 if (value_pos && *value_pos > 0) {
9877 if (name_pos == 0) {
9878 *value_pos += trunc_len;
9879 } else {
9880 /* Move one back to include trunc_str in the value. */
9881 *value_pos -= 1;
9882 }
9883 }
9884 } else if (name_pos < size)
9885 (void) g_strlcpy(label_str + name_pos, trunc_str, size - name_pos);
9886}
9887
9888static void
9889label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
9890{
9891 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
9892}
9893
9894static size_t
9895label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
9896{
9897 size_t name_pos;
9898
9899 /* "%s: %s", hfinfo->name, text */
9900 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
9901 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
9902 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
9903 if (value_pos) {
9904 *value_pos = pos;
9905 }
9906 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
9907 }
9908
9909 if (pos >= ITEM_LABEL_LENGTH240) {
9910 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9911 label_mark_truncated(label_str, name_pos, value_pos);
9912 }
9913
9914 return pos;
9915}
9916
9917static size_t
9918label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
9919{
9920 size_t name_pos;
9921
9922 /* "%s: %s (%s)", hfinfo->name, text, descr */
9923 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
9924 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
9925 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
9926 if (value_pos) {
9927 *value_pos = pos;
9928 }
9929 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9930 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
9931 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
9932 } else {
9933 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
9934 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
9935 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
9936 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
9937 }
9938 }
9939
9940 if (pos >= ITEM_LABEL_LENGTH240) {
9941 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9942 label_mark_truncated(label_str, name_pos, value_pos);
9943 }
9944
9945 return pos;
9946}
9947
9948void
9949proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
9950{
9951 const header_field_info *hfinfo;
9952 const char *str;
9953 const uint8_t *bytes;
9954 uint32_t integer;
9955 const ipv4_addr_and_mask *ipv4;
9956 const ipv6_addr_and_prefix *ipv6;
9957 const e_guid_t *guid;
9958 char *name;
9959 address addr;
9960 char *addr_str;
9961 char *tmp;
9962
9963 if (!label_str) {
9964 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9964, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
9965 return;
9966 }
9967
9968 label_str[0]= '\0';
9969
9970 if (!fi) {
9971 return;
9972 }
9973
9974 hfinfo = fi->hfinfo;
9975
9976 switch (hfinfo->type) {
9977 case FT_NONE:
9978 case FT_PROTOCOL:
9979 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
9980 if (value_pos) {
9981 *value_pos = strlen(hfinfo->name);
9982 }
9983 break;
9984
9985 case FT_BOOLEAN:
9986 fill_label_boolean(fi, label_str, value_pos);
9987 break;
9988
9989 case FT_BYTES:
9990 case FT_UINT_BYTES:
9991 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
9992 fvalue_get_bytes_data(fi->value),
9993 (unsigned)fvalue_length2(fi->value));
9994 label_fill(label_str, 0, hfinfo, tmp, value_pos);
9995 wmem_free(NULL((void*)0), tmp);
9996 break;
9997
9998 case FT_CHAR:
9999 if (hfinfo->bitmask) {
10000 fill_label_bitfield_char(fi, label_str, value_pos);
10001 } else {
10002 fill_label_char(fi, label_str, value_pos);
10003 }
10004 break;
10005
10006 /* Four types of integers to take care of:
10007 * Bitfield, with val_string
10008 * Bitfield, w/o val_string
10009 * Non-bitfield, with val_string
10010 * Non-bitfield, w/o val_string
10011 */
10012 case FT_UINT8:
10013 case FT_UINT16:
10014 case FT_UINT24:
10015 case FT_UINT32:
10016 if (hfinfo->bitmask) {
10017 fill_label_bitfield(fi, label_str, value_pos, false0);
10018 } else {
10019 fill_label_number(fi, label_str, value_pos, false0);
10020 }
10021 break;
10022
10023 case FT_FRAMENUM:
10024 fill_label_number(fi, label_str, value_pos, false0);
10025 break;
10026
10027 case FT_UINT40:
10028 case FT_UINT48:
10029 case FT_UINT56:
10030 case FT_UINT64:
10031 if (hfinfo->bitmask) {
10032 fill_label_bitfield64(fi, label_str, value_pos, false0);
10033 } else {
10034 fill_label_number64(fi, label_str, value_pos, false0);
10035 }
10036 break;
10037
10038 case FT_INT8:
10039 case FT_INT16:
10040 case FT_INT24:
10041 case FT_INT32:
10042 if (hfinfo->bitmask) {
10043 fill_label_bitfield(fi, label_str, value_pos, true1);
10044 } else {
10045 fill_label_number(fi, label_str, value_pos, true1);
10046 }
10047 break;
10048
10049 case FT_INT40:
10050 case FT_INT48:
10051 case FT_INT56:
10052 case FT_INT64:
10053 if (hfinfo->bitmask) {
10054 fill_label_bitfield64(fi, label_str, value_pos, true1);
10055 } else {
10056 fill_label_number64(fi, label_str, value_pos, true1);
10057 }
10058 break;
10059
10060 case FT_FLOAT:
10061 case FT_DOUBLE:
10062 fill_label_float(fi, label_str, value_pos);
10063 break;
10064
10065 case FT_ABSOLUTE_TIME:
10066 {
10067 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10068 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10069 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10070 }
10071 tmp = abs_time_to_str_ex(NULL((void*)0), fvalue_get_time(fi->value), hfinfo->display, flags);
10072 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10073 wmem_free(NULL((void*)0), tmp);
10074 break;
10075 }
10076 case FT_RELATIVE_TIME:
10077 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10078 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10079 wmem_free(NULL((void*)0), tmp);
10080 break;
10081
10082 case FT_IPXNET:
10083 integer = fvalue_get_uinteger(fi->value);
10084 tmp = get_ipxnet_name(NULL((void*)0), integer);
10085 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10086 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10087 wmem_free(NULL((void*)0), tmp);
10088 wmem_free(NULL((void*)0), addr_str);
10089 break;
10090
10091 case FT_VINES:
10092 addr.type = AT_VINES;
10093 addr.len = VINES_ADDR_LEN6;
10094 addr.data = fvalue_get_bytes_data(fi->value);
10095
10096 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10097 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10098 wmem_free(NULL((void*)0), addr_str);
10099 break;
10100
10101 case FT_ETHER:
10102 bytes = fvalue_get_bytes_data(fi->value);
10103
10104 addr.type = AT_ETHER;
10105 addr.len = 6;
10106 addr.data = bytes;
10107
10108 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10109 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10110 wmem_free(NULL((void*)0), addr_str);
10111 break;
10112
10113 case FT_IPv4:
10114 ipv4 = fvalue_get_ipv4(fi->value);
10115 set_address_ipv4(&addr, ipv4);
10116
10117 if (hfinfo->display == BASE_NETMASK) {
10118 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10119 } else {
10120 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10121 }
10122 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10123 wmem_free(NULL((void*)0), addr_str);
10124 free_address(&addr);
10125 break;
10126
10127 case FT_IPv6:
10128 ipv6 = fvalue_get_ipv6(fi->value);
10129 set_address_ipv6(&addr, ipv6);
10130
10131 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10132 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10133 wmem_free(NULL((void*)0), addr_str);
10134 free_address(&addr);
10135 break;
10136
10137 case FT_FCWWN:
10138 bytes = fvalue_get_bytes_data(fi->value);
10139 addr.type = AT_FCWWN;
10140 addr.len = FCWWN_ADDR_LEN8;
10141 addr.data = bytes;
10142
10143 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10144 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10145 wmem_free(NULL((void*)0), addr_str);
10146 break;
10147
10148 case FT_GUID:
10149 guid = fvalue_get_guid(fi->value);
10150 tmp = guid_to_str(NULL((void*)0), guid);
10151 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10152 wmem_free(NULL((void*)0), tmp);
10153 break;
10154
10155 case FT_OID:
10156 bytes = fvalue_get_bytes_data(fi->value);
10157 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10158 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10159 if (name) {
10160 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10161 wmem_free(NULL((void*)0), name);
10162 } else {
10163 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10164 }
10165 wmem_free(NULL((void*)0), tmp);
10166 break;
10167
10168 case FT_REL_OID:
10169 bytes = fvalue_get_bytes_data(fi->value);
10170 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10171 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10172 if (name) {
10173 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10174 wmem_free(NULL((void*)0), name);
10175 } else {
10176 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10177 }
10178 wmem_free(NULL((void*)0), tmp);
10179 break;
10180
10181 case FT_SYSTEM_ID:
10182 bytes = fvalue_get_bytes_data(fi->value);
10183 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10184 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10185 wmem_free(NULL((void*)0), tmp);
10186 break;
10187
10188 case FT_EUI64:
10189 bytes = fvalue_get_bytes_data(fi->value);
10190 addr.type = AT_EUI64;
10191 addr.len = EUI64_ADDR_LEN8;
10192 addr.data = bytes;
10193
10194 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10195 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10196 wmem_free(NULL((void*)0), addr_str);
10197 break;
10198 case FT_STRING:
10199 case FT_STRINGZ:
10200 case FT_UINT_STRING:
10201 case FT_STRINGZPAD:
10202 case FT_STRINGZTRUNC:
10203 case FT_AX25:
10204 str = fvalue_get_string(fi->value);
10205 label_fill(label_str, 0, hfinfo, str, value_pos);
10206 break;
10207
10208 case FT_IEEE_11073_SFLOAT:
10209 case FT_IEEE_11073_FLOAT:
10210 tmp = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, hfinfo->display);
10211 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10212 wmem_free(NULL((void*)0), tmp);
10213 break;
10214
10215 default:
10216 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
))
10217 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
))
10218 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
))
10219 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
))
;
10220 break;
10221 }
10222}
10223
10224static void
10225fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10226{
10227 char *p;
10228 int bitfield_byte_length = 0, bitwidth;
10229 uint64_t unshifted_value;
10230 uint64_t value;
10231
10232 const header_field_info *hfinfo = fi->hfinfo;
10233
10234 value = fvalue_get_uinteger64(fi->value);
10235 if (hfinfo->bitmask) {
10236 /* Figure out the bit width */
10237 bitwidth = hfinfo_container_bitwidth(hfinfo);
10238
10239 /* Un-shift bits */
10240 unshifted_value = value;
10241 unshifted_value <<= hfinfo_bitshift(hfinfo);
10242
10243 /* Create the bitfield first */
10244 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10245 bitfield_byte_length = (int) (p - label_str);
10246 }
10247
10248 /* Fill in the textual info */
10249 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10250}
10251
10252static const char *
10253hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10254{
10255 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10256 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10257
10258 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10259 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10260 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10261 else
10262 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10263 }
10264
10265 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10266 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10267
10268 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10269 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10270
10271 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10272}
10273
10274static const char *
10275hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10276{
10277 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10278 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10279 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10280 else
10281 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10282 }
10283
10284 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10285 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10286
10287 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10288 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10289
10290 /* If this is reached somebody registered a 64-bit field with a 32-bit
10291 * value-string, which isn't right. */
10292 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)
10293 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10294
10295 /* This is necessary to squelch MSVC errors; is there
10296 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10297 never returns? */
10298 return NULL((void*)0);
10299}
10300
10301static const char *
10302hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10303{
10304 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10305 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10306
10307 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)
;
10308
10309 /* This is necessary to squelch MSVC errors; is there
10310 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10311 never returns? */
10312 return NULL((void*)0);
10313}
10314
10315static const char *
10316hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10317{
10318 const char *str = hf_try_val_to_str(value, hfinfo);
10319
10320 return (str) ? str : unknown_str;
10321}
10322
10323static const char *
10324hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10325{
10326 const char *str = hf_try_val64_to_str(value, hfinfo);
10327
10328 return (str) ? str : unknown_str;
10329}
10330
10331/* Fills data for bitfield chars with val_strings */
10332static void
10333fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10334{
10335 char *p;
10336 int bitfield_byte_length, bitwidth;
10337 uint32_t unshifted_value;
10338 uint32_t value;
10339
10340 char buf[32];
10341 const char *out;
10342
10343 const header_field_info *hfinfo = fi->hfinfo;
10344
10345 /* Figure out the bit width */
10346 bitwidth = hfinfo_container_bitwidth(hfinfo);
10347
10348 /* Un-shift bits */
10349 value = fvalue_get_uinteger(fi->value);
10350
10351 unshifted_value = value;
10352 if (hfinfo->bitmask) {
10353 unshifted_value <<= hfinfo_bitshift(hfinfo);
10354 }
10355
10356 /* Create the bitfield first */
10357 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10358 bitfield_byte_length = (int) (p - label_str);
10359
10360 /* Fill in the textual info using stored (shifted) value */
10361 if (hfinfo->display == BASE_CUSTOM) {
10362 char tmp[ITEM_LABEL_LENGTH240];
10363 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10364
10365 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10365, "fmtfunc"))))
;
10366 fmtfunc(tmp, value);
10367 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10368 }
10369 else if (hfinfo->strings) {
10370 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10371
10372 out = hfinfo_char_vals_format(hfinfo, buf, value);
10373 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10374 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10375 else
10376 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10377 }
10378 else {
10379 out = hfinfo_char_value_format(hfinfo, buf, value);
10380
10381 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10382 }
10383}
10384
10385/* Fills data for bitfield ints with val_strings */
10386static void
10387fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10388{
10389 char *p;
10390 int bitfield_byte_length, bitwidth;
10391 uint32_t value, unshifted_value;
10392 char buf[NUMBER_LABEL_LENGTH80];
10393 const char *out;
10394
10395 const header_field_info *hfinfo = fi->hfinfo;
10396
10397 /* Figure out the bit width */
10398 if (fi->flags & FI_VARINT0x00004000)
10399 bitwidth = fi->length*8;
10400 else
10401 bitwidth = hfinfo_container_bitwidth(hfinfo);
10402
10403 /* Un-shift bits */
10404 if (is_signed)
10405 value = fvalue_get_sinteger(fi->value);
10406 else
10407 value = fvalue_get_uinteger(fi->value);
10408
10409 unshifted_value = value;
10410 if (hfinfo->bitmask) {
10411 unshifted_value <<= hfinfo_bitshift(hfinfo);
10412 }
10413
10414 /* Create the bitfield first */
10415 if (fi->flags & FI_VARINT0x00004000)
10416 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10417 else
10418 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10419 bitfield_byte_length = (int) (p - label_str);
10420
10421 /* Fill in the textual info using stored (shifted) value */
10422 if (hfinfo->display == BASE_CUSTOM) {
10423 char tmp[ITEM_LABEL_LENGTH240];
10424 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10425
10426 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10426, "fmtfunc"))))
;
10427 fmtfunc(tmp, value);
10428 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10429 }
10430 else if (hfinfo->strings) {
10431 const char *val_str = hf_try_val_to_str(value, hfinfo);
10432
10433 out = hfinfo_number_vals_format(hfinfo, buf, value);
10434 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10435 /*
10436 * Unique values only display value_string string
10437 * if there is a match. Otherwise it's just a number
10438 */
10439 if (val_str) {
10440 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10441 } else {
10442 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10443 }
10444 } else {
10445 if (val_str == NULL((void*)0))
10446 val_str = "Unknown";
10447
10448 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10449 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10450 else
10451 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10452 }
10453 }
10454 else {
10455 out = hfinfo_number_value_format(hfinfo, buf, value);
10456
10457 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10458 }
10459}
10460
10461static void
10462fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10463{
10464 char *p;
10465 int bitfield_byte_length, bitwidth;
10466 uint64_t value, unshifted_value;
10467 char buf[NUMBER_LABEL_LENGTH80];
10468 const char *out;
10469
10470 const header_field_info *hfinfo = fi->hfinfo;
10471
10472 /* Figure out the bit width */
10473 if (fi->flags & FI_VARINT0x00004000)
10474 bitwidth = fi->length*8;
10475 else
10476 bitwidth = hfinfo_container_bitwidth(hfinfo);
10477
10478 /* Un-shift bits */
10479 if (is_signed)
10480 value = fvalue_get_sinteger64(fi->value);
10481 else
10482 value = fvalue_get_uinteger64(fi->value);
10483
10484 unshifted_value = value;
10485 if (hfinfo->bitmask) {
10486 unshifted_value <<= hfinfo_bitshift(hfinfo);
10487 }
10488
10489 /* Create the bitfield first */
10490 if (fi->flags & FI_VARINT0x00004000)
10491 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10492 else
10493 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10494 bitfield_byte_length = (int) (p - label_str);
10495
10496 /* Fill in the textual info using stored (shifted) value */
10497 if (hfinfo->display == BASE_CUSTOM) {
10498 char tmp[ITEM_LABEL_LENGTH240];
10499 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10500
10501 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10501, "fmtfunc64"
))))
;
10502 fmtfunc64(tmp, value);
10503 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10504 }
10505 else if (hfinfo->strings) {
10506 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10507
10508 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10509 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10510 /*
10511 * Unique values only display value_string string
10512 * if there is a match. Otherwise it's just a number
10513 */
10514 if (val_str) {
10515 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10516 } else {
10517 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10518 }
10519 } else {
10520 if (val_str == NULL((void*)0))
10521 val_str = "Unknown";
10522
10523 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10524 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10525 else
10526 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10527 }
10528 }
10529 else {
10530 out = hfinfo_number_value_format64(hfinfo, buf, value);
10531
10532 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10533 }
10534}
10535
10536static void
10537fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10538{
10539 const header_field_info *hfinfo = fi->hfinfo;
10540 uint32_t value;
10541
10542 char buf[32];
10543 const char *out;
10544
10545 value = fvalue_get_uinteger(fi->value);
10546
10547 /* Fill in the textual info */
10548 if (hfinfo->display == BASE_CUSTOM) {
10549 char tmp[ITEM_LABEL_LENGTH240];
10550 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10551
10552 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10552, "fmtfunc"))))
;
10553 fmtfunc(tmp, value);
10554 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10555 }
10556 else if (hfinfo->strings) {
10557 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10558
10559 out = hfinfo_char_vals_format(hfinfo, buf, value);
10560 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10561 }
10562 else {
10563 out = hfinfo_char_value_format(hfinfo, buf, value);
10564
10565 label_fill(label_str, 0, hfinfo, out, value_pos);
10566 }
10567}
10568
10569static void
10570fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10571{
10572 const header_field_info *hfinfo = fi->hfinfo;
10573 uint32_t value;
10574
10575 char buf[NUMBER_LABEL_LENGTH80];
10576 const char *out;
10577
10578 if (is_signed)
10579 value = fvalue_get_sinteger(fi->value);
10580 else
10581 value = fvalue_get_uinteger(fi->value);
10582
10583 /* Fill in the textual info */
10584 if (hfinfo->display == BASE_CUSTOM) {
10585 char tmp[ITEM_LABEL_LENGTH240];
10586 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10587
10588 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10588, "fmtfunc"))))
;
10589 fmtfunc(tmp, value);
10590 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10591 }
10592 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10593 /*
10594 * It makes no sense to have a value-string table for a
10595 * frame-number field - they're just integers giving
10596 * the ordinal frame number.
10597 */
10598 const char *val_str = hf_try_val_to_str(value, hfinfo);
10599
10600 out = hfinfo_number_vals_format(hfinfo, buf, value);
10601 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10602 /*
10603 * Unique values only display value_string string
10604 * if there is a match. Otherwise it's just a number
10605 */
10606 if (val_str) {
10607 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10608 } else {
10609 label_fill(label_str, 0, hfinfo, out, value_pos);
10610 }
10611 } else {
10612 if (val_str == NULL((void*)0))
10613 val_str = "Unknown";
10614
10615 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10616 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10617 else
10618 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10619 }
10620 }
10621 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
))
) {
10622 char tmp[ITEM_LABEL_LENGTH240];
10623
10624 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10625 display_to_port_type((field_display_e)hfinfo->display), value);
10626 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10627 }
10628 else {
10629 out = hfinfo_number_value_format(hfinfo, buf, value);
10630
10631 label_fill(label_str, 0, hfinfo, out, value_pos);
10632 }
10633}
10634
10635static void
10636fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10637{
10638 const header_field_info *hfinfo = fi->hfinfo;
10639 uint64_t value;
10640
10641 char buf[NUMBER_LABEL_LENGTH80];
10642 const char *out;
10643
10644 if (is_signed)
10645 value = fvalue_get_sinteger64(fi->value);
10646 else
10647 value = fvalue_get_uinteger64(fi->value);
10648
10649 /* Fill in the textual info */
10650 if (hfinfo->display == BASE_CUSTOM) {
10651 char tmp[ITEM_LABEL_LENGTH240];
10652 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10653
10654 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10654, "fmtfunc64"
))))
;
10655 fmtfunc64(tmp, value);
10656 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10657 }
10658 else if (hfinfo->strings) {
10659 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10660
10661 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10662 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10663 /*
10664 * Unique values only display value_string string
10665 * if there is a match. Otherwise it's just a number
10666 */
10667 if (val_str) {
10668 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10669 } else {
10670 label_fill(label_str, 0, hfinfo, out, value_pos);
10671 }
10672 } else {
10673 if (val_str == NULL((void*)0))
10674 val_str = "Unknown";
10675
10676 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10677 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10678 else
10679 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10680 }
10681 }
10682 else {
10683 out = hfinfo_number_value_format64(hfinfo, buf, value);
10684
10685 label_fill(label_str, 0, hfinfo, out, value_pos);
10686 }
10687}
10688
10689static size_t
10690fill_display_label_float(const field_info *fi, char *label_str)
10691{
10692 int display;
10693 int n;
10694 double value;
10695
10696 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10697 value = fvalue_get_floating(fi->value);
10698
10699 if (display == BASE_CUSTOM) {
10700 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10701 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10701, "fmtfunc"))))
;
10702 fmtfunc(label_str, value);
10703 return strlen(label_str);
10704 }
10705
10706 switch (display) {
10707 case BASE_NONE:
10708 if (fi->hfinfo->type == FT_FLOAT) {
10709 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%.*g", FLT_DIG6, value);
10710 } else {
10711 n = (int)strlen(dtoa_g_fmt(label_str, value));
10712 }
10713 break;
10714 case BASE_DEC:
10715 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%f", value);
10716 break;
10717 case BASE_HEX:
10718 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%a", value);
10719 break;
10720 case BASE_EXP:
10721 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%e", value);
10722 break;
10723 default:
10724 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10724
, __func__, "assertion \"not reached\" failed")
;
10725 }
10726 if (n < 0) {
10727 return 0; /* error */
10728 }
10729 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10730 const char *hf_str_val;
10731 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10732 n += protoo_strlcpy(label_str + n, hf_str_val, ITEM_LABEL_LENGTH240 - n);
10733 }
10734 if (n > ITEM_LABEL_LENGTH240) {
10735 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10735, __func__, "label length too small"); } } while (0)
;
10736 return strlen(label_str);
10737 }
10738
10739 return n;
10740}
10741
10742void
10743fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10744{
10745 char tmp[ITEM_LABEL_LENGTH240];
10746
10747 fill_display_label_float(fi, tmp);
10748 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10749}
10750
10751int
10752hfinfo_bitshift(const header_field_info *hfinfo)
10753{
10754 return ws_ctz(hfinfo->bitmask);
10755}
10756
10757
10758static int
10759hfinfo_bitoffset(const header_field_info *hfinfo)
10760{
10761 if (!hfinfo->bitmask) {
10762 return 0;
10763 }
10764
10765 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10766 * as the first bit */
10767 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10768}
10769
10770static int
10771hfinfo_mask_bitwidth(const header_field_info *hfinfo)
10772{
10773 if (!hfinfo->bitmask) {
10774 return 0;
10775 }
10776
10777 /* ilog2 = first set bit, ctz = last set bit */
10778 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
10779}
10780
10781static int
10782hfinfo_type_bitwidth(enum ftenum type)
10783{
10784 int bitwidth = 0;
10785
10786 switch (type) {
10787 case FT_CHAR:
10788 case FT_UINT8:
10789 case FT_INT8:
10790 bitwidth = 8;
10791 break;
10792 case FT_UINT16:
10793 case FT_INT16:
10794 bitwidth = 16;
10795 break;
10796 case FT_UINT24:
10797 case FT_INT24:
10798 bitwidth = 24;
10799 break;
10800 case FT_UINT32:
10801 case FT_INT32:
10802 bitwidth = 32;
10803 break;
10804 case FT_UINT40:
10805 case FT_INT40:
10806 bitwidth = 40;
10807 break;
10808 case FT_UINT48:
10809 case FT_INT48:
10810 bitwidth = 48;
10811 break;
10812 case FT_UINT56:
10813 case FT_INT56:
10814 bitwidth = 56;
10815 break;
10816 case FT_UINT64:
10817 case FT_INT64:
10818 bitwidth = 64;
10819 break;
10820 default:
10821 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 10821))
;
10822 ;
10823 }
10824 return bitwidth;
10825}
10826
10827
10828static int
10829hfinfo_container_bitwidth(const header_field_info *hfinfo)
10830{
10831 if (!hfinfo->bitmask) {
10832 return 0;
10833 }
10834
10835 if (hfinfo->type == FT_BOOLEAN) {
10836 return hfinfo->display; /* hacky? :) */
10837 }
10838
10839 return hfinfo_type_bitwidth(hfinfo->type);
10840}
10841
10842static int
10843hfinfo_hex_digits(const header_field_info *hfinfo)
10844{
10845 int bitwidth;
10846
10847 /* If we have a bitmask, hfinfo->type is the width of the container, so not
10848 * appropriate to determine the number of hex digits for the field.
10849 * So instead, we compute it from the bitmask.
10850 */
10851 if (hfinfo->bitmask != 0) {
10852 bitwidth = hfinfo_mask_bitwidth(hfinfo);
10853 } else {
10854 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
10855 }
10856
10857 /* Divide by 4, rounding up, to get number of hex digits. */
10858 return (bitwidth + 3) / 4;
10859}
10860
10861const char *
10862hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
10863{
10864 char *ptr = &buf[6];
10865 static const char hex_digits[16] =
10866 { '0', '1', '2', '3', '4', '5', '6', '7',
10867 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
10868
10869 *ptr = '\0';
10870 *(--ptr) = '\'';
10871 /* Properly format value */
10872 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
10873 /*
10874 * Printable, so just show the character, and, if it needs
10875 * to be escaped, escape it.
10876 */
10877 *(--ptr) = value;
10878 if (value == '\\' || value == '\'')
10879 *(--ptr) = '\\';
10880 } else {
10881 /*
10882 * Non-printable; show it as an escape sequence.
10883 */
10884 switch (value) {
10885
10886 case '\0':
10887 /*
10888 * Show a NUL with only one digit.
10889 */
10890 *(--ptr) = '0';
10891 break;
10892
10893 case '\a':
10894 *(--ptr) = 'a';
10895 break;
10896
10897 case '\b':
10898 *(--ptr) = 'b';
10899 break;
10900
10901 case '\f':
10902 *(--ptr) = 'f';
10903 break;
10904
10905 case '\n':
10906 *(--ptr) = 'n';
10907 break;
10908
10909 case '\r':
10910 *(--ptr) = 'r';
10911 break;
10912
10913 case '\t':
10914 *(--ptr) = 't';
10915 break;
10916
10917 case '\v':
10918 *(--ptr) = 'v';
10919 break;
10920
10921 default:
10922 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
10923
10924 case BASE_OCT:
10925 *(--ptr) = (value & 0x7) + '0';
10926 value >>= 3;
10927 *(--ptr) = (value & 0x7) + '0';
10928 value >>= 3;
10929 *(--ptr) = (value & 0x7) + '0';
10930 break;
10931
10932 case BASE_HEX:
10933 *(--ptr) = hex_digits[value & 0x0F];
10934 value >>= 4;
10935 *(--ptr) = hex_digits[value & 0x0F];
10936 *(--ptr) = 'x';
10937 break;
10938
10939 default:
10940 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
10941 }
10942 }
10943 *(--ptr) = '\\';
10944 }
10945 *(--ptr) = '\'';
10946 return ptr;
10947}
10948
10949static const char *
10950hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
10951{
10952 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
10953 bool_Bool isint = FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
;
10954
10955 *ptr = '\0';
10956 /* Properly format value */
10957 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
10958 case BASE_DEC:
10959 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
10960
10961 case BASE_DEC_HEX:
10962 *(--ptr) = ')';
10963 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10964 *(--ptr) = '(';
10965 *(--ptr) = ' ';
10966 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
10967 return ptr;
10968
10969 case BASE_OCT:
10970 return oct_to_str_back(ptr, value);
10971
10972 case BASE_HEX:
10973 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10974
10975 case BASE_HEX_DEC:
10976 *(--ptr) = ')';
10977 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
10978 *(--ptr) = '(';
10979 *(--ptr) = ' ';
10980 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10981 return ptr;
10982
10983 case BASE_PT_UDP:
10984 case BASE_PT_TCP:
10985 case BASE_PT_DCCP:
10986 case BASE_PT_SCTP:
10987 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
10988 display_to_port_type((field_display_e)display), value);
10989 return buf;
10990 case BASE_OUI:
10991 {
10992 uint8_t p_oui[3];
10993 const char *manuf_name;
10994
10995 p_oui[0] = value >> 16 & 0xFF;
10996 p_oui[1] = value >> 8 & 0xFF;
10997 p_oui[2] = value & 0xFF;
10998
10999 /* Attempt an OUI lookup. */
11000 manuf_name = uint_get_manuf_name_if_known(value);
11001 if (manuf_name == NULL((void*)0)) {
11002 /* Could not find an OUI. */
11003 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11004 }
11005 else {
11006 /* Found an address string. */
11007 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11008 }
11009 return buf;
11010 }
11011
11012 default:
11013 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11014 }
11015 return ptr;
11016}
11017
11018static const char *
11019hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11020{
11021 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11022 bool_Bool isint = FT_IS_INT(hfinfo->type)(((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
) || ((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
))
;
11023
11024 *ptr = '\0';
11025 /* Properly format value */
11026 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11027 case BASE_DEC:
11028 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11029
11030 case BASE_DEC_HEX:
11031 *(--ptr) = ')';
11032 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11033 *(--ptr) = '(';
11034 *(--ptr) = ' ';
11035 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11036 return ptr;
11037
11038 case BASE_OCT:
11039 return oct64_to_str_back(ptr, value);
11040
11041 case BASE_HEX:
11042 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11043
11044 case BASE_HEX_DEC:
11045 *(--ptr) = ')';
11046 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11047 *(--ptr) = '(';
11048 *(--ptr) = ' ';
11049 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11050 return ptr;
11051
11052 default:
11053 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11054 }
11055
11056 return ptr;
11057}
11058
11059static const char *
11060hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11061{
11062 int display = hfinfo->display;
11063
11064 if (hfinfo->type == FT_FRAMENUM) {
11065 /*
11066 * Frame numbers are always displayed in decimal.
11067 */
11068 display = BASE_DEC;
11069 }
11070
11071 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11072}
11073
11074static const char *
11075hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11076{
11077 int display = hfinfo->display;
11078
11079 if (hfinfo->type == FT_FRAMENUM) {
11080 /*
11081 * Frame numbers are always displayed in decimal.
11082 */
11083 display = BASE_DEC;
11084 }
11085
11086 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11087}
11088
11089static const char *
11090hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11091{
11092 /* Get the underlying BASE_ value */
11093 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11094
11095 return hfinfo_char_value_format_display(display, buf, value);
11096}
11097
11098static const char *
11099hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11100{
11101 /* Get the underlying BASE_ value */
11102 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11103
11104 if (hfinfo->type == FT_FRAMENUM) {
11105 /*
11106 * Frame numbers are always displayed in decimal.
11107 */
11108 display = BASE_DEC;
11109 }
11110
11111 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11112 display = BASE_DEC;
11113 } else if (display == BASE_OUI) {
11114 display = BASE_HEX;
11115 }
11116
11117 switch (display) {
11118 case BASE_NONE:
11119 /* case BASE_DEC: */
11120 case BASE_DEC_HEX:
11121 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11122 case BASE_CUSTOM:
11123 display = BASE_DEC;
11124 break;
11125
11126 /* case BASE_HEX: */
11127 case BASE_HEX_DEC:
11128 display = BASE_HEX;
11129 break;
11130 }
11131
11132 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11133}
11134
11135static const char *
11136hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11137{
11138 /* Get the underlying BASE_ value */
11139 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11140
11141 if (hfinfo->type == FT_FRAMENUM) {
11142 /*
11143 * Frame numbers are always displayed in decimal.
11144 */
11145 display = BASE_DEC;
11146 }
11147
11148 switch (display) {
11149 case BASE_NONE:
11150 /* case BASE_DEC: */
11151 case BASE_DEC_HEX:
11152 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11153 case BASE_CUSTOM:
11154 display = BASE_DEC;
11155 break;
11156
11157 /* case BASE_HEX: */
11158 case BASE_HEX_DEC:
11159 display = BASE_HEX;
11160 break;
11161 }
11162
11163 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11164}
11165
11166static const char *
11167hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11168{
11169 /* Get the underlying BASE_ value */
11170 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11171
11172 return hfinfo_char_value_format_display(display, buf, value);
11173}
11174
11175static const char *
11176hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11177{
11178 /* Get the underlying BASE_ value */
11179 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11180
11181 if (display == BASE_NONE)
11182 return NULL((void*)0);
11183
11184 if (display == BASE_DEC_HEX)
11185 display = BASE_DEC;
11186 if (display == BASE_HEX_DEC)
11187 display = BASE_HEX;
11188
11189 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11190}
11191
11192static const char *
11193hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11194{
11195 /* Get the underlying BASE_ value */
11196 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11197
11198 if (display == BASE_NONE)
11199 return NULL((void*)0);
11200
11201 if (display == BASE_DEC_HEX)
11202 display = BASE_DEC;
11203 if (display == BASE_HEX_DEC)
11204 display = BASE_HEX;
11205
11206 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11207}
11208
11209const char *
11210proto_registrar_get_name(const int n)
11211{
11212 header_field_info *hfinfo;
11213
11214 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11214
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11214
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11214, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11215 return hfinfo->name;
11216}
11217
11218const char *
11219proto_registrar_get_abbrev(const int n)
11220{
11221 header_field_info *hfinfo;
11222
11223 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11223
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11223
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11223, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11224 return hfinfo->abbrev;
11225}
11226
11227enum ftenum
11228proto_registrar_get_ftype(const int n)
11229{
11230 header_field_info *hfinfo;
11231
11232 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11232
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11232
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11232, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11233 return hfinfo->type;
11234}
11235
11236int
11237proto_registrar_get_parent(const int n)
11238{
11239 header_field_info *hfinfo;
11240
11241 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11241
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11241
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11241, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11242 return hfinfo->parent;
11243}
11244
11245bool_Bool
11246proto_registrar_is_protocol(const int n)
11247{
11248 header_field_info *hfinfo;
11249
11250 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11250
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11250
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11250, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11251 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11252}
11253
11254/* Returns length of field in packet (not necessarily the length
11255 * in our internal representation, as in the case of IPv4).
11256 * 0 means undeterminable at time of registration
11257 * -1 means the field is not registered. */
11258int
11259proto_registrar_get_length(const int n)
11260{
11261 header_field_info *hfinfo;
11262
11263 PROTO_REGISTRAR_GET_NTH(n, hfinfo)if((n == 0 || (unsigned)n > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11263
, __func__, "Unregistered hf! index=%d", n); ((void) ((n >
0 && (unsigned)n < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11263
, "n > 0 && (unsigned)n < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[n] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11263, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11264 return ftype_wire_size(hfinfo->type);
11265}
11266
11267/* Looks for a protocol or a field in a proto_tree. Returns true if
11268 * it exists anywhere, or false if it exists nowhere. */
11269bool_Bool
11270proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11271{
11272 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11273
11274 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11275 return true1;
11276 }
11277 else {
11278 return false0;
11279 }
11280}
11281
11282/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11283 * This only works if the hfindex was "primed" before the dissection
11284 * took place, as we just pass back the already-created GPtrArray*.
11285 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11286 * handles that. */
11287GPtrArray *
11288proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11289{
11290 if (!tree)
11291 return NULL((void*)0);
11292
11293 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11294 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11295 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11296 else
11297 return NULL((void*)0);
11298}
11299
11300bool_Bool
11301proto_tracking_interesting_fields(const proto_tree *tree)
11302{
11303 GHashTable *interesting_hfids;
11304
11305 if (!tree)
11306 return false0;
11307
11308 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11309
11310 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11311}
11312
11313/* Helper struct for proto_find_info() and proto_all_finfos() */
11314typedef struct {
11315 GPtrArray *array;
11316 int id;
11317} ffdata_t;
11318
11319/* Helper function for proto_find_info() */
11320static bool_Bool
11321find_finfo(proto_node *node, void * data)
11322{
11323 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11324 if (fi && fi->hfinfo) {
11325 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11326 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11327 }
11328 }
11329
11330 /* Don't stop traversing. */
11331 return false0;
11332}
11333
11334/* Helper function for proto_find_first_info() */
11335static bool_Bool
11336find_first_finfo(proto_node *node, void *data)
11337{
11338 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11339 if (fi && fi->hfinfo) {
11340 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11341 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11342
11343 /* Stop traversing. */
11344 return true1;
11345 }
11346 }
11347
11348 /* Continue traversing. */
11349 return false0;
11350}
11351
11352/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11353* This works on any proto_tree, primed or unprimed, but actually searches
11354* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11355* The caller does need to free the returned GPtrArray with
11356* g_ptr_array_free(<array>, true).
11357*/
11358GPtrArray *
11359proto_find_finfo(proto_tree *tree, const int id)
11360{
11361 ffdata_t ffdata;
11362
11363 ffdata.array = g_ptr_array_new();
11364 ffdata.id = id;
11365
11366 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11367
11368 return ffdata.array;
11369}
11370
11371/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11372* This works on any proto_tree, primed or unprimed, but actually searches
11373* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11374* The caller does need to free the returned GPtrArray with
11375* g_ptr_array_free(<array>, true).
11376*/
11377GPtrArray *
11378proto_find_first_finfo(proto_tree *tree, const int id)
11379{
11380 ffdata_t ffdata;
11381
11382 ffdata.array = g_ptr_array_new();
11383 ffdata.id = id;
11384
11385 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11386
11387 return ffdata.array;
11388}
11389
11390/* Helper function for proto_all_finfos() */
11391static bool_Bool
11392every_finfo(proto_node *node, void * data)
11393{
11394 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11395 if (fi && fi->hfinfo) {
11396 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11397 }
11398
11399 /* Don't stop traversing. */
11400 return false0;
11401}
11402
11403/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11404 * The caller does need to free the returned GPtrArray with
11405 * g_ptr_array_free(<array>, true).
11406 */
11407GPtrArray *
11408proto_all_finfos(proto_tree *tree)
11409{
11410 ffdata_t ffdata;
11411
11412 /* Pre allocate enough space to hold all fields in most cases */
11413 ffdata.array = g_ptr_array_sized_new(512);
11414 ffdata.id = 0;
11415
11416 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11417
11418 return ffdata.array;
11419}
11420
11421
11422typedef struct {
11423 unsigned offset;
11424 field_info *finfo;
11425 tvbuff_t *tvb;
11426} offset_search_t;
11427
11428static bool_Bool
11429check_for_offset(proto_node *node, void * data)
11430{
11431 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11432 offset_search_t *offsearch = (offset_search_t *)data;
11433
11434 /* !fi == the top most container node which holds nothing */
11435 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11436 if (offsearch->offset >= (unsigned) fi->start &&
11437 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11438
11439 offsearch->finfo = fi;
11440 return false0; /* keep traversing */
11441 }
11442 }
11443 return false0; /* keep traversing */
11444}
11445
11446/* Search a proto_tree backwards (from leaves to root) looking for the field
11447 * whose start/length occupies 'offset' */
11448/* XXX - I couldn't find an easy way to search backwards, so I search
11449 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11450 * the one I want to return to the user. This algorithm is inefficient
11451 * and could be re-done, but I'd have to handle all the children and
11452 * siblings of each node myself. When I have more time I'll do that.
11453 * (yeah right) */
11454field_info *
11455proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11456{
11457 offset_search_t offsearch;
11458
11459 offsearch.offset = offset;
11460 offsearch.finfo = NULL((void*)0);
11461 offsearch.tvb = tvb;
11462
11463 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11464
11465 return offsearch.finfo;
11466}
11467
11468typedef struct {
11469 int length;
11470 char *buf;
11471} decoded_data_t;
11472
11473static bool_Bool
11474check_for_undecoded(proto_node *node, void * data)
11475{
11476 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11477 decoded_data_t* decoded = (decoded_data_t*)data;
11478 int i;
11479 unsigned byte;
11480 unsigned bit;
11481
11482 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11483 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11484 byte = i / 8;
11485 bit = i % 8;
11486 decoded->buf[byte] |= (1 << bit);
11487 }
11488 }
11489
11490 return false0;
11491}
11492
11493char*
11494proto_find_undecoded_data(proto_tree *tree, unsigned length)
11495{
11496 decoded_data_t decoded;
11497 decoded.length = length;
11498 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11499
11500 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11501 return decoded.buf;
11502}
11503
11504/* Dumps the protocols in the registration database to stdout. An independent
11505 * program can take this output and format it into nice tables or HTML or
11506 * whatever.
11507 *
11508 * There is one record per line. The fields are tab-delimited.
11509 *
11510 * Field 1 = protocol name
11511 * Field 2 = protocol short name
11512 * Field 3 = protocol filter name
11513 * Field 4 = protocol enabled
11514 * Field 5 = protocol enabled by default
11515 * Field 6 = protocol can toggle
11516 */
11517void
11518proto_registrar_dump_protocols(void)
11519{
11520 protocol_t *protocol;
11521 int i;
11522 void *cookie = NULL((void*)0);
11523
11524
11525 i = proto_get_first_protocol(&cookie);
11526 while (i != -1) {
11527 protocol = find_protocol_by_id(i);
11528 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11529 protocol->name,
11530 protocol->short_name,
11531 protocol->filter_name,
11532 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11533 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11534 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11535 i = proto_get_next_protocol(&cookie);
11536 }
11537}
11538
11539/* Dumps the value_strings, extended value string headers, range_strings
11540 * or true/false strings for fields that have them.
11541 * There is one record per line. Fields are tab-delimited.
11542 * There are four types of records: Value String, Extended Value String Header,
11543 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11544 * the type of record.
11545 *
11546 * Note that a record will be generated only if the value_string,... is referenced
11547 * in a registered hfinfo entry.
11548 *
11549 *
11550 * Value Strings
11551 * -------------
11552 * Field 1 = 'V'
11553 * Field 2 = Field abbreviation to which this value string corresponds
11554 * Field 3 = Integer value
11555 * Field 4 = String
11556 *
11557 * Extended Value String Headers
11558 * -----------------------------
11559 * Field 1 = 'E'
11560 * Field 2 = Field abbreviation to which this extended value string header corresponds
11561 * Field 3 = Extended Value String "Name"
11562 * Field 4 = Number of entries in the associated value_string array
11563 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11564 *
11565 * Range Strings
11566 * -------------
11567 * Field 1 = 'R'
11568 * Field 2 = Field abbreviation to which this range string corresponds
11569 * Field 3 = Integer value: lower bound
11570 * Field 4 = Integer value: upper bound
11571 * Field 5 = String
11572 *
11573 * True/False Strings
11574 * ------------------
11575 * Field 1 = 'T'
11576 * Field 2 = Field abbreviation to which this true/false string corresponds
11577 * Field 3 = True String
11578 * Field 4 = False String
11579 */
11580void
11581proto_registrar_dump_values(void)
11582{
11583 header_field_info *hfinfo;
11584 int i, len, vi;
11585 const value_string *vals;
11586 const val64_string *vals64;
11587 const range_string *range;
11588 const true_false_string *tfs;
11589 const unit_name_string *units;
11590
11591 len = gpa_hfinfo.len;
11592 for (i = 0; i < len ; i++) {
11593 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11594 continue; /* This is a deregistered protocol or field */
11595
11596 PROTO_REGISTRAR_GET_NTH(i, hfinfo)if((i == 0 || (unsigned)i > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11596
, __func__, "Unregistered hf! index=%d", i); ((void) ((i >
0 && (unsigned)i < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11596
, "i > 0 && (unsigned)i < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[i] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11596, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11597
11598 if (hfinfo->id == hf_text_only) {
11599 continue;
11600 }
11601
11602 /* ignore protocols */
11603 if (proto_registrar_is_protocol(i)) {
11604 continue;
11605 }
11606 /* process header fields */
11607#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11608 /*
11609 * If this field isn't at the head of the list of
11610 * fields with this name, skip this field - all
11611 * fields with the same name are really just versions
11612 * of the same field stored in different bits, and
11613 * should have the same type/radix/value list, and
11614 * just differ in their bit masks. (If a field isn't
11615 * a bitfield, but can be, say, 1 or 2 bytes long,
11616 * it can just be made FT_UINT16, meaning the
11617 * *maximum* length is 2 bytes, and be used
11618 * for all lengths.)
11619 */
11620 if (hfinfo->same_name_prev_id != -1)
11621 continue;
11622#endif
11623 vals = NULL((void*)0);
11624 vals64 = NULL((void*)0);
11625 range = NULL((void*)0);
11626 tfs = NULL((void*)0);
11627 units = NULL((void*)0);
11628
11629 if (hfinfo->strings != NULL((void*)0)) {
11630 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11631 (hfinfo->type == FT_CHAR ||
11632 hfinfo->type == FT_UINT8 ||
11633 hfinfo->type == FT_UINT16 ||
11634 hfinfo->type == FT_UINT24 ||
11635 hfinfo->type == FT_UINT32 ||
11636 hfinfo->type == FT_UINT40 ||
11637 hfinfo->type == FT_UINT48 ||
11638 hfinfo->type == FT_UINT56 ||
11639 hfinfo->type == FT_UINT64 ||
11640 hfinfo->type == FT_INT8 ||
11641 hfinfo->type == FT_INT16 ||
11642 hfinfo->type == FT_INT24 ||
11643 hfinfo->type == FT_INT32 ||
11644 hfinfo->type == FT_INT40 ||
11645 hfinfo->type == FT_INT48 ||
11646 hfinfo->type == FT_INT56 ||
11647 hfinfo->type == FT_INT64 ||
11648 hfinfo->type == FT_FLOAT ||
11649 hfinfo->type == FT_DOUBLE)) {
11650
11651 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11652 range = (const range_string *)hfinfo->strings;
11653 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11654 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11655 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11656 } else {
11657 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11658 }
11659 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11660 vals64 = (const val64_string *)hfinfo->strings;
11661 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11662 units = (const unit_name_string *)hfinfo->strings;
11663 } else {
11664 vals = (const value_string *)hfinfo->strings;
11665 }
11666 }
11667 else if (hfinfo->type == FT_BOOLEAN) {
11668 tfs = (const struct true_false_string *)hfinfo->strings;
11669 }
11670 }
11671
11672 /* Print value strings? */
11673 if (vals) {
11674 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11675 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11676 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11677 if (!val64_string_ext_validate(vse_p)) {
11678 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11678, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11679 continue;
11680 }
11681 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11682 printf("E\t%s\t%u\t%s\t%s\n",
11683 hfinfo->abbrev,
11684 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11685 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11686 val64_string_ext_match_type_str(vse_p));
11687 } else {
11688 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11689 if (!value_string_ext_validate(vse_p)) {
11690 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11690, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11691 continue;
11692 }
11693 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11694 printf("E\t%s\t%u\t%s\t%s\n",
11695 hfinfo->abbrev,
11696 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11697 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11698 value_string_ext_match_type_str(vse_p));
11699 }
11700 }
11701 vi = 0;
11702 while (vals[vi].strptr) {
11703 /* Print in the proper base */
11704 if (hfinfo->type == FT_CHAR) {
11705 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11706 printf("V\t%s\t'%c'\t%s\n",
11707 hfinfo->abbrev,
11708 vals[vi].value,
11709 vals[vi].strptr);
11710 } else {
11711 if (hfinfo->display == BASE_HEX) {
11712 printf("V\t%s\t'\\x%02x'\t%s\n",
11713 hfinfo->abbrev,
11714 vals[vi].value,
11715 vals[vi].strptr);
11716 }
11717 else {
11718 printf("V\t%s\t'\\%03o'\t%s\n",
11719 hfinfo->abbrev,
11720 vals[vi].value,
11721 vals[vi].strptr);
11722 }
11723 }
11724 } else {
11725 if (hfinfo->display == BASE_HEX) {
11726 printf("V\t%s\t0x%x\t%s\n",
11727 hfinfo->abbrev,
11728 vals[vi].value,
11729 vals[vi].strptr);
11730 }
11731 else {
11732 printf("V\t%s\t%u\t%s\n",
11733 hfinfo->abbrev,
11734 vals[vi].value,
11735 vals[vi].strptr);
11736 }
11737 }
11738 vi++;
11739 }
11740 }
11741 else if (vals64) {
11742 vi = 0;
11743 while (vals64[vi].strptr) {
11744 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11745 hfinfo->abbrev,
11746 vals64[vi].value,
11747 vals64[vi].strptr);
11748 vi++;
11749 }
11750 }
11751
11752 /* print range strings? */
11753 else if (range) {
11754 vi = 0;
11755 while (range[vi].strptr) {
11756 /* Print in the proper base */
11757 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11758 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11759 hfinfo->abbrev,
11760 range[vi].value_min,
11761 range[vi].value_max,
11762 range[vi].strptr);
11763 }
11764 else {
11765 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11766 hfinfo->abbrev,
11767 range[vi].value_min,
11768 range[vi].value_max,
11769 range[vi].strptr);
11770 }
11771 vi++;
11772 }
11773 }
11774
11775 /* Print true/false strings? */
11776 else if (tfs) {
11777 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11778 tfs->true_string, tfs->false_string);
11779 }
11780 /* Print unit strings? */
11781 else if (units) {
11782 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11783 units->singular, units->plural ? units->plural : "(no plural)");
11784 }
11785 }
11786}
11787
11788/* Prints the number of registered fields.
11789 * Useful for determining an appropriate value for
11790 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
11791 *
11792 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
11793 * the number of fields, true otherwise.
11794 */
11795bool_Bool
11796proto_registrar_dump_fieldcount(void)
11797{
11798 uint32_t i;
11799 header_field_info *hfinfo;
11800 uint32_t deregistered_count = 0;
11801 uint32_t same_name_count = 0;
11802 uint32_t protocol_count = 0;
11803
11804 for (i = 0; i < gpa_hfinfo.len; i++) {
11805 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
11806 deregistered_count++;
11807 continue; /* This is a deregistered protocol or header field */
11808 }
11809
11810 PROTO_REGISTRAR_GET_NTH(i, hfinfo)if((i == 0 || (unsigned)i > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11810
, __func__, "Unregistered hf! index=%d", i); ((void) ((i >
0 && (unsigned)i < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11810
, "i > 0 && (unsigned)i < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[i] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11810, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11811
11812 if (proto_registrar_is_protocol(i))
11813 protocol_count++;
11814
11815 if (hfinfo->same_name_prev_id != -1)
11816 same_name_count++;
11817 }
11818
11819 printf("There are %u header fields registered, of which:\n"
11820 "\t%u are deregistered\n"
11821 "\t%u are protocols\n"
11822 "\t%u have the same name as another field\n\n",
11823 gpa_hfinfo.len, deregistered_count, protocol_count,
11824 same_name_count);
11825
11826 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
11827 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
11828 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
11829 "\n");
11830
11831 printf("The header field table consumes %u KiB of memory.\n",
11832 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
11833 printf("The fields themselves consume %u KiB of memory.\n",
11834 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
11835
11836 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
11837}
11838
11839static void
11840elastic_add_base_mapping(json_dumper *dumper)
11841{
11842 json_dumper_set_member_name(dumper, "settings");
11843 json_dumper_begin_object(dumper);
11844 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
11845 json_dumper_value_anyf(dumper, "%d", 1000000);
11846 json_dumper_end_object(dumper);
11847}
11848
11849static char*
11850ws_type_to_elastic(unsigned type _U___attribute__((unused)))
11851{
11852 switch(type) {
11853 case FT_UINT16:
11854 case FT_INT16:
11855 case FT_INT32:
11856 case FT_UINT24:
11857 case FT_INT24:
11858 return "integer";
11859 case FT_INT8:
11860 case FT_UINT8:
11861 return "short";
11862 case FT_FRAMENUM:
11863 case FT_UINT32:
11864 case FT_UINT40:
11865 case FT_UINT48:
11866 case FT_UINT56:
11867 case FT_UINT64: // Actually it's not handled by 'long' elastic type.
11868 case FT_INT48:
11869 case FT_INT64:
11870 return "long";
11871 case FT_FLOAT:
11872 case FT_DOUBLE:
11873 return "float";
11874 case FT_IPv6:
11875 case FT_IPv4:
11876 return "ip";
11877 case FT_ABSOLUTE_TIME:
11878 case FT_RELATIVE_TIME:
11879 return "date";
11880 case FT_BYTES:
11881 case FT_UINT_BYTES:
11882 return "byte";
11883 case FT_BOOLEAN:
11884 return "boolean";
11885 default:
11886 return NULL((void*)0);
11887 }
11888}
11889
11890static char*
11891dot_to_underscore(char* str)
11892{
11893 unsigned i;
11894 for (i = 0; i < strlen(str); i++) {
11895 if (str[i] == '.')
11896 str[i] = '_';
11897 }
11898 return str;
11899}
11900
11901/* Dumps a mapping file for ElasticSearch
11902 */
11903void
11904proto_registrar_dump_elastic(const char* filter)
11905{
11906 header_field_info *hfinfo;
11907 header_field_info *parent_hfinfo;
11908 unsigned i;
11909 bool_Bool open_object = true1;
11910 const char* prev_proto = NULL((void*)0);
11911 char* str;
11912 char** protos = NULL((void*)0);
11913 char* proto;
11914 bool_Bool found;
11915 unsigned j;
11916 char* type;
11917 char* prev_item = NULL((void*)0);
11918
11919 /* We have filtering protocols. Extract them. */
11920 if (filter) {
11921 protos = g_strsplit(filter, ",", -1);
11922 }
11923
11924 /*
11925 * To help tracking down the json tree, objects have been appended with a comment:
11926 * n.label -> where n is the indentation level and label the name of the object
11927 */
11928
11929 json_dumper dumper = {
11930 .output_file = stdoutstdout,
11931 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
11932 };
11933 json_dumper_begin_object(&dumper); // 1.root
11934 elastic_add_base_mapping(&dumper);
11935
11936 json_dumper_set_member_name(&dumper, "mappings");
11937 json_dumper_begin_object(&dumper); // 2.mappings
11938 json_dumper_set_member_name(&dumper, "dynamic");
11939 json_dumper_value_anyf(&dumper, "false");
11940
11941 json_dumper_set_member_name(&dumper, "properties");
11942 json_dumper_begin_object(&dumper); // 3.properties
11943 json_dumper_set_member_name(&dumper, "timestamp");
11944 json_dumper_begin_object(&dumper); // 4.timestamp
11945 json_dumper_set_member_name(&dumper, "type");
11946 json_dumper_value_string(&dumper, "date");
11947 json_dumper_end_object(&dumper); // 4.timestamp
11948
11949 json_dumper_set_member_name(&dumper, "layers");
11950 json_dumper_begin_object(&dumper); // 4.layers
11951 json_dumper_set_member_name(&dumper, "properties");
11952 json_dumper_begin_object(&dumper); // 5.properties
11953
11954 for (i = 0; i < gpa_hfinfo.len; i++) {
11955 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11956 continue; /* This is a deregistered protocol or header field */
11957
11958 PROTO_REGISTRAR_GET_NTH(i, hfinfo)if((i == 0 || (unsigned)i > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11958
, __func__, "Unregistered hf! index=%d", i); ((void) ((i >
0 && (unsigned)i < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11958
, "i > 0 && (unsigned)i < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[i] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 11958, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11959
11960 /*
11961 * Skip the pseudo-field for "proto_tree_add_text()" since
11962 * we don't want it in the list of filterable protocols.
11963 */
11964 if (hfinfo->id == hf_text_only)
11965 continue;
11966
11967 if (!proto_registrar_is_protocol(i)) {
11968 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11968
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11968
, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 11968
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
11969
11970 /*
11971 * Skip the field if filter protocols have been set and this one's
11972 * parent is not listed.
11973 */
11974 if (protos) {
11975 found = false0;
11976 j = 0;
11977 proto = protos[0];
11978 while(proto) {
11979 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
11980 found = true1;
11981 break;
11982 }
11983 j++;
11984 proto = protos[j];
11985 }
11986 if (!found)
11987 continue;
11988 }
11989
11990 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
11991 json_dumper_end_object(&dumper); // 7.properties
11992 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
11993 open_object = true1;
11994 }
11995
11996 prev_proto = parent_hfinfo->abbrev;
11997
11998 if (open_object) {
11999 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12000 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12001 json_dumper_set_member_name(&dumper, "properties");
12002 json_dumper_begin_object(&dumper); // 7.properties
12003 open_object = false0;
12004 }
12005 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12006 type = ws_type_to_elastic(hfinfo->type);
12007 /* when type is NULL, we have the default mapping: string */
12008 if (type) {
12009 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12010 dot_to_underscore(str);
12011 if (g_strcmp0(prev_item, str)) {
12012 json_dumper_set_member_name(&dumper, str);
12013 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12014 json_dumper_set_member_name(&dumper, "type");
12015 json_dumper_value_string(&dumper, type);
12016 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12017 }
12018 g_free(prev_item);
12019 prev_item = str;
12020 }
12021 }
12022 }
12023 g_free(prev_item);
12024
12025 if (prev_proto) {
12026 json_dumper_end_object(&dumper); // 7.properties
12027 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12028 }
12029
12030 json_dumper_end_object(&dumper); // 5.properties
12031 json_dumper_end_object(&dumper); // 4.layers
12032 json_dumper_end_object(&dumper); // 3.properties
12033 json_dumper_end_object(&dumper); // 2.mappings
12034 json_dumper_end_object(&dumper); // 1.root
12035 bool_Bool ret = json_dumper_finish(&dumper);
12036 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12036, "ret"))))
;
12037
12038 g_strfreev(protos);
12039}
12040
12041/* Dumps the contents of the registration database to stdout. An independent
12042 * program can take this output and format it into nice tables or HTML or
12043 * whatever.
12044 *
12045 * There is one record per line. Each record is either a protocol or a header
12046 * field, differentiated by the first field. The fields are tab-delimited.
12047 *
12048 * Protocols
12049 * ---------
12050 * Field 1 = 'P'
12051 * Field 2 = descriptive protocol name
12052 * Field 3 = protocol abbreviation
12053 *
12054 * Header Fields
12055 * -------------
12056 * Field 1 = 'F'
12057 * Field 2 = descriptive field name
12058 * Field 3 = field abbreviation
12059 * Field 4 = type ( textual representation of the ftenum type )
12060 * Field 5 = parent protocol abbreviation
12061 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12062 * Field 7 = bitmask: format: hex: 0x....
12063 * Field 8 = blurb describing field
12064 */
12065void
12066proto_registrar_dump_fields(void)
12067{
12068 header_field_info *hfinfo, *parent_hfinfo;
12069 int i, len;
12070 const char *enum_name;
12071 const char *base_name;
12072 const char *blurb;
12073 char width[5];
12074
12075 len = gpa_hfinfo.len;
12076 for (i = 0; i < len ; i++) {
12077 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12078 continue; /* This is a deregistered protocol or header field */
12079
12080 PROTO_REGISTRAR_GET_NTH(i, hfinfo)if((i == 0 || (unsigned)i > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 12080
, __func__, "Unregistered hf! index=%d", i); ((void) ((i >
0 && (unsigned)i < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12080
, "i > 0 && (unsigned)i < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[i] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 12080, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12081
12082 /*
12083 * Skip the pseudo-field for "proto_tree_add_text()" since
12084 * we don't want it in the list of filterable fields.
12085 */
12086 if (hfinfo->id == hf_text_only)
12087 continue;
12088
12089 /* format for protocols */
12090 if (proto_registrar_is_protocol(i)) {
12091 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12092 }
12093 /* format for header fields */
12094 else {
12095 /*
12096 * If this field isn't at the head of the list of
12097 * fields with this name, skip this field - all
12098 * fields with the same name are really just versions
12099 * of the same field stored in different bits, and
12100 * should have the same type/radix/value list, and
12101 * just differ in their bit masks. (If a field isn't
12102 * a bitfield, but can be, say, 1 or 2 bytes long,
12103 * it can just be made FT_UINT16, meaning the
12104 * *maximum* length is 2 bytes, and be used
12105 * for all lengths.)
12106 */
12107 if (hfinfo->same_name_prev_id != -1)
12108 continue;
12109
12110 PROTO_REGISTRAR_GET_NTH(hfinfo->parent, parent_hfinfo)if((hfinfo->parent == 0 || (unsigned)hfinfo->parent >
gpa_hfinfo.len) && wireshark_abort_on_dissector_bug)
ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 12110
, __func__, "Unregistered hf! index=%d", hfinfo->parent); (
(void) ((hfinfo->parent > 0 && (unsigned)hfinfo
->parent < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12110
, "hfinfo->parent > 0 && (unsigned)hfinfo->parent < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
parent] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12110
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12111
12112 enum_name = ftype_name(hfinfo->type);
12113 base_name = "";
12114
12115 if (hfinfo->type == FT_CHAR ||
12116 hfinfo->type == FT_UINT8 ||
12117 hfinfo->type == FT_UINT16 ||
12118 hfinfo->type == FT_UINT24 ||
12119 hfinfo->type == FT_UINT32 ||
12120 hfinfo->type == FT_UINT40 ||
12121 hfinfo->type == FT_UINT48 ||
12122 hfinfo->type == FT_UINT56 ||
12123 hfinfo->type == FT_UINT64 ||
12124 hfinfo->type == FT_INT8 ||
12125 hfinfo->type == FT_INT16 ||
12126 hfinfo->type == FT_INT24 ||
12127 hfinfo->type == FT_INT32 ||
12128 hfinfo->type == FT_INT40 ||
12129 hfinfo->type == FT_INT48 ||
12130 hfinfo->type == FT_INT56 ||
12131 hfinfo->type == FT_INT64) {
12132
12133 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12134 case BASE_NONE:
12135 case BASE_DEC:
12136 case BASE_HEX:
12137 case BASE_OCT:
12138 case BASE_DEC_HEX:
12139 case BASE_HEX_DEC:
12140 case BASE_CUSTOM:
12141 case BASE_PT_UDP:
12142 case BASE_PT_TCP:
12143 case BASE_PT_DCCP:
12144 case BASE_PT_SCTP:
12145 case BASE_OUI:
12146 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12147 break;
12148 default:
12149 base_name = "????";
12150 break;
12151 }
12152 } else if (hfinfo->type == FT_BOOLEAN) {
12153 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12154 snprintf(width, sizeof(width), "%d", hfinfo->display);
12155 base_name = width;
12156 }
12157
12158 blurb = hfinfo->blurb;
12159 if (blurb == NULL((void*)0))
12160 blurb = "";
12161 else if (strlen(blurb) == 0)
12162 blurb = "\"\"";
12163
12164 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12165 hfinfo->name, hfinfo->abbrev, enum_name,
12166 parent_hfinfo->abbrev, base_name,
12167 hfinfo->bitmask, blurb);
12168 }
12169 }
12170}
12171
12172/* Dumps all abbreviated field and protocol completions of the given string to
12173 * stdout. An independent program may use this for command-line tab completion
12174 * of fields.
12175 */
12176bool_Bool
12177proto_registrar_dump_field_completions(const char *prefix)
12178{
12179 header_field_info *hfinfo;
12180 int i, len;
12181 size_t prefix_len;
12182 bool_Bool matched = false0;
12183
12184 prefix_len = strlen(prefix);
12185 len = gpa_hfinfo.len;
12186 for (i = 0; i < len ; i++) {
12187 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12188 continue; /* This is a deregistered protocol or header field */
12189
12190 PROTO_REGISTRAR_GET_NTH(i, hfinfo)if((i == 0 || (unsigned)i > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 12190
, __func__, "Unregistered hf! index=%d", i); ((void) ((i >
0 && (unsigned)i < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12190
, "i > 0 && (unsigned)i < gpa_hfinfo.len", "Unregistered hf!"
)))) ; ((void) ((gpa_hfinfo.hfi[i] != ((void*)0)) ? (void)0 :
(proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 12190, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12191
12192 /*
12193 * Skip the pseudo-field for "proto_tree_add_text()" since
12194 * we don't want it in the list of filterable fields.
12195 */
12196 if (hfinfo->id == hf_text_only)
12197 continue;
12198
12199 /* format for protocols */
12200 if (proto_registrar_is_protocol(i)) {
12201 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12202 matched = true1;
12203 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12204 }
12205 }
12206 /* format for header fields */
12207 else {
12208 /*
12209 * If this field isn't at the head of the list of
12210 * fields with this name, skip this field - all
12211 * fields with the same name are really just versions
12212 * of the same field stored in different bits, and
12213 * should have the same type/radix/value list, and
12214 * just differ in their bit masks. (If a field isn't
12215 * a bitfield, but can be, say, 1 or 2 bytes long,
12216 * it can just be made FT_UINT16, meaning the
12217 * *maximum* length is 2 bytes, and be used
12218 * for all lengths.)
12219 */
12220 if (hfinfo->same_name_prev_id != -1)
12221 continue;
12222
12223 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12224 matched = true1;
12225 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12226 }
12227 }
12228 }
12229 return matched;
12230}
12231
12232/* Dumps field types and descriptive names to stdout. An independent
12233 * program can take this output and format it into nice tables or HTML or
12234 * whatever.
12235 *
12236 * There is one record per line. The fields are tab-delimited.
12237 *
12238 * Field 1 = field type name, e.g. FT_UINT8
12239 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12240 */
12241void
12242proto_registrar_dump_ftypes(void)
12243{
12244 int fte;
12245
12246 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12247 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12248 }
12249}
12250
12251/* This function indicates whether it's possible to construct a
12252 * "match selected" display filter string for the specified field,
12253 * returns an indication of whether it's possible, and, if it's
12254 * possible and "filter" is non-null, constructs the filter and
12255 * sets "*filter" to point to it.
12256 * You do not need to [g_]free() this string since it will be automatically
12257 * freed once the next packet is dissected.
12258 */
12259static bool_Bool
12260construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12261 char **filter)
12262{
12263 const header_field_info *hfinfo;
12264 char *ptr;
12265 int buf_len;
12266 int i;
12267 int start, length, length_remaining;
12268 uint8_t c;
12269
12270 if (!finfo)
12271 return false0;
12272
12273 hfinfo = finfo->hfinfo;
12274 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12274, "hfinfo"))))
;
12275
12276 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12277 * then "the numeric value ... is not used when preparing
12278 * filters for the field in question." If it's any other
12279 * base, we'll generate the filter normally (which will
12280 * be numeric, even though the human-readable string does
12281 * work for filtering.)
12282 *
12283 * XXX - It might be nice to use fvalue_to_string_repr() in
12284 * "proto_item_fill_label()" as well, although, there, you'd
12285 * have to deal with the base *and* with resolved values for
12286 * addresses.
12287 *
12288 * Perhaps in addition to taking the repr type (DISPLAY
12289 * or DFILTER) and the display (base), fvalue_to_string_repr()
12290 * should have the the "strings" values in the header_field_info
12291 * structure for the field as a parameter, so it can have
12292 * if the field is Boolean or an enumerated integer type,
12293 * the tables used to generate human-readable values.
12294 */
12295 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12296 const char *str = NULL((void*)0);
12297
12298 switch (hfinfo->type) {
12299
12300 case FT_INT8:
12301 case FT_INT16:
12302 case FT_INT24:
12303 case FT_INT32:
12304 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12305 break;
12306
12307 case FT_CHAR:
12308 case FT_UINT8:
12309 case FT_UINT16:
12310 case FT_UINT24:
12311 case FT_UINT32:
12312 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12313 break;
12314
12315 default:
12316 break;
12317 }
12318
12319 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12320 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12321 return true1;
12322 }
12323 }
12324
12325 switch (hfinfo->type) {
12326
12327 case FT_PROTOCOL:
12328 if (filter != NULL((void*)0))
12329 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12330 break;
12331
12332 case FT_NONE:
12333 /*
12334 * If the length is 0, just match the name of the
12335 * field.
12336 *
12337 * (Also check for negative values, just in case,
12338 * as we'll cast it to an unsigned value later.)
12339 */
12340 length = finfo->length;
12341 if (length == 0) {
12342 if (filter != NULL((void*)0))
12343 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12344 break;
12345 }
12346 if (length < 0)
12347 return false0;
12348
12349 /*
12350 * This doesn't have a value, so we'd match
12351 * on the raw bytes at this address.
12352 *
12353 * Should we be allowed to access to the raw bytes?
12354 * If "edt" is NULL, the answer is "no".
12355 */
12356 if (edt == NULL((void*)0))
12357 return false0;
12358
12359 /*
12360 * Is this field part of the raw frame tvbuff?
12361 * If not, we can't use "frame[N:M]" to match
12362 * it.
12363 *
12364 * XXX - should this be frame-relative, or
12365 * protocol-relative?
12366 *
12367 * XXX - does this fallback for non-registered
12368 * fields even make sense?
12369 */
12370 if (finfo->ds_tvb != edt->tvb)
12371 return false0; /* you lose */
12372
12373 /*
12374 * Don't go past the end of that tvbuff.
12375 */
12376 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12377 if (length > length_remaining)
12378 length = length_remaining;
12379 if (length <= 0)
12380 return false0;
12381
12382 if (filter != NULL((void*)0)) {
12383 start = finfo->start;
12384 buf_len = 32 + length * 3;
12385 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12386 ptr = *filter;
12387
12388 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12389 "frame[%d:%d] == ", finfo->start, length);
12390 for (i=0; i<length; i++) {
12391 c = tvb_get_uint8(finfo->ds_tvb, start);
12392 start++;
12393 if (i == 0 ) {
12394 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12395 }
12396 else {
12397 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12398 }
12399 }
12400 }
12401 break;
12402
12403 /* By default, use the fvalue's "to_string_repr" method. */
12404 default:
12405 if (filter != NULL((void*)0)) {
12406 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12407 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12408 wmem_free(NULL((void*)0), str);
12409 }
12410 break;
12411 }
12412
12413 return true1;
12414}
12415
12416/*
12417 * Returns true if we can do a "match selected" on the field, false
12418 * otherwise.
12419 */
12420bool_Bool
12421proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12422{
12423 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12424}
12425
12426/* This function attempts to construct a "match selected" display filter
12427 * string for the specified field; if it can do so, it returns a pointer
12428 * to the string, otherwise it returns NULL.
12429 *
12430 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12431 */
12432char *
12433proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12434{
12435 char *filter = NULL((void*)0);
12436
12437 if (!construct_match_selected_string(finfo, edt, &filter))
12438 {
12439 wmem_free(NULL((void*)0), filter);
12440 return NULL((void*)0);
12441 }
12442 return filter;
12443}
12444
12445/* This function is common code for all proto_tree_add_bitmask... functions.
12446 */
12447
12448static bool_Bool
12449proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12450 const int len, const int ett, int * const *fields,
12451 const int flags, bool_Bool first,
12452 bool_Bool use_parent_tree,
12453 proto_tree* tree, uint64_t value)
12454{
12455 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12456 uint64_t bitmask = 0;
12457 uint64_t tmpval;
12458 header_field_info *hf;
12459 uint32_t integer32;
12460 int bit_offset;
12461 int no_of_bits;
12462
12463 if (!*fields)
12464 REPORT_DISSECTOR_BUG("Illegal call of proto_item_add_bitmask_tree without fields")proto_report_dissector_bug("Illegal call of proto_item_add_bitmask_tree without fields"
)
;
12465
12466 if (len < 0 || len > 8)
12467 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12468 /**
12469 * packet-frame.c uses len=0 since the value is taken from the packet
12470 * metadata, not the packet bytes. In that case, assume that all bits
12471 * in the provided value are valid.
12472 */
12473 if (len > 0) {
12474 available_bits >>= (8 - (unsigned)len)*8;
12475 }
12476
12477 if (use_parent_tree == false0)
12478 tree = proto_item_add_subtree(item, ett);
12479
12480 while (*fields) {
12481 uint64_t present_bits;
12482 PROTO_REGISTRAR_GET_NTH(**fields,hf)if((**fields == 0 || (unsigned)**fields > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 12482, __func__, "Unregistered hf! index=%d"
, **fields); ((void) ((**fields > 0 && (unsigned)*
*fields < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12482
, "**fields > 0 && (unsigned)**fields < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[**fields]
!= ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 12482, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12483 DISSECTOR_ASSERT_HINT(hf->bitmask != 0, hf->abbrev)((void) ((hf->bitmask != 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12483
, "hf->bitmask != 0", hf->abbrev))))
;
12484
12485 bitmask |= hf->bitmask;
12486
12487 /* Skip fields that aren't fully present */
12488 present_bits = available_bits & hf->bitmask;
12489 if (present_bits != hf->bitmask) {
12490 fields++;
12491 continue;
12492 }
12493
12494 switch (hf->type) {
12495 case FT_CHAR:
12496 case FT_UINT8:
12497 case FT_UINT16:
12498 case FT_UINT24:
12499 case FT_UINT32:
12500 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12501 break;
12502
12503 case FT_INT8:
12504 case FT_INT16:
12505 case FT_INT24:
12506 case FT_INT32:
12507 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12508 break;
12509
12510 case FT_UINT40:
12511 case FT_UINT48:
12512 case FT_UINT56:
12513 case FT_UINT64:
12514 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12515 break;
12516
12517 case FT_INT40:
12518 case FT_INT48:
12519 case FT_INT56:
12520 case FT_INT64:
12521 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12522 break;
12523
12524 case FT_BOOLEAN:
12525 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12526 break;
12527
12528 default:
12529 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
12530 hf->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
12531 hf->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
12532 ftype_name(hf->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
;
12533 break;
12534 }
12535 if (flags & BMT_NO_APPEND0x01) {
12536 fields++;
12537 continue;
12538 }
12539 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12540
12541 /* XXX: README.developer and the comments have always defined
12542 * BMT_NO_INT as "only boolean flags are added to the title /
12543 * don't add non-boolean (integral) fields", but the
12544 * implementation has always added BASE_CUSTOM and fields with
12545 * value_strings, though not fields with unit_strings.
12546 * Possibly this is because some dissectors use a FT_UINT8
12547 * with a value_string for fields that should be a FT_BOOLEAN.
12548 */
12549 switch (hf->type) {
12550 case FT_CHAR:
12551 if (hf->display == BASE_CUSTOM) {
12552 char lbl[ITEM_LABEL_LENGTH240];
12553 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12554
12555 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12555, "fmtfunc"))))
;
12556 fmtfunc(lbl, (uint32_t) tmpval);
12557 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12558 hf->name, lbl);
12559 first = false0;
12560 }
12561 else if (hf->strings) {
12562 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12563 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12564 first = false0;
12565 }
12566 else if (!(flags & BMT_NO_INT0x02)) {
12567 char buf[32];
12568 const char *out;
12569
12570 if (!first) {
12571 proto_item_append_text(item, ", ");
12572 }
12573
12574 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12575 proto_item_append_text(item, "%s: %s", hf->name, out);
12576 first = false0;
12577 }
12578
12579 break;
12580
12581 case FT_UINT8:
12582 case FT_UINT16:
12583 case FT_UINT24:
12584 case FT_UINT32:
12585 if (hf->display == BASE_CUSTOM) {
12586 char lbl[ITEM_LABEL_LENGTH240];
12587 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12588
12589 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12589, "fmtfunc"))))
;
12590 fmtfunc(lbl, (uint32_t) tmpval);
12591 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12592 hf->name, lbl);
12593 first = false0;
12594 }
12595 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12596 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12597 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12598 first = false0;
12599 }
12600 else if (!(flags & BMT_NO_INT0x02)) {
12601 char buf[NUMBER_LABEL_LENGTH80];
12602 const char *out = NULL((void*)0);
12603
12604 if (!first) {
12605 proto_item_append_text(item, ", ");
12606 }
12607
12608 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12609 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12610 }
12611 if (out == NULL((void*)0)) {
12612 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12613 }
12614 proto_item_append_text(item, "%s: %s", hf->name, out);
12615 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12616 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12617 }
12618 first = false0;
12619 }
12620
12621 break;
12622
12623 case FT_INT8:
12624 case FT_INT16:
12625 case FT_INT24:
12626 case FT_INT32:
12627 integer32 = (uint32_t) tmpval;
12628 if (hf->bitmask) {
12629 no_of_bits = ws_count_ones(hf->bitmask);
12630 integer32 = ws_sign_ext32(integer32, no_of_bits);
12631 }
12632 if (hf->display == BASE_CUSTOM) {
12633 char lbl[ITEM_LABEL_LENGTH240];
12634 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12635
12636 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12636, "fmtfunc"))))
;
12637 fmtfunc(lbl, (int32_t) integer32);
12638 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12639 hf->name, lbl);
12640 first = false0;
12641 }
12642 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12643 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12644 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12645 first = false0;
12646 }
12647 else if (!(flags & BMT_NO_INT0x02)) {
12648 char buf[NUMBER_LABEL_LENGTH80];
12649 const char *out = NULL((void*)0);
12650
12651 if (!first) {
12652 proto_item_append_text(item, ", ");
12653 }
12654
12655 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12656 out = hf_try_val_to_str((int32_t) integer32, hf);
12657 }
12658 if (out == NULL((void*)0)) {
12659 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12660 }
12661 proto_item_append_text(item, "%s: %s", hf->name, out);
12662 if (hf->display & BASE_UNIT_STRING0x00001000) {
12663 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12664 }
12665 first = false0;
12666 }
12667
12668 break;
12669
12670 case FT_UINT40:
12671 case FT_UINT48:
12672 case FT_UINT56:
12673 case FT_UINT64:
12674 if (hf->display == BASE_CUSTOM) {
12675 char lbl[ITEM_LABEL_LENGTH240];
12676 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12677
12678 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12678, "fmtfunc"))))
;
12679 fmtfunc(lbl, tmpval);
12680 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12681 hf->name, lbl);
12682 first = false0;
12683 }
12684 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12685 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12686 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12687 first = false0;
12688 }
12689 else if (!(flags & BMT_NO_INT0x02)) {
12690 char buf[NUMBER_LABEL_LENGTH80];
12691 const char *out = NULL((void*)0);
12692
12693 if (!first) {
12694 proto_item_append_text(item, ", ");
12695 }
12696
12697 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12698 out = hf_try_val64_to_str(tmpval, hf);
12699 }
12700 if (out == NULL((void*)0)) {
12701 out = hfinfo_number_value_format64(hf, buf, tmpval);
12702 }
12703 proto_item_append_text(item, "%s: %s", hf->name, out);
12704 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12705 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12706 }
12707 first = false0;
12708 }
12709
12710 break;
12711
12712 case FT_INT40:
12713 case FT_INT48:
12714 case FT_INT56:
12715 case FT_INT64:
12716 if (hf->bitmask) {
12717 no_of_bits = ws_count_ones(hf->bitmask);
12718 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12719 }
12720 if (hf->display == BASE_CUSTOM) {
12721 char lbl[ITEM_LABEL_LENGTH240];
12722 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12723
12724 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12724, "fmtfunc"))))
;
12725 fmtfunc(lbl, (int64_t) tmpval);
12726 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12727 hf->name, lbl);
12728 first = false0;
12729 }
12730 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12731 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12732 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12733 first = false0;
12734 }
12735 else if (!(flags & BMT_NO_INT0x02)) {
12736 char buf[NUMBER_LABEL_LENGTH80];
12737 const char *out = NULL((void*)0);
12738
12739 if (!first) {
12740 proto_item_append_text(item, ", ");
12741 }
12742
12743 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12744 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12745 }
12746 if (out == NULL((void*)0)) {
12747 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12748 }
12749 proto_item_append_text(item, "%s: %s", hf->name, out);
12750 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12751 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12752 }
12753 first = false0;
12754 }
12755
12756 break;
12757
12758 case FT_BOOLEAN:
12759 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12760 /* If we have true/false strings, emit full - otherwise messages
12761 might look weird */
12762 const struct true_false_string *tfs =
12763 (const struct true_false_string *)hf->strings;
12764
12765 if (tmpval) {
12766 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12767 hf->name, tfs->true_string);
12768 first = false0;
12769 } else if (!(flags & BMT_NO_FALSE0x04)) {
12770 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12771 hf->name, tfs->false_string);
12772 first = false0;
12773 }
12774 } else if (hf->bitmask & value) {
12775 /* If the flag is set, show the name */
12776 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12777 first = false0;
12778 }
12779 break;
12780 default:
12781 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()",proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
12782 hf->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
12783 hf->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
12784 ftype_name(hf->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_item_add_bitmask_tree()"
, hf->abbrev, hf->type, ftype_name(hf->type))
;
12785 break;
12786 }
12787
12788 fields++;
12789 }
12790
12791 /* XXX: We don't pass the hfi into this function. Perhaps we should,
12792 * but then again most dissectors don't set the bitmask field for
12793 * the higher level bitmask hfi, so calculate the bitmask from the
12794 * fields present. */
12795 if (item) {
12796 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
12797 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
12798 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset) & 7) <<
5)); } while(0)
;
12799 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((no_of_bits) & 63) <<
8)); } while(0)
;
12800 }
12801 return first;
12802}
12803
12804/* This function will dissect a sequence of bytes that describe a
12805 * bitmask and supply the value of that sequence through a pointer.
12806 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12807 * to be dissected.
12808 * This field will form an expansion under which the individual fields of the
12809 * bitmask is dissected and displayed.
12810 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12811 *
12812 * fields is an array of pointers to int that lists all the fields of the
12813 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12814 * or another integer of the same type/size as hf_hdr with a mask specified.
12815 * This array is terminated by a NULL entry.
12816 *
12817 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12818 * FT_integer fields that have a value_string attached will have the
12819 * matched string displayed on the expansion line.
12820 */
12821proto_item *
12822proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
12823 const unsigned offset, const int hf_hdr,
12824 const int ett, int * const *fields,
12825 const unsigned encoding, uint64_t *retval)
12826{
12827 return proto_tree_add_bitmask_with_flags_ret_uint64(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08, retval);
12828}
12829
12830/* This function will dissect a sequence of bytes that describe a
12831 * bitmask.
12832 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12833 * to be dissected.
12834 * This field will form an expansion under which the individual fields of the
12835 * bitmask is dissected and displayed.
12836 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12837 *
12838 * fields is an array of pointers to int that lists all the fields of the
12839 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12840 * or another integer of the same type/size as hf_hdr with a mask specified.
12841 * This array is terminated by a NULL entry.
12842 *
12843 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12844 * FT_integer fields that have a value_string attached will have the
12845 * matched string displayed on the expansion line.
12846 */
12847proto_item *
12848proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
12849 const unsigned offset, const int hf_hdr,
12850 const int ett, int * const *fields,
12851 const unsigned encoding)
12852{
12853 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
12854}
12855
12856/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12857 * what data is appended to the header.
12858 */
12859proto_item *
12860proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12861 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
12862 uint64_t *retval)
12863{
12864 proto_item *item = NULL((void*)0);
12865 header_field_info *hf;
12866 int len;
12867 uint64_t value;
12868
12869 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf)if((hf_hdr == 0 || (unsigned)hf_hdr > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 12869, __func__, "Unregistered hf! index=%d"
, hf_hdr); ((void) ((hf_hdr > 0 && (unsigned)hf_hdr
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12869
, "hf_hdr > 0 && (unsigned)hf_hdr < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_hdr] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 12869, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12870 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf)((void) (((((((hf)->type) == FT_INT8 || ((hf)->type) ==
FT_INT16 || ((hf)->type) == FT_INT24 || ((hf)->type) ==
FT_INT32) || (((hf)->type) == FT_INT40 || ((hf)->type)
== FT_INT48 || ((hf)->type) == FT_INT56 || ((hf)->type
) == FT_INT64)) || ((((hf)->type) == FT_CHAR || ((hf)->
type) == FT_UINT8 || ((hf)->type) == FT_UINT16 || ((hf)->
type) == FT_UINT24 || ((hf)->type) == FT_UINT32 || ((hf)->
type) == FT_FRAMENUM) || (((hf)->type) == FT_UINT40 || ((hf
)->type) == FT_UINT48 || ((hf)->type) == FT_UINT56 || (
(hf)->type) == FT_UINT64)))) ? (void)0 : proto_report_dissector_bug
("%s:%u: field %s is not of type FT_CHAR or an FT_{U}INTn type"
, "epan/proto.c", 12870, (hf)->abbrev)))
;
12871 len = ftype_wire_size(hf->type);
12872 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12873
12874 if (parent_tree) {
12875 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12876 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12877 flags, false0, false0, NULL((void*)0), value);
12878 }
12879
12880 *retval = value;
12881 if (hf->bitmask) {
12882 /* Mask out irrelevant portions */
12883 *retval &= hf->bitmask;
12884 /* Shift bits */
12885 *retval >>= hfinfo_bitshift(hf);
12886 }
12887
12888 return item;
12889}
12890
12891/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12892 * what data is appended to the header.
12893 */
12894proto_item *
12895proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12896 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
12897{
12898 proto_item *item = NULL((void*)0);
12899 header_field_info *hf;
12900 int len;
12901 uint64_t value;
12902
12903 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf)if((hf_hdr == 0 || (unsigned)hf_hdr > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 12903, __func__, "Unregistered hf! index=%d"
, hf_hdr); ((void) ((hf_hdr > 0 && (unsigned)hf_hdr
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12903
, "hf_hdr > 0 && (unsigned)hf_hdr < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_hdr] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 12903, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12904 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf)((void) (((((((hf)->type) == FT_INT8 || ((hf)->type) ==
FT_INT16 || ((hf)->type) == FT_INT24 || ((hf)->type) ==
FT_INT32) || (((hf)->type) == FT_INT40 || ((hf)->type)
== FT_INT48 || ((hf)->type) == FT_INT56 || ((hf)->type
) == FT_INT64)) || ((((hf)->type) == FT_CHAR || ((hf)->
type) == FT_UINT8 || ((hf)->type) == FT_UINT16 || ((hf)->
type) == FT_UINT24 || ((hf)->type) == FT_UINT32 || ((hf)->
type) == FT_FRAMENUM) || (((hf)->type) == FT_UINT40 || ((hf
)->type) == FT_UINT48 || ((hf)->type) == FT_UINT56 || (
(hf)->type) == FT_UINT64)))) ? (void)0 : proto_report_dissector_bug
("%s:%u: field %s is not of type FT_CHAR or an FT_{U}INTn type"
, "epan/proto.c", 12904, (hf)->abbrev)))
;
12905
12906 if (parent_tree) {
12907 len = ftype_wire_size(hf->type);
12908 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12909 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12910 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12911 flags, false0, false0, NULL((void*)0), value);
12912 }
12913
12914 return item;
12915}
12916
12917/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
12918 can't be retrieved directly from tvb) */
12919proto_item *
12920proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12921 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
12922{
12923 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
12924 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
12925}
12926
12927/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
12928WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
12929proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12930 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
12931{
12932 proto_item *item = NULL((void*)0);
12933 header_field_info *hf;
12934 int len;
12935
12936 PROTO_REGISTRAR_GET_NTH(hf_hdr,hf)if((hf_hdr == 0 || (unsigned)hf_hdr > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 12936, __func__, "Unregistered hf! index=%d"
, hf_hdr); ((void) ((hf_hdr > 0 && (unsigned)hf_hdr
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 12936
, "hf_hdr > 0 && (unsigned)hf_hdr < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_hdr] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 12936, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12937 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf)((void) (((((((hf)->type) == FT_INT8 || ((hf)->type) ==
FT_INT16 || ((hf)->type) == FT_INT24 || ((hf)->type) ==
FT_INT32) || (((hf)->type) == FT_INT40 || ((hf)->type)
== FT_INT48 || ((hf)->type) == FT_INT56 || ((hf)->type
) == FT_INT64)) || ((((hf)->type) == FT_CHAR || ((hf)->
type) == FT_UINT8 || ((hf)->type) == FT_UINT16 || ((hf)->
type) == FT_UINT24 || ((hf)->type) == FT_UINT32 || ((hf)->
type) == FT_FRAMENUM) || (((hf)->type) == FT_UINT40 || ((hf
)->type) == FT_UINT48 || ((hf)->type) == FT_UINT56 || (
(hf)->type) == FT_UINT64)))) ? (void)0 : proto_report_dissector_bug
("%s:%u: field %s is not of type FT_CHAR or an FT_{U}INTn type"
, "epan/proto.c", 12937, (hf)->abbrev)))
;
12938 /* the proto_tree_add_uint/_uint64() calls below
12939 will fail if tvb==NULL and len!=0 */
12940 len = tvb ? ftype_wire_size(hf->type) : 0;
12941
12942 if (parent_tree) {
12943 if (len <= 4)
12944 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
12945 else
12946 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
12947
12948 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12949 flags, false0, false0, NULL((void*)0), value);
12950 }
12951
12952 return item;
12953}
12954
12955/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
12956void
12957proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
12958 const int len, int * const *fields, const unsigned encoding)
12959{
12960 uint64_t value;
12961
12962 if (tree) {
12963 value = get_uint64_value(tree, tvb, offset, len, encoding);
12964 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
12965 BMT_NO_APPEND0x01, false0, true1, tree, value);
12966 }
12967}
12968
12969WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
12970proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
12971 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
12972{
12973 uint64_t value;
12974
12975 value = get_uint64_value(tree, tvb, offset, len, encoding);
12976 if (tree) {
12977 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
12978 BMT_NO_APPEND0x01, false0, true1, tree, value);
12979 }
12980 if (retval) {
12981 *retval = value;
12982 }
12983}
12984
12985WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
12986proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
12987 const int len, int * const *fields, const uint64_t value)
12988{
12989 if (tree) {
12990 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
12991 BMT_NO_APPEND0x01, false0, true1, tree, value);
12992 }
12993}
12994
12995
12996/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
12997 * This is intended to support bitmask fields whose lengths can vary, perhaps
12998 * as the underlying standard evolves over time.
12999 * With this API there is the possibility of being called to display more or
13000 * less data than the dissector was coded to support.
13001 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13002 * Thus when presented with "too much" or "too little" data, MSbits will be
13003 * ignored or MSfields sacrificed.
13004 *
13005 * Only fields for which all defined bits are available are displayed.
13006 */
13007proto_item *
13008proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13009 const unsigned offset, const unsigned len, const int hf_hdr,
13010 const int ett, int * const *fields, struct expert_field* exp,
13011 const unsigned encoding)
13012{
13013 proto_item *item = NULL((void*)0);
13014 header_field_info *hf;
13015 unsigned decodable_len;
13016 unsigned decodable_offset;
13017 uint32_t decodable_value;
13018 uint64_t value;
13019
13020 PROTO_REGISTRAR_GET_NTH(hf_hdr, hf)if((hf_hdr == 0 || (unsigned)hf_hdr > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13020, __func__, "Unregistered hf! index=%d"
, hf_hdr); ((void) ((hf_hdr > 0 && (unsigned)hf_hdr
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13020
, "hf_hdr > 0 && (unsigned)hf_hdr < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_hdr] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13020, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13021 DISSECTOR_ASSERT_FIELD_TYPE_IS_INTEGRAL(hf)((void) (((((((hf)->type) == FT_INT8 || ((hf)->type) ==
FT_INT16 || ((hf)->type) == FT_INT24 || ((hf)->type) ==
FT_INT32) || (((hf)->type) == FT_INT40 || ((hf)->type)
== FT_INT48 || ((hf)->type) == FT_INT56 || ((hf)->type
) == FT_INT64)) || ((((hf)->type) == FT_CHAR || ((hf)->
type) == FT_UINT8 || ((hf)->type) == FT_UINT16 || ((hf)->
type) == FT_UINT24 || ((hf)->type) == FT_UINT32 || ((hf)->
type) == FT_FRAMENUM) || (((hf)->type) == FT_UINT40 || ((hf
)->type) == FT_UINT48 || ((hf)->type) == FT_UINT56 || (
(hf)->type) == FT_UINT64)))) ? (void)0 : proto_report_dissector_bug
("%s:%u: field %s is not of type FT_CHAR or an FT_{U}INTn type"
, "epan/proto.c", 13021, (hf)->abbrev)))
;
13022
13023 decodable_offset = offset;
13024 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13025
13026 /* If we are ftype_wire_size-limited,
13027 * make sure we decode as many LSBs as possible.
13028 */
13029 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13030 decodable_offset += (len - decodable_len);
13031 }
13032
13033 if (parent_tree) {
13034 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13035 decodable_len, encoding);
13036
13037 /* The root item covers all the bytes even if we can't decode them all */
13038 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13039 decodable_value);
13040 }
13041
13042 if (decodable_len < len) {
13043 /* Dissector likely requires updating for new protocol revision */
13044 expert_add_info_format(NULL((void*)0), item, exp,
13045 "Only least-significant %d of %d bytes decoded",
13046 decodable_len, len);
13047 }
13048
13049 if (item) {
13050 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13051 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13052 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13053 }
13054
13055 return item;
13056}
13057
13058/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13059proto_item *
13060proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13061 const unsigned offset, const unsigned len,
13062 const char *name, const char *fallback,
13063 const int ett, int * const *fields,
13064 const unsigned encoding, const int flags)
13065{
13066 proto_item *item = NULL((void*)0);
13067 uint64_t value;
13068
13069 if (parent_tree) {
13070 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13071 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13072 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13073 flags, true1, false0, NULL((void*)0), value) && fallback) {
13074 /* Still at first item - append 'fallback' text if any */
13075 proto_item_append_text(item, "%s", fallback);
13076 }
13077 }
13078
13079 return item;
13080}
13081
13082proto_item *
13083proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13084 const unsigned bit_offset, const int no_of_bits,
13085 const unsigned encoding)
13086{
13087 header_field_info *hfinfo;
13088 int octet_length;
13089 int octet_offset;
13090
13091 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13091, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13091
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13091, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13092
13093 if (no_of_bits < 0) {
13094 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13095 }
13096 octet_length = (no_of_bits + 7) >> 3;
13097 octet_offset = bit_offset >> 3;
13098 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13099
13100 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13101 * but only after doing a bunch more work (which we can, in the common
13102 * case, shortcut here).
13103 */
13104 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13105 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13105
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13105, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13105, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13105, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
13106
13107 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13108}
13109
13110/*
13111 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13112 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13113 * Offset should be given in bits from the start of the tvb.
13114 */
13115
13116static proto_item *
13117_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13118 const unsigned bit_offset, const int no_of_bits,
13119 uint64_t *return_value, const unsigned encoding)
13120{
13121 int offset;
13122 unsigned length;
13123 uint8_t tot_no_bits;
13124 char *bf_str;
13125 char lbl_str[ITEM_LABEL_LENGTH240];
13126 uint64_t value = 0;
13127 uint8_t *bytes = NULL((void*)0);
13128 size_t bytes_length = 0;
13129
13130 proto_item *pi;
13131 header_field_info *hf_field;
13132
13133 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13134 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13134, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13134
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13134, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13135
13136 if (hf_field->bitmask != 0) {
13137 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_ret_val"proto_report_dissector_bug("Incompatible use of proto_tree_add_bits_ret_val"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
13138 " with field '%s' (%s) with bitmask != 0",proto_report_dissector_bug("Incompatible use of proto_tree_add_bits_ret_val"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
13139 hf_field->abbrev, hf_field->name)proto_report_dissector_bug("Incompatible use of proto_tree_add_bits_ret_val"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
;
13140 }
13141
13142 if (no_of_bits < 0) {
13143 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13144 } else if (no_of_bits == 0) {
13145 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of 0",proto_report_dissector_bug("field %s passed to proto_tree_add_bits_ret_val() has a bit width of 0"
, hf_field->abbrev)
13146 hf_field->abbrev)proto_report_dissector_bug("field %s passed to proto_tree_add_bits_ret_val() has a bit width of 0"
, hf_field->abbrev)
;
13147 }
13148
13149 /* Byte align offset */
13150 offset = bit_offset>>3;
13151
13152 /*
13153 * Calculate the number of octets used to hold the bits
13154 */
13155 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13156 length = (tot_no_bits + 7) >> 3;
13157
13158 if (no_of_bits < 65) {
13159 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13160 } else if (hf_field->type != FT_BYTES) {
13161 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 65",proto_report_dissector_bug("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 65"
, hf_field->abbrev, no_of_bits)
13162 hf_field->abbrev, no_of_bits)proto_report_dissector_bug("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 65"
, hf_field->abbrev, no_of_bits)
;
13163 return NULL((void*)0);
13164 }
13165
13166 /* Sign extend for signed types */
13167 switch (hf_field->type) {
13168 case FT_INT8:
13169 case FT_INT16:
13170 case FT_INT24:
13171 case FT_INT32:
13172 case FT_INT40:
13173 case FT_INT48:
13174 case FT_INT56:
13175 case FT_INT64:
13176 value = ws_sign_ext64(value, no_of_bits);
13177 break;
13178
13179 default:
13180 break;
13181 }
13182
13183 if (return_value) {
13184 *return_value = value;
13185 }
13186
13187 /* Coast clear. Try and fake it */
13188 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13189 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13189
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13189, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13189, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13189, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13190
13191 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13192
13193 switch (hf_field->type) {
13194 case FT_BOOLEAN:
13195 /* Boolean field */
13196 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13197 "%s = %s: %s",
13198 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13199 break;
13200
13201 case FT_CHAR:
13202 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13203 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13204 break;
13205
13206 case FT_UINT8:
13207 case FT_UINT16:
13208 case FT_UINT24:
13209 case FT_UINT32:
13210 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13211 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13212 break;
13213
13214 case FT_INT8:
13215 case FT_INT16:
13216 case FT_INT24:
13217 case FT_INT32:
13218 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13219 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13220 break;
13221
13222 case FT_UINT40:
13223 case FT_UINT48:
13224 case FT_UINT56:
13225 case FT_UINT64:
13226 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13227 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13228 break;
13229
13230 case FT_INT40:
13231 case FT_INT48:
13232 case FT_INT56:
13233 case FT_INT64:
13234 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13235 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13236 break;
13237
13238 case FT_BYTES:
13239 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13240 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13241 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13242 proto_item_set_text(pi, "%s", lbl_str);
13243 return pi;
13244
13245 /* TODO: should handle FT_UINT_BYTES ? */
13246
13247 default:
13248 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()",proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13249 hf_field->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13250 hf_field->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13251 ftype_name(hf_field->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
;
13252 return NULL((void*)0);
13253 }
13254
13255 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13256 return pi;
13257}
13258
13259proto_item *
13260proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13261 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13262 uint64_t *return_value)
13263{
13264 proto_item *pi;
13265 int no_of_bits;
13266 int octet_offset;
13267 unsigned mask_initial_bit_offset;
13268 unsigned mask_greatest_bit_offset;
13269 unsigned octet_length;
13270 uint8_t i;
13271 char bf_str[256];
13272 char lbl_str[ITEM_LABEL_LENGTH240];
13273 uint64_t value;
13274 uint64_t composite_bitmask;
13275 uint64_t composite_bitmap;
13276
13277 header_field_info *hf_field;
13278
13279 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13280 PROTO_REGISTRAR_GET_NTH(hfindex, hf_field)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13280, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13280
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13280, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
1
Assuming 'hfindex' is not equal to 0
2
Assuming 'hfindex' is <= field 'len'
3
Assuming 'hfindex' is > 0
4
Assuming 'hfindex' is < field 'len'
5
'?' condition is true
6
Assuming the condition is true
7
'?' condition is true
13281
13282 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13283 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_split_bits_item_ret_val"proto_report_dissector_bug("Incompatible use of proto_tree_add_split_bits_item_ret_val"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
13284 " with field '%s' (%s) with bitmask != 0",proto_report_dissector_bug("Incompatible use of proto_tree_add_split_bits_item_ret_val"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
13285 hf_field->abbrev, hf_field->name)proto_report_dissector_bug("Incompatible use of proto_tree_add_split_bits_item_ret_val"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
;
13286 }
13287
13288 mask_initial_bit_offset = bit_offset % 8;
13289
13290 no_of_bits = 0;
13291 value = 0;
13292 i = 0;
13293 mask_greatest_bit_offset = 0;
13294 composite_bitmask = 0;
13295 composite_bitmap = 0;
13296
13297 while (crumb_spec[i].crumb_bit_length != 0) {
10
Assuming field 'crumb_bit_length' is not equal to 0
11
Loop condition is true. Entering loop body
13298 uint64_t crumb_mask, crumb_value;
13299 uint8_t crumb_end_bit_offset;
13300
13301 crumb_value = tvb_get_bits64(tvb,
13302 bit_offset + crumb_spec[i].crumb_bit_offset,
13303 crumb_spec[i].crumb_bit_length,
13304 ENC_BIG_ENDIAN0x00000000);
13305 value += crumb_value;
13306 no_of_bits += crumb_spec[i].crumb_bit_length;
13307 DISSECTOR_ASSERT_HINT(no_of_bits <= 64, "a value larger than 64 bits cannot be represented")((void) ((no_of_bits <= 64) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13307
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13308
13309 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13310 octet containing the initial offset.
13311 If the mask is beyond 32 bits, then give up on bit map display.
13312 This could be improved in future, probably showing a table
13313 of 32 or 64 bits per row */
13314 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13315 crumb_end_bit_offset = mask_initial_bit_offset
13316 + crumb_spec[i].crumb_bit_offset
13317 + crumb_spec[i].crumb_bit_length;
13318 crumb_mask = (UINT64_C(1)1UL << crumb_spec[i].crumb_bit_length) - 1;
15
Assuming right operand of bit shift is less than 64
16
Value assigned to 'crumb_mask'
13319
13320 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13321 mask_greatest_bit_offset = crumb_end_bit_offset;
13322 }
13323 /* Currently the bitmap of the crumbs are only shown if
13324 * smaller than 32 bits. Do not bother calculating the
13325 * mask if it is larger than that. */
13326 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13327 composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
20
The result of left shift is undefined because the right operand '64' is not smaller than 64, the capacity of 'uint64_t'
13328 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13329 }
13330 }
13331 /* Shift left for the next segment */
13332 value <<= crumb_spec[++i].crumb_bit_length;
13333 }
13334
13335 /* Sign extend for signed types */
13336 switch (hf_field->type) {
13337 case FT_INT8:
13338 case FT_INT16:
13339 case FT_INT24:
13340 case FT_INT32:
13341 case FT_INT40:
13342 case FT_INT48:
13343 case FT_INT56:
13344 case FT_INT64:
13345 value = ws_sign_ext64(value, no_of_bits);
13346 break;
13347 default:
13348 break;
13349 }
13350
13351 if (return_value) {
13352 *return_value = value;
13353 }
13354
13355 /* Coast clear. Try and fake it */
13356 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13357 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13357
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13357, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13357, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13357, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13358
13359 /* initialise the format string */
13360 bf_str[0] = '\0';
13361
13362 octet_offset = bit_offset >> 3;
13363
13364 /* Round up mask length to nearest octet */
13365 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13366 mask_greatest_bit_offset = octet_length << 3;
13367
13368 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13369 It would be a useful enhancement to eliminate this restriction. */
13370 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13371 other_decode_bitfield_value(bf_str,
13372 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13373 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13374 mask_greatest_bit_offset);
13375 } else {
13376 /* If the bitmask is too large, try to describe its contents. */
13377 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13378 }
13379
13380 switch (hf_field->type) {
13381 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13382 /* Boolean field */
13383 return proto_tree_add_boolean_format(tree, hfindex,
13384 tvb, octet_offset, octet_length, value,
13385 "%s = %s: %s",
13386 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13387 break;
13388
13389 case FT_CHAR:
13390 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13391 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13392 break;
13393
13394 case FT_UINT8:
13395 case FT_UINT16:
13396 case FT_UINT24:
13397 case FT_UINT32:
13398 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13399 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13400 break;
13401
13402 case FT_INT8:
13403 case FT_INT16:
13404 case FT_INT24:
13405 case FT_INT32:
13406 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13407 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13408 break;
13409
13410 case FT_UINT40:
13411 case FT_UINT48:
13412 case FT_UINT56:
13413 case FT_UINT64:
13414 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13415 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13416 break;
13417
13418 case FT_INT40:
13419 case FT_INT48:
13420 case FT_INT56:
13421 case FT_INT64:
13422 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13423 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13424 break;
13425
13426 default:
13427 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()",proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13428 hf_field->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13429 hf_field->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13430 ftype_name(hf_field->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_split_bits_item_ret_val()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
;
13431 return NULL((void*)0);
13432 }
13433 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13434 return pi;
13435}
13436
13437void
13438proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13439 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13440{
13441 header_field_info *hfinfo;
13442 int start = bit_offset >> 3;
13443 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13444
13445 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13446 * so that we can use the tree's memory scope in calculating the string */
13447 if (length == -1) {
13448 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13449 } else {
13450 tvb_ensure_bytes_exist(tvb, start, length);
13451 }
13452 if (!tree) return;
13453
13454 PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) &&
wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 13454, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13454
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13454, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13455 proto_tree_add_text_internal(tree, tvb, start, length,
13456 "%s crumb %d of %s (decoded above)",
13457 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13458 tvb_get_bits(tvb,
13459 bit_offset,
13460 crumb_spec[crumb_index].crumb_bit_length,
13461 ENC_BIG_ENDIAN0x00000000),
13462 ENC_BIG_ENDIAN0x00000000),
13463 crumb_index,
13464 hfinfo->name);
13465}
13466
13467proto_item *
13468proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13469 const unsigned bit_offset, const int no_of_bits,
13470 uint64_t *return_value, const unsigned encoding)
13471{
13472 proto_item *item;
13473
13474 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13475 bit_offset, no_of_bits,
13476 return_value, encoding))) {
13477 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset) & 7) <<
5)); } while(0)
;
13478 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((no_of_bits) & 63) <<
8)); } while(0)
;
13479 }
13480 return item;
13481}
13482
13483static proto_item *
13484_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13485 tvbuff_t *tvb, const unsigned bit_offset,
13486 const int no_of_bits, void *value_ptr,
13487 const unsigned encoding, char *value_str)
13488{
13489 int offset;
13490 unsigned length;
13491 uint8_t tot_no_bits;
13492 char *str;
13493 uint64_t value = 0;
13494 header_field_info *hf_field;
13495
13496 /* We do not have to return a value, try to fake it as soon as possible */
13497 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13498 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13498
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13498, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13498, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13498, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13499
13500 if (hf_field->bitmask != 0) {
13501 REPORT_DISSECTOR_BUG("Incompatible use of proto_tree_add_bits_format_value"proto_report_dissector_bug("Incompatible use of proto_tree_add_bits_format_value"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
13502 " with field '%s' (%s) with bitmask != 0",proto_report_dissector_bug("Incompatible use of proto_tree_add_bits_format_value"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
13503 hf_field->abbrev, hf_field->name)proto_report_dissector_bug("Incompatible use of proto_tree_add_bits_format_value"
" with field '%s' (%s) with bitmask != 0", hf_field->abbrev
, hf_field->name)
;
13504 }
13505
13506 if (no_of_bits < 0) {
13507 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13508 } else if (no_of_bits == 0) {
13509 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of 0",proto_report_dissector_bug("field %s passed to proto_tree_add_bits_format_value() has a bit width of 0"
, hf_field->abbrev)
13510 hf_field->abbrev)proto_report_dissector_bug("field %s passed to proto_tree_add_bits_format_value() has a bit width of 0"
, hf_field->abbrev)
;
13511 }
13512
13513 /* Byte align offset */
13514 offset = bit_offset>>3;
13515
13516 /*
13517 * Calculate the number of octets used to hold the bits
13518 */
13519 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13520 length = tot_no_bits>>3;
13521 /* If we are using part of the next octet, increase length by 1 */
13522 if (tot_no_bits & 0x07)
13523 length++;
13524
13525 if (no_of_bits < 65) {
13526 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13527 } else {
13528 REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_format_value() has a bit width of %u > 65",proto_report_dissector_bug("field %s passed to proto_tree_add_bits_format_value() has a bit width of %u > 65"
, hf_field->abbrev, no_of_bits)
13529 hf_field->abbrev, no_of_bits)proto_report_dissector_bug("field %s passed to proto_tree_add_bits_format_value() has a bit width of %u > 65"
, hf_field->abbrev, no_of_bits)
;
13530 return NULL((void*)0);
13531 }
13532
13533 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13534
13535 (void) g_strlcat(str, " = ", 256+64);
13536 (void) g_strlcat(str, hf_field->name, 256+64);
13537
13538 /*
13539 * This function does not receive an actual value but a dimensionless pointer to that value.
13540 * For this reason, the type of the header field is examined in order to determine
13541 * what kind of value we should read from this address.
13542 * The caller of this function must make sure that for the specific header field type the address of
13543 * a compatible value is provided.
13544 */
13545 switch (hf_field->type) {
13546 case FT_BOOLEAN:
13547 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13548 "%s: %s", str, value_str);
13549 break;
13550
13551 case FT_CHAR:
13552 case FT_UINT8:
13553 case FT_UINT16:
13554 case FT_UINT24:
13555 case FT_UINT32:
13556 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13557 "%s: %s", str, value_str);
13558 break;
13559
13560 case FT_UINT40:
13561 case FT_UINT48:
13562 case FT_UINT56:
13563 case FT_UINT64:
13564 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13565 "%s: %s", str, value_str);
13566 break;
13567
13568 case FT_INT8:
13569 case FT_INT16:
13570 case FT_INT24:
13571 case FT_INT32:
13572 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13573 "%s: %s", str, value_str);
13574 break;
13575
13576 case FT_INT40:
13577 case FT_INT48:
13578 case FT_INT56:
13579 case FT_INT64:
13580 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13581 "%s: %s", str, value_str);
13582 break;
13583
13584 case FT_FLOAT:
13585 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13586 "%s: %s", str, value_str);
13587 break;
13588
13589 default:
13590 REPORT_DISSECTOR_BUG("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()",proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13591 hf_field->abbrev,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13592 hf_field->type,proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
13593 ftype_name(hf_field->type))proto_report_dissector_bug("field %s has type %d (%s) not handled in proto_tree_add_bits_format_value()"
, hf_field->abbrev, hf_field->type, ftype_name(hf_field
->type))
;
13594 return NULL((void*)0);
13595 }
13596}
13597
13598static proto_item *
13599proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13600 tvbuff_t *tvb, const unsigned bit_offset,
13601 const int no_of_bits, void *value_ptr,
13602 const unsigned encoding, char *value_str)
13603{
13604 proto_item *item;
13605
13606 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13607 tvb, bit_offset, no_of_bits,
13608 value_ptr, encoding, value_str))) {
13609 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((bit_offset) & 7) <<
5)); } while(0)
;
13610 FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits))do { if (((item)->finfo)) (((item)->finfo))->flags =
(((item)->finfo))->flags | ((((no_of_bits) & 63) <<
8)); } while(0)
;
13611 }
13612 return item;
13613}
13614
13615#define CREATE_VALUE_STRING(tree,dst,format,ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
\
13616 va_start(ap, format)__builtin_va_start(ap, format); \
13617 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13618 va_end(ap)__builtin_va_end(ap);
13619
13620proto_item *
13621proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13622 tvbuff_t *tvb, const unsigned bit_offset,
13623 const int no_of_bits, uint32_t value,
13624 const unsigned encoding,
13625 const char *format, ...)
13626{
13627 va_list ap;
13628 char *dst;
13629 header_field_info *hf_field;
13630
13631 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13632
13633 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13633
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13633, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13633, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13633, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13634
13635 switch (hf_field->type) {
13636 case FT_UINT8:
13637 case FT_UINT16:
13638 case FT_UINT24:
13639 case FT_UINT32:
13640 break;
13641
13642 default:
13643 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hf_field->abbrev)
13644 hf_field->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hf_field->abbrev)
;
13645 return NULL((void*)0);
13646 }
13647
13648 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13649
13650 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13651}
13652
13653proto_item *
13654proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13655 tvbuff_t *tvb, const unsigned bit_offset,
13656 const int no_of_bits, uint64_t value,
13657 const unsigned encoding,
13658 const char *format, ...)
13659{
13660 va_list ap;
13661 char *dst;
13662 header_field_info *hf_field;
13663
13664 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13665
13666 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13666
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13666, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13666, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13666, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13667
13668 switch (hf_field->type) {
13669 case FT_UINT40:
13670 case FT_UINT48:
13671 case FT_UINT56:
13672 case FT_UINT64:
13673 break;
13674
13675 default:
13676 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64",proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hf_field->abbrev)
13677 hf_field->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hf_field->abbrev)
;
13678 return NULL((void*)0);
13679 }
13680
13681 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13682
13683 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13684}
13685
13686proto_item *
13687proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13688 tvbuff_t *tvb, const unsigned bit_offset,
13689 const int no_of_bits, float value,
13690 const unsigned encoding,
13691 const char *format, ...)
13692{
13693 va_list ap;
13694 char *dst;
13695 header_field_info *hf_field;
13696
13697 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13698
13699 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13699
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13699, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13699, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13699, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13700
13701 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_FLOAT)((void) (((hf_field)->type == FT_FLOAT) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_FLOAT", "epan/proto.c",
13701, ((hf_field))->abbrev))))
;
13702
13703 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13704
13705 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13706}
13707
13708proto_item *
13709proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13710 tvbuff_t *tvb, const unsigned bit_offset,
13711 const int no_of_bits, int32_t value,
13712 const unsigned encoding,
13713 const char *format, ...)
13714{
13715 va_list ap;
13716 char *dst;
13717 header_field_info *hf_field;
13718
13719 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13720
13721 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13721
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13721, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13721, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13721, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13722
13723 switch (hf_field->type) {
13724 case FT_INT8:
13725 case FT_INT16:
13726 case FT_INT24:
13727 case FT_INT32:
13728 break;
13729
13730 default:
13731 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32",proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hf_field->abbrev)
13732 hf_field->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hf_field->abbrev)
;
13733 return NULL((void*)0);
13734 }
13735
13736 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13737
13738 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13739}
13740
13741proto_item *
13742proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13743 tvbuff_t *tvb, const unsigned bit_offset,
13744 const int no_of_bits, int64_t value,
13745 const unsigned encoding,
13746 const char *format, ...)
13747{
13748 va_list ap;
13749 char *dst;
13750 header_field_info *hf_field;
13751
13752 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13753
13754 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13754
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13754, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13754, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13754, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13755
13756 switch (hf_field->type) {
13757 case FT_INT40:
13758 case FT_INT48:
13759 case FT_INT56:
13760 case FT_INT64:
13761 break;
13762
13763 default:
13764 REPORT_DISSECTOR_BUG("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64",proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hf_field->abbrev)
13765 hf_field->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hf_field->abbrev)
;
13766 return NULL((void*)0);
13767 }
13768
13769 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13770
13771 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13772}
13773
13774proto_item *
13775proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13776 tvbuff_t *tvb, const unsigned bit_offset,
13777 const int no_of_bits, uint64_t value,
13778 const unsigned encoding,
13779 const char *format, ...)
13780{
13781 va_list ap;
13782 char *dst;
13783 header_field_info *hf_field;
13784
13785 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13786
13787 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hf_field)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13787
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13787, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13787, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13787, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items); ((tree)->
tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf
(((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hf_field->abbrev, prefs.gui_max_tree_items))); } if (!((
(tree)->tree_data)->visible)) { if (proto_item_is_hidden
((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT)
&& (hf_field->ref_type != HF_REF_TYPE_PRINT) &&
(hf_field->type != FT_PROTOCOL || ((tree)->tree_data)->
fake_protocols)) { ((void)0); return proto_tree_add_fake_node
(tree, hf_field); } } }
;
13788
13789 DISSECTOR_ASSERT_FIELD_TYPE(hf_field, FT_BOOLEAN)((void) (((hf_field)->type == FT_BOOLEAN) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_BOOLEAN", "epan/proto.c"
, 13789, ((hf_field))->abbrev))))
;
13790
13791 CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree
)->tree_data->pinfo->pool), format, ap); __builtin_va_end
(ap);
;
13792
13793 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13794}
13795
13796proto_item *
13797proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13798 const unsigned bit_offset, const int no_of_chars)
13799{
13800 proto_item *pi;
13801 header_field_info *hfinfo;
13802 int byte_length;
13803 int byte_offset;
13804 char *string;
13805
13806 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13807
13808 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13808
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13808, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13808, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13808, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
13809
13810 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING)((void) (((hfinfo)->type == FT_STRING) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_STRING", "epan/proto.c"
, 13810, ((hfinfo))->abbrev))))
;
13811
13812 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13813 byte_offset = bit_offset >> 3;
13814
13815 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13816
13817 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13818 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13818, "byte_length >= 0"
))))
;
13819 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13820
13821 return pi;
13822}
13823
13824proto_item *
13825proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13826 const unsigned bit_offset, const int no_of_chars)
13827{
13828 proto_item *pi;
13829 header_field_info *hfinfo;
13830 int byte_length;
13831 int byte_offset;
13832 char *string;
13833
13834 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13835
13836 TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13836
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13836, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13836, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13836, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo)
; } } }
;
13837
13838 DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_STRING)((void) (((hfinfo)->type == FT_STRING) ? (void)0 : (proto_report_dissector_bug
("%s:%u: field %s is not of type ""FT_STRING", "epan/proto.c"
, 13838, ((hfinfo))->abbrev))))
;
13839
13840 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13841 byte_offset = bit_offset >> 3;
13842
13843 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13844
13845 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13846 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13846, "byte_length >= 0"
))))
;
13847 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13848
13849 return pi;
13850}
13851
13852const value_string proto_checksum_vals[] = {
13853 { PROTO_CHECKSUM_E_BAD, "Bad" },
13854 { PROTO_CHECKSUM_E_GOOD, "Good" },
13855 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
13856 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
13857 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
13858
13859 { 0, NULL((void*)0) }
13860};
13861
13862proto_item *
13863proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13864 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
13865 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
13866{
13867 header_field_info *hfinfo;
13868 uint32_t checksum;
13869 uint32_t len;
13870 proto_item* ti = NULL((void*)0);
13871 proto_item* ti2;
13872 bool_Bool incorrect_checksum = true1;
13873
13874 PROTO_REGISTRAR_GET_NTH(hf_checksum, hfinfo)if((hf_checksum == 0 || (unsigned)hf_checksum > gpa_hfinfo
.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13874, __func__, "Unregistered hf! index=%d"
, hf_checksum); ((void) ((hf_checksum > 0 && (unsigned
)hf_checksum < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13874
, "hf_checksum > 0 && (unsigned)hf_checksum < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_checksum
] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13874, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
13875
13876 switch (hfinfo->type) {
13877 case FT_UINT8:
13878 len = 1;
13879 break;
13880 case FT_UINT16:
13881 len = 2;
13882 break;
13883 case FT_UINT24:
13884 len = 3;
13885 break;
13886 case FT_UINT32:
13887 len = 4;
13888 break;
13889 default:
13890 REPORT_DISSECTOR_BUG("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32",proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
13891 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
13892 }
13893
13894 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
13895 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
13896 proto_item_set_generated(ti);
13897 if (hf_checksum_status != -1) {
13898 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
13899 proto_item_set_generated(ti2);
13900 }
13901 return ti;
13902 }
13903
13904 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
13905 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
13906 proto_item_set_generated(ti);
13907 } else {
13908 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
13909 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
13910 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
13911 if (computed_checksum == 0) {
13912 proto_item_append_text(ti, " [correct]");
13913 if (hf_checksum_status != -1) {
13914 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13915 proto_item_set_generated(ti2);
13916 }
13917 incorrect_checksum = false0;
13918 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
13919 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
13920 /* XXX - This can't distinguish between "shouldbe"
13921 * 0x0000 and 0xFFFF unless we know whether there
13922 * were any nonzero bits (other than the checksum).
13923 * Protocols should not use this path if they might
13924 * have an all zero packet.
13925 * Some implementations put the wrong zero; maybe
13926 * we should have a special expert info for that?
13927 */
13928 }
13929 } else {
13930 if (checksum == computed_checksum) {
13931 proto_item_append_text(ti, " [correct]");
13932 if (hf_checksum_status != -1) {
13933 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13934 proto_item_set_generated(ti2);
13935 }
13936 incorrect_checksum = false0;
13937 }
13938 }
13939
13940 if (incorrect_checksum) {
13941 if (hf_checksum_status != -1) {
13942 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
13943 proto_item_set_generated(ti2);
13944 }
13945 if (flags & PROTO_CHECKSUM_ZERO0x08) {
13946 proto_item_append_text(ti, " [incorrect]");
13947 if (bad_checksum_expert != NULL((void*)0))
13948 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
13949 } else {
13950 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
13951 if (bad_checksum_expert != NULL((void*)0))
13952 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);
13953 }
13954 }
13955 } else {
13956 if (hf_checksum_status != -1) {
13957 proto_item_append_text(ti, " [unverified]");
13958 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
13959 proto_item_set_generated(ti2);
13960 }
13961 }
13962 }
13963
13964 return ti;
13965}
13966
13967proto_item *
13968proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13969 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
13970 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
13971{
13972 header_field_info *hfinfo;
13973 uint8_t *checksum = NULL((void*)0);
13974 proto_item* ti = NULL((void*)0);
13975 proto_item* ti2;
13976 bool_Bool incorrect_checksum = true1;
13977
13978 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", 13978, __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", 13978
, "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", 13978, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
13979
13980 if (hfinfo->type != FT_BYTES) {
13981 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)
13982 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
13983 }
13984
13985 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
13986 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
13987 proto_item_set_generated(ti);
13988 if (hf_checksum_status != -1) {
13989 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
13990 proto_item_set_generated(ti2);
13991 }
13992 return ti;
13993 }
13994
13995 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
13996 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
13997 proto_item_set_generated(ti);
13998 } else {
13999 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
))))))
;
14000 tvb_memcpy(tvb, checksum, offset, checksum_len);
14001 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14002 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14003 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14004 if (computed_checksum == 0) {
14005 proto_item_append_text(ti, " [correct]");
14006 if (hf_checksum_status != -1) {
14007 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14008 proto_item_set_generated(ti2);
14009 }
14010 incorrect_checksum = false0;
14011 }
14012 } else {
14013 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14014 proto_item_append_text(ti, " [correct]");
14015 if (hf_checksum_status != -1) {
14016 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14017 proto_item_set_generated(ti2);
14018 }
14019 incorrect_checksum = false0;
14020 }
14021 }
14022
14023 if (incorrect_checksum) {
14024 if (hf_checksum_status != -1) {
14025 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14026 proto_item_set_generated(ti2);
14027 }
14028 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14029 proto_item_append_text(ti, " [incorrect]");
14030 if (bad_checksum_expert != NULL((void*)0))
14031 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14032 } else {
14033 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14034 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))))))
;
14035 for (size_t counter = 0; counter < checksum_len; ++counter) {
14036 snprintf(
14037 /* On ecah iteration inserts two characters */
14038 (char*)&computed_checksum_str[counter << 1],
14039 computed_checksum_str_len - (counter << 1),
14040 "%02x",
14041 computed_checksum[counter]);
14042 }
14043 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14044 if (bad_checksum_expert != NULL((void*)0))
14045 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14046 }
14047 }
14048 } else {
14049 if (hf_checksum_status != -1) {
14050 proto_item_append_text(ti, " [unverified]");
14051 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14052 proto_item_set_generated(ti2);
14053 }
14054 }
14055 }
14056
14057 return ti;
14058}
14059
14060unsigned char
14061proto_check_field_name(const char *field_name)
14062{
14063 return module_check_valid_name(field_name, false0);
14064}
14065
14066unsigned char
14067proto_check_field_name_lower(const char *field_name)
14068{
14069 return module_check_valid_name(field_name, true1);
14070}
14071
14072bool_Bool
14073tree_expanded(int tree_type)
14074{
14075 if (tree_type <= 0) {
14076 return false0;
14077 }
14078 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", 14078, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14079 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14080}
14081
14082void
14083tree_expanded_set(int tree_type, bool_Bool value)
14084{
14085 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", 14085, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14086
14087 if (value)
14088 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14089 else
14090 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14091}
14092
14093/*
14094 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14095 *
14096 * Local variables:
14097 * c-basic-offset: 8
14098 * tab-width: 8
14099 * indent-tabs-mode: t
14100 * End:
14101 *
14102 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14103 * :indentSize=8:tabSize=8:noTabs=false:
14104 */