Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name proto.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-18/lib/clang/18 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/libxml2 -isystem /usr/include/lua5.4 -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-truncation -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -dwarf-debug-flags /usr/lib/llvm-18/bin/clang -### --analyze -x c -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/libxml2 -isystem /usr/include/lua5.4 -fvisibility=hidden -fexcess-precision=fast -fstrict-flex-arrays=3 -fstack-clash-protection -fcf-protection=full -D _GLIBCXX_ASSERTIONS -fstack-protector-strong -fno-delete-null-pointer-checks -fno-strict-overflow -fno-strict-aliasing -fexceptions -Wno-format-truncation -Wno-format-nonliteral -fdiagnostics-color=always -Wno-pointer-sign -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -std=gnu11 -fPIC /builds/wireshark/wireshark/epan/proto.c -o /builds/wireshark/wireshark/sbout/2024-10-21-100301-3898-1 -Xclang -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2024-10-21-100301-3898-1 -x c /builds/wireshark/wireshark/epan/proto.c
1/* proto.c
2 * Routines for protocol tree
3 *
4 * Wireshark - Network traffic analyzer
5 * By Gerald Combs <gerald@wireshark.org>
6 * Copyright 1998 Gerald Combs
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11#include "config.h"
12#define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13
14#include <stdio.h>
15#include <string.h>
16#include <glib.h>
17#include <float.h>
18#include <inttypes.h>
19#include <errno(*__errno_location ()).h>
20
21#include <epan/tfs.h>
22#include <epan/unit_strings.h>
23
24#include <wsutil/array.h>
25#include <wsutil/bits_ctz.h>
26#include <wsutil/bits_count_ones.h>
27#include <wsutil/sign_ext.h>
28#include <wsutil/utf8_entities.h>
29#include <wsutil/json_dumper.h>
30#include <wsutil/wslog.h>
31#include <wsutil/ws_assert.h>
32#include <wsutil/unicode-utils.h>
33
34#include <ftypes/ftypes.h>
35
36#include "packet.h"
37#include "exceptions.h"
38#include "ptvcursor.h"
39#include "strutil.h"
40#include "addr_resolv.h"
41#include "address_types.h"
42#include "oids.h"
43#include "proto.h"
44#include "epan_dissect.h"
45#include "dfilter/dfilter.h"
46#include "tvbuff.h"
47#include <epan/wmem_scopes.h>
48#include "charsets.h"
49#include "column-info.h"
50#include "to_str.h"
51#include "osi-utils.h"
52#include "expert.h"
53#include "show_exception.h"
54#include "in_cksum.h"
55#include "register-int.h"
56
57#include <wsutil/crash_info.h>
58#include <wsutil/epochs.h>
59
60/* Ptvcursor limits */
61#define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62#define SUBTREE_MAX_LEVELS256 256
63
64typedef struct __subtree_lvl {
65 int cursor_offset;
66 proto_item *it;
67 proto_tree *tree;
68} subtree_lvl;
69
70struct ptvcursor {
71 wmem_allocator_t *scope;
72 subtree_lvl *pushed_tree;
73 uint8_t pushed_tree_index;
74 uint8_t pushed_tree_max;
75 proto_tree *tree;
76 tvbuff_t *tvb;
77 int offset;
78};
79
80#define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81
82/** See inlined comments.
83 @param tree the tree to append this item to
84 @param free_block a code block to call to free resources if this returns
85 @return NULL if 'tree' is null */
86#define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 if (!tree) { \
88 free_block; \
89 return NULL((void*)0); \
90 }
91
92/** See inlined comments.
93 @param tree the tree to append this item to
94 @param free_block a code block to call to free resources if this returns
95 @return NULL if 'tree' is null */
96#define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
97 CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
98
99/** See inlined comments.
100 @param length the length of this item
101 @param cleanup_block a code block to call to free resources if this returns
102 @return NULL if 'length' is lower -1 or equal 0 */
103#define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return (
(void*)0); }
\
104 if (length < -1 || length == 0 ) { \
105 cleanup_block; \
106 return NULL((void*)0); \
107 }
108
109/** See inlined comments.
110 @param length the length of this item
111 @return NULL if 'length' is lower -1 or equal 0 */
112#define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
\
113 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
114
115/** See inlined comments.
116 @param tree the tree to append this item to
117 @param hfindex field index
118 @param hfinfo header_field
119 @param free_block a code block to call to free resources if this returns
120 @return the header field matching 'hfinfo' */
121#define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned
)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 121
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 121, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 121, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 121, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { free_block; return tree; } } }
\
122 /* If the tree is not visible and this item is not referenced \
123 we don't have to do much work at all but we should still \
124 return a node so that referenced field items below this node \
125 (think proto_item_add_subtree()) will still have somewhere \
126 to attach to or else filtering will not work (they would be \
127 ignored since tree would be NULL). \
128 DON'T try to fake a node where PTREE_FINFO(tree) is NULL \
129 since dissectors that want to do proto_item_set_len() or \
130 other operations that dereference this would crash. \
131 DON'T try to fake a node where PTREE_FINFO(tree) is visible \
132 because that means we can change its length or repr, and we \
133 don't want to do so with calls intended for this faked new \
134 item, so this item needs a new (hidden) child node. \
135 (PROTO_ITEM_IS_HIDDEN(tree) checks both conditions.) \
136 We fake FT_PROTOCOL unless some clients have requested us \
137 not to do so. \
138 */ \
139 PTREE_DATA(tree)((tree)->tree_data)->count++; \
140 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", 140, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 140, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 140, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
; \
141 if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
142 free_block; \
143 if (wireshark_abort_on_too_many_items) \
144 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", 145
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
145 hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 145
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items)
; \
146 /* Let the exception handler add items to the tree */ \
147 PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
148 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)))
149 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)))
150 "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)))
151 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)))
; \
152 } \
153 if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
154 if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
155 if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
156 && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
157 && (hfinfo->type != FT_PROTOCOL || \
158 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
159 free_block; \
160 /* just return tree back to the caller */\
161 return tree; \
162 } \
163 } \
164 }
165
166/** See inlined comments.
167 @param tree the tree to append this item to
168 @param hfindex field index
169 @param hfinfo header_field
170 @return the header field matching 'hfinfo' */
171#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", 171
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 171, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 171, "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", 171, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
\
172 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", 172
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 172, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 172, "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", 172, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
173
174
175/** See inlined comments.
176 @param pi the created protocol item we're about to return */
177#define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 177, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
\
178 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 178, __func__, "assertion failed: %s", "pi"
); } while (0)
; \
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) return; if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return; }
\
187 if (!pi) \
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)->tree_data)->visible
) && proto_item_is_hidden((pi)))) { return pi; }
\
197 if ((pi == 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 void
280get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
281 int *item_length, const unsigned encoding);
282
283static int
284get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
285 int length, unsigned item_length, const int encoding);
286
287static field_info *
288new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
289 const int start, const int item_length);
290
291static proto_item *
292proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
293 int start, int *length);
294
295static void
296proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
297static void
298proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
299
300static void
301proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
302static void
303proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
304static void
305proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
306static void
307proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
308static void
309proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
310static void
311proto_tree_set_string(field_info *fi, const char* value);
312static void
313proto_tree_set_ax25(field_info *fi, const uint8_t* value);
314static void
315proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
316static void
317proto_tree_set_vines(field_info *fi, const uint8_t* value);
318static void
319proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
320static void
321proto_tree_set_ether(field_info *fi, const uint8_t* value);
322static void
323proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
324static void
325proto_tree_set_ipxnet(field_info *fi, uint32_t value);
326static void
327proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
328static void
329proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
330static void
331proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
332static void
333proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
334static void
335proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
336static void
337proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
338static void
339proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
340static void
341proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
342static void
343proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
344static void
345proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
346static void
347proto_tree_set_boolean(field_info *fi, uint64_t value);
348static void
349proto_tree_set_float(field_info *fi, float value);
350static void
351proto_tree_set_double(field_info *fi, double value);
352static void
353proto_tree_set_uint(field_info *fi, uint32_t value);
354static void
355proto_tree_set_int(field_info *fi, int32_t value);
356static void
357proto_tree_set_uint64(field_info *fi, uint64_t value);
358static void
359proto_tree_set_int64(field_info *fi, int64_t value);
360static void
361proto_tree_set_eui64(field_info *fi, const uint64_t value);
362static void
363proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
364
365/* Handle type length mismatch (now filterable) expert info */
366static int proto_type_length_mismatch;
367static expert_field ei_type_length_mismatch_error;
368static expert_field ei_type_length_mismatch_warn;
369static void register_type_length_mismatch(void);
370
371/* Handle byte array string decoding errors with expert info */
372static int proto_byte_array_string_decoding_error;
373static expert_field ei_byte_array_string_decoding_failed_error;
374static void register_byte_array_string_decodinws_error(void);
375
376/* Handle date and time string decoding errors with expert info */
377static int proto_date_time_string_decoding_error;
378static expert_field ei_date_time_string_decoding_failed_error;
379static void register_date_time_string_decodinws_error(void);
380
381/* Handle string errors expert info */
382static int proto_string_errors;
383static expert_field ei_string_trailing_characters;
384static void register_string_errors(void);
385
386static int proto_register_field_init(header_field_info *hfinfo, const int parent);
387
388/* special-case header field used within proto.c */
389static header_field_info hfi_text_only =
390 { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
391int hf_text_only;
392
393/* Structure for information about a protocol */
394struct _protocol {
395 const char *name; /* long description */
396 const char *short_name; /* short description */
397 const char *filter_name; /* name of this protocol in filters */
398 GPtrArray *fields; /* fields for this protocol */
399 int proto_id; /* field ID for this protocol */
400 bool_Bool is_enabled; /* true if protocol is enabled */
401 bool_Bool enabled_by_default; /* true if protocol is enabled by default */
402 bool_Bool can_toggle; /* true if is_enabled can be changed */
403 int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
404 For dissectors that need a protocol name so they
405 can be added to a dissector table, but use the
406 parent_proto_id for things like enable/disable */
407 GList *heur_list; /* Heuristic dissectors associated with this protocol */
408};
409
410/* List of all protocols */
411static GList *protocols;
412
413/* Structure stored for deregistered g_slice */
414struct g_slice_data {
415 size_t block_size;
416 void *mem_block;
417};
418
419/* Deregistered fields */
420static GPtrArray *deregistered_fields;
421static GPtrArray *deregistered_data;
422static GPtrArray *deregistered_slice;
423
424/* indexed by prefix, contains initializers */
425static GHashTable* prefixes;
426
427/* Contains information about a field when a dissector calls
428 * proto_tree_add_item. */
429#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)))
430#define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
431
432/* Contains the space for proto_nodes. */
433#define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void
*)0); node->next = ((void*)0);
\
434 node->first_child = NULL((void*)0); \
435 node->last_child = NULL((void*)0); \
436 node->next = NULL((void*)0);
437
438#define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
439 wmem_free(pool, node)
440
441/* String space for protocol and field items for the GUI */
442#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;
\
443 il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
444 il->value_pos = 0; \
445 il->value_len = 0;
446#define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
447 wmem_free(pool, il);
448
449#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", 449, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 449, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 449, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
\
450 if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
451 ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 451
, __func__, "Unregistered hf! index=%d", hfindex)
; \
452 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", 452, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!"))))
; \
453 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", 453, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!"))))
; \
454 hfinfo = gpa_hfinfo.hfi[hfindex];
455
456/* List which stores protocols and fields that have been registered */
457typedef struct _gpa_hfinfo_t {
458 uint32_t len;
459 uint32_t allocated_len;
460 header_field_info **hfi;
461} gpa_hfinfo_t;
462
463static gpa_hfinfo_t gpa_hfinfo;
464
465/* Hash table of abbreviations and IDs */
466static GHashTable *gpa_name_map;
467static header_field_info *same_name_hfinfo;
468
469/* Hash table protocol aliases. const char * -> const char * */
470static GHashTable *gpa_protocol_aliases;
471
472/*
473 * We're called repeatedly with the same field name when sorting a column.
474 * Cache our last gpa_name_map hit for faster lookups.
475 */
476static char *last_field_name;
477static header_field_info *last_hfinfo;
478
479static void save_same_name_hfinfo(void *data)
480{
481 same_name_hfinfo = (header_field_info*)data;
482}
483
484/* Points to the first element of an array of bits, indexed by
485 a subtree item type; that array element is true if subtrees of
486 an item of that type are to be expanded. */
487static uint32_t *tree_is_expanded;
488
489/* Number of elements in that array. The entry with index 0 is not used. */
490int num_tree_types = 1;
491
492/* Name hashtables for fast detection of duplicate names */
493static GHashTable* proto_names;
494static GHashTable* proto_short_names;
495static GHashTable* proto_filter_names;
496
497static const char *reserved_filter_names[] = {
498 /* Display filter keywords. */
499 "eq",
500 "ne",
501 "all_eq",
502 "any_eq",
503 "all_ne",
504 "any_ne",
505 "gt",
506 "ge",
507 "lt",
508 "le",
509 "bitand",
510 "bitwise_and",
511 "contains",
512 "matches",
513 "not",
514 "and",
515 "or",
516 "xor",
517 "in",
518 "any",
519 "all",
520 "true",
521 "false",
522 "nan",
523 "inf",
524 NULL((void*)0)
525};
526
527static GHashTable *proto_reserved_filter_names;
528
529static int
530proto_compare_name(const void *p1_arg, const void *p2_arg)
531{
532 const protocol_t *p1 = (const protocol_t *)p1_arg;
533 const protocol_t *p2 = (const protocol_t *)p2_arg;
534
535 return g_ascii_strcasecmp(p1->short_name, p2->short_name);
536}
537
538static GSList *dissector_plugins;
539
540#ifdef HAVE_PLUGINS1
541void
542proto_register_plugin(const proto_plugin *plug)
543{
544 dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
545}
546#else /* HAVE_PLUGINS */
547void
548proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
549{
550 ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 550, __func__, "proto_register_plugin: built without support for binary plugins"
); } } while (0)
;
551}
552#endif /* HAVE_PLUGINS */
553
554static void
555call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
556{
557 proto_plugin *plug = (proto_plugin *)data;
558
559 if (plug->register_protoinfo) {
560 plug->register_protoinfo();
561 }
562}
563
564static void
565call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
566{
567 proto_plugin *plug = (proto_plugin *)data;
568
569 if (plug->register_handoff) {
570 plug->register_handoff();
571 }
572}
573
574/* initialize data structures and register protocols and fields */
575void
576proto_init(GSList *register_all_plugin_protocols_list,
577 GSList *register_all_plugin_handoffs_list,
578 register_cb cb,
579 void *client_data)
580{
581 proto_cleanup_base();
582
583 proto_names = g_hash_table_new(g_str_hash, g_str_equal);
584 proto_short_names = g_hash_table_new(g_str_hash, g_str_equal);
585 proto_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
586
587 proto_reserved_filter_names = g_hash_table_new(g_str_hash, g_str_equal);
588 for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
589 /* GHashTable has no key destructor so the cast is safe. */
590 g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
591 }
592
593 gpa_hfinfo.len = 0;
594 gpa_hfinfo.allocated_len = 0;
595 gpa_hfinfo.hfi = NULL((void*)0);
596 gpa_name_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL((void*)0), save_same_name_hfinfo);
597 gpa_protocol_aliases = g_hash_table_new(g_str_hash, g_str_equal);
598 deregistered_fields = g_ptr_array_new();
599 deregistered_data = g_ptr_array_new();
600 deregistered_slice = g_ptr_array_new();
601
602 /* Initialize the ftype subsystem */
603 ftypes_initialize();
604
605 /* Initialize the address type subsystem */
606 address_types_initialize();
607
608 /* Register one special-case FT_TEXT_ONLY field for use when
609 converting wireshark to new-style proto_tree. These fields
610 are merely strings on the GUI tree; they are not filterable */
611 hf_text_only = proto_register_field_init(&hfi_text_only, -1);
612
613 /* Register the pseudo-protocols used for exceptions. */
614 register_show_exception();
615 register_type_length_mismatch();
616 register_byte_array_string_decodinws_error();
617 register_date_time_string_decodinws_error();
618 register_string_errors();
619 ftypes_register_pseudofields();
620 col_register_protocol();
621
622 /* Have each built-in dissector register its protocols, fields,
623 dissector tables, and dissectors to be called through a
624 handle, and do whatever one-time initialization it needs to
625 do. */
626 register_all_protocols(cb, client_data);
627
628 /* Now call the registration routines for all epan plugins. */
629 for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
630 ((void (*)(register_cb, void *))l->data)(cb, client_data);
631 }
632
633 /* Now call the registration routines for all dissector plugins. */
634 if (cb)
635 (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
636 g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
637
638 /* Now call the "handoff registration" routines of all built-in
639 dissectors; those routines register the dissector in other
640 dissectors' handoff tables, and fetch any dissector handles
641 they need. */
642 register_all_protocol_handoffs(cb, client_data);
643
644 /* Now do the same with epan plugins. */
645 for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
646 ((void (*)(register_cb, void *))l->data)(cb, client_data);
647 }
648
649 /* Now do the same with dissector plugins. */
650 if (cb)
651 (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
652 g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
653
654 /* sort the protocols by protocol name */
655 protocols = g_list_sort(protocols, proto_compare_name);
656
657 /* sort the dissector handles in dissector tables (for -G reports
658 * and -d error messages. The GUI sorts the handles itself.) */
659 packet_all_tables_sort_handles();
660
661 /* We've assigned all the subtree type values; allocate the array
662 for them, and zero it out. */
663 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
)))
;
664}
665
666static void
667proto_cleanup_base(void)
668{
669 protocol_t *protocol;
670 header_field_info *hfinfo;
671
672 /* Free the abbrev/ID hash table */
673 if (gpa_name_map) {
674 g_hash_table_destroy(gpa_name_map);
675 gpa_name_map = NULL((void*)0);
676 }
677 if (gpa_protocol_aliases) {
678 g_hash_table_destroy(gpa_protocol_aliases);
679 gpa_protocol_aliases = NULL((void*)0);
680 }
681 g_free(last_field_name);
682 last_field_name = NULL((void*)0);
683
684 while (protocols) {
685 protocol = (protocol_t *)protocols->data;
686 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", 686
, __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", 686, "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", 686, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol->
proto_id];
;
687 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", 687, "protocol->proto_id == hfinfo->id"
))))
;
688
689 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)
;
690 if (protocol->parent_proto_id != -1) {
691 // pino protocol
692 DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 692, "protocol->fields == ((void*)0)"
))))
; //helpers should not have any registered fields
693 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"
, 693, "protocol->heur_list == ((void*)0)"))))
; //helpers should not have a heuristic list
694 } else {
695 if (protocol->fields) {
696 g_ptr_array_free(protocol->fields, true1);
697 }
698 g_list_free(protocol->heur_list);
699 }
700 protocols = g_list_remove(protocols, protocol);
701 g_free(protocol);
702 }
703
704 if (proto_names) {
705 g_hash_table_destroy(proto_names);
706 proto_names = NULL((void*)0);
707 }
708
709 if (proto_short_names) {
710 g_hash_table_destroy(proto_short_names);
711 proto_short_names = NULL((void*)0);
712 }
713
714 if (proto_filter_names) {
715 g_hash_table_destroy(proto_filter_names);
716 proto_filter_names = NULL((void*)0);
717 }
718
719 if (proto_reserved_filter_names) {
720 g_hash_table_destroy(proto_reserved_filter_names);
721 proto_reserved_filter_names = NULL((void*)0);
722 }
723
724 if (gpa_hfinfo.allocated_len) {
725 gpa_hfinfo.len = 0;
726 gpa_hfinfo.allocated_len = 0;
727 g_free(gpa_hfinfo.hfi);
728 gpa_hfinfo.hfi = NULL((void*)0);
729 }
730
731 if (deregistered_fields) {
732 g_ptr_array_free(deregistered_fields, true1);
733 deregistered_fields = NULL((void*)0);
734 }
735
736 if (deregistered_data) {
737 g_ptr_array_free(deregistered_data, true1);
738 deregistered_data = NULL((void*)0);
739 }
740
741 if (deregistered_slice) {
742 g_ptr_array_free(deregistered_slice, true1);
743 deregistered_slice = NULL((void*)0);
744 }
745
746 g_free(tree_is_expanded);
747 tree_is_expanded = NULL((void*)0);
748
749 if (prefixes)
750 g_hash_table_destroy(prefixes);
751}
752
753void
754proto_cleanup(void)
755{
756 proto_free_deregistered_fields();
757 proto_cleanup_base();
758
759 g_slist_free(dissector_plugins);
760 dissector_plugins = NULL((void*)0);
761}
762
763static bool_Bool
764// NOLINTNEXTLINE(misc-no-recursion)
765proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
766 void *data)
767{
768 proto_node *pnode = tree;
769 proto_node *child;
770 proto_node *current;
771
772 if (func(pnode, data))
773 return true1;
774
775 child = pnode->first_child;
776 while (child != NULL((void*)0)) {
777 /*
778 * The routine we call might modify the child, e.g. by
779 * freeing it, so we get the child's successor before
780 * calling that routine.
781 */
782 current = child;
783 child = current->next;
784 // We recurse here, but we're limited by prefs.gui_max_tree_depth
785 if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
786 return true1;
787 }
788
789 return false0;
790}
791
792void
793proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
794 void *data)
795{
796 proto_node *node = tree;
797 proto_node *current;
798
799 if (!node)
800 return;
801
802 node = node->first_child;
803 while (node != NULL((void*)0)) {
804 current = node;
805 node = current->next;
806 func((proto_tree *)current, data);
807 }
808}
809
810static void
811free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
812{
813 GPtrArray *ptrs = (GPtrArray *)value;
814 int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
815 header_field_info *hfinfo;
816
817 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", 817, __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", 817, "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", 817, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
818 if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
819 /* when a field is referenced by a filter this also
820 affects the refcount for the parent protocol so we need
821 to adjust the refcount for the parent as well
822 */
823 if (hfinfo->parent != -1) {
824 header_field_info *parent_hfinfo;
825 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", 825
, __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", 825, "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", 825, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)"
, "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo
->parent];
;
826 parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
827 }
828 hfinfo->ref_type = HF_REF_TYPE_NONE;
829 }
830
831 g_ptr_array_free(ptrs, true1);
832}
833
834static void
835proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
836{
837 field_info *finfo = PNODE_FINFO(node)((node)->finfo);
838
839 proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
840
841 fvalue_free(finfo->value);
842 finfo->value = NULL((void*)0);
843}
844
845void
846proto_tree_reset(proto_tree *tree)
847{
848 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
849
850 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
851
852 /* free tree data */
853 if (tree_data->interesting_hfids) {
854 /* Free all the GPtrArray's in the interesting_hfids hash. */
855 g_hash_table_foreach(tree_data->interesting_hfids,
856 free_GPtrArray_value, NULL((void*)0));
857
858 /* And then remove all values. */
859 g_hash_table_remove_all(tree_data->interesting_hfids);
860 }
861
862 /* Reset track of the number of children */
863 tree_data->count = 0;
864
865 PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void
*)0); tree->next = ((void*)0);
;
866}
867
868/* frees the resources that the dissection a proto_tree uses */
869void
870proto_tree_free(proto_tree *tree)
871{
872 tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
873
874 proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
875
876 /* free tree data */
877 if (tree_data->interesting_hfids) {
878 /* Free all the GPtrArray's in the interesting_hfids hash. */
879 g_hash_table_foreach(tree_data->interesting_hfids,
880 free_GPtrArray_value, NULL((void*)0));
881
882 /* And then destroy the hash. */
883 g_hash_table_destroy(tree_data->interesting_hfids);
884 }
885
886 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)
;
887
888 g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else
(void) ((proto_tree*) 0 == (tree)); } while (0)
;
889}
890
891/* Is the parsing being done for a visible proto_tree or an invisible one?
892 * By setting this correctly, the proto_tree creation is sped up by not
893 * having to call vsnprintf and copy strings around.
894 */
895bool_Bool
896proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
897{
898 bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
899
900 PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
901
902 return old_visible;
903}
904
905void
906proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
907{
908 if (tree)
909 PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
910}
911
912/* Assume dissector set only its protocol fields.
913 This function is called by dissectors and allows the speeding up of filtering
914 in wireshark; if this function returns false it is safe to reset tree to NULL
915 and thus skip calling most of the expensive proto_tree_add_...()
916 functions.
917 If the tree is visible we implicitly assume the field is referenced.
918*/
919bool_Bool
920proto_field_is_referenced(proto_tree *tree, int proto_id)
921{
922 register header_field_info *hfinfo;
923
924
925 if (!tree)
926 return false0;
927
928 if (PTREE_DATA(tree)((tree)->tree_data)->visible)
929 return true1;
930
931 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", 931, __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", 931, "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", 931, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
932 if (hfinfo->ref_type != HF_REF_TYPE_NONE)
933 return true1;
934
935 if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
936 return true1;
937
938 return false0;
939}
940
941
942/* Finds a record in the hfinfo array by id. */
943header_field_info *
944proto_registrar_get_nth(unsigned hfindex)
945{
946 register header_field_info *hfinfo;
947
948 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", 948, __func__, "Unregistered hf! index=%d",
hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 948, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 948, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
949 return hfinfo;
950}
951
952
953/* Prefix initialization
954 * this allows for a dissector to register a display filter name prefix
955 * so that it can delay the initialization of the hf array as long as
956 * possible.
957 */
958
959/* compute a hash for the part before the dot of a display filter */
960static unsigned
961prefix_hash (const void *key) {
962 /* end the string at the dot and compute its hash */
963 char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
964 char* c = copy;
965 unsigned tmp;
966
967 for (; *c; c++) {
968 if (*c == '.') {
969 *c = 0;
970 break;
971 }
972 }
973
974 tmp = g_str_hash(copy);
975 g_free(copy);
976 return tmp;
977}
978
979/* are both strings equal up to the end or the dot? */
980static gboolean
981prefix_equal (const void *ap, const void *bp) {
982 const char* a = (const char *)ap;
983 const char* b = (const char *)bp;
984
985 do {
986 char ac = *a++;
987 char bc = *b++;
988
989 if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
990
991 if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
992 if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
993
994 if (ac != bc) return FALSE(0);
995 } while (1);
996
997 return FALSE(0);
998}
999
1000/* Register a new prefix for "delayed" initialization of field arrays */
1001void
1002proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1003 if (! prefixes ) {
1004 prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1005 }
1006
1007 g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1008}
1009
1010/* helper to call all prefix initializers */
1011static gboolean
1012initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1013 ((prefix_initializer_t)v)((const char *)k);
1014 return TRUE(!(0));
1015}
1016
1017/** Initialize every remaining uninitialized prefix. */
1018void
1019proto_initialize_all_prefixes(void) {
1020 g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1021}
1022
1023/* Finds a record in the hfinfo array by name.
1024 * If it fails to find it in the already registered fields,
1025 * it tries to find and call an initializer in the prefixes
1026 * table and if so it looks again.
1027 */
1028
1029header_field_info *
1030proto_registrar_get_byname(const char *field_name)
1031{
1032 header_field_info *hfinfo;
1033 prefix_initializer_t pi;
1034
1035 if (!field_name)
1036 return NULL((void*)0);
1037
1038 if (g_strcmp0(field_name, last_field_name) == 0) {
1039 return last_hfinfo;
1040 }
1041
1042 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1043
1044 if (hfinfo) {
1045 g_free(last_field_name);
1046 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1047 last_hfinfo = hfinfo;
1048 return hfinfo;
1049 }
1050
1051 if (!prefixes)
1052 return NULL((void*)0);
1053
1054 if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1055 pi(field_name);
1056 g_hash_table_remove(prefixes, field_name);
1057 } else {
1058 return NULL((void*)0);
1059 }
1060
1061 hfinfo = (header_field_info *)g_hash_table_lookup(gpa_name_map, field_name);
1062
1063 if (hfinfo) {
1064 g_free(last_field_name);
1065 last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1066 last_hfinfo = hfinfo;
1067 }
1068 return hfinfo;
1069}
1070
1071header_field_info*
1072proto_registrar_get_byalias(const char *alias_name)
1073{
1074 if (!alias_name) {
1075 return NULL((void*)0);
1076 }
1077
1078 /* Find our aliased protocol. */
1079 char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1080 char *dot = strchr(an_copy, '.');
1081 if (dot) {
1082 *dot = '\0';
1083 }
1084 const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1085 if (!proto_pfx) {
1086 g_free(an_copy);
1087 return NULL((void*)0);
1088 }
1089
1090 /* Construct our aliased field and look it up. */
1091 GString *filter_name = g_string_new(proto_pfx);
1092 if (dot) {
1093 g_string_append_printf(filter_name, ".%s", dot+1);
1094 }
1095 header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1096 g_free(an_copy);
1097 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)))))
;
1098
1099 return hfinfo;
1100}
1101
1102int
1103proto_registrar_get_id_byname(const char *field_name)
1104{
1105 header_field_info *hfinfo;
1106
1107 hfinfo = proto_registrar_get_byname(field_name);
1108
1109 if (!hfinfo)
1110 return -1;
1111
1112 return hfinfo->id;
1113}
1114
1115static int
1116label_strcat_flags(const header_field_info *hfinfo)
1117{
1118 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1119 return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1120
1121 return 0;
1122}
1123
1124static char *
1125format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1126 const uint8_t *bytes, unsigned length, size_t max_str_len)
1127{
1128 char *str = NULL((void*)0);
1129 const uint8_t *p;
1130 bool_Bool is_printable;
1131
1132 if (bytes) {
1133 if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1134 /*
1135 * If all bytes are valid and printable UTF-8, show the
1136 * bytes as a string - in quotes to indicate that it's
1137 * a string.
1138 */
1139 if (isprint_utf8_string(bytes, length)) {
1140 str = wmem_strdup_printf(scope, "\"%.*s\"",
1141 (int)length, bytes);
1142 return str;
1143 }
1144 } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1145 /*
1146 * Check whether all bytes are printable.
1147 */
1148 is_printable = true1;
1149 for (p = bytes; p < bytes+length; p++) {
1150 if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1151 /* Not printable. */
1152 is_printable = false0;
1153 break;
1154 }
1155 }
1156
1157 /*
1158 * If all bytes are printable ASCII, show the bytes
1159 * as a string - in quotes to indicate that it's
1160 * a string.
1161 */
1162 if (is_printable) {
1163 str = wmem_strdup_printf(scope, "\"%.*s\"",
1164 (int)length, bytes);
1165 return str;
1166 }
1167 }
1168
1169 /*
1170 * Either it's not printable ASCII, or we don't care whether
1171 * it's printable ASCII; show it as hex bytes.
1172 */
1173 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1174 case SEP_DOT:
1175 str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1176 break;
1177 case SEP_DASH:
1178 str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1179 break;
1180 case SEP_COLON:
1181 str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1182 break;
1183 case SEP_SPACE:
1184 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1185 break;
1186 case BASE_NONE:
1187 default:
1188 if (prefs.display_byte_fields_with_spaces) {
1189 str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1190 } else {
1191 str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1192 }
1193 break;
1194 }
1195 }
1196 else {
1197 if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1198 str = wmem_strdup(scope, "<none>");
1199 } else {
1200 str = wmem_strdup(scope, "<MISSING>");
1201 }
1202 }
1203 return str;
1204}
1205
1206static char *
1207format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1208 const uint8_t *bytes, unsigned length)
1209{
1210 return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1211}
1212
1213static void
1214ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1215{
1216 subtree_lvl *pushed_tree;
1217
1218 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"
, 1218, "ptvc->pushed_tree_max <= 256-8"))))
;
1219 ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1220
1221 pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1222 DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1222, "pushed_tree != ((void*)0)"
))))
;
1223 ptvc->pushed_tree = pushed_tree;
1224}
1225
1226static void
1227ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1228{
1229 ptvc->pushed_tree = NULL((void*)0);
1230 ptvc->pushed_tree_max = 0;
1231 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", 1231, "ptvc->pushed_tree_index == 0"
))))
;
1232 ptvc->pushed_tree_index = 0;
1233}
1234
1235/* Allocates an initializes a ptvcursor_t with 3 variables:
1236 * proto_tree, tvbuff, and offset. */
1237ptvcursor_t *
1238ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1239{
1240 ptvcursor_t *ptvc;
1241
1242 ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1243 ptvc->scope = scope;
1244 ptvc->tree = tree;
1245 ptvc->tvb = tvb;
1246 ptvc->offset = offset;
1247 ptvc->pushed_tree = NULL((void*)0);
1248 ptvc->pushed_tree_max = 0;
1249 ptvc->pushed_tree_index = 0;
1250 return ptvc;
1251}
1252
1253
1254/* Frees memory for ptvcursor_t, but nothing deeper than that. */
1255void
1256ptvcursor_free(ptvcursor_t *ptvc)
1257{
1258 ptvcursor_free_subtree_levels(ptvc);
1259 /*g_free(ptvc);*/
1260}
1261
1262/* Returns tvbuff. */
1263tvbuff_t *
1264ptvcursor_tvbuff(ptvcursor_t *ptvc)
1265{
1266 return ptvc->tvb;
1267}
1268
1269/* Returns current offset. */
1270int
1271ptvcursor_current_offset(ptvcursor_t *ptvc)
1272{
1273 return ptvc->offset;
1274}
1275
1276proto_tree *
1277ptvcursor_tree(ptvcursor_t *ptvc)
1278{
1279 if (!ptvc)
1280 return NULL((void*)0);
1281
1282 return ptvc->tree;
1283}
1284
1285void
1286ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1287{
1288 ptvc->tree = tree;
1289}
1290
1291/* creates a subtree, sets it as the working tree and pushes the old working tree */
1292proto_tree *
1293ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1294{
1295 subtree_lvl *subtree;
1296 if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1297 ptvcursor_new_subtree_levels(ptvc);
1298
1299 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1300 subtree->tree = ptvc->tree;
1301 subtree->it= NULL((void*)0);
1302 ptvc->pushed_tree_index++;
1303 return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1304}
1305
1306/* pops a subtree */
1307void
1308ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1309{
1310 subtree_lvl *subtree;
1311
1312 if (ptvc->pushed_tree_index <= 0)
1313 return;
1314
1315 ptvc->pushed_tree_index--;
1316 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1317 if (subtree->it != NULL((void*)0))
1318 proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1319
1320 ptvc->tree = subtree->tree;
1321}
1322
1323/* saves the current tvb offset and the item in the current subtree level */
1324static void
1325ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1326{
1327 subtree_lvl *subtree;
1328
1329 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", 1329, "ptvc->pushed_tree_index > 0"
))))
;
1330
1331 subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1332 subtree->it = it;
1333 subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1334}
1335
1336/* Creates a subtree and adds it to the cursor as the working tree but does not
1337 * save the old working tree */
1338proto_tree *
1339ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1340{
1341 ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1342 return ptvc->tree;
1343}
1344
1345static proto_tree *
1346ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1347{
1348 ptvcursor_push_subtree(ptvc, it, ett_subtree);
1349 if (length == SUBTREE_UNDEFINED_LENGTH-1)
1350 ptvcursor_subtree_set_item(ptvc, it);
1351 return ptvcursor_tree(ptvc);
1352}
1353
1354/* Add an item to the tree and create a subtree
1355 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1356 * In this case, when the subtree will be closed, the parent item length will
1357 * be equal to the advancement of the cursor since the creation of the subtree.
1358 */
1359proto_tree *
1360ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1361 const unsigned encoding, int ett_subtree)
1362{
1363 proto_item *it;
1364
1365 it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1366 return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1367}
1368
1369static proto_item *
1370proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1371
1372/* Add a text node to the tree and create a subtree
1373 * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1374 * In this case, when the subtree will be closed, the item length will be equal
1375 * to the advancement of the cursor since the creation of the subtree.
1376 */
1377proto_tree *
1378ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1379 int ett_subtree, const char *format, ...)
1380{
1381 proto_item *pi;
1382 va_list ap;
1383 header_field_info *hfinfo;
1384 proto_tree *tree;
1385
1386 tree = ptvcursor_tree(ptvc);
1387
1388 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1389
1390 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", 1390
, __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", 1390, "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", 1390, "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", 1390, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
1391
1392 pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1393 ptvcursor_current_offset(ptvc), length);
1394
1395 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1395, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
1396
1397 va_start(ap, format)__builtin_va_start(ap, format);
1398 proto_tree_set_representation(pi, format, ap);
1399 va_end(ap)__builtin_va_end(ap);
1400
1401 return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1402}
1403
1404/* Add a text-only node, leaving it to our caller to fill the text in */
1405static proto_item *
1406proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1407{
1408 proto_item *pi;
1409
1410 if (tree == NULL((void*)0))
1411 return NULL((void*)0);
1412
1413 pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1414
1415 return pi;
1416}
1417
1418/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1419proto_item *
1420proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1421 const char *format, ...)
1422{
1423 proto_item *pi;
1424 va_list ap;
1425 header_field_info *hfinfo;
1426
1427 if (length == -1) {
1428 length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1429 } else {
1430 tvb_ensure_bytes_exist(tvb, start, length);
1431 }
1432
1433 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1434
1435 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", 1435
, __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", 1435, "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", 1435, "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", 1435, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
1436
1437 pi = proto_tree_add_text_node(tree, tvb, start, length);
1438
1439 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1439, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
1440
1441 va_start(ap, format)__builtin_va_start(ap, format);
1442 proto_tree_set_representation(pi, format, ap);
1443 va_end(ap)__builtin_va_end(ap);
1444
1445 return pi;
1446}
1447
1448/* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1449proto_item *
1450proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1451 int length, const char *format, va_list ap)
1452{
1453 proto_item *pi;
1454 header_field_info *hfinfo;
1455
1456 /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1457 * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1458 * the length to be what's in the tvbuff if length is -1, and the
1459 * minimum of length and what's in the tvbuff if not.
1460 */
1461
1462 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1463
1464 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", 1464
, __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", 1464, "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", 1464, "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", 1464, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
1465
1466 pi = proto_tree_add_text_node(tree, tvb, start, length);
1467
1468 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1468, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
1469
1470 proto_tree_set_representation(pi, format, ap);
1471
1472 return pi;
1473}
1474
1475/* Add a text-only node that creates a subtree underneath.
1476 */
1477proto_tree *
1478proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1479{
1480 return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1481}
1482
1483/* Add a text-only node that creates a subtree underneath.
1484 */
1485proto_tree *
1486proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1487{
1488 proto_tree *pt;
1489 proto_item *pi;
1490 va_list ap;
1491
1492 va_start(ap, format)__builtin_va_start(ap, format);
1493 pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1494 va_end(ap)__builtin_va_end(ap);
1495
1496 if (tree_item != NULL((void*)0))
1497 *tree_item = pi;
1498
1499 pt = proto_item_add_subtree(pi, idx);
1500
1501 return pt;
1502}
1503
1504/* Add a text-only node for debugging purposes. The caller doesn't need
1505 * to worry about tvbuff, start, or length. Debug message gets sent to
1506 * STDOUT, too */
1507proto_item *
1508proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1509{
1510 proto_item *pi;
1511 va_list ap;
1512
1513 pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1514
1515 if (pi) {
1516 va_start(ap, format)__builtin_va_start(ap, format);
1517 proto_tree_set_representation(pi, format, ap);
1518 va_end(ap)__builtin_va_end(ap);
1519 }
1520 va_start(ap, format)__builtin_va_start(ap, format);
1521 vprintf(format, ap);
1522 va_end(ap)__builtin_va_end(ap);
1523 printf("\n");
1524
1525 return pi;
1526}
1527
1528proto_item *
1529proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1530{
1531 proto_item *pi;
1532 header_field_info *hfinfo;
1533
1534 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1535
1536 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", 1536
, __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", 1536, "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", 1536, "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", 1536, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
1537
1538 pi = proto_tree_add_text_node(tree, tvb, start, length);
1539
1540 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1540, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
1541
1542 proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1543
1544 return pi;
1545}
1546
1547proto_item *
1548proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1549{
1550 proto_item *pi;
1551 header_field_info *hfinfo;
1552 char *str;
1553
1554 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1555
1556 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", 1556
, __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", 1556, "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", 1556, "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", 1556, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
1557
1558 pi = proto_tree_add_text_node(tree, tvb, start, length);
1559
1560 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 1560, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
1561
1562 str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1563 proto_item_set_text(pi, "%s", str);
1564 wmem_free(NULL((void*)0), str);
1565
1566 return pi;
1567}
1568
1569void proto_report_dissector_bug(const char *format, ...)
1570{
1571 va_list args;
1572
1573 if (wireshark_abort_on_dissector_bug) {
1574 /*
1575 * Try to have the error message show up in the crash
1576 * information.
1577 */
1578 va_start(args, format)__builtin_va_start(args, format);
1579 ws_vadd_crash_info(format, args);
1580 va_end(args)__builtin_va_end(args);
1581
1582 /*
1583 * Print the error message.
1584 */
1585 va_start(args, format)__builtin_va_start(args, format);
1586 vfprintf(stderrstderr, format, args);
1587 va_end(args)__builtin_va_end(args);
1588 putc('\n', stderrstderr);
1589
1590 /*
1591 * And crash.
1592 */
1593 abort();
1594 } else {
1595 va_start(args, format)__builtin_va_start(args, format);
1596 VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1597 va_end(args)__builtin_va_end(args);
1598 }
1599}
1600
1601/* We could probably get away with changing is_error to a minimum length value. */
1602static void
1603report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1604{
1605 if (is_error) {
1606 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1607 } else {
1608 expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1609 }
1610
1611 if (is_error) {
1612 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1613 }
1614}
1615
1616static uint32_t
1617get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1618{
1619 uint32_t value;
1620 bool_Bool length_error;
1621
1622 switch (length) {
1623
1624 case 1:
1625 value = tvb_get_uint8(tvb, offset);
1626 if (encoding & ENC_ZIGBEE0x40000000) {
1627 if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1628 value = 0;
1629 }
1630 }
1631 break;
1632
1633 case 2:
1634 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1635 : tvb_get_ntohs(tvb, offset);
1636 if (encoding & ENC_ZIGBEE0x40000000) {
1637 if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1638 value = 0;
1639 }
1640 }
1641 break;
1642
1643 case 3:
1644 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1645 : tvb_get_ntoh24(tvb, offset);
1646 break;
1647
1648 case 4:
1649 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1650 : tvb_get_ntohl(tvb, offset);
1651 break;
1652
1653 default:
1654 if (length < 1) {
1655 length_error = true1;
1656 value = 0;
1657 } else {
1658 length_error = false0;
1659 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1660 : tvb_get_ntohl(tvb, offset);
1661 }
1662 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1663 break;
1664 }
1665 return value;
1666}
1667
1668static inline uint64_t
1669get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1670{
1671 uint64_t value;
1672 bool_Bool length_error;
1673
1674 switch (length) {
1675
1676 case 1:
1677 value = tvb_get_uint8(tvb, offset);
1678 break;
1679
1680 case 2:
1681 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1682 : tvb_get_ntohs(tvb, offset);
1683 break;
1684
1685 case 3:
1686 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1687 : tvb_get_ntoh24(tvb, offset);
1688 break;
1689
1690 case 4:
1691 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1692 : tvb_get_ntohl(tvb, offset);
1693 break;
1694
1695 case 5:
1696 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh40(tvb, offset)
1697 : tvb_get_ntoh40(tvb, offset);
1698 break;
1699
1700 case 6:
1701 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh48(tvb, offset)
1702 : tvb_get_ntoh48(tvb, offset);
1703 break;
1704
1705 case 7:
1706 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh56(tvb, offset)
1707 : tvb_get_ntoh56(tvb, offset);
1708 break;
1709
1710 case 8:
1711 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh64(tvb, offset)
1712 : tvb_get_ntoh64(tvb, offset);
1713 break;
1714
1715 default:
1716 if (length < 1) {
1717 length_error = true1;
1718 value = 0;
1719 } else {
1720 length_error = false0;
1721 value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh64(tvb, offset)
1722 : tvb_get_ntoh64(tvb, offset);
1723 }
1724 report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1725 break;
1726 }
1727 return value;
1728}
1729
1730static int32_t
1731get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1732{
1733 int32_t value;
1734 bool_Bool length_error;
1735
1736 switch (length) {
1737
1738 case 1:
1739 value = tvb_get_int8(tvb, offset);
1740 break;
1741
1742 case 2:
1743 value = encoding ? tvb_get_letohis(tvb, offset)
1744 : tvb_get_ntohis(tvb, offset);
1745 break;
1746
1747 case 3:
1748 value = encoding ? tvb_get_letohi24(tvb, offset)
1749 : tvb_get_ntohi24(tvb, offset);
1750 break;
1751
1752 case 4:
1753 value = encoding ? tvb_get_letohil(tvb, offset)
1754 : tvb_get_ntohil(tvb, offset);
1755 break;
1756
1757 default:
1758 if (length < 1) {
1759 length_error = true1;
1760 value = 0;
1761 } else {
1762 length_error = false0;
1763 value = encoding ? tvb_get_letohil(tvb, offset)
1764 : tvb_get_ntohil(tvb, offset);
1765 }
1766 report_type_length_mismatch(tree, "a signed integer", length, length_error);
1767 break;
1768 }
1769 return value;
1770}
1771
1772/* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1773 * be cast-able as a int64_t. This is weird, but what the code has always done.
1774 */
1775static inline uint64_t
1776get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1777{
1778 uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1779
1780 switch (length) {
1781 case 7:
1782 value = ws_sign_ext64(value, 56);
1783 break;
1784 case 6:
1785 value = ws_sign_ext64(value, 48);
1786 break;
1787 case 5:
1788 value = ws_sign_ext64(value, 40);
1789 break;
1790 case 4:
1791 value = ws_sign_ext64(value, 32);
1792 break;
1793 case 3:
1794 value = ws_sign_ext64(value, 24);
1795 break;
1796 case 2:
1797 value = ws_sign_ext64(value, 16);
1798 break;
1799 case 1:
1800 value = ws_sign_ext64(value, 8);
1801 break;
1802 }
1803
1804 return value;
1805}
1806
1807/* For FT_STRING */
1808static inline const uint8_t *
1809get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1810 int length, int *ret_length, const unsigned encoding)
1811{
1812 if (length == -1) {
1813 length = tvb_ensure_captured_length_remaining(tvb, start);
1814 }
1815 *ret_length = length;
1816 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1817}
1818
1819/* For FT_STRINGZ */
1820static inline const uint8_t *
1821get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1822 int start, int length, int *ret_length, const unsigned encoding)
1823{
1824 const uint8_t *value;
1825
1826 if (length < -1) {
1827 report_type_length_mismatch(tree, "a string", length, true1);
1828 }
1829 if (length == -1) {
1830 /* This can throw an exception */
1831 value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1832 } else {
1833 /* In this case, length signifies the length of the string.
1834 *
1835 * This could either be a null-padded string, which doesn't
1836 * necessarily have a '\0' at the end, or a null-terminated
1837 * string, with a trailing '\0'. (Yes, there are cases
1838 * where you have a string that's both counted and null-
1839 * terminated.)
1840 *
1841 * In the first case, we must allocate a buffer of length
1842 * "length+1", to make room for a trailing '\0'.
1843 *
1844 * In the second case, we don't assume that there is a
1845 * trailing '\0' there, as the packet might be malformed.
1846 * (XXX - should we throw an exception if there's no
1847 * trailing '\0'?) Therefore, we allocate a buffer of
1848 * length "length+1", and put in a trailing '\0', just to
1849 * be safe.
1850 *
1851 * (XXX - this would change if we made string values counted
1852 * rather than null-terminated.)
1853 */
1854 value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1855 }
1856 *ret_length = length;
1857 return value;
1858}
1859
1860/* For FT_UINT_STRING */
1861static inline const uint8_t *
1862get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1863 tvbuff_t *tvb, int start, int length, int *ret_length,
1864 const unsigned encoding)
1865{
1866 uint32_t n;
1867 const uint8_t *value;
1868
1869 /* I believe it's ok if this is called with a NULL tree */
1870 n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1871 value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1872 length += n;
1873 *ret_length = length;
1874 return value;
1875}
1876
1877/* For FT_STRINGZPAD */
1878static inline const uint8_t *
1879get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1880 int length, int *ret_length, const unsigned encoding)
1881{
1882 /*
1883 * XXX - currently, string values are null-
1884 * terminated, so a "zero-padded" string
1885 * isn't special. If we represent string
1886 * values as something that includes a counted
1887 * array of bytes, we'll need to strip the
1888 * trailing NULs.
1889 */
1890 if (length == -1) {
1891 length = tvb_ensure_captured_length_remaining(tvb, start);
1892 }
1893 *ret_length = length;
1894 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1895}
1896
1897/* For FT_STRINGZTRUNC */
1898static inline const uint8_t *
1899get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1900 int length, int *ret_length, const unsigned encoding)
1901{
1902 /*
1903 * XXX - currently, string values are null-
1904 * terminated, so a "zero-truncated" string
1905 * isn't special. If we represent string
1906 * values as something that includes a counted
1907 * array of bytes, we'll need to strip everything
1908 * starting with the terminating NUL.
1909 */
1910 if (length == -1) {
1911 length = tvb_ensure_captured_length_remaining(tvb, start);
1912 }
1913 *ret_length = length;
1914 return tvb_get_string_enc(scope, tvb, start, length, encoding);
1915}
1916
1917/*
1918 * Deltas between the epochs for various non-UN*X time stamp formats and
1919 * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1920 * stamp format.
1921 */
1922
1923/*
1924 * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1925 * XXX - if it's OK if this is unsigned, can we just use
1926 * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1927 */
1928#define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1929
1930/*
1931 * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1932 */
1933#define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1934
1935/* this can be called when there is no tree, so tree may be null */
1936static void
1937get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1938 const int length, const unsigned encoding, nstime_t *time_stamp,
1939 const bool_Bool is_relative)
1940{
1941 uint32_t tmpsecs;
1942 uint64_t tmp64secs;
1943 uint64_t todusecs;
1944
1945 switch (encoding) {
1946
1947 case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1948 /*
1949 * If the length is 16, 8-byte seconds, followed
1950 * by 8-byte fractional time in nanoseconds,
1951 * both big-endian.
1952 *
1953 * If the length is 12, 8-byte seconds, followed
1954 * by 4-byte fractional time in nanoseconds,
1955 * both big-endian.
1956 *
1957 * If the length is 8, 4-byte seconds, followed
1958 * by 4-byte fractional time in nanoseconds,
1959 * both big-endian.
1960 *
1961 * For absolute times, the seconds are seconds
1962 * since the UN*X epoch.
1963 */
1964 if (length == 16) {
1965 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1966 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1967 } else if (length == 12) {
1968 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1969 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1970 } else if (length == 8) {
1971 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1972 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1973 } else if (length == 4) {
1974 /*
1975 * Backwards compatibility.
1976 * ENC_TIME_SECS_NSECS is 0; using
1977 * ENC_BIG_ENDIAN by itself with a 4-byte
1978 * time-in-seconds value was done in the
1979 * past.
1980 */
1981 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1982 time_stamp->nsecs = 0;
1983 } else {
1984 time_stamp->secs = 0;
1985 time_stamp->nsecs = 0;
1986 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
1987 }
1988 break;
1989
1990 case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
1991 /*
1992 * If the length is 16, 8-byte seconds, followed
1993 * by 8-byte fractional time in nanoseconds,
1994 * both little-endian.
1995 *
1996 * If the length is 12, 8-byte seconds, followed
1997 * by 4-byte fractional time in nanoseconds,
1998 * both little-endian.
1999 *
2000 * If the length is 8, 4-byte seconds, followed
2001 * by 4-byte fractional time in nanoseconds,
2002 * both little-endian.
2003 *
2004 * For absolute times, the seconds are seconds
2005 * since the UN*X epoch.
2006 */
2007 if (length == 16) {
2008 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2009 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2010 } else if (length == 12) {
2011 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2012 time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2013 } else if (length == 8) {
2014 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2015 time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2016 } else if (length == 4) {
2017 /*
2018 * Backwards compatibility.
2019 * ENC_TIME_SECS_NSECS is 0; using
2020 * ENC_LITTLE_ENDIAN by itself with a 4-byte
2021 * time-in-seconds value was done in the
2022 * past.
2023 */
2024 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2025 time_stamp->nsecs = 0;
2026 } else {
2027 time_stamp->secs = 0;
2028 time_stamp->nsecs = 0;
2029 report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2030 }
2031 break;
2032
2033 case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2034 /*
2035 * NTP time stamp, big-endian.
2036 * Only supported for absolute times.
2037 */
2038 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2038, "!is_relative"
))))
;
2039
2040 /* We need a temporary variable here so the unsigned math
2041 * works correctly (for years > 2036 according to RFC 2030
2042 * chapter 3).
2043 *
2044 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2045 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2046 * If bit 0 is not set, the time is in the range 2036-2104 and
2047 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2048 */
2049 tmpsecs = tvb_get_ntohl(tvb, start);
2050 if ((tmpsecs & 0x80000000) != 0)
2051 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2052 else
2053 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2054
2055 if (length == 8) {
2056 tmp64secs = tvb_get_ntoh64(tvb, start);
2057 if (tmp64secs == 0) {
2058 //This is "NULL" time
2059 time_stamp->secs = 0;
2060 time_stamp->nsecs = 0;
2061 } else {
2062 /*
2063 * Convert 1/2^32s of a second to
2064 * nanoseconds.
2065 */
2066 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2067 }
2068 } else if (length == 4) {
2069 /*
2070 * Backwards compatibility.
2071 */
2072 if (tmpsecs == 0) {
2073 //This is "NULL" time
2074 time_stamp->secs = 0;
2075 }
2076 time_stamp->nsecs = 0;
2077 } else {
2078 time_stamp->secs = 0;
2079 time_stamp->nsecs = 0;
2080 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2081 }
2082 break;
2083
2084 case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2085 /*
2086 * NTP time stamp, little-endian.
2087 * Only supported for absolute times.
2088 *
2089 * NTP doesn't use this, because it's an Internet format
2090 * and hence big-endian. Any implementation must decide
2091 * whether the NTP timestamp is a 64-bit unsigned fixed
2092 * point number (RFC 1305, RFC 4330) or a 64-bit struct
2093 * with a 32-bit unsigned seconds field followed by a
2094 * 32-bit fraction field (cf. RFC 5905, which obsoletes
2095 * the previous two).
2096 *
2097 * XXX: We do the latter, but no dissector uses this format.
2098 * OTOH, ERF timestamps do the former, so perhaps we
2099 * should switch the interpretation so that packet-erf.c
2100 * could use this directly?
2101 */
2102 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2102, "!is_relative"
))))
;
2103
2104 /* We need a temporary variable here so the unsigned math
2105 * works correctly (for years > 2036 according to RFC 2030
2106 * chapter 3).
2107 *
2108 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2109 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2110 * If bit 0 is not set, the time is in the range 2036-2104 and
2111 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2112 */
2113 tmpsecs = tvb_get_letohl(tvb, start);
2114 if ((tmpsecs & 0x80000000) != 0)
2115 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2116 else
2117 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2118
2119 if (length == 8) {
2120 tmp64secs = tvb_get_letoh64(tvb, start);
2121 if (tmp64secs == 0) {
2122 //This is "NULL" time
2123 time_stamp->secs = 0;
2124 time_stamp->nsecs = 0;
2125 } else {
2126 /*
2127 * Convert 1/2^32s of a second to
2128 * nanoseconds.
2129 */
2130 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2131 }
2132 } else if (length == 4) {
2133 /*
2134 * Backwards compatibility.
2135 */
2136 if (tmpsecs == 0) {
2137 //This is "NULL" time
2138 time_stamp->secs = 0;
2139 }
2140 time_stamp->nsecs = 0;
2141 } else {
2142 time_stamp->secs = 0;
2143 time_stamp->nsecs = 0;
2144 report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2145 }
2146 break;
2147
2148 case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2149 /*
2150 * S/3x0 and z/Architecture TOD clock time stamp,
2151 * big-endian. The epoch is January 1, 1900,
2152 * 00:00:00 (proleptic?) UTC.
2153 *
2154 * Only supported for absolute times.
2155 */
2156 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2156, "!is_relative"
))))
;
2157 DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2157, "length == 8"
))))
;
2158
2159 if (length == 8) {
2160 todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2161 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2162 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2163 } else {
2164 time_stamp->secs = 0;
2165 time_stamp->nsecs = 0;
2166 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2167 }
2168 break;
2169
2170 case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2171 /*
2172 * S/3x0 and z/Architecture TOD clock time stamp,
2173 * little-endian. The epoch is January 1, 1900,
2174 * 00:00:00 (proleptic?) UTC.
2175 *
2176 * Only supported for absolute times.
2177 */
2178 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2178, "!is_relative"
))))
;
2179
2180 if (length == 8) {
2181 todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2182 time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2183 time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2184 } else {
2185 time_stamp->secs = 0;
2186 time_stamp->nsecs = 0;
2187 report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2188 }
2189 break;
2190
2191 case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2192 /*
2193 * Time stamp using the same seconds/fraction format
2194 * as NTP, but with the origin of the time stamp being
2195 * the UNIX epoch rather than the NTP epoch; big-
2196 * endian.
2197 *
2198 * Only supported for absolute times.
2199 */
2200 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2200, "!is_relative"
))))
;
2201
2202 if (length == 8) {
2203 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2204 /*
2205 * Convert 1/2^32s of a second to nanoseconds.
2206 */
2207 time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2208 } else {
2209 time_stamp->secs = 0;
2210 time_stamp->nsecs = 0;
2211 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2212 }
2213 break;
2214
2215 case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2216 /*
2217 * Time stamp using the same seconds/fraction format
2218 * as NTP, but with the origin of the time stamp being
2219 * the UNIX epoch rather than the NTP epoch; little-
2220 * endian.
2221 *
2222 * Only supported for absolute times.
2223 *
2224 * The RTPS specification explicitly supports Little
2225 * Endian encoding. In one place, it states that its
2226 * Time_t representation "is the one defined by ...
2227 * RFC 1305", but in another explicitly defines it as
2228 * a struct consisting of an 32 bit unsigned seconds
2229 * field and a 32 bit unsigned fraction field, not a 64
2230 * bit fixed point, so we do that here.
2231 * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2232 */
2233 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2233, "!is_relative"
))))
;
2234
2235 if (length == 8) {
2236 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2237 /*
2238 * Convert 1/2^32s of a second to nanoseconds.
2239 */
2240 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2241 } else {
2242 time_stamp->secs = 0;
2243 time_stamp->nsecs = 0;
2244 report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2245 }
2246 break;
2247
2248 case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2249 /*
2250 * MIP6 time stamp, big-endian.
2251 * A 64-bit unsigned integer field containing a timestamp. The
2252 * value indicates the number of seconds since January 1, 1970,
2253 * 00:00 UTC, by using a fixed point format. In this format, the
2254 * integer number of seconds is contained in the first 48 bits of
2255 * the field, and the remaining 16 bits indicate the number of
2256 * 1/65536 fractions of a second.
2257
2258 * Only supported for absolute times.
2259 */
2260 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2260, "!is_relative"
))))
;
2261
2262 if (length == 8) {
2263 /* We need a temporary variable here so the casting and fractions
2264 * of a second work correctly.
2265 */
2266 tmp64secs = tvb_get_ntoh48(tvb, start);
2267 tmpsecs = tvb_get_ntohs(tvb, start + 6);
2268 tmpsecs <<= 16;
2269
2270 if ((tmp64secs == 0) && (tmpsecs == 0)) {
2271 //This is "NULL" time
2272 time_stamp->secs = 0;
2273 time_stamp->nsecs = 0;
2274 } else {
2275 time_stamp->secs = (time_t)tmp64secs;
2276 time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2277 }
2278 } else {
2279 time_stamp->secs = 0;
2280 time_stamp->nsecs = 0;
2281 report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2282 }
2283 break;
2284
2285 case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2286 /*
2287 * If the length is 16, 8-byte seconds, followed
2288 * by 8-byte fractional time in microseconds,
2289 * both big-endian.
2290 *
2291 * If the length is 12, 8-byte seconds, followed
2292 * by 4-byte fractional time in microseconds,
2293 * both big-endian.
2294 *
2295 * If the length is 8, 4-byte seconds, followed
2296 * by 4-byte fractional time in microseconds,
2297 * both big-endian.
2298 *
2299 * For absolute times, the seconds are seconds
2300 * since the UN*X epoch.
2301 */
2302 if (length == 16) {
2303 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2304 time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2305 } else if (length == 12) {
2306 time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2307 time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2308 } else if (length == 8) {
2309 time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2310 time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2311 } else {
2312 time_stamp->secs = 0;
2313 time_stamp->nsecs = 0;
2314 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2315 }
2316 break;
2317
2318 case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2319 /*
2320 * If the length is 16, 8-byte seconds, followed
2321 * by 8-byte fractional time in microseconds,
2322 * both little-endian.
2323 *
2324 * If the length is 12, 8-byte seconds, followed
2325 * by 4-byte fractional time in microseconds,
2326 * both little-endian.
2327 *
2328 * If the length is 8, 4-byte seconds, followed
2329 * by 4-byte fractional time in microseconds,
2330 * both little-endian.
2331 *
2332 * For absolute times, the seconds are seconds
2333 * since the UN*X epoch.
2334 */
2335 if (length == 16) {
2336 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2337 time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2338 } else if (length == 12) {
2339 time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2340 time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2341 } else if (length == 8) {
2342 time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2343 time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2344 } else {
2345 time_stamp->secs = 0;
2346 time_stamp->nsecs = 0;
2347 report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2348 }
2349 break;
2350
2351 case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2352 case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2353 /*
2354 * Seconds, 1 to 8 bytes.
2355 * For absolute times, it's seconds since the
2356 * UN*X epoch.
2357 */
2358 if (length >= 1 && length <= 8) {
2359 time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2360 time_stamp->nsecs = 0;
2361 } else {
2362 time_stamp->secs = 0;
2363 time_stamp->nsecs = 0;
2364 report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2365 }
2366 break;
2367
2368 case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2369 case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2370 /*
2371 * Milliseconds, 1 to 8 bytes.
2372 * For absolute times, it's milliseconds since the
2373 * UN*X epoch.
2374 */
2375 if (length >= 1 && length <= 8) {
2376 uint64_t msecs;
2377
2378 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2379 time_stamp->secs = (time_t)(msecs / 1000);
2380 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2381 } else {
2382 time_stamp->secs = 0;
2383 time_stamp->nsecs = 0;
2384 report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2385 }
2386 break;
2387
2388 case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2389 case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2390 /*
2391 * Microseconds, 1 to 8 bytes.
2392 * For absolute times, it's microseconds since the
2393 * UN*X epoch.
2394 */
2395 if (length >= 1 && length <= 8) {
2396 uint64_t usecs;
2397
2398 usecs = get_uint64_value(tree, tvb, start, length, encoding);
2399 time_stamp->secs = (time_t)(usecs / 1000000);
2400 time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2401 } else {
2402 time_stamp->secs = 0;
2403 time_stamp->nsecs = 0;
2404 report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2405 }
2406 break;
2407
2408 case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2409 case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2410 /*
2411 * nanoseconds, 1 to 8 bytes.
2412 * For absolute times, it's nanoseconds since the
2413 * UN*X epoch.
2414 */
2415
2416 if (length >= 1 && length <= 8) {
2417 uint64_t nsecs;
2418
2419 nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2420 time_stamp->secs = (time_t)(nsecs / 1000000000);
2421 time_stamp->nsecs = (int)(nsecs % 1000000000);
2422 } else {
2423 time_stamp->secs = 0;
2424 time_stamp->nsecs = 0;
2425 report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2426 }
2427 break;
2428
2429 case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2430 /*
2431 * 1/64ths of a second since the UN*X epoch,
2432 * big-endian.
2433 *
2434 * Only supported for absolute times.
2435 */
2436 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2436, "!is_relative"
))))
;
2437
2438 if (length == 8) {
2439 /*
2440 * The upper 48 bits are seconds since the
2441 * UN*X epoch.
2442 */
2443 time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2444 /*
2445 * The lower 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_ntohs(tvb, start+6)/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_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2460 /*
2461 * 1/64ths of a second since the UN*X epoch,
2462 * little-endian.
2463 *
2464 * Only supported for absolute times.
2465 */
2466 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2466, "!is_relative"
))))
;
2467
2468 if (length == 8) {
2469 /*
2470 * XXX - this is assuming that, if anybody
2471 * were ever to use this format - RFC 3971
2472 * doesn't, because that's an Internet
2473 * protocol, and those use network byte
2474 * order, i.e. big-endian - they'd treat it
2475 * as a 64-bit count of 1/2^16s of a second,
2476 * putting the upper 48 bits at the end.
2477 *
2478 * The lower 48 bits are seconds since the
2479 * UN*X epoch.
2480 */
2481 time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2482 /*
2483 * The upper 16 bits are 1/2^16s of a second;
2484 * convert them to nanoseconds.
2485 *
2486 * XXX - this may give the impression of higher
2487 * precision than you actually get.
2488 */
2489 time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2490 } else {
2491 time_stamp->secs = 0;
2492 time_stamp->nsecs = 0;
2493 report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2494 }
2495 break;
2496
2497 case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2498 /*
2499 * NTP time stamp, with 1-second resolution (i.e.,
2500 * seconds since the NTP epoch), big-endian.
2501 * Only supported for absolute times.
2502 */
2503 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2503, "!is_relative"
))))
;
2504
2505 if (length == 4) {
2506 /*
2507 * We need a temporary variable here so the unsigned math
2508 * works correctly (for years > 2036 according to RFC 2030
2509 * chapter 3).
2510 *
2511 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2512 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2513 * If bit 0 is not set, the time is in the range 2036-2104 and
2514 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2515 */
2516 tmpsecs = tvb_get_ntohl(tvb, start);
2517 if ((tmpsecs & 0x80000000) != 0)
2518 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2519 else
2520 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2521 time_stamp->nsecs = 0;
2522 } else {
2523 time_stamp->secs = 0;
2524 time_stamp->nsecs = 0;
2525 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2526 }
2527 break;
2528
2529 case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2530 /*
2531 * NTP time stamp, with 1-second resolution (i.e.,
2532 * seconds since the NTP epoch), little-endian.
2533 * Only supported for absolute times.
2534 */
2535 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2535, "!is_relative"
))))
;
2536
2537 /*
2538 * We need a temporary variable here so the unsigned math
2539 * works correctly (for years > 2036 according to RFC 2030
2540 * chapter 3).
2541 *
2542 * If bit 0 is set, the UTC time is in the range 1968-2036 and
2543 * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2544 * If bit 0 is not set, the time is in the range 2036-2104 and
2545 * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2546 */
2547 if (length == 4) {
2548 tmpsecs = tvb_get_letohl(tvb, start);
2549 if ((tmpsecs & 0x80000000) != 0)
2550 time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2551 else
2552 time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2553 time_stamp->nsecs = 0;
2554 } else {
2555 time_stamp->secs = 0;
2556 time_stamp->nsecs = 0;
2557 report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2558 }
2559 break;
2560
2561 case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2562 /*
2563 * Milliseconds, 6 to 8 bytes.
2564 * For absolute times, it's milliseconds since the
2565 * NTP epoch.
2566 *
2567 * ETSI TS 129.274 8.119 defines this as:
2568 * "a 48 bit unsigned integer in network order format
2569 * ...encoded as the number of milliseconds since
2570 * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2571 * rounded value of 1000 x the value of the 64-bit
2572 * timestamp (Seconds + (Fraction / (1<<32))) defined
2573 * in clause 6 of IETF RFC 5905."
2574 *
2575 * Taken literally, the part after "i.e." would
2576 * mean that the value rolls over before reaching
2577 * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2578 * when the 64 bit timestamp rolls over, and we have
2579 * to pick an NTP Era equivalence class to support
2580 * (such as 1968-01-20 to 2104-02-06).
2581 *
2582 * OTOH, the extra room might be used to store Era
2583 * information instead, in which case times until
2584 * 10819-08-03 can be represented with 6 bytes without
2585 * ambiguity. We handle both implementations, and assume
2586 * that times before 1968-01-20 are not represented.
2587 *
2588 * Only 6 bytes or more makes sense as an absolute
2589 * time. 5 bytes or fewer could express a span of
2590 * less than 35 years, either 1900-1934 or 2036-2070.
2591 */
2592 if (length >= 6 && length <= 8) {
2593 uint64_t msecs;
2594
2595 msecs = get_uint64_value(tree, tvb, start, length, encoding);
2596 tmp64secs = (msecs / 1000);
2597 /*
2598 * Assume that times in the first half of NTP
2599 * Era 0 really represent times in the NTP
2600 * Era 1.
2601 */
2602 if (tmp64secs >= 0x80000000)
2603 time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2604 else
2605 time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2606 time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2607 }
2608 else {
2609 time_stamp->secs = 0;
2610 time_stamp->nsecs = 0;
2611 report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2612 }
2613 break;
2614
2615 case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2616 /*
2617 * MP4 file time stamps, big-endian.
2618 * Only supported for absolute times.
2619 */
2620 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2620, "!is_relative"
))))
;
2621
2622 if (length == 8) {
2623 tmp64secs = tvb_get_ntoh64(tvb, start);
2624 time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2625 time_stamp->nsecs = 0;
2626 } else if (length == 4) {
2627 tmpsecs = tvb_get_ntohl(tvb, start);
2628 time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2629 time_stamp->nsecs = 0;
2630 } else {
2631 time_stamp->secs = 0;
2632 time_stamp->nsecs = 0;
2633 report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2634 }
2635 break;
2636
2637 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2638 /*
2639 * Zigbee ZCL time stamps, big-endian.
2640 * Only supported for absolute times.
2641 */
2642 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2642, "!is_relative"
))))
;
2643
2644 if (length == 8) {
2645 tmp64secs = tvb_get_ntoh64(tvb, start);
2646 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)));
2647 time_stamp->nsecs = 0;
2648 } else if (length == 4) {
2649 tmpsecs = tvb_get_ntohl(tvb, start);
2650 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)));
2651 time_stamp->nsecs = 0;
2652 } else {
2653 time_stamp->secs = 0;
2654 time_stamp->nsecs = 0;
2655 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2656 }
2657 break;
2658
2659 case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2660 /*
2661 * Zigbee ZCL time stamps, little-endian.
2662 * Only supported for absolute times.
2663 */
2664 DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2664, "!is_relative"
))))
;
2665
2666 if (length == 8) {
2667 tmp64secs = tvb_get_letoh64(tvb, start);
2668 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)));
2669 time_stamp->nsecs = 0;
2670 } else if (length == 4) {
2671 tmpsecs = tvb_get_letohl(tvb, start);
2672 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)));
2673 time_stamp->nsecs = 0;
2674 } else {
2675 time_stamp->secs = 0;
2676 time_stamp->nsecs = 0;
2677 report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2678 }
2679 break;
2680
2681 default:
2682 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 2682))
;
2683 break;
2684 }
2685}
2686
2687static void
2688tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2689{
2690 const header_field_info *hfinfo = fi->hfinfo;
2691
2692 if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2693 GPtrArray *ptrs = NULL((void*)0);
2694
2695 if (tree_data->interesting_hfids == NULL((void*)0)) {
2696 /* Initialize the hash because we now know that it is needed */
2697 tree_data->interesting_hfids =
2698 g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2699 } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2700 ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2701 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2702 }
2703
2704 if (!ptrs) {
2705 /* First element triggers the creation of pointer array */
2706 ptrs = g_ptr_array_new();
2707 g_hash_table_insert(tree_data->interesting_hfids,
2708 GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2709 }
2710
2711 g_ptr_array_add(ptrs, fi);
2712 }
2713}
2714
2715
2716/*
2717 * Validates that field length bytes are available starting from
2718 * start (pos/neg). Throws an exception if they aren't.
2719 */
2720static void
2721test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2722 int start, int length, const unsigned encoding)
2723{
2724 int size = length;
2725
2726 if (!tvb)
2727 return;
2728
2729 if ((hfinfo->type == FT_STRINGZ) ||
2730 ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2731 (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
))
))) {
2732 /* If we're fetching until the end of the TVB, only validate
2733 * that the offset is within range.
2734 */
2735 if (length == -1)
2736 size = 0;
2737 }
2738
2739 tvb_ensure_bytes_exist(tvb, start, size);
2740}
2741
2742static void
2743detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2744{
2745 bool_Bool found_stray_character = false0;
2746
2747 if (!string)
2748 return;
2749
2750 switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2751 case ENC_ASCII0x00000000:
2752 case ENC_UTF_80x00000002:
2753 for (int i = (int)strlen(string); i < length; i++) {
2754 if (string[i] != '\0') {
2755 found_stray_character = true1;
2756 break;
2757 }
2758 }
2759 break;
2760
2761 default:
2762 break;
2763 }
2764
2765 if (found_stray_character) {
2766 expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2767 }
2768}
2769
2770static void
2771free_fvalue_cb(void *data)
2772{
2773 fvalue_t *fv = (fvalue_t*)data;
2774 fvalue_free(fv);
2775}
2776
2777/* Add an item to a proto_tree, using the text label registered to that item;
2778 the item is extracted from the tvbuff handed to it. */
2779static proto_item *
2780proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2781 tvbuff_t *tvb, int start, int length,
2782 unsigned encoding)
2783{
2784 proto_item *pi;
2785 uint32_t value, n;
2786 uint64_t value64;
2787 ws_in4_addr ipv4_value;
2788 float floatval;
2789 double doubleval;
2790 const char *stringval = NULL((void*)0);
2791 nstime_t time_stamp;
2792 bool_Bool length_error;
2793
2794 /* Ensure that the newly created fvalue_t is freed if we throw an
2795 * exception before adding it to the tree. (gcc creates clobbering
2796 * when it optimizes the equivalent TRY..EXCEPT implementation.)
2797 * XXX: Move the new_field_info() call inside here?
2798 */
2799 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))
;
2800
2801 switch (new_fi->hfinfo->type) {
2802 case FT_NONE:
2803 /* no value to set for FT_NONE */
2804 break;
2805
2806 case FT_PROTOCOL:
2807 proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2808 break;
2809
2810 case FT_BYTES:
2811 proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2812 break;
2813
2814 case FT_UINT_BYTES:
2815 n = get_uint_value(tree, tvb, start, length, encoding);
2816 proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2817
2818 /* Instead of calling proto_item_set_len(), since we don't yet
2819 * have a proto_item, we set the field_info's length ourselves. */
2820 new_fi->length = n + length;
2821 break;
2822
2823 case FT_BOOLEAN:
2824 /*
2825 * Map all non-zero values to little-endian for
2826 * backwards compatibility.
2827 */
2828 if (encoding)
2829 encoding = ENC_LITTLE_ENDIAN0x80000000;
2830 proto_tree_set_boolean(new_fi,
2831 get_uint64_value(tree, tvb, start, length, encoding));
2832 break;
2833
2834 case FT_CHAR:
2835 /* XXX - make these just FT_UINT? */
2836 case FT_UINT8:
2837 case FT_UINT16:
2838 case FT_UINT24:
2839 case FT_UINT32:
2840 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2841 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2842 value = (uint32_t)value64;
2843 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2844 new_fi->flags |= FI_VARINT0x00004000;
2845 }
2846 }
2847 else {
2848 /*
2849 * Map all non-zero values to little-endian for
2850 * backwards compatibility.
2851 */
2852 if (encoding)
2853 encoding = ENC_LITTLE_ENDIAN0x80000000;
2854
2855 value = get_uint_value(tree, tvb, start, length, encoding);
2856 }
2857 proto_tree_set_uint(new_fi, value);
2858 break;
2859
2860 case FT_UINT40:
2861 case FT_UINT48:
2862 case FT_UINT56:
2863 case FT_UINT64:
2864 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2865 new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2866 if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2867 new_fi->flags |= FI_VARINT0x00004000;
2868 }
2869 }
2870 else {
2871 /*
2872 * Map all other non-zero values to little-endian for
2873 * backwards compatibility.
2874 */
2875 if (encoding)
2876 encoding = ENC_LITTLE_ENDIAN0x80000000;
2877
2878 value64 = get_uint64_value(tree, tvb, start, length, encoding);
2879 }
2880 proto_tree_set_uint64(new_fi, value64);
2881 break;
2882
2883 /* XXX - make these just FT_INT? */
2884 case FT_INT8:
2885 case FT_INT16:
2886 case FT_INT24:
2887 case FT_INT32:
2888 /*
2889 * Map all non-zero values to little-endian for
2890 * backwards compatibility.
2891 */
2892 if (encoding)
2893 encoding = ENC_LITTLE_ENDIAN0x80000000;
2894 proto_tree_set_int(new_fi,
2895 get_int_value(tree, tvb, start, length, encoding));
2896 break;
2897
2898 case FT_INT40:
2899 case FT_INT48:
2900 case FT_INT56:
2901 case FT_INT64:
2902 /*
2903 * Map all non-zero values to little-endian for
2904 * backwards compatibility.
2905 */
2906 if (encoding)
2907 encoding = ENC_LITTLE_ENDIAN0x80000000;
2908 proto_tree_set_int64(new_fi,
2909 get_int64_value(tree, tvb, start, length, encoding));
2910 break;
2911
2912 case FT_IPv4:
2913 /*
2914 * Map all non-zero values to little-endian for
2915 * backwards compatibility.
2916 */
2917 if (encoding)
2918 encoding = ENC_LITTLE_ENDIAN0x80000000;
2919 if (length != FT_IPv4_LEN4) {
2920 length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2921 report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2922 }
2923 ipv4_value = tvb_get_ipv4(tvb, start);
2924 /*
2925 * NOTE: to support code written when
2926 * proto_tree_add_item() took a bool as its
2927 * last argument, with false meaning "big-endian"
2928 * and true meaning "little-endian", we treat any
2929 * non-zero value of "encoding" as meaning
2930 * "little-endian".
2931 */
2932 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);
2933 break;
2934
2935 case FT_IPXNET:
2936 if (length != FT_IPXNET_LEN4) {
2937 length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2938 report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2939 }
2940 proto_tree_set_ipxnet(new_fi,
2941 get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2942 break;
2943
2944 case FT_IPv6:
2945 if (length != FT_IPv6_LEN16) {
2946 length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2947 report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2948 }
2949 proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2950 break;
2951
2952 case FT_FCWWN:
2953 if (length != FT_FCWWN_LEN8) {
2954 length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2955 report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2956 }
2957 proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2958 break;
2959
2960 case FT_AX25:
2961 if (length != 7) {
2962 length_error = length < 7 ? true1 : false0;
2963 report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2964 }
2965 proto_tree_set_ax25_tvb(new_fi, tvb, start);
2966 break;
2967
2968 case FT_VINES:
2969 if (length != VINES_ADDR_LEN6) {
2970 length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2971 report_type_length_mismatch(tree, "a Vines address", length, length_error);
2972 }
2973 proto_tree_set_vines_tvb(new_fi, tvb, start);
2974 break;
2975
2976 case FT_ETHER:
2977 if (length != FT_ETHER_LEN6) {
2978 length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2979 report_type_length_mismatch(tree, "a MAC address", length, length_error);
2980 }
2981 proto_tree_set_ether_tvb(new_fi, tvb, start);
2982 break;
2983
2984 case FT_EUI64:
2985 /*
2986 * Map all non-zero values to little-endian for
2987 * backwards compatibility.
2988 */
2989 if (encoding)
2990 encoding = ENC_LITTLE_ENDIAN0x80000000;
2991 if (length != FT_EUI64_LEN8) {
2992 length_error = length < FT_EUI64_LEN8 ? true1 : false0;
2993 report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
2994 }
2995 proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
2996 break;
2997 case FT_GUID:
2998 /*
2999 * Map all non-zero values to little-endian for
3000 * backwards compatibility.
3001 */
3002 if (encoding)
3003 encoding = ENC_LITTLE_ENDIAN0x80000000;
3004 if (length != FT_GUID_LEN16) {
3005 length_error = length < FT_GUID_LEN16 ? true1 : false0;
3006 report_type_length_mismatch(tree, "a GUID", length, length_error);
3007 }
3008 proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3009 break;
3010
3011 case FT_OID:
3012 case FT_REL_OID:
3013 proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3014 break;
3015
3016 case FT_SYSTEM_ID:
3017 proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3018 break;
3019
3020 case FT_FLOAT:
3021 /*
3022 * NOTE: to support code written when
3023 * proto_tree_add_item() took a bool as its
3024 * last argument, with false meaning "big-endian"
3025 * and true meaning "little-endian", we treat any
3026 * non-zero value of "encoding" as meaning
3027 * "little-endian".
3028 *
3029 * At some point in the future, we might
3030 * support non-IEEE-binary floating-point
3031 * formats in the encoding as well
3032 * (IEEE decimal, System/3x0, VAX).
3033 */
3034 if (encoding)
3035 encoding = ENC_LITTLE_ENDIAN0x80000000;
3036 if (length != 4) {
3037 length_error = length < 4 ? true1 : false0;
3038 report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3039 }
3040 if (encoding)
3041 floatval = tvb_get_letohieee_float(tvb, start);
3042 else
3043 floatval = tvb_get_ntohieee_float(tvb, start);
3044 proto_tree_set_float(new_fi, floatval);
3045 break;
3046
3047 case FT_DOUBLE:
3048 /*
3049 * NOTE: to support code written when
3050 * proto_tree_add_item() took a bool as its
3051 * last argument, with false meaning "big-endian"
3052 * and true meaning "little-endian", we treat any
3053 * non-zero value of "encoding" as meaning
3054 * "little-endian".
3055 *
3056 * At some point in the future, we might
3057 * support non-IEEE-binary floating-point
3058 * formats in the encoding as well
3059 * (IEEE decimal, System/3x0, VAX).
3060 */
3061 if (encoding == true1)
3062 encoding = ENC_LITTLE_ENDIAN0x80000000;
3063 if (length != 8) {
3064 length_error = length < 8 ? true1 : false0;
3065 report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3066 }
3067 if (encoding)
3068 doubleval = tvb_get_letohieee_double(tvb, start);
3069 else
3070 doubleval = tvb_get_ntohieee_double(tvb, start);
3071 proto_tree_set_double(new_fi, doubleval);
3072 break;
3073
3074 case FT_STRING:
3075 stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3076 tvb, start, length, &length, encoding);
3077 proto_tree_set_string(new_fi, stringval);
3078
3079 /* Instead of calling proto_item_set_len(), since we
3080 * don't yet have a proto_item, we set the
3081 * field_info's length ourselves.
3082 *
3083 * XXX - our caller can't use that length to
3084 * advance an offset unless they arrange that
3085 * there always be a protocol tree into which
3086 * we're putting this item.
3087 */
3088 new_fi->length = length;
3089 break;
3090
3091 case FT_STRINGZ:
3092 stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3093 tree, tvb, start, length, &length, encoding);
3094 proto_tree_set_string(new_fi, stringval);
3095
3096 /* Instead of calling proto_item_set_len(),
3097 * since we don't yet have a proto_item, we
3098 * set the field_info's length ourselves.
3099 *
3100 * XXX - our caller can't use that length to
3101 * advance an offset unless they arrange that
3102 * there always be a protocol tree into which
3103 * we're putting this item.
3104 */
3105 new_fi->length = length;
3106 break;
3107
3108 case FT_UINT_STRING:
3109 /*
3110 * NOTE: to support code written when
3111 * proto_tree_add_item() took a bool as its
3112 * last argument, with false meaning "big-endian"
3113 * and true meaning "little-endian", if the
3114 * encoding value is true, treat that as
3115 * ASCII with a little-endian length.
3116 *
3117 * This won't work for code that passes
3118 * arbitrary non-zero values; that code
3119 * will need to be fixed.
3120 */
3121 if (encoding == true1)
3122 encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3123 stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3124 tree, tvb, start, length, &length, encoding);
3125 proto_tree_set_string(new_fi, stringval);
3126
3127 /* Instead of calling proto_item_set_len(), since we
3128 * don't yet have a proto_item, we set the
3129 * field_info's length ourselves.
3130 *
3131 * XXX - our caller can't use that length to
3132 * advance an offset unless they arrange that
3133 * there always be a protocol tree into which
3134 * we're putting this item.
3135 */
3136 new_fi->length = length;
3137 break;
3138
3139 case FT_STRINGZPAD:
3140 stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3141 tvb, start, length, &length, encoding);
3142 proto_tree_set_string(new_fi, stringval);
3143
3144 /* Instead of calling proto_item_set_len(), since we
3145 * don't yet have a proto_item, we set the
3146 * field_info's length ourselves.
3147 *
3148 * XXX - our caller can't use that length to
3149 * advance an offset unless they arrange that
3150 * there always be a protocol tree into which
3151 * we're putting this item.
3152 */
3153 new_fi->length = length;
3154 break;
3155
3156 case FT_STRINGZTRUNC:
3157 stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3158 tvb, start, length, &length, encoding);
3159 proto_tree_set_string(new_fi, stringval);
3160
3161 /* Instead of calling proto_item_set_len(), since we
3162 * don't yet have a proto_item, we set the
3163 * field_info's length ourselves.
3164 *
3165 * XXX - our caller can't use that length to
3166 * advance an offset unless they arrange that
3167 * there always be a protocol tree into which
3168 * we're putting this item.
3169 */
3170 new_fi->length = length;
3171 break;
3172
3173 case FT_ABSOLUTE_TIME:
3174 /*
3175 * Absolute times can be in any of a number of
3176 * formats, and they can be big-endian or
3177 * little-endian.
3178 *
3179 * Historically FT_TIMEs were only timespecs;
3180 * the only question was whether they were stored
3181 * in big- or little-endian format.
3182 *
3183 * For backwards compatibility, we interpret an
3184 * encoding of 1 as meaning "little-endian timespec",
3185 * so that passing true is interpreted as that.
3186 */
3187 if (encoding == true1)
3188 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3189
3190 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3191
3192 proto_tree_set_time(new_fi, &time_stamp);
3193 break;
3194
3195 case FT_RELATIVE_TIME:
3196 /*
3197 * Relative times can be in any of a number of
3198 * formats, and they can be big-endian or
3199 * little-endian.
3200 *
3201 * Historically FT_TIMEs were only timespecs;
3202 * the only question was whether they were stored
3203 * in big- or little-endian format.
3204 *
3205 * For backwards compatibility, we interpret an
3206 * encoding of 1 as meaning "little-endian timespec",
3207 * so that passing true is interpreted as that.
3208 */
3209 if (encoding == true1)
3210 encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3211
3212 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3213
3214 proto_tree_set_time(new_fi, &time_stamp);
3215 break;
3216 case FT_IEEE_11073_SFLOAT:
3217 if (encoding)
3218 encoding = ENC_LITTLE_ENDIAN0x80000000;
3219 if (length != 2) {
3220 length_error = length < 2 ? true1 : false0;
3221 report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3222 }
3223
3224 fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3225
3226 break;
3227 case FT_IEEE_11073_FLOAT:
3228 if (encoding)
3229 encoding = ENC_LITTLE_ENDIAN0x80000000;
3230 if (length != 4) {
3231 length_error = length < 4 ? true1 : false0;
3232 report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3233 }
3234
3235 break;
3236 default:
3237 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))
3238 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))
3239 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))
3240 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))
;
3241 break;
3242 }
3243 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)
;
3244
3245 /* Don't add new node to proto_tree until now so that any exceptions
3246 * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3247 /* XXX. wouldn't be better to add this item to tree, with some special
3248 * flag (FI_EXCEPTION?) to know which item caused exception? For
3249 * strings and bytes, we would have to set new_fi->value to something
3250 * non-NULL, or otherwise ensure that proto_item_fill_display_label
3251 * could handle NULL values. */
3252 CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context
); }
3253 pi = proto_tree_add_node(tree, new_fi);
3254
3255 switch (new_fi->hfinfo->type) {
3256
3257 case FT_STRING:
3258 /* XXX: trailing stray character detection should be done
3259 * _before_ conversion to UTF-8, because conversion can change
3260 * the length, or else get_string_length should return a value
3261 * for the "length in bytes of the string after conversion
3262 * including internal nulls." (Noting that we do, for other
3263 * reasons, still need the "length in bytes in the field",
3264 * especially for FT_STRINGZ.)
3265 *
3266 * This is true even for ASCII and UTF-8, because
3267 * substituting REPLACEMENT CHARACTERS for illegal characters
3268 * can also do so (and for UTF-8 possibly even make the
3269 * string _shorter_).
3270 */
3271 detect_trailing_stray_characters(encoding, stringval, length, pi);
3272 break;
3273
3274 default:
3275 break;
3276 }
3277
3278 return pi;
3279}
3280
3281proto_item *
3282proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3283 const int start, int length,
3284 const unsigned encoding, int32_t *retval)
3285{
3286 header_field_info *hfinfo;
3287 field_info *new_fi;
3288 int32_t value;
3289
3290 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", 3290, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3290,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3290, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3291
3292 switch (hfinfo->type) {
3293 case FT_INT8:
3294 case FT_INT16:
3295 case FT_INT24:
3296 case FT_INT32:
3297 break;
3298 case FT_INT64:
3299 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)
3300 hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3301 default:
3302 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)
3303 hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()"
, hfinfo->abbrev)
;
3304 }
3305
3306 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3307 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3308 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3309 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3310 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3311 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3312 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3313
3314 if (encoding & ENC_STRING0x03000000) {
3315 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3316 }
3317 /* I believe it's ok if this is called with a NULL tree */
3318 value = get_int_value(tree, tvb, start, length, encoding);
3319
3320 if (retval) {
3321 int no_of_bits;
3322 *retval = value;
3323 if (hfinfo->bitmask) {
3324 /* Mask out irrelevant portions */
3325 *retval &= (uint32_t)(hfinfo->bitmask);
3326 /* Shift bits */
3327 *retval >>= hfinfo_bitshift(hfinfo);
3328 }
3329 no_of_bits = ws_count_ones(hfinfo->bitmask);
3330 *retval = ws_sign_ext32(*retval, no_of_bits);
3331 }
3332
3333 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3334
3335 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", 3335
, __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", 3335, "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", 3335, "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", 3335, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
3336
3337 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3338
3339 proto_tree_set_int(new_fi, value);
3340
3341 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3342
3343 return proto_tree_add_node(tree, new_fi);
3344}
3345
3346proto_item *
3347proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3348 const int start, int length,
3349 const unsigned encoding, uint32_t *retval)
3350{
3351 header_field_info *hfinfo;
3352 field_info *new_fi;
3353 uint32_t value;
3354
3355 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", 3355, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3355,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3355, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3356
3357 switch (hfinfo->type) {
3358 case FT_CHAR:
3359 case FT_UINT8:
3360 case FT_UINT16:
3361 case FT_UINT24:
3362 case FT_UINT32:
3363 break;
3364 default:
3365 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)
3366 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)
;
3367 }
3368
3369 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3370 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3371 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3372 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3373 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3374 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3375 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3376
3377 if (encoding & ENC_STRING0x03000000) {
3378 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3379 }
3380 /* I believe it's ok if this is called with a NULL tree */
3381 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3382 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3383 uint64_t temp64;
3384 tvb_get_varint(tvb, start, length, &temp64, encoding);
3385 value = (uint32_t)temp64;
3386 } else {
3387 value = get_uint_value(tree, tvb, start, length, encoding);
3388 }
3389
3390 if (retval) {
3391 *retval = value;
3392 if (hfinfo->bitmask) {
3393 /* Mask out irrelevant portions */
3394 *retval &= (uint32_t)(hfinfo->bitmask);
3395 /* Shift bits */
3396 *retval >>= hfinfo_bitshift(hfinfo);
3397 }
3398 }
3399
3400 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3401
3402 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", 3402
, __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", 3402, "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", 3402, "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", 3402, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
3403
3404 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3405
3406 proto_tree_set_uint(new_fi, value);
3407
3408 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3409 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3410 new_fi->flags |= FI_VARINT0x00004000;
3411 }
3412 return proto_tree_add_node(tree, new_fi);
3413}
3414
3415/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3416 * and returns proto_item* and uint value retreived*/
3417proto_item *
3418ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3419 const unsigned encoding, uint32_t *retval)
3420{
3421 field_info *new_fi;
3422 header_field_info *hfinfo;
3423 int item_length;
3424 int offset;
3425 uint32_t value;
3426
3427 offset = ptvc->offset;
3428 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", 3428, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3428,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3428, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3429
3430 switch (hfinfo->type) {
3431 case FT_CHAR:
3432 case FT_UINT8:
3433 case FT_UINT16:
3434 case FT_UINT24:
3435 case FT_UINT32:
3436 break;
3437 default:
3438 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)
3439 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)
;
3440 }
3441
3442 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3443 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3444
3445 /* I believe it's ok if this is called with a NULL tree */
3446 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3447 value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3448
3449 if (retval) {
3450 *retval = value;
3451 if (hfinfo->bitmask) {
3452 /* Mask out irrelevant portions */
3453 *retval &= (uint32_t)(hfinfo->bitmask);
3454 /* Shift bits */
3455 *retval >>= hfinfo_bitshift(hfinfo);
3456 }
3457 }
3458
3459 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3460 item_length, encoding);
3461
3462 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3463
3464 /* Coast clear. Try and fake it */
3465 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", 3465
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3465, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3465, "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", 3465, __func__, "Adding %s would put more than %d 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 ptvc->tree; } }
}
;
3466
3467 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3468
3469 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3470 offset, length, encoding);
3471}
3472
3473/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3474 * and returns proto_item* and int value retreived*/
3475proto_item *
3476ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3477 const unsigned encoding, int32_t *retval)
3478{
3479 field_info *new_fi;
3480 header_field_info *hfinfo;
3481 int item_length;
3482 int offset;
3483 uint32_t value;
3484
3485 offset = ptvc->offset;
3486 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", 3486, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3486,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3486, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3487
3488 switch (hfinfo->type) {
3489 case FT_INT8:
3490 case FT_INT16:
3491 case FT_INT24:
3492 case FT_INT32:
3493 break;
3494 default:
3495 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)
3496 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
3497 }
3498
3499 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3500 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3501
3502 /* I believe it's ok if this is called with a NULL tree */
3503 /* XXX - modify if we ever support EBCDIC FT_CHAR */
3504 value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3505
3506 if (retval) {
3507 int no_of_bits;
3508 *retval = value;
3509 if (hfinfo->bitmask) {
3510 /* Mask out irrelevant portions */
3511 *retval &= (uint32_t)(hfinfo->bitmask);
3512 /* Shift bits */
3513 *retval >>= hfinfo_bitshift(hfinfo);
3514 }
3515 no_of_bits = ws_count_ones(hfinfo->bitmask);
3516 *retval = ws_sign_ext32(*retval, no_of_bits);
3517 }
3518
3519 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3520 item_length, encoding);
3521
3522 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3523
3524 /* Coast clear. Try and fake it */
3525 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", 3525
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3525, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3525, "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", 3525, __func__, "Adding %s would put more than %d 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 ptvc->tree; } }
}
;
3526
3527 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3528
3529 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3530 offset, length, encoding);
3531}
3532
3533/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3534 * and returns proto_item* and string value retreived */
3535proto_item*
3536ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3537{
3538 header_field_info *hfinfo;
3539 field_info *new_fi;
3540 const uint8_t *value;
3541 int item_length;
3542 int offset;
3543
3544 offset = ptvc->offset;
3545
3546 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", 3546
, __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", 3546, "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", 3546, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[hf];
;
3547
3548 switch (hfinfo->type) {
3549 case FT_STRING:
3550 value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3551 break;
3552 case FT_STRINGZ:
3553 value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3554 break;
3555 case FT_UINT_STRING:
3556 value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3557 break;
3558 case FT_STRINGZPAD:
3559 value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3560 break;
3561 case FT_STRINGZTRUNC:
3562 value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3563 break;
3564 default:
3565 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)
3566 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)
;
3567 }
3568
3569 if (retval)
3570 *retval = value;
3571
3572 ptvc->offset += item_length;
3573
3574 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3575
3576 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", 3576, __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", 3576,
"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", 3576, "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", 3576
, __func__, "Adding %s would put more than %d 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 ptvc->tree; } }
}
;
3577
3578 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3579
3580 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3581 offset, length, encoding);
3582}
3583
3584/* Gets data from tvbuff, adds it to proto_tree, increments offset,
3585 * and returns proto_item* and boolean value retreived */
3586proto_item*
3587ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3588{
3589 header_field_info *hfinfo;
3590 field_info *new_fi;
3591 int item_length;
3592 int offset;
3593 uint64_t value, bitval;
3594
3595 offset = ptvc->offset;
3596 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", 3596, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3596,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3596, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3597
3598 if (hfinfo->type != FT_BOOLEAN) {
3599 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)
3600 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3601 }
3602
3603 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3604 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3605 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3606 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3607 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3608 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3609 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3610
3611 if (encoding & ENC_STRING0x03000000) {
3612 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3613 }
3614
3615 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3616 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3617
3618 /* I believe it's ok if this is called with a NULL tree */
3619 value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3620
3621 if (retval) {
3622 bitval = value;
3623 if (hfinfo->bitmask) {
3624 /* Mask out irrelevant portions */
3625 bitval &= hfinfo->bitmask;
3626 }
3627 *retval = (bitval != 0);
3628 }
3629
3630 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
3631 item_length, encoding);
3632
3633 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3634
3635 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", 3635, __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", 3635,
"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", 3635, "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", 3635
, __func__, "Adding %s would put more than %d 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 ptvc->tree; } }
}
;
3636
3637 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3638
3639 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3640 offset, length, encoding);
3641}
3642
3643proto_item *
3644proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3645 const int start, int length, const unsigned encoding, uint64_t *retval)
3646{
3647 header_field_info *hfinfo;
3648 field_info *new_fi;
3649 uint64_t value;
3650
3651 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", 3651, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3651,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3651, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3652
3653 switch (hfinfo->type) {
3654 case FT_UINT40:
3655 case FT_UINT48:
3656 case FT_UINT56:
3657 case FT_UINT64:
3658 break;
3659 default:
3660 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)
3661 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64"
, hfinfo->abbrev)
;
3662 }
3663
3664 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3665 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3666 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3667 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3668 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3669 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3670 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3671
3672 if (encoding & ENC_STRING0x03000000) {
3673 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3674 }
3675 /* I believe it's ok if this is called with a NULL tree */
3676 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3677 tvb_get_varint(tvb, start, length, &value, encoding);
3678 } else {
3679 value = get_uint64_value(tree, tvb, start, length, encoding);
3680 }
3681
3682 if (retval) {
3683 *retval = value;
3684 if (hfinfo->bitmask) {
3685 /* Mask out irrelevant portions */
3686 *retval &= hfinfo->bitmask;
3687 /* Shift bits */
3688 *retval >>= hfinfo_bitshift(hfinfo);
3689 }
3690 }
3691
3692 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3693
3694 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", 3694
, __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", 3694, "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", 3694, "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", 3694, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
3695
3696 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3697
3698 proto_tree_set_uint64(new_fi, value);
3699
3700 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3701 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3702 new_fi->flags |= FI_VARINT0x00004000;
3703 }
3704
3705 return proto_tree_add_node(tree, new_fi);
3706}
3707
3708proto_item *
3709proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3710 const int start, int length, const unsigned encoding, int64_t *retval)
3711{
3712 header_field_info *hfinfo;
3713 field_info *new_fi;
3714 int64_t value;
3715
3716 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", 3716, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3716,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3716, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3717
3718 switch (hfinfo->type) {
3719 case FT_INT40:
3720 case FT_INT48:
3721 case FT_INT56:
3722 case FT_INT64:
3723 break;
3724 default:
3725 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)
3726 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
3727 }
3728
3729 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3730 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3731 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3732 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3733 *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3734 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3735 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3736
3737 if (encoding & ENC_STRING0x03000000) {
3738 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3739 }
3740 /* I believe it's ok if this is called with a NULL tree */
3741 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3742 tvb_get_varint(tvb, start, length, &value, encoding);
3743 }
3744 else {
3745 value = get_int64_value(tree, tvb, start, length, encoding);
3746 }
3747
3748 if (retval) {
3749 *retval = value;
3750 }
3751
3752 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3753
3754 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", 3754
, __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", 3754, "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", 3754, "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", 3754, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
3755
3756 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3757
3758 proto_tree_set_int64(new_fi, value);
3759
3760 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3761 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3762 new_fi->flags |= FI_VARINT0x00004000;
3763 }
3764
3765 return proto_tree_add_node(tree, new_fi);
3766}
3767
3768proto_item *
3769proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3770 const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3771{
3772 header_field_info *hfinfo;
3773 field_info *new_fi;
3774 uint64_t value;
3775
3776 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", 3776, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3776,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3776, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3777
3778 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
))
)) {
3779 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)
3780 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT"
, hfinfo->abbrev)
;
3781 }
3782
3783 /* length validation for native number encoding caught by get_uint64_value() */
3784 /* length has to be -1 or > 0 regardless of encoding */
3785 if (length == 0)
3786 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)
3787 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint"
, length)
;
3788
3789 if (encoding & ENC_STRING0x03000000) {
3790 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3791 }
3792
3793 length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3794
3795 if (retval) {
3796 *retval = value;
3797 if (hfinfo->bitmask) {
3798 /* Mask out irrelevant portions */
3799 *retval &= hfinfo->bitmask;
3800 /* Shift bits */
3801 *retval >>= hfinfo_bitshift(hfinfo);
3802 }
3803 }
3804
3805 if (lenretval) {
3806 *lenretval = length;
3807 }
3808
3809 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3810
3811 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", 3811
, __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", 3811, "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", 3811, "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", 3811, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
3812
3813 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3814
3815 proto_tree_set_uint64(new_fi, value);
3816
3817 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3818 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3819 new_fi->flags |= FI_VARINT0x00004000;
3820 }
3821
3822 return proto_tree_add_node(tree, new_fi);
3823
3824}
3825
3826proto_item *
3827proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3828 const int start, int length,
3829 const unsigned encoding, bool_Bool *retval)
3830{
3831 header_field_info *hfinfo;
3832 field_info *new_fi;
3833 uint64_t value, bitval;
3834
3835 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", 3835, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3835,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3835, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3836
3837 if (hfinfo->type != FT_BOOLEAN) {
3838 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)
3839 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN"
, hfinfo->abbrev)
;
3840 }
3841
3842 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3843 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3844 if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3845 {if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3846 *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3847 }if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
3848 } )if (length < -1 || length == 0 ) { { if(retval) { *retval =
0; } }; return ((void*)0); }
;
3849
3850 if (encoding & ENC_STRING0x03000000) {
3851 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3852 }
3853 /* I believe it's ok if this is called with a NULL tree */
3854 value = get_uint64_value(tree, tvb, start, length, encoding);
3855
3856 if (retval) {
3857 bitval = value;
3858 if (hfinfo->bitmask) {
3859 /* Mask out irrelevant portions */
3860 bitval &= hfinfo->bitmask;
3861 }
3862 *retval = (bitval != 0);
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 tree; } } }
;
3868
3869 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3870
3871 proto_tree_set_boolean(new_fi, value);
3872
3873 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3874
3875 return proto_tree_add_node(tree, new_fi);
3876}
3877
3878proto_item *
3879proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3880 const int start, int length,
3881 const unsigned encoding, float *retval)
3882{
3883 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3884 field_info *new_fi;
3885 float value;
3886
3887 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", 3887,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3888
3889 if (hfinfo->type != FT_FLOAT) {
3890 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)
;
3891 }
3892
3893 if (length != 4) {
3894 report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3895 }
3896
3897 /* treat any nonzero encoding as little endian for backwards compatibility */
3898 value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3899 if (retval) {
3900 *retval = value;
3901 }
3902
3903 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3904
3905 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", 3905
, __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", 3905, "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", 3905, "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", 3905, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
3906
3907 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3908 if (encoding) {
3909 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3910 }
3911
3912 proto_tree_set_float(new_fi, value);
3913
3914 return proto_tree_add_node(tree, new_fi);
3915}
3916
3917proto_item *
3918proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3919 const int start, int length,
3920 const unsigned encoding, double *retval)
3921{
3922 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3923 field_info *new_fi;
3924 double value;
3925
3926 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", 3926,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
3927
3928 if (hfinfo->type != FT_DOUBLE) {
3929 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)
;
3930 }
3931
3932 if (length != 8) {
3933 report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3934 }
3935
3936 /* treat any nonzero encoding as little endian for backwards compatibility */
3937 value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3938 if (retval) {
3939 *retval = value;
3940 }
3941
3942 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3943
3944 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", 3944
, __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", 3944, "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", 3944, "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", 3944, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
3945
3946 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3947 if (encoding) {
3948 new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3949 }
3950
3951 proto_tree_set_double(new_fi, value);
3952
3953 return proto_tree_add_node(tree, new_fi);
3954}
3955
3956proto_item *
3957proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3958 const int start, int length,
3959 const unsigned encoding, ws_in4_addr *retval)
3960{
3961 header_field_info *hfinfo;
3962 field_info *new_fi;
3963 ws_in4_addr value;
3964
3965 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", 3965, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3965,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3965, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
3966
3967 switch (hfinfo->type) {
3968 case FT_IPv4:
3969 break;
3970 default:
3971 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)
3972 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4",
hfinfo->abbrev)
;
3973 }
3974
3975 if (length != FT_IPv4_LEN4)
3976 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)
3977 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4"
, length)
;
3978
3979 if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3980 REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3981 }
3982
3983 /*
3984 * NOTE: to support code written when proto_tree_add_item() took
3985 * a bool as its last argument, with false meaning "big-endian"
3986 * and true meaning "little-endian", we treat any non-zero value
3987 * of "encoding" as meaning "little-endian".
3988 */
3989 value = tvb_get_ipv4(tvb, start);
3990 if (encoding)
3991 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))))
;
3992
3993 if (retval) {
3994 *retval = value;
3995 }
3996
3997 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3998
3999 TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 ||
(unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug
) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3999
, __func__, "Unregistered hf! index=%d", hfinfo->id); ((void
) ((hfinfo->id > 0 && (unsigned)hfinfo->id <
gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3999, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo->
id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 3999, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items
) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3999, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) &&
(hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo
->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols
)) { ((void)0); return tree; } } }
;
4000
4001 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4002
4003 proto_tree_set_ipv4(new_fi, value);
4004
4005 new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4006 return proto_tree_add_node(tree, new_fi);
4007}
4008
4009proto_item *
4010proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4011 const int start, int length,
4012 const unsigned encoding, ws_in6_addr *addr)
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_IPv6:
4021 break;
4022 default:
4023 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)
4024 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6",
hfinfo->abbrev)
;
4025 }
4026
4027 if (length != FT_IPv6_LEN16)
4028 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)
4029 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6"
, length)
;
4030
4031 if (encoding) {
4032 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"
)
;
4033 }
4034
4035 tvb_get_ipv6(tvb, start, addr);
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 tree; } } }
;
4040
4041 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4042
4043 proto_tree_set_ipv6(new_fi, addr);
4044
4045 return proto_tree_add_node(tree, new_fi);
4046}
4047
4048proto_item *
4049proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4050 const int start, int length, const unsigned encoding, uint8_t *retval) {
4051
4052 header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4053 field_info *new_fi;
4054
4055 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", 4055,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4056
4057 switch (hfinfo->type) {
4058 case FT_ETHER:
4059 break;
4060 default:
4061 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)
4062 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER"
, hfinfo->abbrev)
;
4063 }
4064
4065 if (length != FT_ETHER_LEN6)
4066 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)
4067 length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether"
, length)
;
4068
4069 if (encoding) {
4070 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"
)
;
4071 }
4072
4073 tvb_memcpy(tvb, retval, start, length);
4074
4075 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4076
4077 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", 4077
, __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", 4077, "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", 4077, "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", 4077, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4078
4079 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4080
4081 proto_tree_set_ether(new_fi, retval);
4082
4083 return proto_tree_add_node(tree, new_fi);
4084}
4085
4086
4087proto_item *
4088proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4089 tvbuff_t *tvb,
4090 const int start, int length,
4091 const unsigned encoding,
4092 wmem_allocator_t *scope,
4093 const uint8_t **retval,
4094 int *lenretval)
4095{
4096 proto_item *pi;
4097 header_field_info *hfinfo;
4098 field_info *new_fi;
4099 const uint8_t *value;
4100
4101 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", 4101, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4101,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4101, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4102
4103 switch (hfinfo->type) {
4104 case FT_STRING:
4105 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4106 break;
4107 case FT_STRINGZ:
4108 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4109 break;
4110 case FT_UINT_STRING:
4111 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4112 break;
4113 case FT_STRINGZPAD:
4114 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4115 break;
4116 case FT_STRINGZTRUNC:
4117 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4118 break;
4119 default:
4120 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)
4121 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)
;
4122 }
4123
4124 if (retval)
4125 *retval = value;
4126
4127 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4128
4129 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", 4129
, __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", 4129, "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", 4129, "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", 4129, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4130
4131 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4132
4133 proto_tree_set_string(new_fi, value);
4134
4135 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4136
4137 pi = proto_tree_add_node(tree, new_fi);
4138
4139 switch (hfinfo->type) {
4140
4141 case FT_STRINGZ:
4142 case FT_STRINGZPAD:
4143 case FT_STRINGZTRUNC:
4144 case FT_UINT_STRING:
4145 break;
4146
4147 case FT_STRING:
4148 detect_trailing_stray_characters(encoding, value, length, pi);
4149 break;
4150
4151 default:
4152 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4152
, __func__, "assertion \"not reached\" failed")
;
4153 }
4154
4155 return pi;
4156}
4157
4158proto_item *
4159proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4160 const int start, int length,
4161 const unsigned encoding, wmem_allocator_t *scope,
4162 const uint8_t **retval)
4163{
4164 return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4165 tvb, start, length, encoding, scope, retval, &length);
4166}
4167
4168proto_item *
4169proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4170 tvbuff_t *tvb,
4171 const int start, int length,
4172 const unsigned encoding,
4173 wmem_allocator_t *scope,
4174 char **retval,
4175 int *lenretval)
4176{
4177 proto_item *pi;
4178 header_field_info *hfinfo;
4179 field_info *new_fi;
4180 const uint8_t *value;
4181 uint32_t n = 0;
4182
4183 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", 4183, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4183,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4183, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4184
4185 switch (hfinfo->type) {
4186 case FT_STRING:
4187 value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4188 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4189 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4190 break;
4191 case FT_STRINGZ:
4192 value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4193 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4194 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4195 break;
4196 case FT_UINT_STRING:
4197 value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4198 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4199 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4200 break;
4201 case FT_STRINGZPAD:
4202 value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4203 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4204 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4205 break;
4206 case FT_STRINGZTRUNC:
4207 value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4208 *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4209 ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4210 break;
4211 case FT_BYTES:
4212 tvb_ensure_bytes_exist(tvb, start, length);
4213 value = tvb_get_ptr(tvb, start, length);
4214 *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4215 *lenretval = length;
4216 break;
4217 case FT_UINT_BYTES:
4218 n = get_uint_value(tree, tvb, start, length, encoding);
4219 tvb_ensure_bytes_exist(tvb, start + length, n);
4220 value = tvb_get_ptr(tvb, start + length, n);
4221 *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4222 *lenretval = length + n;
4223 break;
4224 default:
4225 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)
4226 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)
;
4227 }
4228
4229 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4230
4231 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", 4231
, __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", 4231, "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", 4231, "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", 4231, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4232
4233 new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4234
4235 switch (hfinfo->type) {
4236
4237 case FT_STRING:
4238 case FT_STRINGZ:
4239 case FT_UINT_STRING:
4240 case FT_STRINGZPAD:
4241 case FT_STRINGZTRUNC:
4242 proto_tree_set_string(new_fi, value);
4243 break;
4244
4245 case FT_BYTES:
4246 proto_tree_set_bytes(new_fi, value, length);
4247 break;
4248
4249 case FT_UINT_BYTES:
4250 proto_tree_set_bytes(new_fi, value, n);
4251 break;
4252
4253 default:
4254 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4254
, __func__, "assertion \"not reached\" failed")
;
4255 }
4256
4257 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4258
4259 pi = proto_tree_add_node(tree, new_fi);
4260
4261 switch (hfinfo->type) {
4262
4263 case FT_STRINGZ:
4264 case FT_STRINGZPAD:
4265 case FT_STRINGZTRUNC:
4266 case FT_UINT_STRING:
4267 break;
4268
4269 case FT_STRING:
4270 detect_trailing_stray_characters(encoding, value, length, pi);
4271 break;
4272
4273 case FT_BYTES:
4274 case FT_UINT_BYTES:
4275 break;
4276
4277 default:
4278 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4278
, __func__, "assertion \"not reached\" failed")
;
4279 }
4280
4281 return pi;
4282}
4283
4284proto_item *
4285proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4286 tvbuff_t *tvb,
4287 const int start, int length,
4288 const unsigned encoding,
4289 wmem_allocator_t *scope,
4290 char **retval)
4291{
4292 return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4293 tvb, start, length, encoding, scope, retval, &length);
4294}
4295
4296proto_item *
4297proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4298 tvbuff_t *tvb,
4299 const int start, int length, const unsigned encoding,
4300 wmem_allocator_t *scope, char **retval)
4301{
4302 header_field_info *hfinfo;
4303 field_info *new_fi;
4304 nstime_t time_stamp;
4305 int flags;
4306
4307 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", 4307, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4307,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4307, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4308
4309 switch (hfinfo->type) {
4310 case FT_ABSOLUTE_TIME:
4311 get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4312 flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4313 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4314 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4315 }
4316 *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4317 break;
4318 case FT_RELATIVE_TIME:
4319 get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4320 *retval = rel_time_to_secs_str(scope, &time_stamp);
4321 break;
4322 default:
4323 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)
4324 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME"
, hfinfo->abbrev)
;
4325 }
4326
4327 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4328
4329 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", 4329
, __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", 4329, "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", 4329, "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", 4329, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4330
4331 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4332
4333 switch (hfinfo->type) {
4334
4335 case FT_ABSOLUTE_TIME:
4336 case FT_RELATIVE_TIME:
4337 proto_tree_set_time(new_fi, &time_stamp);
4338 break;
4339 default:
4340 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4340
, __func__, "assertion \"not reached\" failed")
;
4341 }
4342
4343 new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4344
4345 return proto_tree_add_node(tree, new_fi);
4346}
4347
4348/* Gets data from tvbuff, adds it to proto_tree, increments offset,
4349 and returns proto_item* */
4350proto_item *
4351ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4352 const unsigned encoding)
4353{
4354 field_info *new_fi;
4355 header_field_info *hfinfo;
4356 int item_length;
4357 int offset;
4358
4359 offset = ptvc->offset;
4360 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", 4360, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4360,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4360, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4361 get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4362 test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4363
4364 ptvc->offset += get_full_length(hfinfo, ptvc->tvb, offset, length,
4365 item_length, encoding);
4366
4367 CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4368
4369 /* Coast clear. Try and fake it */
4370 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", 4370
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4370, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4370, "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", 4370, __func__, "Adding %s would put more than %d 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 ptvc->tree; } }
}
;
4371
4372 new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4373
4374 return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4375 offset, length, encoding);
4376}
4377
4378/* Add an item to a proto_tree, using the text label registered to that item;
4379 the item is extracted from the tvbuff handed to it. */
4380proto_item *
4381proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4382 const int start, int length, const unsigned encoding)
4383{
4384 field_info *new_fi;
4385 int item_length;
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 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4393
4394 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", 4394
, __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", 4394, "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", 4394, "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", 4394, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4395
4396 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4397
4398 return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4399}
4400
4401proto_item *
4402proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4403 const int start, int length, const unsigned encoding)
4404{
4405 register header_field_info *hfinfo;
4406
4407 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", 4407, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4407,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4407, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4408 return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4409}
4410
4411/* Add an item to a proto_tree, using the text label registered to that item;
4412 the item is extracted from the tvbuff handed to it.
4413
4414 Return the length of the item through the pointer. */
4415proto_item *
4416proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4417 tvbuff_t *tvb, const int start,
4418 int length, const unsigned encoding,
4419 int *lenretval)
4420{
4421 field_info *new_fi;
4422 int item_length;
4423 proto_item *item;
4424
4425 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", 4425,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4426
4427 get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4428 test_length(hfinfo, tvb, start, item_length, encoding);
4429
4430 if (!tree) {
4431 /*
4432 * We need to get the correct item length here.
4433 * That's normally done by proto_tree_new_item(),
4434 * but we won't be calling it.
4435 */
4436 *lenretval = get_full_length(hfinfo, tvb, start, length,
4437 item_length, encoding);
4438 return NULL((void*)0);
4439 }
4440
4441 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", 4448
, __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", 4448, "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", 4448, "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", 4448
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
4442 /*((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", 4448
, __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", 4448, "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", 4448, "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", 4448
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
4443 * 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", 4448
, __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", 4448, "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", 4448, "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", 4448
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
4444 * 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", 4448
, __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", 4448, "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", 4448, "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", 4448
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
4445 */((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", 4448
, __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", 4448, "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", 4448, "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", 4448
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
4446 *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", 4448
, __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", 4448, "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", 4448, "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", 4448
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
4447 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", 4448
, __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", 4448, "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", 4448, "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", 4448
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
4448 })((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", 4448
, __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", 4448, "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", 4448, "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", 4448
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4449
4450 new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4451
4452 item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4453 *lenretval = new_fi->length;
4454 return item;
4455}
4456
4457proto_item *
4458proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4459 const int start, int length,
4460 const unsigned encoding, int *lenretval)
4461{
4462 register header_field_info *hfinfo;
4463
4464 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", 4464, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4464,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4464, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4465 return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4466}
4467
4468/* which FT_ types can use proto_tree_add_bytes_item() */
4469static inline bool_Bool
4470validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4471{
4472 return (type == FT_BYTES ||
4473 type == FT_UINT_BYTES ||
4474 type == FT_OID ||
4475 type == FT_REL_OID ||
4476 type == FT_SYSTEM_ID );
4477}
4478
4479/* Note: this does no validation that the byte array of an FT_OID or
4480 FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4481 so I think it's ok to continue not validating it?
4482 */
4483proto_item *
4484proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4485 const int start, int length, const unsigned encoding,
4486 GByteArray *retval, int *endoff, int *err)
4487{
4488 field_info *new_fi;
4489 GByteArray *bytes = retval;
4490 GByteArray *created_bytes = NULL((void*)0);
4491 bool_Bool failed = false0;
4492 uint32_t n = 0;
4493 header_field_info *hfinfo;
4494 bool_Bool generate = (bytes || tree) ? true1 : false0;
4495
4496 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", 4496, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4496,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4496, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4497
4498 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", 4498,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4499
4500 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", 4501, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
4501 "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", 4501, "validate_proto_tree_add_bytes_ftype(hfinfo->type)"
, "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type"
))))
;
4502
4503 CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void
*)0); }
;
4504
4505 if (encoding & ENC_STR_NUM0x01000000) {
4506 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"
)
;
4507 }
4508
4509 if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4510 if (hfinfo->type == FT_UINT_BYTES) {
4511 /* can't decode FT_UINT_BYTES from strings */
4512 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")
4513 "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")
;
4514 }
4515
4516 if (!bytes) {
4517 /* caller doesn't care about return value, but we need it to
4518 call tvb_get_string_bytes() and set the tree later */
4519 bytes = created_bytes = g_byte_array_new();
4520 }
4521
4522 /*
4523 * bytes might be NULL after this, but can't add expert
4524 * error until later; if it's NULL, just note that
4525 * it failed.
4526 */
4527 bytes = tvb_get_string_bytes(tvb, start, length, encoding, bytes, endoff);
4528 if (bytes == NULL((void*)0))
4529 failed = true1;
4530 }
4531 else if (generate) {
4532 tvb_ensure_bytes_exist(tvb, start, length);
4533
4534 if (hfinfo->type == FT_UINT_BYTES) {
4535 n = length; /* n is now the "header" length */
4536 length = get_uint_value(tree, tvb, start, n, encoding);
4537 /* length is now the value's length; only store the value in the array */
4538 tvb_ensure_bytes_exist(tvb, start + n, length);
4539 if (!bytes) {
4540 /* caller doesn't care about return value, but
4541 * we may need it to set the tree later */
4542 bytes = created_bytes = g_byte_array_new();
4543 }
4544 g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4545 }
4546 else if (length > 0) {
4547 if (!bytes) {
4548 /* caller doesn't care about return value, but
4549 * we may need it to set the tree later */
4550 bytes = created_bytes = g_byte_array_new();
4551 }
4552 g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4553 }
4554
4555 if (endoff)
4556 *endoff = start + n + length;
4557 }
4558
4559 if (err)
4560 *err = failed ? EINVAL22 : 0;
4561
4562 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); }
4563 {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4564 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); }
4565 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); }
4566 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); }
4567 bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
4568 } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes
, 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return
((void*)0); }
;
4569
4570 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", 4576
, __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", 4576, "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", 4576, "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", 4576
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree
; } } }
4571 {((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", 4576
, __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", 4576, "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", 4576, "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", 4576
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree
; } } }
4572 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", 4576
, __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", 4576, "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", 4576, "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", 4576
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree
; } } }
4573 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", 4576
, __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", 4576, "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", 4576, "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", 4576
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree
; } } }
4574 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", 4576
, __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", 4576, "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", 4576, "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", 4576
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree
; } } }
4575 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", 4576
, __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", 4576, "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", 4576, "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", 4576
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree
; } } }
4576 } )((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", 4576
, __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", 4576, "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", 4576, "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", 4576
, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree
; } } }
;
4577
4578 /* n will be zero except when it's a FT_UINT_BYTES */
4579 new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4580
4581 if (encoding & ENC_STRING0x03000000) {
4582 if (failed)
4583 expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4584
4585 if (bytes)
4586 proto_tree_set_bytes_gbytearray(new_fi, bytes);
4587 else
4588 proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4589
4590 if (created_bytes)
4591 g_byte_array_free(created_bytes, true1);
4592 }
4593 else {
4594 /* n will be zero except when it's a FT_UINT_BYTES */
4595 proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4596
4597 /* XXX: If we have a non-NULL tree but NULL retval, we don't
4598 * use the byte array created above in this case.
4599 */
4600 if (created_bytes)
4601 g_byte_array_free(created_bytes, true1);
4602
4603 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4604 (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)
;
4605 }
4606
4607 return proto_tree_add_node(tree, new_fi);
4608}
4609
4610
4611proto_item *
4612proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4613 const int start, int length, const unsigned encoding,
4614 nstime_t *retval, int *endoff, int *err)
4615{
4616 field_info *new_fi;
4617 nstime_t time_stamp;
4618 int saved_err = 0;
4619 header_field_info *hfinfo;
4620
4621 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", 4621, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4621,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4621, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4622
4623 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", 4623,
"hfinfo != ((void*)0)", "Not passed hfi!"))))
;
4624
4625 CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4626 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4627 if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4628 {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4629 nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4630 }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
4631 } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero
(retval); } }; return ((void*)0); }
;
4632
4633 nstime_set_zero(&time_stamp);
4634
4635 if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4636 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", 4636, ((hfinfo))->abbrev))))
;
4637 /* The only string format that could be a relative time is
4638 * ENC_ISO_8601_TIME, and that is treated as an absolute time
4639 * relative to "now" currently.
4640 */
4641 if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4642 saved_err = EINVAL22;
4643 }
4644 else {
4645 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", 4645, ((hfinfo))->abbrev))))
;
4646 const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4647
4648 tvb_ensure_bytes_exist(tvb, start, length);
4649 get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4650 if (endoff) *endoff = start + length;
4651 }
4652
4653 if (err) *err = saved_err;
4654
4655 if (retval) {
4656 retval->secs = time_stamp.secs;
4657 retval->nsecs = time_stamp.nsecs;
4658 }
4659
4660 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4661
4662 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", 4662
, __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", 4662, "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", 4662, "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", 4662, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4663
4664 new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4665
4666 proto_tree_set_time(new_fi, &time_stamp);
4667
4668 if (encoding & ENC_STRING0x03000000) {
4669 if (saved_err)
4670 expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4671 }
4672 else {
4673 FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | ((
encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while
(0)
4674 (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)
;
4675 }
4676
4677 return proto_tree_add_node(tree, new_fi);
4678}
4679
4680/* Add a FT_NONE to a proto_tree */
4681proto_item *
4682proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4683 const int start, int length, const char *format,
4684 ...)
4685{
4686 proto_item *pi;
4687 va_list ap;
4688 header_field_info *hfinfo;
4689
4690 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4691
4692 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", 4692
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4692, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4692, "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", 4692, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4693
4694 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", 4694
, ((hfinfo))->abbrev))))
;
4695
4696 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4697
4698 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4698, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
4699
4700 va_start(ap, format)__builtin_va_start(ap, format);
4701 proto_tree_set_representation(pi, format, ap);
4702 va_end(ap)__builtin_va_end(ap);
4703
4704 /* no value to set for FT_NONE */
4705 return pi;
4706}
4707
4708/* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4709 * offset, and returns proto_item* */
4710proto_item *
4711ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4712 const unsigned encoding)
4713{
4714 proto_item *item;
4715
4716 item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4717 length, encoding);
4718
4719 return item;
4720}
4721
4722/* Advance the ptvcursor's offset within its tvbuff without
4723 * adding anything to the proto_tree. */
4724void
4725ptvcursor_advance(ptvcursor_t* ptvc, int length)
4726{
4727 ptvc->offset += length;
4728}
4729
4730
4731static void
4732proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4733{
4734 fvalue_set_protocol(fi->value, tvb, field_data, length);
4735}
4736
4737/* Add a FT_PROTOCOL to a proto_tree */
4738proto_item *
4739proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4740 int start, int length, const char *format, ...)
4741{
4742 proto_item *pi;
4743 tvbuff_t *protocol_tvb;
4744 va_list ap;
4745 header_field_info *hfinfo;
4746 char* protocol_rep;
4747
4748 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4749
4750 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", 4750
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4750, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4750, "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", 4750, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4751
4752 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"
, 4752, ((hfinfo))->abbrev))))
;
4753
4754 /*
4755 * This can throw an exception, so do it before we allocate anything.
4756 */
4757 protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4758
4759 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4760
4761 va_start(ap, format)__builtin_va_start(ap, format);
4762 protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4763 proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4764 g_free(protocol_rep);
4765 va_end(ap)__builtin_va_end(ap);
4766
4767 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4767, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
4768
4769 va_start(ap, format)__builtin_va_start(ap, format);
4770 proto_tree_set_representation(pi, format, ap);
4771 va_end(ap)__builtin_va_end(ap);
4772
4773 return pi;
4774}
4775
4776/* Add a FT_BYTES to a proto_tree */
4777proto_item *
4778proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4779 int length, const uint8_t *start_ptr)
4780{
4781 proto_item *pi;
4782 header_field_info *hfinfo;
4783 int item_length;
4784
4785 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", 4785, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4785,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4785, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4786 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4787 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4788
4789 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4790
4791 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", 4791
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4791, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4791, "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", 4791, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4792
4793 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",
4793, ((hfinfo))->abbrev))))
;
4794
4795 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4796 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4797
4798 return pi;
4799}
4800
4801/* Add a FT_BYTES to a proto_tree */
4802proto_item *
4803proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4804 int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4805{
4806 proto_item *pi;
4807 header_field_info *hfinfo;
4808 int item_length;
4809
4810 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", 4810, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4810,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4810, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
4811 get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4812 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4813
4814 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4815
4816 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", 4816
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4816, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4816, "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", 4816, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4817
4818 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",
4818, ((hfinfo))->abbrev))))
;
4819
4820 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4821 proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4822
4823 return pi;
4824}
4825
4826proto_item *
4827proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4828 int start, int length,
4829 const uint8_t *start_ptr,
4830 const char *format, ...)
4831{
4832 proto_item *pi;
4833 va_list ap;
4834
4835 if (start_ptr == NULL((void*)0))
4836 start_ptr = tvb_get_ptr(tvb, start, length);
4837
4838 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4839
4840 TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (!(((pi)->tree_data)->visible
) && proto_item_is_hidden((pi)))) { return pi; }
;
4841
4842 va_start(ap, format)__builtin_va_start(ap, format);
4843 proto_tree_set_representation_value(pi, format, ap);
4844 va_end(ap)__builtin_va_end(ap);
4845
4846 return pi;
4847}
4848
4849proto_item *
4850proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4851 int start, int length, const uint8_t *start_ptr,
4852 const char *format, ...)
4853{
4854 proto_item *pi;
4855 va_list ap;
4856
4857 if (start_ptr == NULL((void*)0))
4858 start_ptr = tvb_get_ptr(tvb, start, length);
4859
4860 pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4861
4862 TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (!(((pi)->tree_data)->visible
) && proto_item_is_hidden((pi)))) { return pi; }
;
4863
4864 va_start(ap, format)__builtin_va_start(ap, format);
4865 proto_tree_set_representation(pi, format, ap);
4866 va_end(ap)__builtin_va_end(ap);
4867
4868 return pi;
4869}
4870
4871static void
4872proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4873{
4874 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4874, "length >= 0"
))))
;
4875 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", 4875, "start_ptr != ((void*)0) || length == 0"
))))
;
4876
4877 fvalue_set_bytes_data(fi->value, start_ptr, length);
4878}
4879
4880
4881static void
4882proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4883{
4884 tvb_ensure_bytes_exist(tvb, offset, length);
4885 proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4886}
4887
4888static void
4889proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4890{
4891 GByteArray *bytes;
4892
4893 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4893, "value != ((void*)0)"
))))
;
4894
4895 bytes = byte_array_dup(value);
4896
4897 fvalue_set_byte_array(fi->value, bytes);
4898}
4899
4900/* Add a FT_*TIME to a proto_tree */
4901proto_item *
4902proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4903 int length, const nstime_t *value_ptr)
4904{
4905 proto_item *pi;
4906 header_field_info *hfinfo;
4907
4908 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4909
4910 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", 4910
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4910, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4910, "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", 4910, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4911
4912 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", 4912, ((hfinfo))->abbrev))))
;
4913
4914 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4915 proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4916
4917 return pi;
4918}
4919
4920proto_item *
4921proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4922 int start, int length, nstime_t *value_ptr,
4923 const char *format, ...)
4924{
4925 proto_item *pi;
4926 va_list ap;
4927
4928 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4929 if (pi != tree) {
4930 va_start(ap, format)__builtin_va_start(ap, format);
4931 proto_tree_set_representation_value(pi, format, ap);
4932 va_end(ap)__builtin_va_end(ap);
4933 }
4934
4935 return pi;
4936}
4937
4938proto_item *
4939proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4940 int start, int length, nstime_t *value_ptr,
4941 const char *format, ...)
4942{
4943 proto_item *pi;
4944 va_list ap;
4945
4946 pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4947 if (pi != tree) {
4948 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 4948, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
4949
4950 va_start(ap, format)__builtin_va_start(ap, format);
4951 proto_tree_set_representation(pi, format, ap);
4952 va_end(ap)__builtin_va_end(ap);
4953 }
4954
4955 return pi;
4956}
4957
4958/* Set the FT_*TIME value */
4959static void
4960proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4961{
4962 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4962, "value_ptr != ((void*)0)"
))))
;
4963
4964 fvalue_set_time(fi->value, value_ptr);
4965}
4966
4967/* Add a FT_IPXNET to a proto_tree */
4968proto_item *
4969proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4970 int length, uint32_t value)
4971{
4972 proto_item *pi;
4973 header_field_info *hfinfo;
4974
4975 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4976
4977 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", 4977
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4977, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 4977, "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", 4977, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
4978
4979 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"
, 4979, ((hfinfo))->abbrev))))
;
4980
4981 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4982 proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
4983
4984 return pi;
4985}
4986
4987proto_item *
4988proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4989 int start, int length, uint32_t value,
4990 const char *format, ...)
4991{
4992 proto_item *pi;
4993 va_list ap;
4994
4995 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
4996 if (pi != tree) {
4997 va_start(ap, format)__builtin_va_start(ap, format);
4998 proto_tree_set_representation_value(pi, format, ap);
4999 va_end(ap)__builtin_va_end(ap);
5000 }
5001
5002 return pi;
5003}
5004
5005proto_item *
5006proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5007 int start, int length, uint32_t value,
5008 const char *format, ...)
5009{
5010 proto_item *pi;
5011 va_list ap;
5012
5013 pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5014 if (pi != tree) {
5015 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5015, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
5016
5017 va_start(ap, format)__builtin_va_start(ap, format);
5018 proto_tree_set_representation(pi, format, ap);
5019 va_end(ap)__builtin_va_end(ap);
5020 }
5021
5022 return pi;
5023}
5024
5025/* Set the FT_IPXNET value */
5026static void
5027proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5028{
5029 fvalue_set_uinteger(fi->value, value);
5030}
5031
5032/* Add a FT_IPv4 to a proto_tree */
5033proto_item *
5034proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5035 int length, ws_in4_addr value)
5036{
5037 proto_item *pi;
5038 header_field_info *hfinfo;
5039
5040 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5041
5042 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", 5042
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5042, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5042, "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", 5042, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
5043
5044 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", 5044
, ((hfinfo))->abbrev))))
;
5045
5046 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5047 proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5048
5049 return pi;
5050}
5051
5052proto_item *
5053proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5054 int start, int length, ws_in4_addr value,
5055 const char *format, ...)
5056{
5057 proto_item *pi;
5058 va_list ap;
5059
5060 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5061 if (pi != tree) {
5062 va_start(ap, format)__builtin_va_start(ap, format);
5063 proto_tree_set_representation_value(pi, format, ap);
5064 va_end(ap)__builtin_va_end(ap);
5065 }
5066
5067 return pi;
5068}
5069
5070proto_item *
5071proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5072 int start, int length, ws_in4_addr value,
5073 const char *format, ...)
5074{
5075 proto_item *pi;
5076 va_list ap;
5077
5078 pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5079 if (pi != tree) {
5080 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5080, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
5081
5082 va_start(ap, format)__builtin_va_start(ap, format);
5083 proto_tree_set_representation(pi, format, ap);
5084 va_end(ap)__builtin_va_end(ap);
5085 }
5086
5087 return pi;
5088}
5089
5090/* Set the FT_IPv4 value */
5091static void
5092proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5093{
5094 ipv4_addr_and_mask ipv4;
5095 ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5096 fvalue_set_ipv4(fi->value, &ipv4);
5097}
5098
5099/* Add a FT_IPv6 to a proto_tree */
5100proto_item *
5101proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5102 int length, const ws_in6_addr *value)
5103{
5104 proto_item *pi;
5105 header_field_info *hfinfo;
5106
5107 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5108
5109 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", 5109
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5109, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5109, "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", 5109, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
5110
5111 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", 5111
, ((hfinfo))->abbrev))))
;
5112
5113 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5114 proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5115
5116 return pi;
5117}
5118
5119proto_item *
5120proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5121 int start, int length,
5122 const ws_in6_addr *value_ptr,
5123 const char *format, ...)
5124{
5125 proto_item *pi;
5126 va_list ap;
5127
5128 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5129 if (pi != tree) {
5130 va_start(ap, format)__builtin_va_start(ap, format);
5131 proto_tree_set_representation_value(pi, format, ap);
5132 va_end(ap)__builtin_va_end(ap);
5133 }
5134
5135 return pi;
5136}
5137
5138proto_item *
5139proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5140 int start, int length,
5141 const ws_in6_addr *value_ptr,
5142 const char *format, ...)
5143{
5144 proto_item *pi;
5145 va_list ap;
5146
5147 pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5148 if (pi != tree) {
5149 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5149, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
5150
5151 va_start(ap, format)__builtin_va_start(ap, format);
5152 proto_tree_set_representation(pi, format, ap);
5153 va_end(ap)__builtin_va_end(ap);
5154 }
5155
5156 return pi;
5157}
5158
5159/* Set the FT_IPv6 value */
5160static void
5161proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5162{
5163 DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5163, "value != ((void*)0)"
))))
;
5164 ipv6_addr_and_prefix ipv6;
5165 ipv6.addr = *value;
5166 ipv6.prefix = 128;
5167 fvalue_set_ipv6(fi->value, &ipv6);
5168}
5169
5170static void
5171proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5172{
5173 proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5174}
5175
5176/* Set the FT_FCWWN value */
5177static void
5178proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5179{
5180 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5180, "value_ptr != ((void*)0)"
))))
;
5181 fvalue_set_fcwwn(fi->value, value_ptr);
5182}
5183
5184static void
5185proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5186{
5187 proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5188}
5189
5190/* Add a FT_GUID to a proto_tree */
5191proto_item *
5192proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5193 int length, const e_guid_t *value_ptr)
5194{
5195 proto_item *pi;
5196 header_field_info *hfinfo;
5197
5198 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5199
5200 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", 5200
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5200, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5200, "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", 5200, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
5201
5202 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", 5202
, ((hfinfo))->abbrev))))
;
5203
5204 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5205 proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5206
5207 return pi;
5208}
5209
5210proto_item *
5211proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5212 int start, int length,
5213 const e_guid_t *value_ptr,
5214 const char *format, ...)
5215{
5216 proto_item *pi;
5217 va_list ap;
5218
5219 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5220 if (pi != tree) {
5221 va_start(ap, format)__builtin_va_start(ap, format);
5222 proto_tree_set_representation_value(pi, format, ap);
5223 va_end(ap)__builtin_va_end(ap);
5224 }
5225
5226 return pi;
5227}
5228
5229proto_item *
5230proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5231 int start, int length, const e_guid_t *value_ptr,
5232 const char *format, ...)
5233{
5234 proto_item *pi;
5235 va_list ap;
5236
5237 pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5238 if (pi != tree) {
5239 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5239, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
5240
5241 va_start(ap, format)__builtin_va_start(ap, format);
5242 proto_tree_set_representation(pi, format, ap);
5243 va_end(ap)__builtin_va_end(ap);
5244 }
5245
5246 return pi;
5247}
5248
5249/* Set the FT_GUID value */
5250static void
5251proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5252{
5253 DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5253, "value_ptr != ((void*)0)"
))))
;
5254 fvalue_set_guid(fi->value, value_ptr);
5255}
5256
5257static void
5258proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5259 const unsigned encoding)
5260{
5261 e_guid_t guid;
5262
5263 tvb_get_guid(tvb, start, &guid, encoding);
5264 proto_tree_set_guid(fi, &guid);
5265}
5266
5267/* Add a FT_OID to a proto_tree */
5268proto_item *
5269proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5270 int length, const uint8_t* value_ptr)
5271{
5272 proto_item *pi;
5273 header_field_info *hfinfo;
5274
5275 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5276
5277 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", 5277
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5277, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5277, "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", 5277, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
5278
5279 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", 5279
, ((hfinfo))->abbrev))))
;
5280
5281 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5282 proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5283
5284 return pi;
5285}
5286
5287proto_item *
5288proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5289 int start, int length,
5290 const uint8_t* value_ptr,
5291 const char *format, ...)
5292{
5293 proto_item *pi;
5294 va_list ap;
5295
5296 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5297 if (pi != tree) {
5298 va_start(ap, format)__builtin_va_start(ap, format);
5299 proto_tree_set_representation_value(pi, format, ap);
5300 va_end(ap)__builtin_va_end(ap);
5301 }
5302
5303 return pi;
5304}
5305
5306proto_item *
5307proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5308 int start, int length, const uint8_t* value_ptr,
5309 const char *format, ...)
5310{
5311 proto_item *pi;
5312 va_list ap;
5313
5314 pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5315 if (pi != tree) {
5316 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5316, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
5317
5318 va_start(ap, format)__builtin_va_start(ap, format);
5319 proto_tree_set_representation(pi, format, ap);
5320 va_end(ap)__builtin_va_end(ap);
5321 }
5322
5323 return pi;
5324}
5325
5326/* Set the FT_OID value */
5327static void
5328proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5329{
5330 GByteArray *bytes;
5331
5332 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", 5332, "value_ptr != ((void*)0) || length == 0"
))))
;
5333
5334 bytes = g_byte_array_new();
5335 if (length > 0) {
5336 g_byte_array_append(bytes, value_ptr, length);
5337 }
5338 fvalue_set_byte_array(fi->value, bytes);
5339}
5340
5341static void
5342proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5343{
5344 proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5345}
5346
5347/* Set the FT_SYSTEM_ID value */
5348static void
5349proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5350{
5351 GByteArray *bytes;
5352
5353 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", 5353, "value_ptr != ((void*)0) || length == 0"
))))
;
5354
5355 bytes = g_byte_array_new();
5356 if (length > 0) {
5357 g_byte_array_append(bytes, value_ptr, length);
5358 }
5359 fvalue_set_byte_array(fi->value, bytes);
5360}
5361
5362static void
5363proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5364{
5365 proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5366}
5367
5368/* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5369 * proto_tree. Creates own copy of string, and frees it when the proto_tree
5370 * is destroyed. */
5371proto_item *
5372proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5373 int length, const char* value)
5374{
5375 proto_item *pi;
5376 header_field_info *hfinfo;
5377 int item_length;
5378
5379 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", 5379, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5379,
"hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5379, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
5380 get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5381 /*
5382 * Special case - if the length is 0, skip the test, so that
5383 * we can have an empty string right after the end of the
5384 * packet. (This handles URL-encoded forms where the last field
5385 * has no value so the form ends right after the =.)
5386 */
5387 if (item_length != 0)
5388 test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5389
5390 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5391
5392 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", 5392
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5392, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5392, "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", 5392, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
5393
5394 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", 5394, ((hfinfo))->abbrev))))
;
5395
5396 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5397 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5397, "length >= 0"
))))
;
5398
5399 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", 5399, __func__, value, -1, __uni_endptr); } }
while (0); } } while (0)
;
5400 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5401
5402 return pi;
5403}
5404
5405proto_item *
5406proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5407 int start, int length, const char* value,
5408 const char *format,
5409 ...)
5410{
5411 proto_item *pi;
5412 va_list ap;
5413
5414 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5415 if (pi != tree) {
5416 va_start(ap, format)__builtin_va_start(ap, format);
5417 proto_tree_set_representation_value(pi, format, ap);
5418 va_end(ap)__builtin_va_end(ap);
5419 }
5420
5421 return pi;
5422}
5423
5424proto_item *
5425proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5426 int start, int length, const char* value,
5427 const char *format, ...)
5428{
5429 proto_item *pi;
5430 va_list ap;
5431
5432 pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5433 if (pi != tree) {
5434 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5434, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
5435
5436 va_start(ap, format)__builtin_va_start(ap, format);
5437 proto_tree_set_representation(pi, format, ap);
5438 va_end(ap)__builtin_va_end(ap);
5439 }
5440
5441 return pi;
5442}
5443
5444/* Set the FT_STRING value */
5445static void
5446proto_tree_set_string(field_info *fi, const char* value)
5447{
5448 if (value) {
5449 fvalue_set_string(fi->value, value);
5450 } else {
5451 /*
5452 * XXX - why is a null value for a string field
5453 * considered valid?
5454 */
5455 fvalue_set_string(fi->value, "[ Null ]");
5456 }
5457}
5458
5459/* Set the FT_AX25 value */
5460static void
5461proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5462{
5463 fvalue_set_ax25(fi->value, value);
5464}
5465
5466static void
5467proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5468{
5469 proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5470}
5471
5472/* Set the FT_VINES value */
5473static void
5474proto_tree_set_vines(field_info *fi, const uint8_t* value)
5475{
5476 fvalue_set_vines(fi->value, value);
5477}
5478
5479static void
5480proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5481{
5482 proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5483}
5484
5485/* Add a FT_ETHER to a proto_tree */
5486proto_item *
5487proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5488 int length, const uint8_t* value)
5489{
5490 proto_item *pi;
5491 header_field_info *hfinfo;
5492
5493 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5494
5495 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", 5495
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5495, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5495, "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", 5495, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
5496
5497 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",
5497, ((hfinfo))->abbrev))))
;
5498
5499 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5500 proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5501
5502 return pi;
5503}
5504
5505proto_item *
5506proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5507 int start, int length, const uint8_t* value,
5508 const char *format, ...)
5509{
5510 proto_item *pi;
5511 va_list ap;
5512
5513 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5514 if (pi != tree) {
5515 va_start(ap, format)__builtin_va_start(ap, format);
5516 proto_tree_set_representation_value(pi, format, ap);
5517 va_end(ap)__builtin_va_end(ap);
5518 }
5519
5520 return pi;
5521}
5522
5523proto_item *
5524proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5525 int start, int length, const uint8_t* value,
5526 const char *format, ...)
5527{
5528 proto_item *pi;
5529 va_list ap;
5530
5531 pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5532 if (pi != tree) {
5533 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5533, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
5534
5535 va_start(ap, format)__builtin_va_start(ap, format);
5536 proto_tree_set_representation(pi, format, ap);
5537 va_end(ap)__builtin_va_end(ap);
5538 }
5539
5540 return pi;
5541}
5542
5543/* Set the FT_ETHER value */
5544static void
5545proto_tree_set_ether(field_info *fi, const uint8_t* value)
5546{
5547 fvalue_set_ether(fi->value, value);
5548}
5549
5550static void
5551proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5552{
5553 proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5554}
5555
5556/* Add a FT_BOOLEAN to a proto_tree */
5557proto_item *
5558proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5559 int length, uint64_t value)
5560{
5561 proto_item *pi;
5562 header_field_info *hfinfo;
5563
5564 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5565
5566 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", 5566
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5566, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5566, "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", 5566, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
5567
5568 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"
, 5568, ((hfinfo))->abbrev))))
;
5569
5570 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5571 proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5572
5573 return pi;
5574}
5575
5576proto_item *
5577proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5578 tvbuff_t *tvb, int start, int length,
5579 uint64_t value, const char *format, ...)
5580{
5581 proto_item *pi;
5582 va_list ap;
5583
5584 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5585 if (pi != tree) {
5586 va_start(ap, format)__builtin_va_start(ap, format);
5587 proto_tree_set_representation_value(pi, format, ap);
5588 va_end(ap)__builtin_va_end(ap);
5589 }
5590
5591 return pi;
5592}
5593
5594proto_item *
5595proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5596 int start, int length, uint64_t value,
5597 const char *format, ...)
5598{
5599 proto_item *pi;
5600 va_list ap;
5601
5602 pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5603 if (pi != tree) {
5604 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5604, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
5605
5606 va_start(ap, format)__builtin_va_start(ap, format);
5607 proto_tree_set_representation(pi, format, ap);
5608 va_end(ap)__builtin_va_end(ap);
5609 }
5610
5611 return pi;
5612}
5613
5614/* Set the FT_BOOLEAN value */
5615static void
5616proto_tree_set_boolean(field_info *fi, uint64_t value)
5617{
5618 proto_tree_set_uint64(fi, value);
5619}
5620
5621/* Generate, into "buf", a string showing the bits of a bitfield.
5622 Return a pointer to the character after that string. */
5623static char *
5624other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5625{
5626 int i = 0;
5627 uint64_t bit;
5628 char *p;
5629
5630 p = buf;
5631
5632 /* This is a devel error. It is safer to stop here. */
5633 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5633, "width >= 1"
))))
;
5634
5635 bit = UINT64_C(1)1UL << (width - 1);
5636 for (;;) {
5637 if (mask & bit) {
5638 /* This bit is part of the field. Show its value. */
5639 if (val & bit)
5640 *p++ = '1';
5641 else
5642 *p++ = '0';
5643 } else {
5644 /* This bit is not part of the field. */
5645 *p++ = '.';
5646 }
5647 bit >>= 1;
5648 i++;
5649 if (i >= width)
5650 break;
5651 if (i % 4 == 0)
5652 *p++ = ' ';
5653 }
5654 *p = '\0';
5655 return p;
5656}
5657
5658static char *
5659decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5660{
5661 char *p;
5662
5663 p = other_decode_bitfield_value(buf, val, mask, width);
5664 p = g_stpcpy(p, " = ");
5665
5666 return p;
5667}
5668
5669static char *
5670other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5671{
5672 int i = 0;
5673 uint64_t bit;
5674 char *p;
5675
5676 p = buf;
5677
5678 /* This is a devel error. It is safer to stop here. */
5679 DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5679, "width >= 1"
))))
;
5680
5681 bit = UINT64_C(1)1UL << (width - 1);
5682 for (;;) {
5683 if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5684 (mask & bit)) {
5685 /* This bit is part of the field. Show its value. */
5686 if (val & bit)
5687 *p++ = '1';
5688 else
5689 *p++ = '0';
5690 } else {
5691 /* This bit is not part of the field. */
5692 *p++ = '.';
5693 }
5694 bit >>= 1;
5695 i++;
5696 if (i >= width)
5697 break;
5698 if (i % 4 == 0)
5699 *p++ = ' ';
5700 }
5701
5702 *p = '\0';
5703 return p;
5704}
5705
5706static char *
5707decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5708{
5709 char *p;
5710
5711 p = other_decode_bitfield_varint_value(buf, val, mask, width);
5712 p = g_stpcpy(p, " = ");
5713
5714 return p;
5715}
5716
5717/* Add a FT_FLOAT to a proto_tree */
5718proto_item *
5719proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5720 int length, float value)
5721{
5722 proto_item *pi;
5723 header_field_info *hfinfo;
5724
5725 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5726
5727 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", 5727
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5727, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5727, "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", 5727, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
5728
5729 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",
5729, ((hfinfo))->abbrev))))
;
5730
5731 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5732 proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5733
5734 return pi;
5735}
5736
5737proto_item *
5738proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5739 int start, int length, float value,
5740 const char *format, ...)
5741{
5742 proto_item *pi;
5743 va_list ap;
5744
5745 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5746 if (pi != tree) {
5747 va_start(ap, format)__builtin_va_start(ap, format);
5748 proto_tree_set_representation_value(pi, format, ap);
5749 va_end(ap)__builtin_va_end(ap);
5750 }
5751
5752 return pi;
5753}
5754
5755proto_item *
5756proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5757 int start, int length, float value,
5758 const char *format, ...)
5759{
5760 proto_item *pi;
5761 va_list ap;
5762
5763 pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5764 if (pi != tree) {
5765 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5765, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
5766
5767 va_start(ap, format)__builtin_va_start(ap, format);
5768 proto_tree_set_representation(pi, format, ap);
5769 va_end(ap)__builtin_va_end(ap);
5770 }
5771
5772 return pi;
5773}
5774
5775/* Set the FT_FLOAT value */
5776static void
5777proto_tree_set_float(field_info *fi, float value)
5778{
5779 fvalue_set_floating(fi->value, value);
5780}
5781
5782/* Add a FT_DOUBLE to a proto_tree */
5783proto_item *
5784proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5785 int length, double value)
5786{
5787 proto_item *pi;
5788 header_field_info *hfinfo;
5789
5790 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5791
5792 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", 5792
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5792, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5792, "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", 5792, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
5793
5794 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"
, 5794, ((hfinfo))->abbrev))))
;
5795
5796 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5797 proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5798
5799 return pi;
5800}
5801
5802proto_item *
5803proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5804 int start, int length, double value,
5805 const char *format, ...)
5806{
5807 proto_item *pi;
5808 va_list ap;
5809
5810 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5811 if (pi != tree) {
5812 va_start(ap, format)__builtin_va_start(ap, format);
5813 proto_tree_set_representation_value(pi, format, ap);
5814 va_end(ap)__builtin_va_end(ap);
5815 }
5816
5817 return pi;
5818}
5819
5820proto_item *
5821proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5822 int start, int length, double value,
5823 const char *format, ...)
5824{
5825 proto_item *pi;
5826 va_list ap;
5827
5828 pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5829 if (pi != tree) {
5830 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5830, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
5831
5832 va_start(ap, format)__builtin_va_start(ap, format);
5833 proto_tree_set_representation(pi, format, ap);
5834 va_end(ap)__builtin_va_end(ap);
5835 }
5836
5837 return pi;
5838}
5839
5840/* Set the FT_DOUBLE value */
5841static void
5842proto_tree_set_double(field_info *fi, double value)
5843{
5844 fvalue_set_floating(fi->value, value);
5845}
5846
5847/* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5848proto_item *
5849proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5850 int length, uint32_t value)
5851{
5852 proto_item *pi = NULL((void*)0);
5853 header_field_info *hfinfo;
5854
5855 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5856
5857 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", 5857
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5857, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5857, "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", 5857, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
5858
5859 switch (hfinfo->type) {
5860 case FT_CHAR:
5861 case FT_UINT8:
5862 case FT_UINT16:
5863 case FT_UINT24:
5864 case FT_UINT32:
5865 case FT_FRAMENUM:
5866 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5867 proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5868 break;
5869
5870 default:
5871 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)
5872 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)
;
5873 }
5874
5875 return pi;
5876}
5877
5878proto_item *
5879proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5880 int start, int length, uint32_t value,
5881 const char *format, ...)
5882{
5883 proto_item *pi;
5884 va_list ap;
5885
5886 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5887 if (pi != tree) {
5888 va_start(ap, format)__builtin_va_start(ap, format);
5889 proto_tree_set_representation_value(pi, format, ap);
5890 va_end(ap)__builtin_va_end(ap);
5891 }
5892
5893 return pi;
5894}
5895
5896proto_item *
5897proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5898 int start, int length, uint32_t value,
5899 const char *format, ...)
5900{
5901 proto_item *pi;
5902 va_list ap;
5903
5904 pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5905 if (pi != tree) {
5906 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5906, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
5907
5908 va_start(ap, format)__builtin_va_start(ap, format);
5909 proto_tree_set_representation(pi, format, ap);
5910 va_end(ap)__builtin_va_end(ap);
5911 }
5912
5913 return pi;
5914}
5915
5916/* Set the FT_UINT{8,16,24,32} value */
5917static void
5918proto_tree_set_uint(field_info *fi, uint32_t value)
5919{
5920 const header_field_info *hfinfo;
5921 uint32_t integer;
5922
5923 hfinfo = fi->hfinfo;
5924 integer = value;
5925
5926 if (hfinfo->bitmask) {
5927 /* Mask out irrelevant portions */
5928 integer &= (uint32_t)(hfinfo->bitmask);
5929
5930 /* Shift bits */
5931 integer >>= hfinfo_bitshift(hfinfo);
5932
5933 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
5934 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)
;
5935 }
5936
5937 fvalue_set_uinteger(fi->value, integer);
5938}
5939
5940/* Add FT_UINT{40,48,56,64} to a proto_tree */
5941proto_item *
5942proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5943 int length, uint64_t value)
5944{
5945 proto_item *pi = NULL((void*)0);
5946 header_field_info *hfinfo;
5947
5948 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5949
5950 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", 5950
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5950, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 5950, "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", 5950, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
5951
5952 switch (hfinfo->type) {
5953 case FT_UINT40:
5954 case FT_UINT48:
5955 case FT_UINT56:
5956 case FT_UINT64:
5957 case FT_FRAMENUM:
5958 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5959 proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5960 break;
5961
5962 default:
5963 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)
5964 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)
;
5965 }
5966
5967 return pi;
5968}
5969
5970proto_item *
5971proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5972 int start, int length, uint64_t value,
5973 const char *format, ...)
5974{
5975 proto_item *pi;
5976 va_list ap;
5977
5978 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5979 if (pi != tree) {
5980 va_start(ap, format)__builtin_va_start(ap, format);
5981 proto_tree_set_representation_value(pi, format, ap);
5982 va_end(ap)__builtin_va_end(ap);
5983 }
5984
5985 return pi;
5986}
5987
5988proto_item *
5989proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5990 int start, int length, uint64_t value,
5991 const char *format, ...)
5992{
5993 proto_item *pi;
5994 va_list ap;
5995
5996 pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
5997 if (pi != tree) {
5998 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 5998, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
5999
6000 va_start(ap, format)__builtin_va_start(ap, format);
6001 proto_tree_set_representation(pi, format, ap);
6002 va_end(ap)__builtin_va_end(ap);
6003 }
6004
6005 return pi;
6006}
6007
6008/* Set the FT_UINT{40,48,56,64} value */
6009static void
6010proto_tree_set_uint64(field_info *fi, uint64_t value)
6011{
6012 const header_field_info *hfinfo;
6013 uint64_t integer;
6014
6015 hfinfo = fi->hfinfo;
6016 integer = value;
6017
6018 if (hfinfo->bitmask) {
6019 /* Mask out irrelevant portions */
6020 integer &= hfinfo->bitmask;
6021
6022 /* Shift bits */
6023 integer >>= hfinfo_bitshift(hfinfo);
6024
6025 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
6026 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)
;
6027 }
6028
6029 fvalue_set_uinteger64(fi->value, integer);
6030}
6031
6032/* Add FT_INT{8,16,24,32} to a proto_tree */
6033proto_item *
6034proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6035 int length, int32_t value)
6036{
6037 proto_item *pi = NULL((void*)0);
6038 header_field_info *hfinfo;
6039
6040 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6041
6042 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", 6042
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6042, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6042, "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", 6042, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
6043
6044 switch (hfinfo->type) {
6045 case FT_INT8:
6046 case FT_INT16:
6047 case FT_INT24:
6048 case FT_INT32:
6049 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6050 proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6051 break;
6052
6053 default:
6054 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)
6055 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32"
, hfinfo->abbrev)
;
6056 }
6057
6058 return pi;
6059}
6060
6061proto_item *
6062proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6063 int start, int length, int32_t value,
6064 const char *format, ...)
6065{
6066 proto_item *pi;
6067 va_list ap;
6068
6069 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6070 if (pi != tree) {
6071 va_start(ap, format)__builtin_va_start(ap, format);
6072 proto_tree_set_representation_value(pi, format, ap);
6073 va_end(ap)__builtin_va_end(ap);
6074 }
6075
6076 return pi;
6077}
6078
6079proto_item *
6080proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6081 int start, int length, int32_t value,
6082 const char *format, ...)
6083{
6084 proto_item *pi;
6085 va_list ap;
6086
6087 pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6088 if (pi != tree) {
6089 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6089, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
6090
6091 va_start(ap, format)__builtin_va_start(ap, format);
6092 proto_tree_set_representation(pi, format, ap);
6093 va_end(ap)__builtin_va_end(ap);
6094 }
6095
6096 return pi;
6097}
6098
6099/* Set the FT_INT{8,16,24,32} value */
6100static void
6101proto_tree_set_int(field_info *fi, int32_t value)
6102{
6103 const header_field_info *hfinfo;
6104 uint32_t integer;
6105 int no_of_bits;
6106
6107 hfinfo = fi->hfinfo;
6108 integer = (uint32_t) value;
6109
6110 if (hfinfo->bitmask) {
6111 /* Mask out irrelevant portions */
6112 integer &= (uint32_t)(hfinfo->bitmask);
6113
6114 /* Shift bits */
6115 integer >>= hfinfo_bitshift(hfinfo);
6116
6117 no_of_bits = ws_count_ones(hfinfo->bitmask);
6118 integer = ws_sign_ext32(integer, no_of_bits);
6119
6120 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
6121 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)
;
6122 }
6123
6124 fvalue_set_sinteger(fi->value, integer);
6125}
6126
6127/* Add FT_INT{40,48,56,64} to a proto_tree */
6128proto_item *
6129proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6130 int length, int64_t value)
6131{
6132 proto_item *pi = NULL((void*)0);
6133 header_field_info *hfinfo;
6134
6135 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6136
6137 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", 6137
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6137, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6137, "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", 6137, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
6138
6139 switch (hfinfo->type) {
6140 case FT_INT40:
6141 case FT_INT48:
6142 case FT_INT56:
6143 case FT_INT64:
6144 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6145 proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6146 break;
6147
6148 default:
6149 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)
6150 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64"
, hfinfo->abbrev)
;
6151 }
6152
6153 return pi;
6154}
6155
6156proto_item *
6157proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6158 int start, int length, int64_t value,
6159 const char *format, ...)
6160{
6161 proto_item *pi;
6162 va_list ap;
6163
6164 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6165 if (pi != tree) {
6166 va_start(ap, format)__builtin_va_start(ap, format);
6167 proto_tree_set_representation_value(pi, format, ap);
6168 va_end(ap)__builtin_va_end(ap);
6169 }
6170
6171 return pi;
6172}
6173
6174/* Set the FT_INT{40,48,56,64} value */
6175static void
6176proto_tree_set_int64(field_info *fi, int64_t value)
6177{
6178 const header_field_info *hfinfo;
6179 uint64_t integer;
6180 int no_of_bits;
6181
6182 hfinfo = fi->hfinfo;
6183 integer = value;
6184
6185 if (hfinfo->bitmask) {
6186 /* Mask out irrelevant portions */
6187 integer &= hfinfo->bitmask;
6188
6189 /* Shift bits */
6190 integer >>= hfinfo_bitshift(hfinfo);
6191
6192 no_of_bits = ws_count_ones(hfinfo->bitmask);
6193 integer = ws_sign_ext64(integer, no_of_bits);
6194
6195 FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset
(hfinfo)) & 7) << 5)); } while(0)
;
6196 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)
;
6197 }
6198
6199 fvalue_set_sinteger64(fi->value, integer);
6200}
6201
6202proto_item *
6203proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6204 int start, int length, int64_t value,
6205 const char *format, ...)
6206{
6207 proto_item *pi;
6208 va_list ap;
6209
6210 pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6211 if (pi != tree) {
6212 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6212, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
6213
6214 va_start(ap, format)__builtin_va_start(ap, format);
6215 proto_tree_set_representation(pi, format, ap);
6216 va_end(ap)__builtin_va_end(ap);
6217 }
6218
6219 return pi;
6220}
6221
6222/* Add a FT_EUI64 to a proto_tree */
6223proto_item *
6224proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6225 int length, const uint64_t value)
6226{
6227 proto_item *pi;
6228 header_field_info *hfinfo;
6229
6230 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6231
6232 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", 6232
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6232, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 6232, "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", 6232, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
6233
6234 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",
6234, ((hfinfo))->abbrev))))
;
6235
6236 pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6237 proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6238
6239 return pi;
6240}
6241
6242proto_item *
6243proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6244 int start, int length, const uint64_t value,
6245 const char *format, ...)
6246{
6247 proto_item *pi;
6248 va_list ap;
6249
6250 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6251 if (pi != tree) {
6252 va_start(ap, format)__builtin_va_start(ap, format);
6253 proto_tree_set_representation_value(pi, format, ap);
6254 va_end(ap)__builtin_va_end(ap);
6255 }
6256
6257 return pi;
6258}
6259
6260proto_item *
6261proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6262 int start, int length, const uint64_t value,
6263 const char *format, ...)
6264{
6265 proto_item *pi;
6266 va_list ap;
6267
6268 pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6269 if (pi != tree) {
6270 TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6270, __func__, "assertion failed: %s", "pi"
); } while (0); if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return pi; }
;
6271
6272 va_start(ap, format)__builtin_va_start(ap, format);
6273 proto_tree_set_representation(pi, format, ap);
6274 va_end(ap)__builtin_va_end(ap);
6275 }
6276
6277 return pi;
6278}
6279
6280/* Set the FT_EUI64 value */
6281static void
6282proto_tree_set_eui64(field_info *fi, const uint64_t value)
6283{
6284 fvalue_set_uinteger64(fi->value, value);
6285}
6286static void
6287proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6288{
6289 if (encoding)
6290 {
6291 proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6292 } else {
6293 proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6294 }
6295}
6296
6297proto_item *
6298proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6299 const mac_hf_list_t *list_generic,
6300 int idx, tvbuff_t *tvb,
6301 proto_tree *tree, int offset)
6302{
6303 const uint8_t addr[6];
6304 const char *addr_name = NULL((void*)0);
6305 const char *oui_name = NULL((void*)0);
6306 proto_item *addr_item = NULL((void*)0);
6307 proto_tree *addr_tree = NULL((void*)0);
6308 proto_item *ret_val = NULL((void*)0);
6309
6310 if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6311 return NULL((void*)0);
6312 }
6313
6314 /* Resolve what we can of the address */
6315 tvb_memcpy(tvb, (void *)addr, offset, 6);
6316 if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6317 addr_name = get_ether_name(addr);
6318 }
6319 if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6320 oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6321 }
6322
6323 /* Add the item for the specific address type */
6324 ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_NA0x00000000);
6325 if (idx >= 0) {
6326 addr_tree = proto_item_add_subtree(ret_val, idx);
6327 }
6328 else {
6329 addr_tree = tree;
6330 }
6331
6332 if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6333 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6334 tvb, offset, 6, addr_name);
6335 proto_item_set_generated(addr_item);
6336 proto_item_set_hidden(addr_item);
6337 }
6338
6339 if (list_specific->hf_oui != NULL((void*)0)) {
6340 addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_NA0x00000000);
6341 proto_item_set_generated(addr_item);
6342 proto_item_set_hidden(addr_item);
6343
6344 if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6345 addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6346 proto_item_set_generated(addr_item);
6347 proto_item_set_hidden(addr_item);
6348 }
6349 }
6350
6351 if (list_specific->hf_lg != NULL((void*)0)) {
6352 proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6353 }
6354 if (list_specific->hf_ig != NULL((void*)0)) {
6355 proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6356 }
6357
6358 /* Were we given a list for generic address fields? If not, stop here */
6359 if (list_generic == NULL((void*)0)) {
6360 return ret_val;
6361 }
6362
6363 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_NA0x00000000);
6364 proto_item_set_hidden(addr_item);
6365
6366 if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6367 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6368 tvb, offset, 6, addr_name);
6369 proto_item_set_generated(addr_item);
6370 proto_item_set_hidden(addr_item);
6371 }
6372
6373 if (list_generic->hf_oui != NULL((void*)0)) {
6374 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_NA0x00000000);
6375 proto_item_set_generated(addr_item);
6376 proto_item_set_hidden(addr_item);
6377
6378 if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6379 addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6380 proto_item_set_generated(addr_item);
6381 proto_item_set_hidden(addr_item);
6382 }
6383 }
6384
6385 if (list_generic->hf_lg != NULL((void*)0)) {
6386 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6387 proto_item_set_hidden(addr_item);
6388 }
6389 if (list_generic->hf_ig != NULL((void*)0)) {
6390 addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6391 proto_item_set_hidden(addr_item);
6392 }
6393 return ret_val;
6394}
6395
6396/* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6397static proto_item *
6398proto_tree_add_node(proto_tree *tree, field_info *fi)
6399{
6400 proto_node *pnode, *tnode, *sibling;
6401 field_info *tfi;
6402 unsigned depth = 1;
6403
6404 /*
6405 * Restrict our depth. proto_tree_traverse_pre_order and
6406 * proto_tree_traverse_post_order (and possibly others) are recursive
6407 * so we need to be mindful of our stack size.
6408 */
6409 if (tree->first_child == NULL((void*)0)) {
6410 for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6411 depth++;
6412 if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6413 fvalue_free(fi->value);
6414 fi->value = NULL((void*)0);
6415 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__)), 6418)))
6416 "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__)), 6418)))
6417 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__)), 6418)))
6418 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__)), 6418)))
;
6419 }
6420 }
6421 }
6422
6423 /*
6424 * Make sure "tree" is ready to have subtrees under it, by
6425 * checking whether it's been given an ett_ value.
6426 *
6427 * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6428 * node of the protocol tree. That node is not displayed,
6429 * so it doesn't need an ett_ value to remember whether it
6430 * was expanded.
6431 */
6432 tnode = tree;
6433 tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6434 if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6435 /* Since we are not adding fi to a node, its fvalue won't get
6436 * freed by proto_tree_free_node(), so free it now.
6437 */
6438 fvalue_free(fi->value);
6439 fi->value = NULL((void*)0);
6440 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", 6441)
6441 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", 6441)
;
6442 /* XXX - is it safe to continue here? */
6443 }
6444
6445 pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo->
pool)), sizeof(proto_node)))
;
6446 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
6447 pnode->parent = tnode;
6448 PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6449 pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6450
6451 if (tnode->last_child != NULL((void*)0)) {
6452 sibling = tnode->last_child;
6453 DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6453, "sibling->next == ((void*)0)"
))))
;
6454 sibling->next = pnode;
6455 } else
6456 tnode->first_child = pnode;
6457 tnode->last_child = pnode;
6458
6459 tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6460
6461 return (proto_item *)pnode;
6462}
6463
6464
6465/* Generic way to allocate field_info and add to proto_tree.
6466 * Sets *pfi to address of newly-allocated field_info struct */
6467static proto_item *
6468proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6469 int *length)
6470{
6471 proto_item *pi;
6472 field_info *fi;
6473 int item_length;
6474
6475 get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6476 fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6477 pi = proto_tree_add_node(tree, fi);
6478
6479 return pi;
6480}
6481
6482
6483static void
6484get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6485 int *item_length, const unsigned encoding)
6486{
6487 int length_remaining;
6488
6489 /*
6490 * We only allow a null tvbuff if the item has a zero length,
6491 * i.e. if there's no data backing it.
6492 */
6493 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", 6493, "tvb != ((void*)0) || *length == 0"
))))
;
6494
6495 /*
6496 * XXX - in some protocols, there are 32-bit unsigned length
6497 * fields, so lengths in protocol tree and tvbuff routines
6498 * should really be unsigned. We should have, for those
6499 * field types for which "to the end of the tvbuff" makes sense,
6500 * additional routines that take no length argument and
6501 * add fields that run to the end of the tvbuff.
6502 */
6503 if (*length == -1) {
6504 /*
6505 * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6506 * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6507 * of -1 means "set the length to what remains in the
6508 * tvbuff".
6509 *
6510 * The assumption is either that
6511 *
6512 * 1) the length of the item can only be determined
6513 * by dissection (typically true of items with
6514 * subitems, which are probably FT_NONE or
6515 * FT_PROTOCOL)
6516 *
6517 * or
6518 *
6519 * 2) if the tvbuff is "short" (either due to a short
6520 * snapshot length or due to lack of reassembly of
6521 * fragments/segments/whatever), we want to display
6522 * what's available in the field (probably FT_BYTES
6523 * or FT_STRING) and then throw an exception later
6524 *
6525 * or
6526 *
6527 * 3) the field is defined to be "what's left in the
6528 * packet"
6529 *
6530 * so we set the length to what remains in the tvbuff so
6531 * that, if we throw an exception while dissecting, it
6532 * has what is probably the right value.
6533 *
6534 * For FT_STRINGZ, it means "the string is null-terminated,
6535 * not null-padded; set the length to the actual length
6536 * of the string", and if the tvbuff if short, we just
6537 * throw an exception.
6538 *
6539 * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV, it means "find the end of the string",
6540 * and if the tvbuff if short, we just throw an exception.
6541 *
6542 * It's not valid for any other type of field. For those
6543 * fields, we treat -1 the same way we treat other
6544 * negative values - we assume the length is a Really
6545 * Big Positive Number, and throw a ReportedBoundsError
6546 * exception, under the assumption that the Really Big
6547 * Length would run past the end of the packet.
6548 */
6549 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
))
)) {
6550 if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6551 /*
6552 * Leave the length as -1, so our caller knows
6553 * it was -1.
6554 */
6555 *item_length = *length;
6556 return;
6557 } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6558 switch (tvb_get_uint8(tvb, start) >> 6)
6559 {
6560 case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6561 *item_length = 1;
6562 break;
6563 case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6564 *item_length = 2;
6565 break;
6566 case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6567 *item_length = 4;
6568 break;
6569 case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6570 *item_length = 8;
6571 break;
6572 }
6573 }
6574 }
6575
6576 switch (hfinfo->type) {
6577
6578 case FT_PROTOCOL:
6579 case FT_NONE:
6580 case FT_BYTES:
6581 case FT_STRING:
6582 case FT_STRINGZPAD:
6583 case FT_STRINGZTRUNC:
6584 /*
6585 * We allow FT_PROTOCOLs to be zero-length -
6586 * for example, an ONC RPC NULL procedure has
6587 * neither arguments nor reply, so the
6588 * payload for that protocol is empty.
6589 *
6590 * We also allow the others to be zero-length -
6591 * because that's the way the code has been for a
6592 * long, long time.
6593 *
6594 * However, we want to ensure that the start
6595 * offset is not *past* the byte past the end
6596 * of the tvbuff: we throw an exception in that
6597 * case.
6598 */
6599 *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6600 DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6600, "*length >= 0"
))))
;
6601 break;
6602
6603 case FT_STRINGZ:
6604 /*
6605 * Leave the length as -1, so our caller knows
6606 * it was -1.
6607 */
6608 break;
6609
6610 default:
6611 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6612 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 6612))
;
6613 }
6614 *item_length = *length;
6615 } else {
6616 *item_length = *length;
6617 if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6618 /*
6619 * These types are for interior nodes of the
6620 * tree, and don't have data associated with
6621 * them; if the length is negative (XXX - see
6622 * above) or goes past the end of the tvbuff,
6623 * cut it short at the end of the tvbuff.
6624 * That way, if this field is selected in
6625 * Wireshark, we don't highlight stuff past
6626 * the end of the data.
6627 */
6628 /* XXX - what to do, if we don't have a tvb? */
6629 if (tvb) {
6630 length_remaining = tvb_captured_length_remaining(tvb, start);
6631 if (*item_length < 0 ||
6632 (*item_length > 0 &&
6633 (length_remaining < *item_length)))
6634 *item_length = length_remaining;
6635 }
6636 }
6637 if (*item_length < 0) {
6638 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6639 }
6640 }
6641}
6642
6643static int
6644get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6645 int length, unsigned item_length, const int encoding)
6646{
6647 uint32_t n;
6648
6649 /*
6650 * We need to get the correct item length here.
6651 * That's normally done by proto_tree_new_item(),
6652 * but we won't be calling it.
6653 */
6654 switch (hfinfo->type) {
6655
6656 case FT_NONE:
6657 case FT_PROTOCOL:
6658 case FT_BYTES:
6659 /*
6660 * The length is the specified length.
6661 */
6662 break;
6663
6664 case FT_UINT_BYTES:
6665 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6666 item_length += n;
6667 if ((int)item_length < length) {
6668 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6669 }
6670 break;
6671
6672 /* XXX - make these just FT_UINT? */
6673 case FT_UINT8:
6674 case FT_UINT16:
6675 case FT_UINT24:
6676 case FT_UINT32:
6677 case FT_UINT40:
6678 case FT_UINT48:
6679 case FT_UINT56:
6680 case FT_UINT64:
6681 /* XXX - make these just FT_INT? */
6682 case FT_INT8:
6683 case FT_INT16:
6684 case FT_INT24:
6685 case FT_INT32:
6686 case FT_INT40:
6687 case FT_INT48:
6688 case FT_INT56:
6689 case FT_INT64:
6690 if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6691 if (length < -1) {
6692 report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6693 }
6694 if (length == -1) {
6695 uint64_t dummy;
6696 /* This can throw an exception */
6697 /* XXX - do this without fetching the varint? */
6698 length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6699 if (length == 0) {
6700 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6701 }
6702 }
6703 item_length = length;
6704 break;
6705 }
6706
6707 /*
6708 * The length is the specified length.
6709 */
6710 break;
6711
6712 case FT_BOOLEAN:
6713 case FT_CHAR:
6714 case FT_IPv4:
6715 case FT_IPXNET:
6716 case FT_IPv6:
6717 case FT_FCWWN:
6718 case FT_AX25:
6719 case FT_VINES:
6720 case FT_ETHER:
6721 case FT_EUI64:
6722 case FT_GUID:
6723 case FT_OID:
6724 case FT_REL_OID:
6725 case FT_SYSTEM_ID:
6726 case FT_FLOAT:
6727 case FT_DOUBLE:
6728 case FT_STRING:
6729 /*
6730 * The length is the specified length.
6731 */
6732 break;
6733
6734 case FT_STRINGZ:
6735 if (length < -1) {
6736 report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6737 }
6738 if (length == -1) {
6739 /* This can throw an exception */
6740 /* XXX - do this without fetching the string? */
6741 wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6742 }
6743 item_length = length;
6744 break;
6745
6746 case FT_UINT_STRING:
6747 n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6748 item_length += n;
6749 if ((int)item_length < length) {
6750 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6751 }
6752 break;
6753
6754 case FT_STRINGZPAD:
6755 case FT_STRINGZTRUNC:
6756 case FT_ABSOLUTE_TIME:
6757 case FT_RELATIVE_TIME:
6758 case FT_IEEE_11073_SFLOAT:
6759 case FT_IEEE_11073_FLOAT:
6760 /*
6761 * The length is the specified length.
6762 */
6763 break;
6764
6765 default:
6766 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
))
6767 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
))
6768 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
))
6769 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
))
;
6770 break;
6771 }
6772 return item_length;
6773}
6774
6775static field_info *
6776new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6777 const int start, const int item_length)
6778{
6779 field_info *fi;
6780
6781 FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo
->pool)), sizeof(field_info)))
;
6782
6783 fi->hfinfo = hfinfo;
6784 fi->start = start;
6785 fi->start += (tvb)?tvb_raw_offset(tvb):0;
6786 fi->length = item_length;
6787 fi->tree_type = -1;
6788 fi->flags = 0;
6789 if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6790 /* If the tree is not visible, set the item hidden, unless we
6791 * need the representation or length and can't fake them.
6792 */
6793 if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6794 FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); }
while(0)
;
6795 }
6796 }
6797 fi->value = fvalue_new(fi->hfinfo->type);
6798 fi->rep = NULL((void*)0);
6799
6800 /* add the data source tvbuff */
6801 fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6802
6803 fi->appendix_start = 0;
6804 fi->appendix_length = 0;
6805
6806 fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6807 fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6808
6809 return fi;
6810}
6811
6812static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6813{
6814 if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6815 return 0;
6816 }
6817
6818 /* Search for field name */
6819 char *ptr = strstr(representation, hfinfo->name);
6820 if (!ptr) {
6821 return 0;
6822 }
6823
6824 /* Check if field name ends with the ": " delimiter */
6825 ptr += strlen(hfinfo->name);
6826 if (strncmp(ptr, ": ", 2) == 0) {
6827 ptr += 2;
6828 }
6829
6830 /* Return offset to after field name */
6831 return ptr - representation;
6832}
6833
6834/* If the protocol tree is to be visible, set the representation of a
6835 proto_tree entry with the name of the field for the item and with
6836 the value formatted with the supplied printf-style format and
6837 argument list. */
6838static void
6839proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6840{
6841 ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR
, "epan/proto.c", 6841, __func__, "assertion failed: %s", "pi"
); } while (0)
;
6842
6843 /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6844 * items string representation */
6845 if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6846 size_t name_pos, ret = 0;
6847 char *str;
6848 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6849 const header_field_info *hf;
6850
6851 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6851, "fi"))))
;
6852
6853 hf = fi->hfinfo;
6854
6855 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;
;
6856 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))
)) {
6857 uint64_t val;
6858 char *p;
6859
6860 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)
)
6861 val = fvalue_get_uinteger(fi->value);
6862 else
6863 val = fvalue_get_uinteger64(fi->value);
6864
6865 val <<= hfinfo_bitshift(hf);
6866
6867 p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
6868 ret = (p - fi->rep->representation);
6869 }
6870
6871 /* put in the hf name */
6872 name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf->
name, 0)
;
6873
6874 ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": "
, 0)
;
6875 /* If possible, Put in the value of the string */
6876 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6877 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"
, 6877, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6878 fi->rep->value_pos = ret;
6879 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
6880 if (ret >= ITEM_LABEL_LENGTH240) {
6881 /* Uh oh, we don't have enough room. Tell the user
6882 * that the field is truncated.
6883 */
6884 label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
6885 }
6886 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6887 }
6888}
6889
6890/* If the protocol tree is to be visible, set the representation of a
6891 proto_tree entry with the representation formatted with the supplied
6892 printf-style format and argument list. */
6893static void
6894proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
6895{
6896 size_t ret; /*tmp return value */
6897 char *str;
6898 field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6899
6900 DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 6900, "fi"))))
;
6901
6902 if (!proto_item_is_hidden(pi)) {
6903 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;
;
6904
6905 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
6906 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"
, 6906, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
6907 fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
6908 ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
6909 if (ret >= ITEM_LABEL_LENGTH240) {
6910 /* Uh oh, we don't have enough room. Tell the user
6911 * that the field is truncated.
6912 */
6913 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
6914 }
6915 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
6916 }
6917}
6918
6919static int
6920protoo_strlcpy(char *dest, const char *src, size_t dest_size)
6921{
6922 if (dest_size == 0) return 0;
6923
6924 size_t res = g_strlcpy(dest, src, dest_size);
6925
6926 /* At most dest_size - 1 characters will be copied
6927 * (unless dest_size is 0). */
6928 if (res >= dest_size)
6929 res = dest_size - 1;
6930 return (int) res;
6931}
6932
6933static header_field_info *
6934hfinfo_same_name_get_prev(const header_field_info *hfinfo)
6935{
6936 header_field_info *dup_hfinfo;
6937
6938 if (hfinfo->same_name_prev_id == -1)
6939 return NULL((void*)0);
6940 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", 6940
, __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", 6940, "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", 6940,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo
->same_name_prev_id];
;
6941 return dup_hfinfo;
6942}
6943
6944static void
6945hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
6946{
6947 g_free(last_field_name);
6948 last_field_name = NULL((void*)0);
6949
6950 if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
6951 /* No hfinfo with the same name */
6952 g_hash_table_steal(gpa_name_map, hfinfo->abbrev);
6953 return;
6954 }
6955
6956 if (hfinfo->same_name_next) {
6957 hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
6958 }
6959
6960 if (hfinfo->same_name_prev_id != -1) {
6961 header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
6962 same_name_prev->same_name_next = hfinfo->same_name_next;
6963 if (!hfinfo->same_name_next) {
6964 /* It's always the latest added hfinfo which is stored in gpa_name_map */
6965 g_hash_table_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
6966 }
6967 }
6968}
6969
6970int
6971proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
6972{
6973 const header_field_info *hfinfo = finfo->hfinfo;
6974 int label_len = 0;
6975 char *tmp_str;
6976 const char *str;
6977 const uint8_t *bytes;
6978 uint32_t number;
6979 uint64_t number64;
6980 const char *hf_str_val;
6981 char number_buf[NUMBER_LABEL_LENGTH80];
6982 const char *number_out;
6983 address addr;
6984 const ipv4_addr_and_mask *ipv4;
6985 const ipv6_addr_and_prefix *ipv6;
6986
6987 switch (hfinfo->type) {
6988
6989 case FT_NONE:
6990 case FT_PROTOCOL:
6991 return protoo_strlcpy(display_label_str, UTF8_CHECK_MARK"\xe2\x9c\x93", label_str_size);
6992
6993 case FT_UINT_BYTES:
6994 case FT_BYTES:
6995 tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
6996 hfinfo,
6997 fvalue_get_bytes_data(finfo->value),
6998 (unsigned)fvalue_length2(finfo->value),
6999 label_str_size);
7000 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7001 wmem_free(NULL((void*)0), tmp_str);
7002 break;
7003
7004 case FT_ABSOLUTE_TIME:
7005 {
7006 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7007 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7008 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7009 }
7010 tmp_str = abs_time_to_str_ex(NULL((void*)0), fvalue_get_time(finfo->value), hfinfo->display, flags);
7011 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7012 wmem_free(NULL((void*)0), tmp_str);
7013 break;
7014 }
7015
7016 case FT_RELATIVE_TIME:
7017 tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7018 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7019 wmem_free(NULL((void*)0), tmp_str);
7020 break;
7021
7022 case FT_BOOLEAN:
7023 number64 = fvalue_get_uinteger64(finfo->value);
7024 label_len = protoo_strlcpy(display_label_str,
7025 tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7026 break;
7027
7028 case FT_CHAR:
7029 number = fvalue_get_uinteger(finfo->value);
7030
7031 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7032 char tmp[ITEM_LABEL_LENGTH240];
7033 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7034
7035 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7035, "fmtfunc"))))
;
7036 fmtfunc(tmp, number);
7037
7038 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
7039
7040 } else if (hfinfo->strings) {
7041 number_out = hf_try_val_to_str(number, hfinfo);
7042
7043 if (!number_out) {
7044 number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7045 }
7046
7047 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7048
7049 } else {
7050 number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7051
7052 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7053 }
7054
7055 break;
7056
7057 /* XXX - make these just FT_NUMBER? */
7058 case FT_INT8:
7059 case FT_INT16:
7060 case FT_INT24:
7061 case FT_INT32:
7062 case FT_UINT8:
7063 case FT_UINT16:
7064 case FT_UINT24:
7065 case FT_UINT32:
7066 case FT_FRAMENUM:
7067 hf_str_val = NULL((void*)0);
7068 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
))
?
7069 (uint32_t) fvalue_get_sinteger(finfo->value) :
7070 fvalue_get_uinteger(finfo->value);
7071
7072 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7073 char tmp[ITEM_LABEL_LENGTH240];
7074 custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7075
7076 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 7076, "fmtfunc"))))
;
7077 fmtfunc(tmp, number);
7078
7079 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
7080
7081 } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7082 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7083 number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7084 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7085 hf_str_val = hf_try_val_to_str(number, hfinfo);
7086 label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7087 } else {
7088 number_out = hf_try_val_to_str(number, hfinfo);
7089
7090 if (!number_out) {
7091 number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7092 }
7093
7094 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7095 }
7096 } else {
7097 number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7098
7099 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7100 }
7101
7102 break;
7103
7104 case FT_INT40:
7105 case FT_INT48:
7106 case FT_INT56:
7107 case FT_INT64:
7108 case FT_UINT40:
7109 case FT_UINT48:
7110 case FT_UINT56:
7111 case FT_UINT64:
7112 hf_str_val = NULL((void*)0);
7113 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
))
?
7114 (uint64_t) fvalue_get_sinteger64(finfo->value) :
7115 fvalue_get_uinteger64(finfo->value);
7116
7117 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7118 char tmp[ITEM_LABEL_LENGTH240];
7119 custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7120
7121 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 7121, "fmtfunc64"
))))
;
7122 fmtfunc64(tmp, number64);
7123
7124 label_len = protoo_strlcpy(display_label_str, tmp, label_str_size);
7125 } else if (hfinfo->strings) {
7126 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7127 number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7128 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7129 hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7130 label_len += protoo_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7131 } else {
7132 number_out = hf_try_val64_to_str(number64, hfinfo);
7133
7134 if (!number_out)
7135 number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7136
7137 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7138 }
7139 } else {
7140 number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7141
7142 label_len = protoo_strlcpy(display_label_str, number_out, label_str_size);
7143 }
7144
7145 break;
7146
7147 case FT_EUI64:
7148 tmp_str = eui64_to_str(NULL((void*)0), fvalue_get_uinteger64(finfo->value));
7149 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7150 wmem_free(NULL((void*)0), tmp_str);
7151 break;
7152
7153 case FT_IPv4:
7154 ipv4 = fvalue_get_ipv4(finfo->value);
7155 //XXX: Should we ignore the mask?
7156 set_address_ipv4(&addr, ipv4);
7157 tmp_str = address_to_display(NULL((void*)0), &addr);
7158 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7159 wmem_free(NULL((void*)0), tmp_str);
7160 free_address(&addr);
7161 break;
7162
7163 case FT_IPv6:
7164 ipv6 = fvalue_get_ipv6(finfo->value);
7165 set_address_ipv6(&addr, ipv6);
7166 tmp_str = address_to_display(NULL((void*)0), &addr);
7167 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7168 wmem_free(NULL((void*)0), tmp_str);
7169 free_address(&addr);
7170 break;
7171
7172 case FT_FCWWN:
7173 set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7174 tmp_str = address_to_display(NULL((void*)0), &addr);
7175 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7176 wmem_free(NULL((void*)0), tmp_str);
7177 break;
7178
7179 case FT_ETHER:
7180 set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7181 tmp_str = address_to_display(NULL((void*)0), &addr);
7182 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7183 wmem_free(NULL((void*)0), tmp_str);
7184 break;
7185
7186 case FT_GUID:
7187 tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7188 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7189 wmem_free(NULL((void*)0), tmp_str);
7190 break;
7191
7192 case FT_REL_OID:
7193 bytes = fvalue_get_bytes_data(finfo->value);
7194 tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7195 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7196 wmem_free(NULL((void*)0), tmp_str);
7197 break;
7198
7199 case FT_OID:
7200 bytes = fvalue_get_bytes_data(finfo->value);
7201 tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7202 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7203 wmem_free(NULL((void*)0), tmp_str);
7204 break;
7205
7206 case FT_SYSTEM_ID:
7207 bytes = fvalue_get_bytes_data(finfo->value);
7208 tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7209 label_len = protoo_strlcpy(display_label_str, tmp_str, label_str_size);
7210 wmem_free(NULL((void*)0), tmp_str);
7211 break;
7212
7213 case FT_FLOAT:
7214 case FT_DOUBLE:
7215 label_len = (int)fill_display_label_float(finfo, display_label_str);
7216 break;
7217
7218 case FT_STRING:
7219 case FT_STRINGZ:
7220 case FT_UINT_STRING:
7221 case FT_STRINGZPAD:
7222 case FT_STRINGZTRUNC:
7223 str = fvalue_get_string(finfo->value);
7224 label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7225 if (label_len >= label_str_size) {
7226 /* Truncation occurred. Get the real length
7227 * copied (not including '\0') */
7228 label_len = label_str_size ? label_str_size - 1 : 0;
7229 }
7230 break;
7231
7232 default:
7233 /* First try ftype string representation */
7234 tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7235 if (!tmp_str) {
7236 /* Default to show as bytes */
7237 bytes = fvalue_get_bytes_data(finfo->value);
7238 tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo->
value), 36)
;
7239 }
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 return label_len;
7245}
7246
7247/* -------------------------- */
7248/* Sets the text for a custom column from proto fields.
7249 *
7250 * @param[out] result The "resolved" column text (human readable, uses strings)
7251 * @param[out] expr The "unresolved" column text (values, display repr)
7252 * @return The filter (abbrev) for the field (XXX: Only the first if multifield)
7253 */
7254const char *
7255proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7256 char *result, char *expr, const int size)
7257{
7258 int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7259 GPtrArray *finfos;
7260 field_info *finfo = NULL((void*)0);
7261 header_field_info* hfinfo;
7262 const char *abbrev = NULL((void*)0);
7263
7264 const char *hf_str_val;
7265 char *str;
7266 col_custom_t *field_idx;
7267 int field_id;
7268 int ii = 0;
7269
7270 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7270, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7271 while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7272 field_id = field_idx->field_id;
7273 if (field_id == 0) {
7274 GPtrArray *fvals = NULL((void*)0);
7275 bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7276 if (fvals != NULL((void*)0)) {
7277
7278 // XXX - Handling occurrences is unusual when more
7279 // than one field is involved, e.g. there's four
7280 // results for tcp.port + tcp.port. We may really
7281 // want to apply it to the operands, not the output.
7282 // Note that occurrences are not quite the same as
7283 // the layer operator (should the grammar support
7284 // both?)
7285 /* Calculate single index or set outer boundaries */
7286 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7287 if (occurrence < 0) {
7288 i = occurrence + len;
7289 last = i;
7290 } else if (occurrence > 0) {
7291 i = occurrence - 1;
7292 last = i;
7293 } else {
7294 i = 0;
7295 last = len - 1;
7296 }
7297 if (i < 0 || i >= len) {
7298 g_ptr_array_unref(fvals);
7299 continue;
7300 }
7301 for (; i <= last; i++) {
7302 /* XXX - We could have a "resolved" result
7303 * for types where the value depends only
7304 * on the type, e.g. FT_IPv4, and not on
7305 * hfinfo->strings. Supporting the latter
7306 * requires knowing which hfinfo matched
7307 * if there are multiple with the same
7308 * abbreviation. In any case, we need to
7309 * know the expected return type of the
7310 * field expression.
7311 */
7312 str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7313 if (offset_r && (offset_r < (size - 1)))
7314 result[offset_r++] = ',';
7315 if (offset_e && (offset_e < (size - 1)))
7316 expr[offset_e++] = ',';
7317 offset_r += protoo_strlcpy(result+offset_r, str, size-offset_r);
7318 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
7319 g_free(str);
7320 }
7321 g_ptr_array_unref(fvals);
7322 } else if (passed) {
7323 // XXX - Occurrence doesn't make sense for a test
7324 // output, it should be applied to the operands.
7325 if (offset_r && (offset_r < (size - 1)))
7326 result[offset_r++] = ',';
7327 if (offset_e && (offset_e < (size - 1)))
7328 expr[offset_e++] = ',';
7329 /* Prevent multiple check marks */
7330 if (strstr(result, UTF8_CHECK_MARK"\xe2\x9c\x93" ",") == NULL((void*)0)) {
7331 offset_r += protoo_strlcpy(result+offset_r, UTF8_CHECK_MARK"\xe2\x9c\x93", size-offset_r);
7332 } else {
7333 result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7334 }
7335 if (strstr(expr, UTF8_CHECK_MARK"\xe2\x9c\x93" ",") == NULL((void*)0)) {
7336 offset_e += protoo_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\xe2\x9c\x93", size-offset_e);
7337 } else {
7338 expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7339 }
7340 }
7341 continue;
7342 }
7343 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", 7343
, __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", 7343,
"(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", 7343,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7344
7345 /* do we need to rewind ? */
7346 if (!hfinfo)
7347 return "";
7348
7349 if (occurrence < 0) {
7350 /* Search other direction */
7351 while (hfinfo->same_name_prev_id != -1) {
7352 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", 7352
, __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", 7352, "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", 7352,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7353 }
7354 }
7355
7356 prev_len = 0; /* Reset handled occurrences */
7357
7358 while (hfinfo) {
7359 finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7360
7361 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7362 if (occurrence < 0) {
7363 hfinfo = hfinfo->same_name_next;
7364 } else {
7365 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7366 }
7367 continue;
7368 }
7369
7370 /* Are there enough occurrences of the field? */
7371 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7372 if (occurrence < 0) {
7373 hfinfo = hfinfo->same_name_next;
7374 } else {
7375 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7376 }
7377 prev_len += len;
7378 continue;
7379 }
7380
7381 /* Calculate single index or set outer boundaries */
7382 if (occurrence < 0) {
7383 i = occurrence + len + prev_len;
7384 last = i;
7385 } else if (occurrence > 0) {
7386 i = occurrence - 1 - prev_len;
7387 last = i;
7388 } else {
7389 i = 0;
7390 last = len - 1;
7391 }
7392
7393 prev_len += len; /* Count handled occurrences */
7394
7395 while (i <= last) {
7396 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7397
7398 if (offset_r && (offset_r < (size - 1)))
7399 result[offset_r++] = ',';
7400
7401 if (display_details) {
7402 char representation[ITEM_LABEL_LENGTH240];
7403 size_t offset = 0;
7404
7405 if (finfo->rep && finfo->rep->value_len) {
7406 g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7407 MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo->
rep->value_len + 1) : (240))
);
7408 } else {
7409 proto_item_fill_label(finfo, representation, &offset);
7410 }
7411 offset_r += protoo_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7412 } else {
7413 switch (hfinfo->type) {
7414
7415 case FT_NONE:
7416 case FT_PROTOCOL:
7417 /* Prevent multiple check marks */
7418 if (strstr(result, UTF8_CHECK_MARK"\xe2\x9c\x93" ",") == NULL((void*)0)) {
7419 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7420 } else {
7421 result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7422 }
7423 break;
7424
7425 default:
7426 offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7427 break;
7428 }
7429 }
7430
7431 if (offset_e && (offset_e < (size - 1)))
7432 expr[offset_e++] = ',';
7433
7434 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
))
)) {
7435 /* Integer types with BASE_NONE never get the numeric value. */
7436 if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16
|| (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32
)
) {
7437 hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7438 } 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
)
) {
7439 hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7440 } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48
|| (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64
)
) {
7441 hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7442 } else { // if (FT_IS_UINT64(hfinfo->type)) {
7443 hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7444 }
7445 snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7446 offset_e = (int)strlen(expr);
7447 } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7448 /* Prevent multiple check marks */
7449 if (strstr(expr, UTF8_CHECK_MARK"\xe2\x9c\x93" ",") == NULL((void*)0)) {
7450 offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7451 } else {
7452 expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7453 }
7454 } else {
7455 str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7456 offset_e += protoo_strlcpy(expr+offset_e, str, size-offset_e);
7457 wmem_free(NULL((void*)0), str);
7458 }
7459 i++;
7460 }
7461
7462 /* XXX: Why is only the first abbreviation returned for a multifield
7463 * custom column? */
7464 if (!abbrev) {
7465 /* Store abbrev for return value */
7466 abbrev = hfinfo->abbrev;
7467 }
7468
7469 if (occurrence == 0) {
7470 /* Fetch next hfinfo with same name (abbrev) */
7471 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7472 } else {
7473 hfinfo = NULL((void*)0);
7474 }
7475 }
7476 }
7477
7478 if (offset_r >= (size - 1)) {
7479 mark_truncated(result, 0, size, NULL((void*)0));
7480 }
7481 if (offset_e >= (size - 1)) {
7482 mark_truncated(expr, 0, size, NULL((void*)0));
7483 }
7484 return abbrev ? abbrev : "";
7485}
7486
7487char *
7488proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7489{
7490 int len, prev_len, last, i;
7491 GPtrArray *finfos;
7492 field_info *finfo = NULL((void*)0);
7493 header_field_info* hfinfo;
7494
7495 char *filter = NULL((void*)0);
7496 GPtrArray *filter_array;
7497
7498 col_custom_t *col_custom;
7499 int field_id;
7500
7501 ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full
("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7501, __func__, "assertion failed: %s"
, "field_ids != ((void*)0)"); } while (0)
;
7502 filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7503 for (GSList *iter = field_ids; iter; iter = iter->next) {
7504 col_custom = (col_custom_t*)iter->data;
7505 field_id = col_custom->field_id;
7506 if (field_id == 0) {
7507 GPtrArray *fvals = NULL((void*)0);
7508 bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7509 if (fvals != NULL((void*)0)) {
7510 // XXX - Handling occurrences is unusual when more
7511 // than one field is involved, e.g. there's four
7512 // results for tcp.port + tcp.port. We really
7513 // want to apply it to the operands, not the output.
7514 /* Calculate single index or set outer boundaries */
7515 len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7516 if (occurrence < 0) {
7517 i = occurrence + len;
7518 last = i;
7519 } else if (occurrence > 0) {
7520 i = occurrence - 1;
7521 last = i;
7522 } else {
7523 i = 0;
7524 last = len - 1;
7525 }
7526 if (i < 0 || i >= len) {
7527 g_ptr_array_unref(fvals);
7528 continue;
7529 }
7530 for (; i <= last; i++) {
7531 /* XXX - Should multiple values for one
7532 * field use set membership to reduce
7533 * verbosity, here and below? */
7534 char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7535 filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7536 wmem_free(NULL((void*)0), str);
7537 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7538 g_ptr_array_add(filter_array, filter);
7539 }
7540 }
7541 g_ptr_array_unref(fvals);
7542 } else if (passed) {
7543 filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7544 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7545 g_ptr_array_add(filter_array, filter);
7546 }
7547 } else {
7548 filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7549 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7550 g_ptr_array_add(filter_array, filter);
7551 }
7552 }
7553 continue;
7554 }
7555
7556 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", 7556
, __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", 7556,
"(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", 7556,
"gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];
;
7557
7558 /* do we need to rewind ? */
7559 if (!hfinfo)
7560 return NULL((void*)0);
7561
7562 if (occurrence < 0) {
7563 /* Search other direction */
7564 while (hfinfo->same_name_prev_id != -1) {
7565 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", 7565
, __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", 7565, "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", 7565,
"gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo->
same_name_prev_id];
;
7566 }
7567 }
7568
7569 prev_len = 0; /* Reset handled occurrences */
7570
7571 while (hfinfo) {
7572 finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7573
7574 if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7575 if (occurrence < 0) {
7576 hfinfo = hfinfo->same_name_next;
7577 } else {
7578 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7579 }
7580 continue;
7581 }
7582
7583 /* Are there enough occurrences of the field? */
7584 if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7585 if (occurrence < 0) {
7586 hfinfo = hfinfo->same_name_next;
7587 } else {
7588 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7589 }
7590 prev_len += len;
7591 continue;
7592 }
7593
7594 /* Calculate single index or set outer boundaries */
7595 if (occurrence < 0) {
7596 i = occurrence + len + prev_len;
7597 last = i;
7598 } else if (occurrence > 0) {
7599 i = occurrence - 1 - prev_len;
7600 last = i;
7601 } else {
7602 i = 0;
7603 last = len - 1;
7604 }
7605
7606 prev_len += len; /* Count handled occurrences */
7607
7608 while (i <= last) {
7609 finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7610
7611 filter = proto_construct_match_selected_string(finfo, edt);
7612 if (filter) {
7613 /* Only add the same expression once (especially for FT_PROTOCOL).
7614 * The ptr array doesn't have NULL entries so g_str_equal is fine.
7615 */
7616 if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7617 g_ptr_array_add(filter_array, filter);
7618 }
7619 }
7620 i++;
7621 }
7622
7623 if (occurrence == 0) {
7624 /* Fetch next hfinfo with same name (abbrev) */
7625 hfinfo = hfinfo_same_name_get_prev(hfinfo);
7626 } else {
7627 hfinfo = NULL((void*)0);
7628 }
7629 }
7630 }
7631
7632 g_ptr_array_add(filter_array, NULL((void*)0));
7633
7634 /* XXX: Should this be || or && ? */
7635 char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7636
7637 g_ptr_array_free(filter_array, true1);
7638
7639 return output;
7640}
7641
7642/* Set text of proto_item after having already been created. */
7643void
7644proto_item_set_text(proto_item *pi, const char *format, ...)
7645{
7646 field_info *fi = NULL((void*)0);
7647 va_list ap;
7648
7649 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi) return; if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return; }
;
7650
7651 fi = PITEM_FINFO(pi)((pi)->finfo);
7652 if (fi == NULL((void*)0))
7653 return;
7654
7655 if (fi->rep) {
7656 ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep
);
;
7657 fi->rep = NULL((void*)0);
7658 }
7659
7660 va_start(ap, format)__builtin_va_start(ap, format);
7661 proto_tree_set_representation(pi, format, ap);
7662 va_end(ap)__builtin_va_end(ap);
7663}
7664
7665/* Append to text of proto_item after having already been created. */
7666void
7667proto_item_append_text(proto_item *pi, const char *format, ...)
7668{
7669 field_info *fi = NULL((void*)0);
7670 size_t curlen;
7671 char *str;
7672 va_list ap;
7673
7674 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi) return; if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return; }
;
7675
7676 fi = PITEM_FINFO(pi)((pi)->finfo);
7677 if (fi == NULL((void*)0)) {
7678 return;
7679 }
7680
7681 if (!proto_item_is_hidden(pi)) {
7682 /*
7683 * If we don't already have a representation,
7684 * generate the default representation.
7685 */
7686 if (fi->rep == NULL((void*)0)) {
7687 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;
;
7688 proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7689 /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7690 if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7691 (strncmp(format, ": ", 2) == 0)) {
7692 fi->rep->value_pos += 2;
7693 }
7694 }
7695 if (fi->rep) {
7696 curlen = strlen(fi->rep->representation);
7697 /* curlen doesn't include the \0 byte.
7698 * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7699 * the representation has already been truncated (of an up
7700 * to 4 byte UTF-8 character) or is just at the maximum length
7701 * unless we search for " [truncated]" (which may not be
7702 * at the start.)
7703 * It's safer to do nothing.
7704 */
7705 if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7706 va_start(ap, format)__builtin_va_start(ap, format);
7707 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7708 va_end(ap)__builtin_va_end(ap);
7709 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"
, 7709, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7710 /* Keep fi->rep->value_pos */
7711 curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7712 if (curlen >= ITEM_LABEL_LENGTH240) {
7713 /* Uh oh, we don't have enough room. Tell the user
7714 * that the field is truncated.
7715 */
7716 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7717 }
7718 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7719 }
7720 }
7721 }
7722}
7723
7724/* Prepend to text of proto_item after having already been created. */
7725void
7726proto_item_prepend_text(proto_item *pi, const char *format, ...)
7727{
7728 field_info *fi = NULL((void*)0);
7729 size_t pos;
7730 char representation[ITEM_LABEL_LENGTH240];
7731 char *str;
7732 va_list ap;
7733
7734 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi) 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, representation, &fi->rep->value_pos);
7749 } else
7750 (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7751
7752 va_start(ap, format)__builtin_va_start(ap, format);
7753 str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7754 va_end(ap)__builtin_va_end(ap);
7755 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"
, 7755, __func__, str, -1, __uni_endptr); } } while (0); } } while
(0)
;
7756 fi->rep->value_pos += strlen(str);
7757 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7758 pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7759 /* XXX: As above, if the old representation is close to the label
7760 * length, it might already be marked as truncated. */
7761 if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7762 /* Uh oh, we don't have enough room. Tell the user
7763 * that the field is truncated.
7764 */
7765 LABEL_MARK_TRUNCATED_START(fi->rep->representation, &fi->rep->value_pos)label_mark_truncated(fi->rep->representation, 0, &fi
->rep->value_pos)
;
7766 }
7767 fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7768 }
7769}
7770
7771static void
7772finfo_set_len(field_info *fi, const int length)
7773{
7774 int length_remaining;
7775
7776 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", 7776,
"length >= 0", fi->hfinfo->abbrev))))
;
7777 length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7778 if (length > length_remaining)
7779 fi->length = length_remaining;
7780 else
7781 fi->length = length;
7782
7783 /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7784 if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7785 fvalue_set_protocol(fi->value, NULL((void*)0), NULL((void*)0), fi->length);
7786 }
7787
7788 /*
7789 * You cannot just make the "len" field of a GByteArray
7790 * larger, if there's no data to back that length;
7791 * you can only make it smaller.
7792 */
7793 if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7794 GBytes *bytes = fvalue_get_bytes(fi->value);
7795 size_t size;
7796 const void *data = g_bytes_get_data(bytes, &size);
7797 if ((size_t)fi->length <= size) {
7798 fvalue_set_bytes_data(fi->value, data, fi->length);
7799 }
7800 g_bytes_unref(bytes);
7801 }
7802}
7803
7804void
7805proto_item_set_len(proto_item *pi, const int length)
7806{
7807 field_info *fi;
7808
7809 /* If the item is not visible, we can't set the length because
7810 * we can't distinguish which proto item this is being called
7811 * on, since faked items share proto items. (#17877)
7812 */
7813 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi) return; if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return; }
;
7814
7815 fi = PITEM_FINFO(pi)((pi)->finfo);
7816 if (fi == NULL((void*)0))
7817 return;
7818
7819 finfo_set_len(fi, length);
7820}
7821
7822/*
7823 * Sets the length of the item based on its start and on the specified
7824 * offset, which is the offset past the end of the item; as the start
7825 * in the item is relative to the beginning of the data source tvbuff,
7826 * we need to pass in a tvbuff - the end offset is relative to the beginning
7827 * of that tvbuff.
7828 */
7829void
7830proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7831{
7832 field_info *fi;
7833 int length;
7834
7835 /* As with proto_item_set_len() above */
7836 TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi) return; if (!(((pi)->tree_data)->visible) &&
proto_item_is_hidden((pi))) { return; }
;
7837
7838 fi = PITEM_FINFO(pi)((pi)->finfo);
7839 if (fi == NULL((void*)0))
7840 return;
7841
7842 end += tvb_raw_offset(tvb);
7843 DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7843, "end >= fi->start"
))))
;
7844 length = end - fi->start;
7845
7846 finfo_set_len(fi, length);
7847}
7848
7849int
7850proto_item_get_len(const proto_item *pi)
7851{
7852 field_info *fi;
7853
7854 if (!pi)
7855 return -1;
7856 fi = PITEM_FINFO(pi)((pi)->finfo);
7857 return fi ? fi->length : -1;
7858}
7859
7860void
7861proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
7862 if (!ti) {
7863 return;
7864 }
7865 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)
;
7866 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)
;
7867}
7868
7869char *
7870proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
7871{
7872 field_info *fi;
7873
7874 if (!pi)
7875 return "";
7876 fi = PITEM_FINFO(pi)((pi)->finfo);
7877 DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7877, "fi->hfinfo != ((void*)0)"
))))
;
7878 return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
7879}
7880
7881proto_tree *
7882proto_tree_create_root(packet_info *pinfo)
7883{
7884 proto_node *pnode;
7885
7886 /* Initialize the proto_node */
7887 pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
7888 PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = ((
void*)0); pnode->next = ((void*)0);
;
7889 pnode->parent = NULL((void*)0);
7890 PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
7891 pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
7892
7893 /* Make sure we can access pinfo everywhere */
7894 pnode->tree_data->pinfo = pinfo;
7895
7896 /* Don't initialize the tree_data_t. Wait until we know we need it */
7897 pnode->tree_data->interesting_hfids = NULL((void*)0);
7898
7899 /* Set the default to false so it's easier to
7900 * find errors; if we expect to see the protocol tree
7901 * but for some reason the default 'visible' is not
7902 * changed, then we'll find out very quickly. */
7903 pnode->tree_data->visible = false0;
7904
7905 /* Make sure that we fake protocols (if possible) */
7906 pnode->tree_data->fake_protocols = true1;
7907
7908 /* Keep track of the number of children */
7909 pnode->tree_data->count = 0;
7910
7911 return (proto_tree *)pnode;
7912}
7913
7914
7915/* "prime" a proto_tree with a single hfid that a dfilter
7916 * is interested in. */
7917void
7918proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
7919{
7920 header_field_info *hfinfo;
7921
7922 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", 7922, __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", 7922, "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", 7922, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
7923 /* this field is referenced by a filter so increase the refcount.
7924 also increase the refcount for the parent, i.e the protocol.
7925 Don't increase the refcount if we're already printing the
7926 type, as that is a superset of direct reference.
7927 */
7928 if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
7929 hfinfo->ref_type = HF_REF_TYPE_DIRECT;
7930 }
7931 /* only increase the refcount if there is a parent.
7932 if this is a protocol and not a field then parent will be -1
7933 and there is no parent to add any refcounting for.
7934 */
7935 if (hfinfo->parent != -1) {
7936 header_field_info *parent_hfinfo;
7937 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", 7937
, __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", 7937,
"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", 7937,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
7938
7939 /* Mark parent as indirectly referenced unless it is already directly
7940 * referenced, i.e. the user has specified the parent in a filter.
7941 */
7942 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
7943 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
7944 }
7945}
7946
7947/* "prime" a proto_tree with a single hfid that a dfilter
7948 * is interested in. */
7949void
7950proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
7951{
7952 header_field_info *hfinfo;
7953
7954 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", 7954, __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", 7954, "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", 7954, "gpa_hfinfo.hfi[hfid] != ((void*)0)",
"Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];
;
7955 /* this field is referenced by an (output) filter so increase the refcount.
7956 also increase the refcount for the parent, i.e the protocol.
7957 */
7958 hfinfo->ref_type = HF_REF_TYPE_PRINT;
7959 /* only increase the refcount if there is a parent.
7960 if this is a protocol and not a field then parent will be -1
7961 and there is no parent to add any refcounting for.
7962 */
7963 if (hfinfo->parent != -1) {
7964 header_field_info *parent_hfinfo;
7965 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", 7965
, __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", 7965,
"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", 7965,
"gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
7966
7967 /* Mark parent as indirectly referenced unless it is already directly
7968 * referenced, i.e. the user has specified the parent in a filter.
7969 */
7970 if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
7971 parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
7972 }
7973}
7974
7975proto_tree *
7976proto_item_add_subtree(proto_item *pi, const int idx) {
7977 field_info *fi;
7978
7979 if (!pi)
7980 return NULL((void*)0);
7981
7982 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", 7982, "idx >= 0 && idx < num_tree_types"
))))
;
7983
7984 fi = PITEM_FINFO(pi)((pi)->finfo);
7985 if (!fi)
7986 return (proto_tree *)pi;
7987
7988 fi->tree_type = idx;
7989
7990 return (proto_tree *)pi;
7991}
7992
7993proto_tree *
7994proto_item_get_subtree(proto_item *pi) {
7995 field_info *fi;
7996
7997 if (!pi)
7998 return NULL((void*)0);
7999 fi = PITEM_FINFO(pi)((pi)->finfo);
8000 if ( (!fi) || (fi->tree_type == -1) )
8001 return NULL((void*)0);
8002 return (proto_tree *)pi;
8003}
8004
8005proto_item *
8006proto_item_get_parent(const proto_item *ti) {
8007 /* XXX: If we're faking items, this will return the parent of the
8008 * faked item, which may not be the logical parent expected.
8009 * We have no way of knowing exactly which real item the fake
8010 * item refers to here (the original item or one of its children
8011 * using it as a fake), and thus whether the parent should be the
8012 * faked item itself or the faked item's parent.
8013 *
8014 * In that case, there's a good chance we end up returning the
8015 * root node of the protocol tree, which has "PNODE_FINFO()" null.
8016 *
8017 * If we later add items to _that_, they will not be faked even though
8018 * they _should_ be, hurting performance (#8069). Also protocol
8019 * hierarchy stats (which fakes everything but protocols) may
8020 * behave oddly if unexpected items are added under the root node.
8021 */
8022 if (!ti)
8023 return NULL((void*)0);
8024 return ti->parent;
8025}
8026
8027proto_item *
8028proto_item_get_parent_nth(proto_item *ti, int gen) {
8029 /* XXX: Same issue as above, even more so. */
8030 if (!ti)
8031 return NULL((void*)0);
8032 while (gen--) {
8033 ti = ti->parent;
8034 if (!ti)
8035 return NULL((void*)0);
8036 }
8037 return ti;
8038}
8039
8040
8041proto_item *
8042proto_tree_get_parent(proto_tree *tree) {
8043 if (!tree)
8044 return NULL((void*)0);
8045 return (proto_item *)tree;
8046}
8047
8048proto_tree *
8049proto_tree_get_parent_tree(proto_tree *tree) {
8050 /* XXX: Same issue as proto_item_get_parent */
8051 if (!tree)
8052 return NULL((void*)0);
8053
8054 /* we're the root tree, there's no parent
8055 return ourselves so the caller has at least a tree to attach to */
8056 if (!tree->parent)
8057 return tree;
8058
8059 return (proto_tree *)tree->parent;
8060}
8061
8062proto_tree *
8063proto_tree_get_root(proto_tree *tree) {
8064 if (!tree)
8065 return NULL((void*)0);
8066 while (tree->parent) {
8067 tree = tree->parent;
8068 }
8069 return tree;
8070}
8071
8072void
8073proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8074 proto_item *item_to_move)
8075{
8076 /* This function doesn't generate any values. It only reorganizes the prococol tree
8077 * so we can bail out immediately if it isn't visible. */
8078 if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8079 return;
8080
8081 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", 8081, "item_to_move->parent == tree"
))))
;
8082 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", 8082, "fixed_item->parent == tree"
))))
;
8083
8084 /*** cut item_to_move out ***/
8085
8086 /* is item_to_move the first? */
8087 if (tree->first_child == item_to_move) {
8088 /* simply change first child to next */
8089 tree->first_child = item_to_move->next;
8090
8091 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", 8091, "tree->last_child != item_to_move"
))))
;
8092 } else {
8093 proto_item *curr_item;
8094 /* find previous and change it's next */
8095 for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8096 if (curr_item->next == item_to_move) {
8097 break;
8098 }
8099 }
8100
8101 DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 8101, "curr_item"
))))
;
8102
8103 curr_item->next = item_to_move->next;
8104
8105 /* fix last_child if required */
8106 if (tree->last_child == item_to_move) {
8107 tree->last_child = curr_item;
8108 }
8109 }
8110
8111 /*** insert to_move after fixed ***/
8112 item_to_move->next = fixed_item->next;
8113 fixed_item->next = item_to_move;
8114 if (tree->last_child == fixed_item) {
8115 tree->last_child = item_to_move;
8116 }
8117}
8118
8119void
8120proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8121 const int length)
8122{
8123 field_info *fi;
8124
8125 if (tree == NULL((void*)0))
8126 return;
8127
8128 fi = PTREE_FINFO(tree)((tree)->finfo);
8129 if (fi == NULL((void*)0))
8130 return;
8131
8132 start += tvb_raw_offset(tvb);
8133 DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8133, "start >= 0"
))))
;
8134 DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8134, "length >= 0"
))))
;
8135
8136 fi->appendix_start = start;
8137 fi->appendix_length = length;
8138}
8139
8140static void
8141check_protocol_filter_name_or_fail(const char *filter_name)
8142{
8143 /* Require at least two characters. */
8144 if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8145 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)
;
8146 }
8147
8148 if (proto_check_field_name(filter_name) != '\0') {
8149 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)
8150 " 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)
8151 " 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)
;
8152 }
8153
8154 /* Check that it doesn't match some very common numeric forms. */
8155 if (filter_name[0] == '0' &&
8156 (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8157 filter_name[1] == 'b' || filter_name[1] == 'B')) {
8158 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])
8159 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])
;
8160 }
8161
8162 /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8163
8164 /* Check that it contains at least one letter. */
8165 bool_Bool have_letter = false0;
8166 for (const char *s = filter_name; *s != '\0'; s++) {
8167 if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8168 have_letter = true1;
8169 break;
8170 }
8171 }
8172 if (!have_letter) {
8173 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)
8174 filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z."
, filter_name)
;
8175 }
8176
8177 /* Check for reserved keywords. */
8178 if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8179 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)
8180 " 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)
;
8181 }
8182}
8183
8184int
8185proto_register_protocol(const char *name, const char *short_name,
8186 const char *filter_name)
8187{
8188 protocol_t *protocol;
8189 header_field_info *hfinfo;
8190
8191 /*
8192 * Make sure there's not already a protocol with any of those
8193 * names. Crash if there is, as that's an error in the code
8194 * or an inappropriate plugin.
8195 * This situation has to be fixed to not register more than one
8196 * protocol with the same name.
8197 */
8198
8199 if (g_hash_table_lookup(proto_names, name)) {
8200 /* ws_error will terminate the program */
8201 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)
8202 " 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)
;
8203 }
8204
8205 if (g_hash_table_lookup(proto_short_names, short_name)) {
8206 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)
8207 " 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)
;
8208 }
8209
8210 check_protocol_filter_name_or_fail(filter_name);
8211
8212 if (g_hash_table_lookup(proto_filter_names, filter_name)) {
8213 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)
8214 " 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)
;
8215 }
8216
8217 /*
8218 * Add this protocol to the list of known protocols;
8219 * the list is sorted by protocol short name.
8220 */
8221 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8222 protocol->name = name;
8223 protocol->short_name = short_name;
8224 protocol->filter_name = filter_name;
8225 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8226 protocol->is_enabled = true1; /* protocol is enabled by default */
8227 protocol->enabled_by_default = true1; /* see previous comment */
8228 protocol->can_toggle = true1;
8229 protocol->parent_proto_id = -1;
8230 protocol->heur_list = NULL((void*)0);
8231
8232 /* List will be sorted later by name, when all protocols completed registering */
8233 protocols = g_list_prepend(protocols, protocol);
8234 g_hash_table_insert(proto_names, (void *)name, protocol);
8235 g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol);
8236 g_hash_table_insert(proto_short_names, (void *)short_name, protocol);
8237
8238 /* Here we allocate a new header_field_info struct */
8239 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8240 hfinfo->name = name;
8241 hfinfo->abbrev = filter_name;
8242 hfinfo->type = FT_PROTOCOL;
8243 hfinfo->display = BASE_NONE;
8244 hfinfo->strings = protocol;
8245 hfinfo->bitmask = 0;
8246 hfinfo->ref_type = HF_REF_TYPE_NONE;
8247 hfinfo->blurb = NULL((void*)0);
8248 hfinfo->parent = -1; /* This field differentiates protos and fields */
8249
8250 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8251 return protocol->proto_id;
8252}
8253
8254int
8255proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8256{
8257 protocol_t *protocol;
8258 header_field_info *hfinfo;
8259
8260 /*
8261 * Helper protocols don't need the strict rules as a "regular" protocol
8262 * Just register it in a list and make a hf_ field from it
8263 */
8264 if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8265 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)
;
8266 }
8267
8268 if (parent_proto <= 0) {
8269 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)
8270 " 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)
;
8271 }
8272
8273 check_protocol_filter_name_or_fail(filter_name);
8274
8275 /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8276 protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8277 protocol->name = name;
8278 protocol->short_name = short_name;
8279 protocol->filter_name = filter_name;
8280 protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8281
8282 /* Enabling and toggling is really determined by parent protocol,
8283 but provide default values here */
8284 protocol->is_enabled = true1;
8285 protocol->enabled_by_default = true1;
8286 protocol->can_toggle = true1;
8287
8288 protocol->parent_proto_id = parent_proto;
8289 protocol->heur_list = NULL((void*)0);
8290
8291 /* List will be sorted later by name, when all protocols completed registering */
8292 protocols = g_list_prepend(protocols, protocol);
8293
8294 /* Here we allocate a new header_field_info struct */
8295 hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info
)))
;
8296 hfinfo->name = name;
8297 hfinfo->abbrev = filter_name;
8298 hfinfo->type = field_type;
8299 hfinfo->display = BASE_NONE;
8300 if (field_type == FT_BYTES) {
8301 hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8302 }
8303 hfinfo->strings = protocol;
8304 hfinfo->bitmask = 0;
8305 hfinfo->ref_type = HF_REF_TYPE_NONE;
8306 hfinfo->blurb = NULL((void*)0);
8307 hfinfo->parent = -1; /* This field differentiates protos and fields */
8308
8309 protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8310 return protocol->proto_id;
8311}
8312
8313bool_Bool
8314proto_deregister_protocol(const char *short_name)
8315{
8316 protocol_t *protocol;
8317 header_field_info *hfinfo;
8318 int proto_id;
8319 unsigned i;
8320
8321 proto_id = proto_get_id_by_short_name(short_name);
8322 protocol = find_protocol_by_id(proto_id);
8323 if (protocol == NULL((void*)0))
8324 return false0;
8325
8326 g_hash_table_remove(proto_names, protocol->name);
8327 g_hash_table_remove(proto_short_names, (void *)short_name);
8328 g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8329
8330 if (protocol->fields) {
8331 for (i = 0; i < protocol->fields->len; i++) {
8332 hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8333 hfinfo_remove_from_gpa_name_map(hfinfo);
8334 expert_deregister_expertinfo(hfinfo->abbrev);
8335 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8336 }
8337 g_ptr_array_free(protocol->fields, true1);
8338 protocol->fields = NULL((void*)0);
8339 }
8340
8341 g_list_free(protocol->heur_list);
8342
8343 /* Remove this protocol from the list of known protocols */
8344 protocols = g_list_remove(protocols, protocol);
8345
8346 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8347 g_hash_table_steal(gpa_name_map, protocol->filter_name);
8348
8349 g_free(last_field_name);
8350 last_field_name = NULL((void*)0);
8351
8352 return true1;
8353}
8354
8355void
8356proto_register_alias(const int proto_id, const char *alias_name)
8357{
8358 protocol_t *protocol;
8359
8360 protocol = find_protocol_by_id(proto_id);
8361 if (alias_name && protocol) {
8362 g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8363 }
8364}
8365
8366/*
8367 * Routines to use to iterate over the protocols.
8368 * The argument passed to the iterator routines is an opaque cookie to
8369 * their callers; it's the GList pointer for the current element in
8370 * the list.
8371 * The ID of the protocol is returned, or -1 if there is no protocol.
8372 */
8373int
8374proto_get_first_protocol(void **cookie)
8375{
8376 protocol_t *protocol;
8377
8378 if (protocols == NULL((void*)0))
8379 return -1;
8380 *cookie = protocols;
8381 protocol = (protocol_t *)protocols->data;
8382 return protocol->proto_id;
8383}
8384
8385int
8386proto_get_data_protocol(void *cookie)
8387{
8388 GList *list_item = (GList *)cookie;
8389
8390 protocol_t *protocol = (protocol_t *)list_item->data;
8391 return protocol->proto_id;
8392}
8393
8394int
8395proto_get_next_protocol(void **cookie)
8396{
8397 GList *list_item = (GList *)*cookie;
8398 protocol_t *protocol;
8399
8400 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8401 if (list_item == NULL((void*)0))
8402 return -1;
8403 *cookie = list_item;
8404 protocol = (protocol_t *)list_item->data;
8405 return protocol->proto_id;
8406}
8407
8408header_field_info *
8409proto_get_first_protocol_field(const int proto_id, void **cookie)
8410{
8411 protocol_t *protocol = find_protocol_by_id(proto_id);
8412
8413 if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8414 return NULL((void*)0);
8415
8416 *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8417 return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8418}
8419
8420header_field_info *
8421proto_get_next_protocol_field(const int proto_id, void **cookie)
8422{
8423 protocol_t *protocol = find_protocol_by_id(proto_id);
8424 unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8425
8426 i++;
8427
8428 if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8429 return NULL((void*)0);
8430
8431 *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8432 return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8433}
8434
8435protocol_t *
8436find_protocol_by_id(const int proto_id)
8437{
8438 header_field_info *hfinfo;
8439
8440 if (proto_id <= 0)
8441 return NULL((void*)0);
8442
8443 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", 8443, __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", 8443,
"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", 8443, "gpa_hfinfo.hfi[proto_id] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];
;
8444 if (hfinfo->type != FT_PROTOCOL) {
8445 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", 8445, "hfinfo->display & 0x00004000"
))))
;
8446 }
8447 return (protocol_t *)hfinfo->strings;
8448}
8449
8450int
8451proto_get_id(const protocol_t *protocol)
8452{
8453 return protocol->proto_id;
8454}
8455
8456bool_Bool
8457proto_name_already_registered(const char *name)
8458{
8459 DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 8459, "name", "No name present"))))
;
8460
8461 if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8462 return true1;
8463 return false0;
8464}
8465
8466int
8467proto_get_id_by_filter_name(const char *filter_name)
8468{
8469 const protocol_t *protocol = NULL((void*)0);
8470
8471 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", 8471,
"filter_name", "No filter name present"))))
;
8472
8473 protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8474
8475 if (protocol == NULL((void*)0))
8476 return -1;
8477 return protocol->proto_id;
8478}
8479
8480int
8481proto_get_id_by_short_name(const char *short_name)
8482{
8483 const protocol_t *protocol = NULL((void*)0);
8484
8485 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", 8485,
"short_name", "No short name present"))))
;
8486
8487 protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8488
8489 if (protocol == NULL((void*)0))
8490 return -1;
8491 return protocol->proto_id;
8492}
8493
8494const char *
8495proto_get_protocol_name(const int proto_id)
8496{
8497 protocol_t *protocol;
8498
8499 protocol = find_protocol_by_id(proto_id);
8500
8501 if (protocol == NULL((void*)0))
8502 return NULL((void*)0);
8503 return protocol->name;
8504}
8505
8506const char *
8507proto_get_protocol_short_name(const protocol_t *protocol)
8508{
8509 if (protocol == NULL((void*)0))
8510 return "(none)";
8511 return protocol->short_name;
8512}
8513
8514const char *
8515proto_get_protocol_long_name(const protocol_t *protocol)
8516{
8517 if (protocol == NULL((void*)0))
8518 return "(none)";
8519 return protocol->name;
8520}
8521
8522const char *
8523proto_get_protocol_filter_name(const int proto_id)
8524{
8525 protocol_t *protocol;
8526
8527 protocol = find_protocol_by_id(proto_id);
8528 if (protocol == NULL((void*)0))
8529 return "(none)";
8530 return protocol->filter_name;
8531}
8532
8533void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8534{
8535 heur_dtbl_entry_t* heuristic_dissector;
8536
8537 if (protocol == NULL((void*)0))
8538 return;
8539
8540 heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8541 if (heuristic_dissector != NULL((void*)0))
8542 {
8543 protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8544 }
8545}
8546
8547void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8548{
8549 if (protocol == NULL((void*)0))
8550 return;
8551
8552 g_list_foreach(protocol->heur_list, func, user_data);
8553}
8554
8555void
8556proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8557 bool_Bool *is_tcp, bool_Bool *is_udp,
8558 bool_Bool *is_sctp, bool_Bool *is_tls,
8559 bool_Bool *is_rtp,
8560 bool_Bool *is_lte_rlc)
8561{
8562 wmem_list_frame_t *protos = wmem_list_head(layers);
8563 int proto_id;
8564 const char *proto_name;
8565
8566 /* Walk the list of a available protocols in the packet and
8567 attempt to find "major" ones. */
8568 /* It might make more sense to assemble and return a bitfield. */
8569 while (protos != NULL((void*)0))
8570 {
8571 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8572 proto_name = proto_get_protocol_filter_name(proto_id);
8573
8574 if (is_ip && ((!strcmp(proto_name, "ip")) ||
8575 (!strcmp(proto_name, "ipv6")))) {
8576 *is_ip = true1;
8577 } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8578 *is_tcp = true1;
8579 } else if (is_udp && !strcmp(proto_name, "udp")) {
8580 *is_udp = true1;
8581 } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8582 *is_sctp = true1;
8583 } else if (is_tls && !strcmp(proto_name, "tls")) {
8584 *is_tls = true1;
8585 } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8586 *is_rtp = true1;
8587 } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8588 *is_lte_rlc = true1;
8589 }
8590
8591 protos = wmem_list_frame_next(protos);
8592 }
8593}
8594
8595bool_Bool
8596proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8597{
8598 wmem_list_frame_t *protos = wmem_list_head(layers);
8599 int proto_id;
8600 const char *name;
8601
8602 /* Walk the list of a available protocols in the packet and
8603 attempt to find the specified protocol. */
8604 while (protos != NULL((void*)0))
8605 {
8606 proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8607 name = proto_get_protocol_filter_name(proto_id);
8608
8609 if (!strcmp(name, proto_name))
8610 {
8611 return true1;
8612 }
8613
8614 protos = wmem_list_frame_next(protos);
8615 }
8616
8617 return false0;
8618}
8619
8620char *
8621proto_list_layers(const packet_info *pinfo)
8622{
8623 wmem_strbuf_t *buf;
8624 wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8625
8626 buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8627
8628 /* Walk the list of layers in the packet and
8629 return a string of all entries. */
8630 while (layers != NULL((void*)0))
8631 {
8632 wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8633
8634 layers = wmem_list_frame_next(layers);
8635 if (layers != NULL((void*)0)) {
8636 wmem_strbuf_append_c(buf, ':');
8637 }
8638 }
8639
8640 return wmem_strbuf_finalize(buf);
8641}
8642
8643bool_Bool
8644proto_is_pino(const protocol_t *protocol)
8645{
8646 return (protocol->parent_proto_id != -1);
8647}
8648
8649bool_Bool
8650// NOLINTNEXTLINE(misc-no-recursion)
8651proto_is_protocol_enabled(const protocol_t *protocol)
8652{
8653 if (protocol == NULL((void*)0))
8654 return false0;
8655
8656 //parent protocol determines enable/disable for helper dissectors
8657 if (proto_is_pino(protocol))
8658 return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8659
8660 return protocol->is_enabled;
8661}
8662
8663bool_Bool
8664// NOLINTNEXTLINE(misc-no-recursion)
8665proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8666{
8667 //parent protocol determines enable/disable for helper dissectors
8668 if (proto_is_pino(protocol))
8669 return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8670
8671 return protocol->enabled_by_default;
8672}
8673
8674bool_Bool
8675// NOLINTNEXTLINE(misc-no-recursion)
8676proto_can_toggle_protocol(const int proto_id)
8677{
8678 protocol_t *protocol;
8679
8680 protocol = find_protocol_by_id(proto_id);
8681 //parent protocol determines toggling for helper dissectors
8682 if (proto_is_pino(protocol))
8683 return proto_can_toggle_protocol(protocol->parent_proto_id);
8684
8685 return protocol->can_toggle;
8686}
8687
8688void
8689proto_disable_by_default(const int proto_id)
8690{
8691 protocol_t *protocol;
8692
8693 protocol = find_protocol_by_id(proto_id);
8694 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8694, "protocol->can_toggle"
))))
;
8695 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", 8695, "proto_is_pino(protocol) == 0"
))))
;
8696 protocol->is_enabled = false0;
8697 protocol->enabled_by_default = false0;
8698}
8699
8700void
8701proto_set_decoding(const int proto_id, const bool_Bool enabled)
8702{
8703 protocol_t *protocol;
8704
8705 protocol = find_protocol_by_id(proto_id);
8706 DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8706, "protocol->can_toggle"
))))
;
8707 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", 8707, "proto_is_pino(protocol) == 0"
))))
;
8708 protocol->is_enabled = enabled;
8709}
8710
8711void
8712proto_disable_all(void)
8713{
8714 /* This doesn't explicitly disable heuristic protocols,
8715 * but the heuristic doesn't get called if the parent
8716 * protocol isn't enabled.
8717 */
8718 protocol_t *protocol;
8719 GList *list_item = protocols;
8720
8721 if (protocols == NULL((void*)0))
8722 return;
8723
8724 while (list_item) {
8725 protocol = (protocol_t *)list_item->data;
8726 if (protocol->can_toggle) {
8727 protocol->is_enabled = false0;
8728 }
8729 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8730 }
8731}
8732
8733static void
8734heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8735{
8736 heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8737
8738 heur->enabled = heur->enabled_by_default;
8739}
8740
8741void
8742proto_reenable_all(void)
8743{
8744 protocol_t *protocol;
8745 GList *list_item = protocols;
8746
8747 if (protocols == NULL((void*)0))
8748 return;
8749
8750 while (list_item) {
8751 protocol = (protocol_t *)list_item->data;
8752 if (protocol->can_toggle)
8753 protocol->is_enabled = protocol->enabled_by_default;
8754 proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8755 list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0)
)
;
8756 }
8757}
8758
8759void
8760proto_set_cant_toggle(const int proto_id)
8761{
8762 protocol_t *protocol;
8763
8764 protocol = find_protocol_by_id(proto_id);
8765 protocol->can_toggle = false0;
8766}
8767
8768static int
8769proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8770{
8771 if (proto != NULL((void*)0)) {
8772 g_ptr_array_add(proto->fields, hfi);
8773 }
8774
8775 return proto_register_field_init(hfi, parent);
8776}
8777
8778/* for use with static arrays only, since we don't allocate our own copies
8779of the header_field_info struct contained within the hf_register_info struct */
8780void
8781proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8782{
8783 hf_register_info *ptr = hf;
8784 protocol_t *proto;
8785 int i;
8786
8787 proto = find_protocol_by_id(parent);
8788
8789 if (proto->fields == NULL((void*)0)) {
8790 proto->fields = g_ptr_array_sized_new(num_records);
8791 }
8792
8793 for (i = 0; i < num_records; i++, ptr++) {
8794 /*
8795 * Make sure we haven't registered this yet.
8796 * Most fields have variables associated with them
8797 * that are initialized to -1; some have array elements,
8798 * or possibly uninitialized variables, so we also allow
8799 * 0 (which is unlikely to be the field ID we get back
8800 * from "proto_register_field_init()").
8801 */
8802 if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8803 REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
8804 "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)
8805 ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered"
, ptr->hfinfo.abbrev)
;
8806 return;
8807 }
8808
8809 *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8810 }
8811}
8812
8813/* deregister already registered fields */
8814void
8815proto_deregister_field (const int parent, int hf_id)
8816{
8817 header_field_info *hfi;
8818 protocol_t *proto;
8819 unsigned i;
8820
8821 g_free(last_field_name);
8822 last_field_name = NULL((void*)0);
8823
8824 if (hf_id == -1 || hf_id == 0)
8825 return;
8826
8827 proto = find_protocol_by_id (parent);
8828 if (!proto || proto->fields == NULL((void*)0)) {
8829 return;
8830 }
8831
8832 for (i = 0; i < proto->fields->len; i++) {
8833 hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8834 if (hfi->id == hf_id) {
8835 /* Found the hf_id in this protocol */
8836 g_hash_table_steal(gpa_name_map, hfi->abbrev);
8837 g_ptr_array_remove_index_fast(proto->fields, i);
8838 g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8839 return;
8840 }
8841 }
8842}
8843
8844void
8845proto_add_deregistered_data (void *data)
8846{
8847 g_ptr_array_add(deregistered_data, data);
8848}
8849
8850void
8851proto_add_deregistered_slice (size_t block_size, void *mem_block)
8852{
8853 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
)))
;
8854
8855 slice_data->block_size = block_size;
8856 slice_data->mem_block = mem_block;
8857
8858 g_ptr_array_add(deregistered_slice, slice_data);
8859}
8860
8861void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
8862{
8863 if (field_strings == NULL((void*)0)) {
8864 return;
8865 }
8866
8867 switch (field_type) {
8868 case FT_FRAMENUM:
8869 /* This is just an integer represented as a pointer */
8870 break;
8871 case FT_PROTOCOL: {
8872 protocol_t *protocol = (protocol_t *)field_strings;
8873 g_free((char *)protocol->short_name);
8874 break;
8875 }
8876 case FT_BOOLEAN: {
8877 true_false_string *tf = (true_false_string *)field_strings;
8878 g_free((char *)tf->true_string);
8879 g_free((char *)tf->false_string);
8880 break;
8881 }
8882 case FT_UINT40:
8883 case FT_INT40:
8884 case FT_UINT48:
8885 case FT_INT48:
8886 case FT_UINT56:
8887 case FT_INT56:
8888 case FT_UINT64:
8889 case FT_INT64: {
8890 if (field_display & BASE_UNIT_STRING0x00001000) {
8891 unit_name_string *unit = (unit_name_string *)field_strings;
8892 g_free((char *)unit->singular);
8893 g_free((char *)unit->plural);
8894 } else if (field_display & BASE_RANGE_STRING0x00000100) {
8895 range_string *rs = (range_string *)field_strings;
8896 while (rs->strptr) {
8897 g_free((char *)rs->strptr);
8898 rs++;
8899 }
8900 } else if (field_display & BASE_EXT_STRING0x00000200) {
8901 val64_string_ext *vse = (val64_string_ext *)field_strings;
8902 val64_string *vs = (val64_string *)vse->_vs_p;
8903 while (vs->strptr) {
8904 g_free((char *)vs->strptr);
8905 vs++;
8906 }
8907 val64_string_ext_free(vse);
8908 field_strings = NULL((void*)0);
8909 } else if (field_display == BASE_CUSTOM) {
8910 /* this will be a pointer to a function, don't free that */
8911 field_strings = NULL((void*)0);
8912 } else {
8913 val64_string *vs64 = (val64_string *)field_strings;
8914 while (vs64->strptr) {
8915 g_free((char *)vs64->strptr);
8916 vs64++;
8917 }
8918 }
8919 break;
8920 }
8921 case FT_CHAR:
8922 case FT_UINT8:
8923 case FT_INT8:
8924 case FT_UINT16:
8925 case FT_INT16:
8926 case FT_UINT24:
8927 case FT_INT24:
8928 case FT_UINT32:
8929 case FT_INT32:
8930 case FT_FLOAT:
8931 case FT_DOUBLE: {
8932 if (field_display & BASE_UNIT_STRING0x00001000) {
8933 unit_name_string *unit = (unit_name_string *)field_strings;
8934 g_free((char *)unit->singular);
8935 g_free((char *)unit->plural);
8936 } else if (field_display & BASE_RANGE_STRING0x00000100) {
8937 range_string *rs = (range_string *)field_strings;
8938 while (rs->strptr) {
8939 g_free((char *)rs->strptr);
8940 rs++;
8941 }
8942 } else if (field_display & BASE_EXT_STRING0x00000200) {
8943 value_string_ext *vse = (value_string_ext *)field_strings;
8944 value_string *vs = (value_string *)vse->_vs_p;
8945 while (vs->strptr) {
8946 g_free((char *)vs->strptr);
8947 vs++;
8948 }
8949 value_string_ext_free(vse);
8950 field_strings = NULL((void*)0);
8951 } else if (field_display == BASE_CUSTOM) {
8952 /* this will be a pointer to a function, don't free that */
8953 field_strings = NULL((void*)0);
8954 } else {
8955 value_string *vs = (value_string *)field_strings;
8956 while (vs->strptr) {
8957 g_free((char *)vs->strptr);
8958 vs++;
8959 }
8960 }
8961 break;
8962 default:
8963 break;
8964 }
8965 }
8966
8967 if (field_type != FT_FRAMENUM) {
8968 g_free((void *)field_strings);
8969 }
8970}
8971
8972static void
8973free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
8974{
8975 header_field_info *hfi = (header_field_info *) data;
8976 int hf_id = hfi->id;
8977
8978 g_free((char *)hfi->name);
8979 g_free((char *)hfi->abbrev);
8980 g_free((char *)hfi->blurb);
8981
8982 proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
8983
8984 if (hfi->parent == -1)
8985 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)
;
8986
8987 gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
8988}
8989
8990static void
8991free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
8992{
8993 g_free (data);
8994}
8995
8996static void
8997free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
8998{
8999 struct g_slice_data *slice_data = (struct g_slice_data *)data;
9000
9001 g_slice_free1(slice_data->block_size, slice_data->mem_block);
9002 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)
;
9003}
9004
9005/* free deregistered fields and data */
9006void
9007proto_free_deregistered_fields (void)
9008{
9009 expert_free_deregistered_expertinfos();
9010
9011 g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9012 g_ptr_array_free(deregistered_fields, true1);
9013 deregistered_fields = g_ptr_array_new();
9014
9015 g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9016 g_ptr_array_free(deregistered_data, true1);
9017 deregistered_data = g_ptr_array_new();
9018
9019 g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9020 g_ptr_array_free(deregistered_slice, true1);
9021 deregistered_slice = g_ptr_array_new();
9022}
9023
9024static const value_string hf_display[] = {
9025 { BASE_NONE, "BASE_NONE" },
9026 { BASE_DEC, "BASE_DEC" },
9027 { BASE_HEX, "BASE_HEX" },
9028 { BASE_OCT, "BASE_OCT" },
9029 { BASE_DEC_HEX, "BASE_DEC_HEX" },
9030 { BASE_HEX_DEC, "BASE_HEX_DEC" },
9031 { BASE_CUSTOM, "BASE_CUSTOM" },
9032 { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9033 { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9034 { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9035 { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9036 { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9037 { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9038 { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9039 { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9040 { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9041 { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9042 { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9043 { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9044 { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9045 { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9046 { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9047 { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9048 { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9049 { BASE_PT_UDP, "BASE_PT_UDP" },
9050 { BASE_PT_TCP, "BASE_PT_TCP" },
9051 { BASE_PT_DCCP, "BASE_PT_DCCP" },
9052 { BASE_PT_SCTP, "BASE_PT_SCTP" },
9053 { BASE_OUI, "BASE_OUI" },
9054 { 0, NULL((void*)0) } };
9055
9056const char* proto_field_display_to_string(int field_display)
9057{
9058 return val_to_str_const(field_display, hf_display, "Unknown");
9059}
9060
9061static inline port_type
9062display_to_port_type(field_display_e e)
9063{
9064 switch (e) {
9065 case BASE_PT_UDP:
9066 return PT_UDP;
9067 case BASE_PT_TCP:
9068 return PT_TCP;
9069 case BASE_PT_DCCP:
9070 return PT_DCCP;
9071 case BASE_PT_SCTP:
9072 return PT_SCTP;
9073 default:
9074 break;
9075 }
9076 return PT_NONE;
9077}
9078
9079/* temporary function containing assert part for easier profiling */
9080static void
9081tmp_fld_check_assert(header_field_info *hfinfo)
9082{
9083 char* tmp_str;
9084
9085 /* The field must have a name (with length > 0) */
9086 if (!hfinfo->name || !hfinfo->name[0]) {
9087 if (hfinfo->abbrev)
9088 /* Try to identify the field */
9089 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)
9090 hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name"
, hfinfo->abbrev)
;
9091 else
9092 /* Hum, no luck */
9093 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)"
)
;
9094 }
9095
9096 /* fields with an empty string for an abbreviation aren't filterable */
9097 if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9098 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)
;
9099
9100 /* These types of fields are allowed to have value_strings,
9101 * true_false_strings or a protocol_t struct
9102 */
9103 if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9104 switch (hfinfo->type) {
9105
9106 /*
9107 * These types are allowed to support display value_strings,
9108 * value64_strings, the extended versions of the previous
9109 * two, range strings, or unit strings.
9110 */
9111 case FT_CHAR:
9112 case FT_UINT8:
9113 case FT_UINT16:
9114 case FT_UINT24:
9115 case FT_UINT32:
9116 case FT_UINT40:
9117 case FT_UINT48:
9118 case FT_UINT56:
9119 case FT_UINT64:
9120 case FT_INT8:
9121 case FT_INT16:
9122 case FT_INT24:
9123 case FT_INT32:
9124 case FT_INT40:
9125 case FT_INT48:
9126 case FT_INT56:
9127 case FT_INT64:
9128 case FT_BOOLEAN:
9129 case FT_PROTOCOL:
9130 break;
9131
9132 /*
9133 * This is allowed to have a value of type
9134 * enum ft_framenum_type to indicate what relationship
9135 * the frame in question has to the frame in which
9136 * the field is put.
9137 */
9138 case FT_FRAMENUM:
9139 break;
9140
9141 /*
9142 * These types are allowed to support only unit strings.
9143 */
9144 case FT_FLOAT:
9145 case FT_DOUBLE:
9146 if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9147 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))
9148 " (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))
9149 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))
;
9150 }
9151 break;
9152
9153 /*
9154 * This type is only allowed to support a string if it's
9155 * a protocol (for pinos).
9156 */
9157 case FT_BYTES:
9158 if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9159 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))
9160 " (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))
9161 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))
;
9162 }
9163 break;
9164
9165 default:
9166 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))
9167 " (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))
9168 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))
;
9169 }
9170 }
9171
9172 /* TODO: This check may slow down startup, and output quite a few warnings.
9173 It would be good to be able to enable this (and possibly other checks?)
9174 in non-release builds. */
9175#ifdef ENABLE_CHECK_FILTER
9176 /* Check for duplicate value_string values.
9177 There are lots that have the same value *and* string, so for now only
9178 report those that have same value but different string. */
9179 if ((hfinfo->strings != NULL((void*)0)) &&
9180 !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9181 !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9182 !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9183 (
9184 (hfinfo->type == FT_CHAR) ||
9185 (hfinfo->type == FT_UINT8) ||
9186 (hfinfo->type == FT_UINT16) ||
9187 (hfinfo->type == FT_UINT24) ||
9188 (hfinfo->type == FT_UINT32) ||
9189 (hfinfo->type == FT_INT8) ||
9190 (hfinfo->type == FT_INT16) ||
9191 (hfinfo->type == FT_INT24) ||
9192 (hfinfo->type == FT_INT32) )) {
9193
9194 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9195 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9196 const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9197 CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9198 } else {
9199 const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9200 CHECK_HF_VALUE(value_string, "u", start_values);
9201 }
9202 } else {
9203 const value_string *start_values = (const value_string*)hfinfo->strings;
9204 CHECK_HF_VALUE(value_string, "u", start_values);
9205 }
9206 }
9207
9208 if (hfinfo->type == FT_BOOLEAN) {
9209 const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9210 if (tfs) {
9211 if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9212 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"
, 9214, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9213 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9214, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
9214 tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9214, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")"
, hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs
->true_string); } } while (0)
;
9215 }
9216 }
9217 }
9218
9219 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9220 const range_string *rs = (const range_string*)(hfinfo->strings);
9221 if (rs) {
9222 const range_string *this_it = rs;
9223
9224 do {
9225 if (this_it->value_max < this_it->value_min) {
9226 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"
, 9230, __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)
9227 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9230, __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)
9228 this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9230, __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)
9229 this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9230, __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)
9230 this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9230, __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)
;
9231 ++this_it;
9232 continue;
9233 }
9234
9235 for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9236 /* Not OK if this one is completely hidden by an earlier one! */
9237 if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9238 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"
, 9244, __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)
9239 "(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"
, 9244, __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)
9240 hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9244, __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)
9241 prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9244, __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)
9242 prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9244, __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)
9243 this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9244, __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)
9244 this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9244, __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)
;
9245 }
9246 }
9247 ++this_it;
9248 } while (this_it->strptr);
9249 }
9250 }
9251#endif
9252
9253 switch (hfinfo->type) {
9254
9255 case FT_CHAR:
9256 /* Require the char type to have BASE_HEX, BASE_OCT,
9257 * BASE_CUSTOM, or BASE_NONE as its base.
9258 *
9259 * If the display value is BASE_NONE and there is a
9260 * strings conversion then the dissector writer is
9261 * telling us that the field's numerical value is
9262 * meaningless; we'll avoid showing the value to the
9263 * user.
9264 */
9265 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9266 case BASE_HEX:
9267 case BASE_OCT:
9268 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9269 break;
9270 case BASE_NONE:
9271 if (hfinfo->strings == NULL((void*)0))
9272 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
))
9273 " 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
))
9274 " 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
))
9275 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
))
9276 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
))
;
9277 break;
9278 default:
9279 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9280 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)
9281 " 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)
9282 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)
9283 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)
;
9284 //wmem_free(NULL, tmp_str);
9285 }
9286 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9287 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
))
9288 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
))
9289 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
))
;
9290 }
9291 break;
9292 case FT_INT8:
9293 case FT_INT16:
9294 case FT_INT24:
9295 case FT_INT32:
9296 case FT_INT40:
9297 case FT_INT48:
9298 case FT_INT56:
9299 case FT_INT64:
9300 /* Hexadecimal and octal are, in printf() and everywhere
9301 * else, unsigned so don't allow dissectors to register a
9302 * signed field to be displayed unsigned. (Else how would
9303 * we display negative values?)
9304 */
9305 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9306 case BASE_HEX:
9307 case BASE_OCT:
9308 case BASE_DEC_HEX:
9309 case BASE_HEX_DEC:
9310 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9311 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)
9312 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)
9313 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)
;
9314 //wmem_free(NULL, tmp_str);
9315 }
9316 /* FALL THROUGH */
9317 case FT_UINT8:
9318 case FT_UINT16:
9319 case FT_UINT24:
9320 case FT_UINT32:
9321 case FT_UINT40:
9322 case FT_UINT48:
9323 case FT_UINT56:
9324 case FT_UINT64:
9325 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
))
) {
9326 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9327 if (hfinfo->type != FT_UINT16) {
9328 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))
9329 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))
9330 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))
;
9331 }
9332 if (hfinfo->strings != NULL((void*)0)) {
9333 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)
9334 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)
9335 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)
;
9336 }
9337 if (hfinfo->bitmask != 0) {
9338 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)
9339 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)
9340 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)
;
9341 }
9342 wmem_free(NULL((void*)0), tmp_str);
9343 break;
9344 }
9345
9346 if (hfinfo->display == BASE_OUI) {
9347 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9348 if (hfinfo->type != FT_UINT24) {
9349 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))
9350 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))
9351 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))
;
9352 }
9353 if (hfinfo->strings != NULL((void*)0)) {
9354 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)
9355 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)
9356 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)
;
9357 }
9358 if (hfinfo->bitmask != 0) {
9359 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)
9360 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)
9361 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)
;
9362 }
9363 wmem_free(NULL((void*)0), tmp_str);
9364 break;
9365 }
9366
9367 /* Require integral types (other than frame number,
9368 * which is always displayed in decimal) to have a
9369 * number base.
9370 *
9371 * If the display value is BASE_NONE and there is a
9372 * strings conversion then the dissector writer is
9373 * telling us that the field's numerical value is
9374 * meaningless; we'll avoid showing the value to the
9375 * user.
9376 */
9377 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9378 case BASE_DEC:
9379 case BASE_HEX:
9380 case BASE_OCT:
9381 case BASE_DEC_HEX:
9382 case BASE_HEX_DEC:
9383 case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9384 break;
9385 case BASE_NONE:
9386 if (hfinfo->strings == NULL((void*)0)) {
9387 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
))
9388 " 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
))
9389 " 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
))
9390 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
))
9391 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
))
;
9392 }
9393 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9394 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
))
9395 " 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
))
9396 " 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
))
9397 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
))
9398 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
))
;
9399 }
9400 break;
9401
9402 default:
9403 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9404 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)
9405 " 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)
9406 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)
9407 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)
;
9408 //wmem_free(NULL, tmp_str);
9409 }
9410 break;
9411 case FT_BYTES:
9412 case FT_UINT_BYTES:
9413 /* Require bytes to have a "display type" that could
9414 * add a character between displayed bytes.
9415 */
9416 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9417 case BASE_NONE:
9418 case SEP_DOT:
9419 case SEP_DASH:
9420 case SEP_COLON:
9421 case SEP_SPACE:
9422 break;
9423 default:
9424 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9425 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)
9426 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)
;
9427 //wmem_free(NULL, tmp_str);
9428 }
9429 if (hfinfo->bitmask != 0)
9430 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
))
9431 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
))
9432 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
))
;
9433 //allowed to support string if its a protocol (for pinos)
9434 if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9435 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
))
9436 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
))
9437 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
))
;
9438 break;
9439
9440 case FT_PROTOCOL:
9441 case FT_FRAMENUM:
9442 if (hfinfo->display != BASE_NONE) {
9443 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9444 REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %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)
9445 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)
9446 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)
;
9447 //wmem_free(NULL, tmp_str);
9448 }
9449 if (hfinfo->bitmask != 0)
9450 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
))
9451 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
))
9452 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
))
;
9453 break;
9454
9455 case FT_BOOLEAN:
9456 break;
9457
9458 case FT_ABSOLUTE_TIME:
9459 if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL &&
((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)
) {
9460 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9461 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)
9462 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)
;
9463 //wmem_free(NULL, tmp_str);
9464 }
9465 if (hfinfo->bitmask != 0)
9466 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
))
9467 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
))
9468 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
))
;
9469 break;
9470
9471 case FT_STRING:
9472 case FT_STRINGZ:
9473 case FT_UINT_STRING:
9474 case FT_STRINGZPAD:
9475 case FT_STRINGZTRUNC:
9476 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9477 case BASE_NONE:
9478 case BASE_STR_WSP:
9479 break;
9480
9481 default:
9482 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9483 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)
9484 " 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)
9485 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)
9486 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)
;
9487 //wmem_free(NULL, tmp_str);
9488 }
9489
9490 if (hfinfo->bitmask != 0)
9491 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
))
9492 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
))
9493 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
))
;
9494 if (hfinfo->strings != NULL((void*)0))
9495 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
))
9496 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
))
9497 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
))
;
9498 break;
9499
9500 case FT_IPv4:
9501 switch (hfinfo->display) {
9502 case BASE_NONE:
9503 case BASE_NETMASK:
9504 break;
9505
9506 default:
9507 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9508 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)
9509 " 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)
9510 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)
9511 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)
;
9512 //wmem_free(NULL, tmp_str);
9513 break;
9514 }
9515 break;
9516 case FT_FLOAT:
9517 case FT_DOUBLE:
9518 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9519 case BASE_NONE:
9520 case BASE_DEC:
9521 case BASE_HEX:
9522 case BASE_EXP:
9523 case BASE_CUSTOM:
9524 break;
9525 default:
9526 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9527 REPORT_DISSECTOR_BUG("Field '%s' (%s) is 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)
9528 " 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)
9529 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)
9530 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)
;
9531 //wmem_free(NULL, tmp_str);
9532 }
9533 if (hfinfo->bitmask != 0)
9534 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
))
9535 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
))
9536 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
))
;
9537 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9538 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
))
9539 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
))
9540 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
))
;
9541 break;
9542 default:
9543 if (hfinfo->display != BASE_NONE) {
9544 tmp_str = val_to_str_wmem(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9545 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)
9546 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)
9547 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)
9548 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)
;
9549 //wmem_free(NULL, tmp_str);
9550 }
9551 if (hfinfo->bitmask != 0)
9552 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
))
9553 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
))
9554 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
))
;
9555 if (hfinfo->strings != NULL((void*)0))
9556 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
))
9557 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
))
9558 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
))
;
9559 break;
9560 }
9561}
9562
9563#ifdef ENABLE_CHECK_FILTER
9564static enum ftenum
9565_ftype_common(enum ftenum type)
9566{
9567 switch (type) {
9568 case FT_INT8:
9569 case FT_INT16:
9570 case FT_INT24:
9571 case FT_INT32:
9572 return FT_INT32;
9573
9574 case FT_CHAR:
9575 case FT_UINT8:
9576 case FT_UINT16:
9577 case FT_UINT24:
9578 case FT_UINT32:
9579 case FT_IPXNET:
9580 case FT_FRAMENUM:
9581 return FT_UINT32;
9582
9583 case FT_UINT64:
9584 case FT_EUI64:
9585 return FT_UINT64;
9586
9587 case FT_STRING:
9588 case FT_STRINGZ:
9589 case FT_UINT_STRING:
9590 return FT_STRING;
9591
9592 case FT_FLOAT:
9593 case FT_DOUBLE:
9594 return FT_DOUBLE;
9595
9596 case FT_BYTES:
9597 case FT_UINT_BYTES:
9598 case FT_ETHER:
9599 case FT_OID:
9600 return FT_BYTES;
9601
9602 case FT_ABSOLUTE_TIME:
9603 case FT_RELATIVE_TIME:
9604 return FT_ABSOLUTE_TIME;
9605
9606 default:
9607 return type;
9608 }
9609}
9610#endif
9611
9612static void
9613register_type_length_mismatch(void)
9614{
9615 static ei_register_info ei[] = {
9616 { &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)}}
}},
9617 { &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)}}
}},
9618 };
9619
9620 expert_module_t* expert_type_length_mismatch;
9621
9622 proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9623
9624 expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9625 expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9626
9627 /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9628 disabling them makes no sense. */
9629 proto_set_cant_toggle(proto_type_length_mismatch);
9630}
9631
9632static void
9633register_byte_array_string_decodinws_error(void)
9634{
9635 static ei_register_info ei[] = {
9636 { &ei_byte_array_string_decoding_failed_error,
9637 { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9638 "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)}}
9639 }
9640 },
9641 };
9642
9643 expert_module_t* expert_byte_array_string_decoding_error;
9644
9645 proto_byte_array_string_decoding_error =
9646 proto_register_protocol("Byte Array-String Decoding Error",
9647 "Byte Array-string decoding error",
9648 "_ws.byte_array_string.decoding_error");
9649
9650 expert_byte_array_string_decoding_error =
9651 expert_register_protocol(proto_byte_array_string_decoding_error);
9652 expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9653
9654 /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9655 disabling them makes no sense. */
9656 proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9657}
9658
9659static void
9660register_date_time_string_decodinws_error(void)
9661{
9662 static ei_register_info ei[] = {
9663 { &ei_date_time_string_decoding_failed_error,
9664 { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9665 "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)}}
9666 }
9667 },
9668 };
9669
9670 expert_module_t* expert_date_time_string_decoding_error;
9671
9672 proto_date_time_string_decoding_error =
9673 proto_register_protocol("Date and Time-String Decoding Error",
9674 "Date and Time-string decoding error",
9675 "_ws.date_time_string.decoding_error");
9676
9677 expert_date_time_string_decoding_error =
9678 expert_register_protocol(proto_date_time_string_decoding_error);
9679 expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9680
9681 /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9682 disabling them makes no sense. */
9683 proto_set_cant_toggle(proto_date_time_string_decoding_error);
9684}
9685
9686static void
9687register_string_errors(void)
9688{
9689 static ei_register_info ei[] = {
9690 { &ei_string_trailing_characters,
9691 { "_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)}}
}
9692 },
9693 };
9694
9695 expert_module_t* expert_string_errors;
9696
9697 proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9698
9699 expert_string_errors = expert_register_protocol(proto_string_errors);
9700 expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9701
9702 /* "String Errors" isn't really a protocol, it's an error indication;
9703 disabling them makes no sense. */
9704 proto_set_cant_toggle(proto_string_errors);
9705}
9706
9707#define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
9708static int
9709proto_register_field_init(header_field_info *hfinfo, const int parent)
9710{
9711
9712 tmp_fld_check_assert(hfinfo);
9713
9714 hfinfo->parent = parent;
9715 hfinfo->same_name_next = NULL((void*)0);
9716 hfinfo->same_name_prev_id = -1;
9717
9718 /* if we always add and never delete, then id == len - 1 is correct */
9719 if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9720 if (!gpa_hfinfo.hfi) {
9721 gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9722 gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9723 /* The entry with index 0 is not used. */
9724 gpa_hfinfo.hfi[0] = NULL((void*)0);
9725 gpa_hfinfo.len = 1;
9726 } else {
9727 gpa_hfinfo.allocated_len += 1000;
9728 gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9729 sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9730 /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9731 }
9732 }
9733 gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9734 gpa_hfinfo.len++;
9735 hfinfo->id = gpa_hfinfo.len - 1;
9736
9737 /* if we have real names, enter this field in the name tree */
9738 if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) {
9739
9740 header_field_info *same_name_next_hfinfo;
9741 unsigned char c;
9742
9743 /* Check that the filter name (abbreviation) is legal;
9744 * it must contain only alphanumerics, '-', "_", and ".". */
9745 c = proto_check_field_name(hfinfo->abbrev);
9746 if (c) {
9747 if (c == '.') {
9748 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)
;
9749 } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9750 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)
;
9751 } else {
9752 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)
;
9753 }
9754 }
9755
9756 /* We allow multiple hfinfo's to be registered under the same
9757 * abbreviation. This was done for X.25, as, depending
9758 * on whether it's modulo-8 or modulo-128 operation,
9759 * some bitfield fields may be in different bits of
9760 * a byte, and we want to be able to refer to that field
9761 * with one name regardless of whether the packets
9762 * are modulo-8 or modulo-128 packets. */
9763
9764 same_name_hfinfo = NULL((void*)0);
9765
9766 g_hash_table_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9767 /* GLIB 2.x - if it is already present
9768 * the previous hfinfo with the same name is saved
9769 * to same_name_hfinfo by value destroy callback */
9770 if (same_name_hfinfo) {
9771 /* There's already a field with this name.
9772 * Put the current field *before* that field
9773 * in the list of fields with this name, Thus,
9774 * we end up with an effectively
9775 * doubly-linked-list of same-named hfinfo's,
9776 * with the head of the list (stored in the
9777 * hash) being the last seen hfinfo.
9778 */
9779 same_name_next_hfinfo =
9780 same_name_hfinfo->same_name_next;
9781
9782 hfinfo->same_name_next = same_name_next_hfinfo;
9783 if (same_name_next_hfinfo)
9784 same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9785
9786 same_name_hfinfo->same_name_next = hfinfo;
9787 hfinfo->same_name_prev_id = same_name_hfinfo->id;
9788#ifdef ENABLE_CHECK_FILTER
9789 while (same_name_hfinfo) {
9790 if (_ftype_common(hfinfo->type) != _ftype_common(same_name_hfinfo->type))
9791 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"
, 9791, __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)
;
9792 same_name_hfinfo = same_name_hfinfo->same_name_next;
9793 }
9794#endif
9795 }
9796 }
9797
9798 return hfinfo->id;
9799}
9800
9801void
9802proto_register_subtree_array(int * const *indices, const int num_indices)
9803{
9804 int i;
9805 int *const *ptr = indices;
9806
9807 /*
9808 * If we've already allocated the array of tree types, expand
9809 * it; this lets plugins such as mate add tree types after
9810 * the initial startup. (If we haven't already allocated it,
9811 * we don't allocate it; on the first pass, we just assign
9812 * ett values and keep track of how many we've assigned, and
9813 * when we're finished registering all dissectors we allocate
9814 * the array, so that we do only one allocation rather than
9815 * wasting CPU time and memory by growing the array for each
9816 * dissector that registers ett values.)
9817 */
9818 if (tree_is_expanded != NULL((void*)0)) {
9819 tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9820
9821 /* set new items to 0 */
9822 /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9823 for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9824 tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9825 }
9826
9827 /*
9828 * Assign "num_indices" subtree numbers starting at "num_tree_types",
9829 * returning the indices through the pointers in the array whose
9830 * first element is pointed to by "indices", and update
9831 * "num_tree_types" appropriately.
9832 */
9833 for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9834 if (**ptr != -1 && **ptr != 0) {
9835 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.")
9836 " 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.")
9837 " 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.")
9838 " 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.")
;
9839 }
9840 **ptr = num_tree_types;
9841 }
9842}
9843
9844static void
9845mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
9846{
9847 static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\xe2\x80\xa6" "]";
9848 const size_t trunc_len = sizeof(trunc_str)-1;
9849 char *last_char;
9850
9851 /* ..... field_name: dataaaaaaaaaaaaa
9852 * |
9853 * ^^^^^ name_pos
9854 *
9855 * ..... field_name […]: dataaaaaaaaaaaaa
9856 *
9857 * name_pos==0 means that we have only data or only a field_name
9858 */
9859
9860 if (name_pos < size - trunc_len) {
9861 memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
9862 memcpy(label_str + name_pos, trunc_str, trunc_len);
9863
9864 /* in general, label_str is UTF-8
9865 we can truncate it only at the beginning of a new character
9866 we go backwards from the byte right after our buffer and
9867 find the next starting byte of a UTF-8 character, this is
9868 where we cut
9869 there's no need to use g_utf8_find_prev_char(), the search
9870 will always succeed since we copied trunc_str into the
9871 buffer */
9872 /* g_utf8_prev_char does not deference the memory address
9873 * passed in (until after decrementing it, so it is perfectly
9874 * legal to pass in a pointer one past the last element.
9875 */
9876 last_char = g_utf8_prev_char(label_str + size);
9877 *last_char = '\0';
9878
9879 if (value_pos && *value_pos > 0) {
9880 if (name_pos == 0) {
9881 *value_pos += trunc_len;
9882 } else {
9883 /* Move one back to include trunc_str in the value. */
9884 *value_pos -= 1;
9885 }
9886 }
9887 } else if (name_pos < size)
9888 (void) g_strlcpy(label_str + name_pos, trunc_str, size - name_pos);
9889}
9890
9891static void
9892label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
9893{
9894 mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
9895}
9896
9897static size_t
9898label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
9899{
9900 size_t name_pos;
9901
9902 /* "%s: %s", hfinfo->name, text */
9903 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
9904 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
9905 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
9906 if (value_pos) {
9907 *value_pos = pos;
9908 }
9909 pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
9910 }
9911
9912 if (pos >= ITEM_LABEL_LENGTH240) {
9913 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9914 label_mark_truncated(label_str, name_pos, value_pos);
9915 }
9916
9917 return pos;
9918}
9919
9920static size_t
9921label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
9922{
9923 size_t name_pos;
9924
9925 /* "%s: %s (%s)", hfinfo->name, text, descr */
9926 name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
9927 if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
9928 pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
9929 if (value_pos) {
9930 *value_pos = pos;
9931 }
9932 if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9933 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
9934 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
9935 } else {
9936 pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0
)
;
9937 pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
9938 pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)"
, 0)
;
9939 pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
9940 }
9941 }
9942
9943 if (pos >= ITEM_LABEL_LENGTH240) {
9944 /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
9945 label_mark_truncated(label_str, name_pos, value_pos);
9946 }
9947
9948 return pos;
9949}
9950
9951void
9952proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
9953{
9954 const header_field_info *hfinfo;
9955 const char *str;
9956 const uint8_t *bytes;
9957 uint32_t integer;
9958 uint64_t integer64;
9959 const ipv4_addr_and_mask *ipv4;
9960 const ipv6_addr_and_prefix *ipv6;
9961 const e_guid_t *guid;
9962 char *name;
9963 address addr;
9964 char *addr_str;
9965 char *tmp;
9966
9967 if (!label_str) {
9968 ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 9968, __func__, "NULL label_str passed to proto_item_fill_label."
); } } while (0)
;
9969 return;
9970 }
9971
9972 label_str[0]= '\0';
9973
9974 if (!fi) {
9975 return;
9976 }
9977
9978 hfinfo = fi->hfinfo;
9979
9980 switch (hfinfo->type) {
9981 case FT_NONE:
9982 case FT_PROTOCOL:
9983 (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
9984 if (value_pos) {
9985 *value_pos = strlen(hfinfo->name);
9986 }
9987 break;
9988
9989 case FT_BOOLEAN:
9990 fill_label_boolean(fi, label_str, value_pos);
9991 break;
9992
9993 case FT_BYTES:
9994 case FT_UINT_BYTES:
9995 tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
9996 fvalue_get_bytes_data(fi->value),
9997 (unsigned)fvalue_length2(fi->value));
9998 label_fill(label_str, 0, hfinfo, tmp, value_pos);
9999 wmem_free(NULL((void*)0), tmp);
10000 break;
10001
10002 case FT_CHAR:
10003 if (hfinfo->bitmask) {
10004 fill_label_bitfield_char(fi, label_str, value_pos);
10005 } else {
10006 fill_label_char(fi, label_str, value_pos);
10007 }
10008 break;
10009
10010 /* Four types of integers to take care of:
10011 * Bitfield, with val_string
10012 * Bitfield, w/o val_string
10013 * Non-bitfield, with val_string
10014 * Non-bitfield, w/o val_string
10015 */
10016 case FT_UINT8:
10017 case FT_UINT16:
10018 case FT_UINT24:
10019 case FT_UINT32:
10020 if (hfinfo->bitmask) {
10021 fill_label_bitfield(fi, label_str, value_pos, false0);
10022 } else {
10023 fill_label_number(fi, label_str, value_pos, false0);
10024 }
10025 break;
10026
10027 case FT_FRAMENUM:
10028 fill_label_number(fi, label_str, value_pos, false0);
10029 break;
10030
10031 case FT_UINT40:
10032 case FT_UINT48:
10033 case FT_UINT56:
10034 case FT_UINT64:
10035 if (hfinfo->bitmask) {
10036 fill_label_bitfield64(fi, label_str, value_pos, false0);
10037 } else {
10038 fill_label_number64(fi, label_str, value_pos, false0);
10039 }
10040 break;
10041
10042 case FT_INT8:
10043 case FT_INT16:
10044 case FT_INT24:
10045 case FT_INT32:
10046 if (hfinfo->bitmask) {
10047 fill_label_bitfield(fi, label_str, value_pos, true1);
10048 } else {
10049 fill_label_number(fi, label_str, value_pos, true1);
10050 }
10051 break;
10052
10053 case FT_INT40:
10054 case FT_INT48:
10055 case FT_INT56:
10056 case FT_INT64:
10057 if (hfinfo->bitmask) {
10058 fill_label_bitfield64(fi, label_str, value_pos, true1);
10059 } else {
10060 fill_label_number64(fi, label_str, value_pos, true1);
10061 }
10062 break;
10063
10064 case FT_FLOAT:
10065 case FT_DOUBLE:
10066 fill_label_float(fi, label_str, value_pos);
10067 break;
10068
10069 case FT_ABSOLUTE_TIME:
10070 {
10071 int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10072 if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10073 flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10074 }
10075 tmp = abs_time_to_str_ex(NULL((void*)0), fvalue_get_time(fi->value), hfinfo->display, flags);
10076 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10077 wmem_free(NULL((void*)0), tmp);
10078 break;
10079 }
10080 case FT_RELATIVE_TIME:
10081 tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10082 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10083 wmem_free(NULL((void*)0), tmp);
10084 break;
10085
10086 case FT_IPXNET:
10087 integer = fvalue_get_uinteger(fi->value);
10088 tmp = get_ipxnet_name(NULL((void*)0), integer);
10089 addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10090 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10091 wmem_free(NULL((void*)0), tmp);
10092 wmem_free(NULL((void*)0), addr_str);
10093 break;
10094
10095 case FT_VINES:
10096 addr.type = AT_VINES;
10097 addr.len = VINES_ADDR_LEN6;
10098 addr.data = fvalue_get_bytes_data(fi->value);
10099
10100 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10101 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10102 wmem_free(NULL((void*)0), addr_str);
10103 break;
10104
10105 case FT_ETHER:
10106 bytes = fvalue_get_bytes_data(fi->value);
10107
10108 addr.type = AT_ETHER;
10109 addr.len = 6;
10110 addr.data = bytes;
10111
10112 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10113 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10114 wmem_free(NULL((void*)0), addr_str);
10115 break;
10116
10117 case FT_IPv4:
10118 ipv4 = fvalue_get_ipv4(fi->value);
10119 set_address_ipv4(&addr, ipv4);
10120
10121 if (hfinfo->display == BASE_NETMASK) {
10122 addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10123 } else {
10124 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10125 }
10126 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10127 wmem_free(NULL((void*)0), addr_str);
10128 free_address(&addr);
10129 break;
10130
10131 case FT_IPv6:
10132 ipv6 = fvalue_get_ipv6(fi->value);
10133 set_address_ipv6(&addr, ipv6);
10134
10135 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10136 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10137 wmem_free(NULL((void*)0), addr_str);
10138 free_address(&addr);
10139 break;
10140
10141 case FT_FCWWN:
10142 bytes = fvalue_get_bytes_data(fi->value);
10143 addr.type = AT_FCWWN;
10144 addr.len = FCWWN_ADDR_LEN8;
10145 addr.data = bytes;
10146
10147 addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10148 label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10149 wmem_free(NULL((void*)0), addr_str);
10150 break;
10151
10152 case FT_GUID:
10153 guid = fvalue_get_guid(fi->value);
10154 tmp = guid_to_str(NULL((void*)0), guid);
10155 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10156 wmem_free(NULL((void*)0), tmp);
10157 break;
10158
10159 case FT_OID:
10160 bytes = fvalue_get_bytes_data(fi->value);
10161 name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10162 tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10163 if (name) {
10164 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10165 wmem_free(NULL((void*)0), name);
10166 } else {
10167 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10168 }
10169 wmem_free(NULL((void*)0), tmp);
10170 break;
10171
10172 case FT_REL_OID:
10173 bytes = fvalue_get_bytes_data(fi->value);
10174 name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10175 tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10176 if (name) {
10177 label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10178 wmem_free(NULL((void*)0), name);
10179 } else {
10180 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10181 }
10182 wmem_free(NULL((void*)0), tmp);
10183 break;
10184
10185 case FT_SYSTEM_ID:
10186 bytes = fvalue_get_bytes_data(fi->value);
10187 tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10188 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10189 wmem_free(NULL((void*)0), tmp);
10190 break;
10191
10192 case FT_EUI64:
10193 integer64 = fvalue_get_uinteger64(fi->value);
10194 addr_str = eui64_to_str(NULL((void*)0), integer64);
10195 tmp = (char*)eui64_to_display(NULL((void*)0), integer64);
10196 label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10197 wmem_free(NULL((void*)0), tmp);
10198 wmem_free(NULL((void*)0), addr_str);
10199 break;
10200 case FT_STRING:
10201 case FT_STRINGZ:
10202 case FT_UINT_STRING:
10203 case FT_STRINGZPAD:
10204 case FT_STRINGZTRUNC:
10205 case FT_AX25:
10206 str = fvalue_get_string(fi->value);
10207 label_fill(label_str, 0, hfinfo, str, value_pos);
10208 break;
10209
10210 case FT_IEEE_11073_SFLOAT:
10211 case FT_IEEE_11073_FLOAT:
10212 tmp = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, hfinfo->display);
10213 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10214 wmem_free(NULL((void*)0), tmp);
10215 break;
10216
10217 default:
10218 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
))
10219 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
))
10220 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
))
10221 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
))
;
10222 break;
10223 }
10224}
10225
10226static void
10227fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10228{
10229 char *p;
10230 int bitfield_byte_length = 0, bitwidth;
10231 uint64_t unshifted_value;
10232 uint64_t value;
10233
10234 const header_field_info *hfinfo = fi->hfinfo;
10235
10236 value = fvalue_get_uinteger64(fi->value);
10237 if (hfinfo->bitmask) {
10238 /* Figure out the bit width */
10239 bitwidth = hfinfo_container_bitwidth(hfinfo);
10240
10241 /* Un-shift bits */
10242 unshifted_value = value;
10243 unshifted_value <<= hfinfo_bitshift(hfinfo);
10244
10245 /* Create the bitfield first */
10246 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10247 bitfield_byte_length = (int) (p - label_str);
10248 }
10249
10250 /* Fill in the textual info */
10251 label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10252}
10253
10254static const char *
10255hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10256{
10257 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10258 return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10259
10260 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10261 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10262 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10263 else
10264 return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10265 }
10266
10267 if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10268 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10269
10270 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10271 return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10272
10273 return try_val_to_str(value, (const value_string *) hfinfo->strings);
10274}
10275
10276static const char *
10277hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10278{
10279 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10280 if (hfinfo->display & BASE_EXT_STRING0x00000200)
10281 return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10282 else
10283 return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10284 }
10285
10286 if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10287 return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10288
10289 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10290 return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10291
10292 /* If this is reached somebody registered a 64-bit field with a 32-bit
10293 * value-string, which isn't right. */
10294 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)
10295 hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string"
, hfinfo->abbrev)
;
10296
10297 /* This is necessary to squelch MSVC errors; is there
10298 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10299 never returns? */
10300 return NULL((void*)0);
10301}
10302
10303static const char *
10304hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10305{
10306 if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10307 return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10308
10309 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)
;
10310
10311 /* This is necessary to squelch MSVC errors; is there
10312 any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10313 never returns? */
10314 return NULL((void*)0);
10315}
10316
10317static const char *
10318hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10319{
10320 const char *str = hf_try_val_to_str(value, hfinfo);
10321
10322 return (str) ? str : unknown_str;
10323}
10324
10325static const char *
10326hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10327{
10328 const char *str = hf_try_val64_to_str(value, hfinfo);
10329
10330 return (str) ? str : unknown_str;
10331}
10332
10333/* Fills data for bitfield chars with val_strings */
10334static void
10335fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10336{
10337 char *p;
10338 int bitfield_byte_length, bitwidth;
10339 uint32_t unshifted_value;
10340 uint32_t value;
10341
10342 char buf[32];
10343 const char *out;
10344
10345 const header_field_info *hfinfo = fi->hfinfo;
10346
10347 /* Figure out the bit width */
10348 bitwidth = hfinfo_container_bitwidth(hfinfo);
10349
10350 /* Un-shift bits */
10351 value = fvalue_get_uinteger(fi->value);
10352
10353 unshifted_value = value;
10354 if (hfinfo->bitmask) {
10355 unshifted_value <<= hfinfo_bitshift(hfinfo);
10356 }
10357
10358 /* Create the bitfield first */
10359 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10360 bitfield_byte_length = (int) (p - label_str);
10361
10362 /* Fill in the textual info using stored (shifted) value */
10363 if (hfinfo->display == BASE_CUSTOM) {
10364 char tmp[ITEM_LABEL_LENGTH240];
10365 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10366
10367 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10367, "fmtfunc"))))
;
10368 fmtfunc(tmp, value);
10369 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10370 }
10371 else if (hfinfo->strings) {
10372 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10373
10374 out = hfinfo_char_vals_format(hfinfo, buf, value);
10375 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10376 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10377 else
10378 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10379 }
10380 else {
10381 out = hfinfo_char_value_format(hfinfo, buf, value);
10382
10383 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10384 }
10385}
10386
10387/* Fills data for bitfield ints with val_strings */
10388static void
10389fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10390{
10391 char *p;
10392 int bitfield_byte_length, bitwidth;
10393 uint32_t value, unshifted_value;
10394 char buf[NUMBER_LABEL_LENGTH80];
10395 const char *out;
10396
10397 const header_field_info *hfinfo = fi->hfinfo;
10398
10399 /* Figure out the bit width */
10400 if (fi->flags & FI_VARINT0x00004000)
10401 bitwidth = fi->length*8;
10402 else
10403 bitwidth = hfinfo_container_bitwidth(hfinfo);
10404
10405 /* Un-shift bits */
10406 if (is_signed)
10407 value = fvalue_get_sinteger(fi->value);
10408 else
10409 value = fvalue_get_uinteger(fi->value);
10410
10411 unshifted_value = value;
10412 if (hfinfo->bitmask) {
10413 unshifted_value <<= hfinfo_bitshift(hfinfo);
10414 }
10415
10416 /* Create the bitfield first */
10417 if (fi->flags & FI_VARINT0x00004000)
10418 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10419 else
10420 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10421 bitfield_byte_length = (int) (p - label_str);
10422
10423 /* Fill in the textual info using stored (shifted) value */
10424 if (hfinfo->display == BASE_CUSTOM) {
10425 char tmp[ITEM_LABEL_LENGTH240];
10426 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10427
10428 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10428, "fmtfunc"))))
;
10429 fmtfunc(tmp, value);
10430 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10431 }
10432 else if (hfinfo->strings) {
10433 const char *val_str = hf_try_val_to_str(value, hfinfo);
10434
10435 out = hfinfo_number_vals_format(hfinfo, buf, value);
10436 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10437 /*
10438 * Unique values only display value_string string
10439 * if there is a match. Otherwise it's just a number
10440 */
10441 if (val_str) {
10442 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10443 } else {
10444 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10445 }
10446 } else {
10447 if (val_str == NULL((void*)0))
10448 val_str = "Unknown";
10449
10450 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10451 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10452 else
10453 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10454 }
10455 }
10456 else {
10457 out = hfinfo_number_value_format(hfinfo, buf, value);
10458
10459 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10460 }
10461}
10462
10463static void
10464fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10465{
10466 char *p;
10467 int bitfield_byte_length, bitwidth;
10468 uint64_t value, unshifted_value;
10469 char buf[NUMBER_LABEL_LENGTH80];
10470 const char *out;
10471
10472 const header_field_info *hfinfo = fi->hfinfo;
10473
10474 /* Figure out the bit width */
10475 if (fi->flags & FI_VARINT0x00004000)
10476 bitwidth = fi->length*8;
10477 else
10478 bitwidth = hfinfo_container_bitwidth(hfinfo);
10479
10480 /* Un-shift bits */
10481 if (is_signed)
10482 value = fvalue_get_sinteger64(fi->value);
10483 else
10484 value = fvalue_get_uinteger64(fi->value);
10485
10486 unshifted_value = value;
10487 if (hfinfo->bitmask) {
10488 unshifted_value <<= hfinfo_bitshift(hfinfo);
10489 }
10490
10491 /* Create the bitfield first */
10492 if (fi->flags & FI_VARINT0x00004000)
10493 p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10494 else
10495 p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10496 bitfield_byte_length = (int) (p - label_str);
10497
10498 /* Fill in the textual info using stored (shifted) value */
10499 if (hfinfo->display == BASE_CUSTOM) {
10500 char tmp[ITEM_LABEL_LENGTH240];
10501 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10502
10503 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10503, "fmtfunc64"
))))
;
10504 fmtfunc64(tmp, value);
10505 label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10506 }
10507 else if (hfinfo->strings) {
10508 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10509
10510 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10511 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10512 /*
10513 * Unique values only display value_string string
10514 * if there is a match. Otherwise it's just a number
10515 */
10516 if (val_str) {
10517 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10518 } else {
10519 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10520 }
10521 } else {
10522 if (val_str == NULL((void*)0))
10523 val_str = "Unknown";
10524
10525 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10526 label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10527 else
10528 label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10529 }
10530 }
10531 else {
10532 out = hfinfo_number_value_format64(hfinfo, buf, value);
10533
10534 label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10535 }
10536}
10537
10538static void
10539fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10540{
10541 const header_field_info *hfinfo = fi->hfinfo;
10542 uint32_t value;
10543
10544 char buf[32];
10545 const char *out;
10546
10547 value = fvalue_get_uinteger(fi->value);
10548
10549 /* Fill in the textual info */
10550 if (hfinfo->display == BASE_CUSTOM) {
10551 char tmp[ITEM_LABEL_LENGTH240];
10552 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10553
10554 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10554, "fmtfunc"))))
;
10555 fmtfunc(tmp, value);
10556 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10557 }
10558 else if (hfinfo->strings) {
10559 const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10560
10561 out = hfinfo_char_vals_format(hfinfo, buf, value);
10562 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10563 }
10564 else {
10565 out = hfinfo_char_value_format(hfinfo, buf, value);
10566
10567 label_fill(label_str, 0, hfinfo, out, value_pos);
10568 }
10569}
10570
10571static void
10572fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10573{
10574 const header_field_info *hfinfo = fi->hfinfo;
10575 uint32_t value;
10576
10577 char buf[NUMBER_LABEL_LENGTH80];
10578 const char *out;
10579
10580 if (is_signed)
10581 value = fvalue_get_sinteger(fi->value);
10582 else
10583 value = fvalue_get_uinteger(fi->value);
10584
10585 /* Fill in the textual info */
10586 if (hfinfo->display == BASE_CUSTOM) {
10587 char tmp[ITEM_LABEL_LENGTH240];
10588 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10589
10590 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10590, "fmtfunc"))))
;
10591 fmtfunc(tmp, value);
10592 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10593 }
10594 else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10595 /*
10596 * It makes no sense to have a value-string table for a
10597 * frame-number field - they're just integers giving
10598 * the ordinal frame number.
10599 */
10600 const char *val_str = hf_try_val_to_str(value, hfinfo);
10601
10602 out = hfinfo_number_vals_format(hfinfo, buf, value);
10603 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10604 /*
10605 * Unique values only display value_string string
10606 * if there is a match. Otherwise it's just a number
10607 */
10608 if (val_str) {
10609 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10610 } else {
10611 label_fill(label_str, 0, hfinfo, out, value_pos);
10612 }
10613 } else {
10614 if (val_str == NULL((void*)0))
10615 val_str = "Unknown";
10616
10617 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10618 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10619 else
10620 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10621 }
10622 }
10623 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
))
) {
10624 char tmp[ITEM_LABEL_LENGTH240];
10625
10626 port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10627 display_to_port_type((field_display_e)hfinfo->display), value);
10628 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10629 }
10630 else {
10631 out = hfinfo_number_value_format(hfinfo, buf, value);
10632
10633 label_fill(label_str, 0, hfinfo, out, value_pos);
10634 }
10635}
10636
10637static void
10638fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10639{
10640 const header_field_info *hfinfo = fi->hfinfo;
10641 uint64_t value;
10642
10643 char buf[NUMBER_LABEL_LENGTH80];
10644 const char *out;
10645
10646 if (is_signed)
10647 value = fvalue_get_sinteger64(fi->value);
10648 else
10649 value = fvalue_get_uinteger64(fi->value);
10650
10651 /* Fill in the textual info */
10652 if (hfinfo->display == BASE_CUSTOM) {
10653 char tmp[ITEM_LABEL_LENGTH240];
10654 const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10655
10656 DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug(
"%s:%u: failed assertion \"%s\"", "epan/proto.c", 10656, "fmtfunc64"
))))
;
10657 fmtfunc64(tmp, value);
10658 label_fill(label_str, 0, hfinfo, tmp, value_pos);
10659 }
10660 else if (hfinfo->strings) {
10661 const char *val_str = hf_try_val64_to_str(value, hfinfo);
10662
10663 out = hfinfo_number_vals_format64(hfinfo, buf, value);
10664 if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10665 /*
10666 * Unique values only display value_string string
10667 * if there is a match. Otherwise it's just a number
10668 */
10669 if (val_str) {
10670 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10671 } else {
10672 label_fill(label_str, 0, hfinfo, out, value_pos);
10673 }
10674 } else {
10675 if (val_str == NULL((void*)0))
10676 val_str = "Unknown";
10677
10678 if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10679 label_fill(label_str, 0, hfinfo, val_str, value_pos);
10680 else
10681 label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10682 }
10683 }
10684 else {
10685 out = hfinfo_number_value_format64(hfinfo, buf, value);
10686
10687 label_fill(label_str, 0, hfinfo, out, value_pos);
10688 }
10689}
10690
10691static size_t
10692fill_display_label_float(const field_info *fi, char *label_str)
10693{
10694 int display;
10695 int digits;
10696 int n;
10697 double value;
10698
10699 display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10700 value = fvalue_get_floating(fi->value);
10701
10702 if (display == BASE_CUSTOM) {
10703 const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10704 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 10704, "fmtfunc"))))
;
10705 fmtfunc(label_str, value);
10706 return strlen(label_str);
10707 }
10708
10709 switch (display) {
10710 case BASE_NONE:
10711 if (fi->hfinfo->type == FT_FLOAT)
10712 digits = FLT_DIG6;
10713 else
10714 digits = DBL_DIG15;
10715
10716 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%.*g", digits, value);
10717 break;
10718 case BASE_DEC:
10719 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%f", value);
10720 break;
10721 case BASE_HEX:
10722 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%a", value);
10723 break;
10724 case BASE_EXP:
10725 n = snprintf(label_str, ITEM_LABEL_LENGTH240, "%e", value);
10726 break;
10727 default:
10728 ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10728
, __func__, "assertion \"not reached\" failed")
;
10729 }
10730 if (n < 0) {
10731 return 0; /* error */
10732 }
10733 if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10734 const char *hf_str_val;
10735 hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10736 n += protoo_strlcpy(label_str + n, hf_str_val, ITEM_LABEL_LENGTH240 - n);
10737 }
10738 if (n > ITEM_LABEL_LENGTH240) {
10739 ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 10739, __func__, "label length too small"); } } while (0)
;
10740 return strlen(label_str);
10741 }
10742
10743 return n;
10744}
10745
10746void
10747fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10748{
10749 char tmp[ITEM_LABEL_LENGTH240];
10750
10751 fill_display_label_float(fi, tmp);
10752 label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10753}
10754
10755int
10756hfinfo_bitshift(const header_field_info *hfinfo)
10757{
10758 return ws_ctz(hfinfo->bitmask);
10759}
10760
10761
10762static int
10763hfinfo_bitoffset(const header_field_info *hfinfo)
10764{
10765 if (!hfinfo->bitmask) {
10766 return 0;
10767 }
10768
10769 /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10770 * as the first bit */
10771 return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10772}
10773
10774static int
10775hfinfo_mask_bitwidth(const header_field_info *hfinfo)
10776{
10777 if (!hfinfo->bitmask) {
10778 return 0;
10779 }
10780
10781 /* ilog2 = first set bit, ctz = last set bit */
10782 return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
10783}
10784
10785static int
10786hfinfo_type_bitwidth(enum ftenum type)
10787{
10788 int bitwidth = 0;
10789
10790 switch (type) {
10791 case FT_CHAR:
10792 case FT_UINT8:
10793 case FT_INT8:
10794 bitwidth = 8;
10795 break;
10796 case FT_UINT16:
10797 case FT_INT16:
10798 bitwidth = 16;
10799 break;
10800 case FT_UINT24:
10801 case FT_INT24:
10802 bitwidth = 24;
10803 break;
10804 case FT_UINT32:
10805 case FT_INT32:
10806 bitwidth = 32;
10807 break;
10808 case FT_UINT40:
10809 case FT_INT40:
10810 bitwidth = 40;
10811 break;
10812 case FT_UINT48:
10813 case FT_INT48:
10814 bitwidth = 48;
10815 break;
10816 case FT_UINT56:
10817 case FT_INT56:
10818 bitwidth = 56;
10819 break;
10820 case FT_UINT64:
10821 case FT_INT64:
10822 bitwidth = 64;
10823 break;
10824 default:
10825 DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\""
, "epan/proto.c", 10825))
;
10826 ;
10827 }
10828 return bitwidth;
10829}
10830
10831
10832static int
10833hfinfo_container_bitwidth(const header_field_info *hfinfo)
10834{
10835 if (!hfinfo->bitmask) {
10836 return 0;
10837 }
10838
10839 if (hfinfo->type == FT_BOOLEAN) {
10840 return hfinfo->display; /* hacky? :) */
10841 }
10842
10843 return hfinfo_type_bitwidth(hfinfo->type);
10844}
10845
10846static int
10847hfinfo_hex_digits(const header_field_info *hfinfo)
10848{
10849 int bitwidth;
10850
10851 /* If we have a bitmask, hfinfo->type is the width of the container, so not
10852 * appropriate to determine the number of hex digits for the field.
10853 * So instead, we compute it from the bitmask.
10854 */
10855 if (hfinfo->bitmask != 0) {
10856 bitwidth = hfinfo_mask_bitwidth(hfinfo);
10857 } else {
10858 bitwidth = hfinfo_type_bitwidth(hfinfo->type);
10859 }
10860
10861 /* Divide by 4, rounding up, to get number of hex digits. */
10862 return (bitwidth + 3) / 4;
10863}
10864
10865const char *
10866hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
10867{
10868 char *ptr = &buf[6];
10869 static const char hex_digits[16] =
10870 { '0', '1', '2', '3', '4', '5', '6', '7',
10871 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
10872
10873 *ptr = '\0';
10874 *(--ptr) = '\'';
10875 /* Properly format value */
10876 if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
10877 /*
10878 * Printable, so just show the character, and, if it needs
10879 * to be escaped, escape it.
10880 */
10881 *(--ptr) = value;
10882 if (value == '\\' || value == '\'')
10883 *(--ptr) = '\\';
10884 } else {
10885 /*
10886 * Non-printable; show it as an escape sequence.
10887 */
10888 switch (value) {
10889
10890 case '\0':
10891 /*
10892 * Show a NUL with only one digit.
10893 */
10894 *(--ptr) = '0';
10895 break;
10896
10897 case '\a':
10898 *(--ptr) = 'a';
10899 break;
10900
10901 case '\b':
10902 *(--ptr) = 'b';
10903 break;
10904
10905 case '\f':
10906 *(--ptr) = 'f';
10907 break;
10908
10909 case '\n':
10910 *(--ptr) = 'n';
10911 break;
10912
10913 case '\r':
10914 *(--ptr) = 'r';
10915 break;
10916
10917 case '\t':
10918 *(--ptr) = 't';
10919 break;
10920
10921 case '\v':
10922 *(--ptr) = 'v';
10923 break;
10924
10925 default:
10926 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
10927
10928 case BASE_OCT:
10929 *(--ptr) = (value & 0x7) + '0';
10930 value >>= 3;
10931 *(--ptr) = (value & 0x7) + '0';
10932 value >>= 3;
10933 *(--ptr) = (value & 0x7) + '0';
10934 break;
10935
10936 case BASE_HEX:
10937 *(--ptr) = hex_digits[value & 0x0F];
10938 value >>= 4;
10939 *(--ptr) = hex_digits[value & 0x0F];
10940 *(--ptr) = 'x';
10941 break;
10942
10943 default:
10944 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
10945 }
10946 }
10947 *(--ptr) = '\\';
10948 }
10949 *(--ptr) = '\'';
10950 return ptr;
10951}
10952
10953static const char *
10954hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
10955{
10956 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
10957 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
))
;
10958
10959 *ptr = '\0';
10960 /* Properly format value */
10961 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
10962 case BASE_DEC:
10963 return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
10964
10965 case BASE_DEC_HEX:
10966 *(--ptr) = ')';
10967 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10968 *(--ptr) = '(';
10969 *(--ptr) = ' ';
10970 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
10971 return ptr;
10972
10973 case BASE_OCT:
10974 return oct_to_str_back(ptr, value);
10975
10976 case BASE_HEX:
10977 return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10978
10979 case BASE_HEX_DEC:
10980 *(--ptr) = ')';
10981 ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
10982 *(--ptr) = '(';
10983 *(--ptr) = ' ';
10984 ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
10985 return ptr;
10986
10987 case BASE_PT_UDP:
10988 case BASE_PT_TCP:
10989 case BASE_PT_DCCP:
10990 case BASE_PT_SCTP:
10991 port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
10992 display_to_port_type((field_display_e)display), value);
10993 return buf;
10994 case BASE_OUI:
10995 {
10996 uint8_t p_oui[3];
10997 const char *manuf_name;
10998
10999 p_oui[0] = value >> 16 & 0xFF;
11000 p_oui[1] = value >> 8 & 0xFF;
11001 p_oui[2] = value & 0xFF;
11002
11003 /* Attempt an OUI lookup. */
11004 manuf_name = uint_get_manuf_name_if_known(value);
11005 if (manuf_name == NULL((void*)0)) {
11006 /* Could not find an OUI. */
11007 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11008 }
11009 else {
11010 /* Found an address string. */
11011 snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11012 }
11013 return buf;
11014 }
11015
11016 default:
11017 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11018 }
11019 return ptr;
11020}
11021
11022static const char *
11023hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11024{
11025 char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11026 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
))
;
11027
11028 *ptr = '\0';
11029 /* Properly format value */
11030 switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11031 case BASE_DEC:
11032 return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11033
11034 case BASE_DEC_HEX:
11035 *(--ptr) = ')';
11036 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11037 *(--ptr) = '(';
11038 *(--ptr) = ' ';
11039 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11040 return ptr;
11041
11042 case BASE_OCT:
11043 return oct64_to_str_back(ptr, value);
11044
11045 case BASE_HEX:
11046 return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11047
11048 case BASE_HEX_DEC:
11049 *(--ptr) = ')';
11050 ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11051 *(--ptr) = '(';
11052 *(--ptr) = ' ';
11053 ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11054 return ptr;
11055
11056 default:
11057 REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) &
0xFF))
;
11058 }
11059
11060 return ptr;
11061}
11062
11063static const char *
11064hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11065{
11066 int display = hfinfo->display;
11067
11068 if (hfinfo->type == FT_FRAMENUM) {
11069 /*
11070 * Frame numbers are always displayed in decimal.
11071 */
11072 display = BASE_DEC;
11073 }
11074
11075 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11076}
11077
11078static const char *
11079hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11080{
11081 int display = hfinfo->display;
11082
11083 if (hfinfo->type == FT_FRAMENUM) {
11084 /*
11085 * Frame numbers are always displayed in decimal.
11086 */
11087 display = BASE_DEC;
11088 }
11089
11090 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11091}
11092
11093static const char *
11094hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11095{
11096 /* Get the underlying BASE_ value */
11097 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11098
11099 return hfinfo_char_value_format_display(display, buf, value);
11100}
11101
11102static const char *
11103hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11104{
11105 /* Get the underlying BASE_ value */
11106 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11107
11108 if (hfinfo->type == FT_FRAMENUM) {
11109 /*
11110 * Frame numbers are always displayed in decimal.
11111 */
11112 display = BASE_DEC;
11113 }
11114
11115 if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)==
BASE_PT_DCCP||(display)==BASE_PT_SCTP))
) {
11116 display = BASE_DEC;
11117 } else if (display == BASE_OUI) {
11118 display = BASE_HEX;
11119 }
11120
11121 switch (display) {
11122 case BASE_NONE:
11123 /* case BASE_DEC: */
11124 case BASE_DEC_HEX:
11125 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11126 case BASE_CUSTOM:
11127 display = BASE_DEC;
11128 break;
11129
11130 /* case BASE_HEX: */
11131 case BASE_HEX_DEC:
11132 display = BASE_HEX;
11133 break;
11134 }
11135
11136 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11137}
11138
11139static const char *
11140hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11141{
11142 /* Get the underlying BASE_ value */
11143 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11144
11145 if (hfinfo->type == FT_FRAMENUM) {
11146 /*
11147 * Frame numbers are always displayed in decimal.
11148 */
11149 display = BASE_DEC;
11150 }
11151
11152 switch (display) {
11153 case BASE_NONE:
11154 /* case BASE_DEC: */
11155 case BASE_DEC_HEX:
11156 case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11157 case BASE_CUSTOM:
11158 display = BASE_DEC;
11159 break;
11160
11161 /* case BASE_HEX: */
11162 case BASE_HEX_DEC:
11163 display = BASE_HEX;
11164 break;
11165 }
11166
11167 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11168}
11169
11170static const char *
11171hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11172{
11173 /* Get the underlying BASE_ value */
11174 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11175
11176 return hfinfo_char_value_format_display(display, buf, value);
11177}
11178
11179static const char *
11180hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11181{
11182 /* Get the underlying BASE_ value */
11183 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11184
11185 if (display == BASE_NONE)
11186 return NULL((void*)0);
11187
11188 if (display == BASE_DEC_HEX)
11189 display = BASE_DEC;
11190 if (display == BASE_HEX_DEC)
11191 display = BASE_HEX;
11192
11193 return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11194}
11195
11196static const char *
11197hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11198{
11199 /* Get the underlying BASE_ value */
11200 int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11201
11202 if (display == BASE_NONE)
11203 return NULL((void*)0);
11204
11205 if (display == BASE_DEC_HEX)
11206 display = BASE_DEC;
11207 if (display == BASE_HEX_DEC)
11208 display = BASE_HEX;
11209
11210 return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11211}
11212
11213const char *
11214proto_registrar_get_name(const int n)
11215{
11216 header_field_info *hfinfo;
11217
11218 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", 11218
, __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", 11218
, "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", 11218, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11219 return hfinfo->name;
11220}
11221
11222const char *
11223proto_registrar_get_abbrev(const int n)
11224{
11225 header_field_info *hfinfo;
11226
11227 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", 11227
, __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", 11227
, "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", 11227, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11228 return hfinfo->abbrev;
11229}
11230
11231enum ftenum
11232proto_registrar_get_ftype(const int n)
11233{
11234 header_field_info *hfinfo;
11235
11236 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", 11236
, __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", 11236
, "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", 11236, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11237 return hfinfo->type;
11238}
11239
11240int
11241proto_registrar_get_parent(const int n)
11242{
11243 header_field_info *hfinfo;
11244
11245 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", 11245
, __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", 11245
, "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", 11245, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11246 return hfinfo->parent;
11247}
11248
11249bool_Bool
11250proto_registrar_is_protocol(const int n)
11251{
11252 header_field_info *hfinfo;
11253
11254 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", 11254
, __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", 11254
, "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", 11254, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11255 return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11256}
11257
11258/* Returns length of field in packet (not necessarily the length
11259 * in our internal representation, as in the case of IPv4).
11260 * 0 means undeterminable at time of registration
11261 * -1 means the field is not registered. */
11262int
11263proto_registrar_get_length(const int n)
11264{
11265 header_field_info *hfinfo;
11266
11267 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", 11267
, __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", 11267
, "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", 11267, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[n];
;
11268 return ftype_wire_size(hfinfo->type);
11269}
11270
11271/* Looks for a protocol or a field in a proto_tree. Returns true if
11272 * it exists anywhere, or false if it exists nowhere. */
11273bool_Bool
11274proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11275{
11276 GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11277
11278 if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11279 return true1;
11280 }
11281 else {
11282 return false0;
11283 }
11284}
11285
11286/* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11287 * This only works if the hfindex was "primed" before the dissection
11288 * took place, as we just pass back the already-created GPtrArray*.
11289 * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11290 * handles that. */
11291GPtrArray *
11292proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11293{
11294 if (!tree)
11295 return NULL((void*)0);
11296
11297 if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11298 return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11299 GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11300 else
11301 return NULL((void*)0);
11302}
11303
11304bool_Bool
11305proto_tracking_interesting_fields(const proto_tree *tree)
11306{
11307 GHashTable *interesting_hfids;
11308
11309 if (!tree)
11310 return false0;
11311
11312 interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11313
11314 return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11315}
11316
11317/* Helper struct for proto_find_info() and proto_all_finfos() */
11318typedef struct {
11319 GPtrArray *array;
11320 int id;
11321} ffdata_t;
11322
11323/* Helper function for proto_find_info() */
11324static bool_Bool
11325find_finfo(proto_node *node, void * data)
11326{
11327 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11328 if (fi && fi->hfinfo) {
11329 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11330 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11331 }
11332 }
11333
11334 /* Don't stop traversing. */
11335 return false0;
11336}
11337
11338/* Helper function for proto_find_first_info() */
11339static bool_Bool
11340find_first_finfo(proto_node *node, void *data)
11341{
11342 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11343 if (fi && fi->hfinfo) {
11344 if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11345 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11346
11347 /* Stop traversing. */
11348 return true1;
11349 }
11350 }
11351
11352 /* Continue traversing. */
11353 return false0;
11354}
11355
11356/* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11357* This works on any proto_tree, primed or unprimed, but actually searches
11358* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11359* The caller does need to free the returned GPtrArray with
11360* g_ptr_array_free(<array>, true).
11361*/
11362GPtrArray *
11363proto_find_finfo(proto_tree *tree, const int id)
11364{
11365 ffdata_t ffdata;
11366
11367 ffdata.array = g_ptr_array_new();
11368 ffdata.id = id;
11369
11370 proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11371
11372 return ffdata.array;
11373}
11374
11375/* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11376* This works on any proto_tree, primed or unprimed, but actually searches
11377* the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11378* The caller does need to free the returned GPtrArray with
11379* g_ptr_array_free(<array>, true).
11380*/
11381GPtrArray *
11382proto_find_first_finfo(proto_tree *tree, const int id)
11383{
11384 ffdata_t ffdata;
11385
11386 ffdata.array = g_ptr_array_new();
11387 ffdata.id = id;
11388
11389 proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11390
11391 return ffdata.array;
11392}
11393
11394/* Helper function for proto_all_finfos() */
11395static bool_Bool
11396every_finfo(proto_node *node, void * data)
11397{
11398 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11399 if (fi && fi->hfinfo) {
11400 g_ptr_array_add(((ffdata_t*)data)->array, fi);
11401 }
11402
11403 /* Don't stop traversing. */
11404 return false0;
11405}
11406
11407/* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11408 * The caller does need to free the returned GPtrArray with
11409 * g_ptr_array_free(<array>, true).
11410 */
11411GPtrArray *
11412proto_all_finfos(proto_tree *tree)
11413{
11414 ffdata_t ffdata;
11415
11416 /* Pre allocate enough space to hold all fields in most cases */
11417 ffdata.array = g_ptr_array_sized_new(512);
11418 ffdata.id = 0;
11419
11420 proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11421
11422 return ffdata.array;
11423}
11424
11425
11426typedef struct {
11427 unsigned offset;
11428 field_info *finfo;
11429 tvbuff_t *tvb;
11430} offset_search_t;
11431
11432static bool_Bool
11433check_for_offset(proto_node *node, void * data)
11434{
11435 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11436 offset_search_t *offsearch = (offset_search_t *)data;
11437
11438 /* !fi == the top most container node which holds nothing */
11439 if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11440 if (offsearch->offset >= (unsigned) fi->start &&
11441 offsearch->offset < (unsigned) (fi->start + fi->length)) {
11442
11443 offsearch->finfo = fi;
11444 return false0; /* keep traversing */
11445 }
11446 }
11447 return false0; /* keep traversing */
11448}
11449
11450/* Search a proto_tree backwards (from leaves to root) looking for the field
11451 * whose start/length occupies 'offset' */
11452/* XXX - I couldn't find an easy way to search backwards, so I search
11453 * forwards, w/o stopping. Therefore, the last finfo I find will the be
11454 * the one I want to return to the user. This algorithm is inefficient
11455 * and could be re-done, but I'd have to handle all the children and
11456 * siblings of each node myself. When I have more time I'll do that.
11457 * (yeah right) */
11458field_info *
11459proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11460{
11461 offset_search_t offsearch;
11462
11463 offsearch.offset = offset;
11464 offsearch.finfo = NULL((void*)0);
11465 offsearch.tvb = tvb;
11466
11467 proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11468
11469 return offsearch.finfo;
11470}
11471
11472typedef struct {
11473 int length;
11474 char *buf;
11475} decoded_data_t;
11476
11477static bool_Bool
11478check_for_undecoded(proto_node *node, void * data)
11479{
11480 field_info *fi = PNODE_FINFO(node)((node)->finfo);
11481 decoded_data_t* decoded = (decoded_data_t*)data;
11482 int i;
11483 unsigned byte;
11484 unsigned bit;
11485
11486 if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11487 for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11488 byte = i / 8;
11489 bit = i % 8;
11490 decoded->buf[byte] |= (1 << bit);
11491 }
11492 }
11493
11494 return false0;
11495}
11496
11497char*
11498proto_find_undecoded_data(proto_tree *tree, unsigned length)
11499{
11500 decoded_data_t decoded;
11501 decoded.length = length;
11502 decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11503
11504 proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11505 return decoded.buf;
11506}
11507
11508/* Dumps the protocols in the registration database to stdout. An independent
11509 * program can take this output and format it into nice tables or HTML or
11510 * whatever.
11511 *
11512 * There is one record per line. The fields are tab-delimited.
11513 *
11514 * Field 1 = protocol name
11515 * Field 2 = protocol short name
11516 * Field 3 = protocol filter name
11517 * Field 4 = protocol enabled
11518 * Field 5 = protocol enabled by default
11519 * Field 6 = protocol can toggle
11520 */
11521void
11522proto_registrar_dump_protocols(void)
11523{
11524 protocol_t *protocol;
11525 int i;
11526 void *cookie = NULL((void*)0);
11527
11528
11529 i = proto_get_first_protocol(&cookie);
11530 while (i != -1) {
11531 protocol = find_protocol_by_id(i);
11532 printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11533 protocol->name,
11534 protocol->short_name,
11535 protocol->filter_name,
11536 (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11537 (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11538 (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11539 i = proto_get_next_protocol(&cookie);
11540 }
11541}
11542
11543/* Dumps the value_strings, extended value string headers, range_strings
11544 * or true/false strings for fields that have them.
11545 * There is one record per line. Fields are tab-delimited.
11546 * There are four types of records: Value String, Extended Value String Header,
11547 * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11548 * the type of record.
11549 *
11550 * Note that a record will be generated only if the value_string,... is referenced
11551 * in a registered hfinfo entry.
11552 *
11553 *
11554 * Value Strings
11555 * -------------
11556 * Field 1 = 'V'
11557 * Field 2 = Field abbreviation to which this value string corresponds
11558 * Field 3 = Integer value
11559 * Field 4 = String
11560 *
11561 * Extended Value String Headers
11562 * -----------------------------
11563 * Field 1 = 'E'
11564 * Field 2 = Field abbreviation to which this extended value string header corresponds
11565 * Field 3 = Extended Value String "Name"
11566 * Field 4 = Number of entries in the associated value_string array
11567 * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11568 *
11569 * Range Strings
11570 * -------------
11571 * Field 1 = 'R'
11572 * Field 2 = Field abbreviation to which this range string corresponds
11573 * Field 3 = Integer value: lower bound
11574 * Field 4 = Integer value: upper bound
11575 * Field 5 = String
11576 *
11577 * True/False Strings
11578 * ------------------
11579 * Field 1 = 'T'
11580 * Field 2 = Field abbreviation to which this true/false string corresponds
11581 * Field 3 = True String
11582 * Field 4 = False String
11583 */
11584void
11585proto_registrar_dump_values(void)
11586{
11587 header_field_info *hfinfo;
11588 int i, len, vi;
11589 const value_string *vals;
11590 const val64_string *vals64;
11591 const range_string *range;
11592 const true_false_string *tfs;
11593 const unit_name_string *units;
11594
11595 len = gpa_hfinfo.len;
11596 for (i = 0; i < len ; i++) {
11597 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11598 continue; /* This is a deregistered protocol or field */
11599
11600 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", 11600
, __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", 11600
, "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", 11600, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11601
11602 if (hfinfo->id == hf_text_only) {
11603 continue;
11604 }
11605
11606 /* ignore protocols */
11607 if (proto_registrar_is_protocol(i)) {
11608 continue;
11609 }
11610 /* process header fields */
11611#if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11612 /*
11613 * If this field isn't at the head of the list of
11614 * fields with this name, skip this field - all
11615 * fields with the same name are really just versions
11616 * of the same field stored in different bits, and
11617 * should have the same type/radix/value list, and
11618 * just differ in their bit masks. (If a field isn't
11619 * a bitfield, but can be, say, 1 or 2 bytes long,
11620 * it can just be made FT_UINT16, meaning the
11621 * *maximum* length is 2 bytes, and be used
11622 * for all lengths.)
11623 */
11624 if (hfinfo->same_name_prev_id != -1)
11625 continue;
11626#endif
11627 vals = NULL((void*)0);
11628 vals64 = NULL((void*)0);
11629 range = NULL((void*)0);
11630 tfs = NULL((void*)0);
11631 units = NULL((void*)0);
11632
11633 if (hfinfo->strings != NULL((void*)0)) {
11634 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11635 (hfinfo->type == FT_CHAR ||
11636 hfinfo->type == FT_UINT8 ||
11637 hfinfo->type == FT_UINT16 ||
11638 hfinfo->type == FT_UINT24 ||
11639 hfinfo->type == FT_UINT32 ||
11640 hfinfo->type == FT_UINT40 ||
11641 hfinfo->type == FT_UINT48 ||
11642 hfinfo->type == FT_UINT56 ||
11643 hfinfo->type == FT_UINT64 ||
11644 hfinfo->type == FT_INT8 ||
11645 hfinfo->type == FT_INT16 ||
11646 hfinfo->type == FT_INT24 ||
11647 hfinfo->type == FT_INT32 ||
11648 hfinfo->type == FT_INT40 ||
11649 hfinfo->type == FT_INT48 ||
11650 hfinfo->type == FT_INT56 ||
11651 hfinfo->type == FT_INT64 ||
11652 hfinfo->type == FT_FLOAT ||
11653 hfinfo->type == FT_DOUBLE)) {
11654
11655 if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11656 range = (const range_string *)hfinfo->strings;
11657 } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11658 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11659 vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11660 } else {
11661 vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11662 }
11663 } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11664 vals64 = (const val64_string *)hfinfo->strings;
11665 } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11666 units = (const unit_name_string *)hfinfo->strings;
11667 } else {
11668 vals = (const value_string *)hfinfo->strings;
11669 }
11670 }
11671 else if (hfinfo->type == FT_BOOLEAN) {
11672 tfs = (const struct true_false_string *)hfinfo->strings;
11673 }
11674 }
11675
11676 /* Print value strings? */
11677 if (vals) {
11678 if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11679 if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11680 val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11681 if (!val64_string_ext_validate(vse_p)) {
11682 ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11682, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11683 continue;
11684 }
11685 try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11686 printf("E\t%s\t%u\t%s\t%s\n",
11687 hfinfo->abbrev,
11688 VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11689 VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11690 val64_string_ext_match_type_str(vse_p));
11691 } else {
11692 value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11693 if (!value_string_ext_validate(vse_p)) {
11694 ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c"
, 11694, __func__, "Invalid value_string_ext ptr for: %s", hfinfo
->abbrev); } } while (0)
;
11695 continue;
11696 }
11697 try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11698 printf("E\t%s\t%u\t%s\t%s\n",
11699 hfinfo->abbrev,
11700 VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11701 VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11702 value_string_ext_match_type_str(vse_p));
11703 }
11704 }
11705 vi = 0;
11706 while (vals[vi].strptr) {
11707 /* Print in the proper base */
11708 if (hfinfo->type == FT_CHAR) {
11709 if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT
) != 0)
) {
11710 printf("V\t%s\t'%c'\t%s\n",
11711 hfinfo->abbrev,
11712 vals[vi].value,
11713 vals[vi].strptr);
11714 } else {
11715 if (hfinfo->display == BASE_HEX) {
11716 printf("V\t%s\t'\\x%02x'\t%s\n",
11717 hfinfo->abbrev,
11718 vals[vi].value,
11719 vals[vi].strptr);
11720 }
11721 else {
11722 printf("V\t%s\t'\\%03o'\t%s\n",
11723 hfinfo->abbrev,
11724 vals[vi].value,
11725 vals[vi].strptr);
11726 }
11727 }
11728 } else {
11729 if (hfinfo->display == BASE_HEX) {
11730 printf("V\t%s\t0x%x\t%s\n",
11731 hfinfo->abbrev,
11732 vals[vi].value,
11733 vals[vi].strptr);
11734 }
11735 else {
11736 printf("V\t%s\t%u\t%s\n",
11737 hfinfo->abbrev,
11738 vals[vi].value,
11739 vals[vi].strptr);
11740 }
11741 }
11742 vi++;
11743 }
11744 }
11745 else if (vals64) {
11746 vi = 0;
11747 while (vals64[vi].strptr) {
11748 printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11749 hfinfo->abbrev,
11750 vals64[vi].value,
11751 vals64[vi].strptr);
11752 vi++;
11753 }
11754 }
11755
11756 /* print range strings? */
11757 else if (range) {
11758 vi = 0;
11759 while (range[vi].strptr) {
11760 /* Print in the proper base */
11761 if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11762 printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11763 hfinfo->abbrev,
11764 range[vi].value_min,
11765 range[vi].value_max,
11766 range[vi].strptr);
11767 }
11768 else {
11769 printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11770 hfinfo->abbrev,
11771 range[vi].value_min,
11772 range[vi].value_max,
11773 range[vi].strptr);
11774 }
11775 vi++;
11776 }
11777 }
11778
11779 /* Print true/false strings? */
11780 else if (tfs) {
11781 printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11782 tfs->true_string, tfs->false_string);
11783 }
11784 /* Print unit strings? */
11785 else if (units) {
11786 printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11787 units->singular, units->plural ? units->plural : "(no plural)");
11788 }
11789 }
11790}
11791
11792/* Prints the number of registered fields.
11793 * Useful for determining an appropriate value for
11794 * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
11795 *
11796 * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
11797 * the number of fields, true otherwise.
11798 */
11799bool_Bool
11800proto_registrar_dump_fieldcount(void)
11801{
11802 uint32_t i;
11803 header_field_info *hfinfo;
11804 uint32_t deregistered_count = 0;
11805 uint32_t same_name_count = 0;
11806 uint32_t protocol_count = 0;
11807
11808 for (i = 0; i < gpa_hfinfo.len; i++) {
11809 if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
11810 deregistered_count++;
11811 continue; /* This is a deregistered protocol or header field */
11812 }
11813
11814 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", 11814
, __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", 11814
, "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", 11814, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11815
11816 if (proto_registrar_is_protocol(i))
11817 protocol_count++;
11818
11819 if (hfinfo->same_name_prev_id != -1)
11820 same_name_count++;
11821 }
11822
11823 printf("There are %u header fields registered, of which:\n"
11824 "\t%u are deregistered\n"
11825 "\t%u are protocols\n"
11826 "\t%u have the same name as another field\n\n",
11827 gpa_hfinfo.len, deregistered_count, protocol_count,
11828 same_name_count);
11829
11830 printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
11831 (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
11832 "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
11833 "\n");
11834
11835 printf("The header field table consumes %u KiB of memory.\n",
11836 (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
11837 printf("The fields themselves consume %u KiB of memory.\n",
11838 (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
11839
11840 return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
11841}
11842
11843static void
11844elastic_add_base_mapping(json_dumper *dumper)
11845{
11846 json_dumper_set_member_name(dumper, "settings");
11847 json_dumper_begin_object(dumper);
11848 json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
11849 json_dumper_value_anyf(dumper, "%d", 1000000);
11850 json_dumper_end_object(dumper);
11851}
11852
11853static char*
11854ws_type_to_elastic(unsigned type _U___attribute__((unused)))
11855{
11856 switch(type) {
11857 case FT_UINT16:
11858 case FT_INT16:
11859 case FT_INT32:
11860 case FT_UINT24:
11861 case FT_INT24:
11862 return "integer";
11863 case FT_INT8:
11864 case FT_UINT8:
11865 return "short";
11866 case FT_FRAMENUM:
11867 case FT_UINT32:
11868 case FT_UINT40:
11869 case FT_UINT48:
11870 case FT_UINT56:
11871 case FT_UINT64: // Actually it's not handled by 'long' elastic type.
11872 case FT_INT48:
11873 case FT_INT64:
11874 return "long";
11875 case FT_FLOAT:
11876 case FT_DOUBLE:
11877 return "float";
11878 case FT_IPv6:
11879 case FT_IPv4:
11880 return "ip";
11881 case FT_ABSOLUTE_TIME:
11882 case FT_RELATIVE_TIME:
11883 return "date";
11884 case FT_BYTES:
11885 case FT_UINT_BYTES:
11886 return "byte";
11887 case FT_BOOLEAN:
11888 return "boolean";
11889 default:
11890 return NULL((void*)0);
11891 }
11892}
11893
11894static char*
11895dot_to_underscore(char* str)
11896{
11897 unsigned i;
11898 for (i = 0; i < strlen(str); i++) {
11899 if (str[i] == '.')
11900 str[i] = '_';
11901 }
11902 return str;
11903}
11904
11905/* Dumps a mapping file for ElasticSearch
11906 */
11907void
11908proto_registrar_dump_elastic(const char* filter)
11909{
11910 header_field_info *hfinfo;
11911 header_field_info *parent_hfinfo;
11912 unsigned i;
11913 bool_Bool open_object = true1;
11914 const char* prev_proto = NULL((void*)0);
11915 char* str;
11916 char** protos = NULL((void*)0);
11917 char* proto;
11918 bool_Bool found;
11919 unsigned j;
11920 char* type;
11921 char* prev_item = NULL((void*)0);
11922
11923 /* We have filtering protocols. Extract them. */
11924 if (filter) {
11925 protos = g_strsplit(filter, ",", -1);
11926 }
11927
11928 /*
11929 * To help tracking down the json tree, objects have been appended with a comment:
11930 * n.label -> where n is the indentation level and label the name of the object
11931 */
11932
11933 json_dumper dumper = {
11934 .output_file = stdoutstdout,
11935 .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
11936 };
11937 json_dumper_begin_object(&dumper); // 1.root
11938 elastic_add_base_mapping(&dumper);
11939
11940 json_dumper_set_member_name(&dumper, "mappings");
11941 json_dumper_begin_object(&dumper); // 2.mappings
11942 json_dumper_set_member_name(&dumper, "dynamic");
11943 json_dumper_value_anyf(&dumper, "false");
11944
11945 json_dumper_set_member_name(&dumper, "properties");
11946 json_dumper_begin_object(&dumper); // 3.properties
11947 json_dumper_set_member_name(&dumper, "timestamp");
11948 json_dumper_begin_object(&dumper); // 4.timestamp
11949 json_dumper_set_member_name(&dumper, "type");
11950 json_dumper_value_string(&dumper, "date");
11951 json_dumper_end_object(&dumper); // 4.timestamp
11952
11953 json_dumper_set_member_name(&dumper, "layers");
11954 json_dumper_begin_object(&dumper); // 4.layers
11955 json_dumper_set_member_name(&dumper, "properties");
11956 json_dumper_begin_object(&dumper); // 5.properties
11957
11958 for (i = 0; i < gpa_hfinfo.len; i++) {
11959 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11960 continue; /* This is a deregistered protocol or header field */
11961
11962 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", 11962
, __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", 11962
, "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", 11962, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
11963
11964 /*
11965 * Skip the pseudo-field for "proto_tree_add_text()" since
11966 * we don't want it in the list of filterable protocols.
11967 */
11968 if (hfinfo->id == hf_text_only)
11969 continue;
11970
11971 if (!proto_registrar_is_protocol(i)) {
11972 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", 11972
, __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", 11972
, "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", 11972
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
11973
11974 /*
11975 * Skip the field if filter protocols have been set and this one's
11976 * parent is not listed.
11977 */
11978 if (protos) {
11979 found = false0;
11980 j = 0;
11981 proto = protos[0];
11982 while(proto) {
11983 if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
11984 found = true1;
11985 break;
11986 }
11987 j++;
11988 proto = protos[j];
11989 }
11990 if (!found)
11991 continue;
11992 }
11993
11994 if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
11995 json_dumper_end_object(&dumper); // 7.properties
11996 json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
11997 open_object = true1;
11998 }
11999
12000 prev_proto = parent_hfinfo->abbrev;
12001
12002 if (open_object) {
12003 json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12004 json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12005 json_dumper_set_member_name(&dumper, "properties");
12006 json_dumper_begin_object(&dumper); // 7.properties
12007 open_object = false0;
12008 }
12009 /* Skip the fields that would map into string. This is the default in elasticsearch. */
12010 type = ws_type_to_elastic(hfinfo->type);
12011 /* when type is NULL, we have the default mapping: string */
12012 if (type) {
12013 str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo->
abbrev)
;
12014 dot_to_underscore(str);
12015 if (g_strcmp0(prev_item, str)) {
12016 json_dumper_set_member_name(&dumper, str);
12017 json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12018 json_dumper_set_member_name(&dumper, "type");
12019 json_dumper_value_string(&dumper, type);
12020 json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12021 }
12022 g_free(prev_item);
12023 prev_item = str;
12024 }
12025 }
12026 }
12027 g_free(prev_item);
12028
12029 if (prev_proto) {
12030 json_dumper_end_object(&dumper); // 7.properties
12031 json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12032 }
12033
12034 json_dumper_end_object(&dumper); // 5.properties
12035 json_dumper_end_object(&dumper); // 4.layers
12036 json_dumper_end_object(&dumper); // 3.properties
12037 json_dumper_end_object(&dumper); // 2.mappings
12038 json_dumper_end_object(&dumper); // 1.root
12039 bool_Bool ret = json_dumper_finish(&dumper);
12040 DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12040, "ret"))))
;
12041
12042 g_strfreev(protos);
12043}
12044
12045/* Dumps the contents of the registration database to stdout. An independent
12046 * program can take this output and format it into nice tables or HTML or
12047 * whatever.
12048 *
12049 * There is one record per line. Each record is either a protocol or a header
12050 * field, differentiated by the first field. The fields are tab-delimited.
12051 *
12052 * Protocols
12053 * ---------
12054 * Field 1 = 'P'
12055 * Field 2 = descriptive protocol name
12056 * Field 3 = protocol abbreviation
12057 *
12058 * Header Fields
12059 * -------------
12060 * Field 1 = 'F'
12061 * Field 2 = descriptive field name
12062 * Field 3 = field abbreviation
12063 * Field 4 = type ( textual representation of the ftenum type )
12064 * Field 5 = parent protocol abbreviation
12065 * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12066 * Field 7 = bitmask: format: hex: 0x....
12067 * Field 8 = blurb describing field
12068 */
12069void
12070proto_registrar_dump_fields(void)
12071{
12072 header_field_info *hfinfo, *parent_hfinfo;
12073 int i, len;
12074 const char *enum_name;
12075 const char *base_name;
12076 const char *blurb;
12077 char width[5];
12078
12079 len = gpa_hfinfo.len;
12080 for (i = 0; i < len ; i++) {
12081 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12082 continue; /* This is a deregistered protocol or header field */
12083
12084 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", 12084
, __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", 12084
, "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", 12084, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12085
12086 /*
12087 * Skip the pseudo-field for "proto_tree_add_text()" since
12088 * we don't want it in the list of filterable fields.
12089 */
12090 if (hfinfo->id == hf_text_only)
12091 continue;
12092
12093 /* format for protocols */
12094 if (proto_registrar_is_protocol(i)) {
12095 printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12096 }
12097 /* format for header fields */
12098 else {
12099 /*
12100 * If this field isn't at the head of the list of
12101 * fields with this name, skip this field - all
12102 * fields with the same name are really just versions
12103 * of the same field stored in different bits, and
12104 * should have the same type/radix/value list, and
12105 * just differ in their bit masks. (If a field isn't
12106 * a bitfield, but can be, say, 1 or 2 bytes long,
12107 * it can just be made FT_UINT16, meaning the
12108 * *maximum* length is 2 bytes, and be used
12109 * for all lengths.)
12110 */
12111 if (hfinfo->same_name_prev_id != -1)
12112 continue;
12113
12114 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", 12114
, __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", 12114
, "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", 12114
, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!"
)))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];
;
12115
12116 enum_name = ftype_name(hfinfo->type);
12117 base_name = "";
12118
12119 if (hfinfo->type == FT_CHAR ||
12120 hfinfo->type == FT_UINT8 ||
12121 hfinfo->type == FT_UINT16 ||
12122 hfinfo->type == FT_UINT24 ||
12123 hfinfo->type == FT_UINT32 ||
12124 hfinfo->type == FT_UINT40 ||
12125 hfinfo->type == FT_UINT48 ||
12126 hfinfo->type == FT_UINT56 ||
12127 hfinfo->type == FT_UINT64 ||
12128 hfinfo->type == FT_INT8 ||
12129 hfinfo->type == FT_INT16 ||
12130 hfinfo->type == FT_INT24 ||
12131 hfinfo->type == FT_INT32 ||
12132 hfinfo->type == FT_INT40 ||
12133 hfinfo->type == FT_INT48 ||
12134 hfinfo->type == FT_INT56 ||
12135 hfinfo->type == FT_INT64) {
12136
12137 switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12138 case BASE_NONE:
12139 case BASE_DEC:
12140 case BASE_HEX:
12141 case BASE_OCT:
12142 case BASE_DEC_HEX:
12143 case BASE_HEX_DEC:
12144 case BASE_CUSTOM:
12145 case BASE_PT_UDP:
12146 case BASE_PT_TCP:
12147 case BASE_PT_DCCP:
12148 case BASE_PT_SCTP:
12149 case BASE_OUI:
12150 base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12151 break;
12152 default:
12153 base_name = "????";
12154 break;
12155 }
12156 } else if (hfinfo->type == FT_BOOLEAN) {
12157 /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12158 snprintf(width, sizeof(width), "%d", hfinfo->display);
12159 base_name = width;
12160 }
12161
12162 blurb = hfinfo->blurb;
12163 if (blurb == NULL((void*)0))
12164 blurb = "";
12165 else if (strlen(blurb) == 0)
12166 blurb = "\"\"";
12167
12168 printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12169 hfinfo->name, hfinfo->abbrev, enum_name,
12170 parent_hfinfo->abbrev, base_name,
12171 hfinfo->bitmask, blurb);
12172 }
12173 }
12174}
12175
12176/* Dumps all abbreviated field and protocol completions of the given string to
12177 * stdout. An independent program may use this for command-line tab completion
12178 * of fields.
12179 */
12180bool_Bool
12181proto_registrar_dump_field_completions(const char *prefix)
12182{
12183 header_field_info *hfinfo;
12184 int i, len;
12185 size_t prefix_len;
12186 bool_Bool matched = false0;
12187
12188 prefix_len = strlen(prefix);
12189 len = gpa_hfinfo.len;
12190 for (i = 0; i < len ; i++) {
12191 if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12192 continue; /* This is a deregistered protocol or header field */
12193
12194 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", 12194
, __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", 12194
, "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", 12194, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!"
)))) ; hfinfo = gpa_hfinfo.hfi[i];
;
12195
12196 /*
12197 * Skip the pseudo-field for "proto_tree_add_text()" since
12198 * we don't want it in the list of filterable fields.
12199 */
12200 if (hfinfo->id == hf_text_only)
12201 continue;
12202
12203 /* format for protocols */
12204 if (proto_registrar_is_protocol(i)) {
12205 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12206 matched = true1;
12207 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12208 }
12209 }
12210 /* format for header fields */
12211 else {
12212 /*
12213 * If this field isn't at the head of the list of
12214 * fields with this name, skip this field - all
12215 * fields with the same name are really just versions
12216 * of the same field stored in different bits, and
12217 * should have the same type/radix/value list, and
12218 * just differ in their bit masks. (If a field isn't
12219 * a bitfield, but can be, say, 1 or 2 bytes long,
12220 * it can just be made FT_UINT16, meaning the
12221 * *maximum* length is 2 bytes, and be used
12222 * for all lengths.)
12223 */
12224 if (hfinfo->same_name_prev_id != -1)
12225 continue;
12226
12227 if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12228 matched = true1;
12229 printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12230 }
12231 }
12232 }
12233 return matched;
12234}
12235
12236/* Dumps field types and descriptive names to stdout. An independent
12237 * program can take this output and format it into nice tables or HTML or
12238 * whatever.
12239 *
12240 * There is one record per line. The fields are tab-delimited.
12241 *
12242 * Field 1 = field type name, e.g. FT_UINT8
12243 * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12244 */
12245void
12246proto_registrar_dump_ftypes(void)
12247{
12248 int fte;
12249
12250 for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12251 printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12252 }
12253}
12254
12255/* This function indicates whether it's possible to construct a
12256 * "match selected" display filter string for the specified field,
12257 * returns an indication of whether it's possible, and, if it's
12258 * possible and "filter" is non-null, constructs the filter and
12259 * sets "*filter" to point to it.
12260 * You do not need to [g_]free() this string since it will be automatically
12261 * freed once the next packet is dissected.
12262 */
12263static bool_Bool
12264construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12265 char **filter)
12266{
12267 const header_field_info *hfinfo;
12268 char *ptr;
12269 int buf_len;
12270 int i;
12271 int start, length, length_remaining;
12272 uint8_t c;
12273
12274 if (!finfo)
12275 return false0;
12276
12277 hfinfo = finfo->hfinfo;
12278 DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12278, "hfinfo"))))
;
12279
12280 /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12281 * then "the numeric value ... is not used when preparing
12282 * filters for the field in question." If it's any other
12283 * base, we'll generate the filter normally (which will
12284 * be numeric, even though the human-readable string does
12285 * work for filtering.)
12286 *
12287 * XXX - It might be nice to use fvalue_to_string_repr() in
12288 * "proto_item_fill_label()" as well, although, there, you'd
12289 * have to deal with the base *and* with resolved values for
12290 * addresses.
12291 *
12292 * Perhaps in addition to taking the repr type (DISPLAY
12293 * or DFILTER) and the display (base), fvalue_to_string_repr()
12294 * should have the the "strings" values in the header_field_info
12295 * structure for the field as a parameter, so it can have
12296 * if the field is Boolean or an enumerated integer type,
12297 * the tables used to generate human-readable values.
12298 */
12299 if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12300 const char *str = NULL((void*)0);
12301
12302 switch (hfinfo->type) {
12303
12304 case FT_INT8:
12305 case FT_INT16:
12306 case FT_INT24:
12307 case FT_INT32:
12308 str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12309 break;
12310
12311 case FT_CHAR:
12312 case FT_UINT8:
12313 case FT_UINT16:
12314 case FT_UINT24:
12315 case FT_UINT32:
12316 str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12317 break;
12318
12319 default:
12320 break;
12321 }
12322
12323 if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12324 *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12325 return true1;
12326 }
12327 }
12328
12329 switch (hfinfo->type) {
12330
12331 case FT_PROTOCOL:
12332 if (filter != NULL((void*)0))
12333 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12334 break;
12335
12336 case FT_NONE:
12337 /*
12338 * If the length is 0, just match the name of the
12339 * field.
12340 *
12341 * (Also check for negative values, just in case,
12342 * as we'll cast it to an unsigned value later.)
12343 */
12344 length = finfo->length;
12345 if (length == 0) {
12346 if (filter != NULL((void*)0))
12347 *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12348 break;
12349 }
12350 if (length < 0)
12351 return false0;
12352
12353 /*
12354 * This doesn't have a value, so we'd match
12355 * on the raw bytes at this address.
12356 *
12357 * Should we be allowed to access to the raw bytes?
12358 * If "edt" is NULL, the answer is "no".
12359 */
12360 if (edt == NULL((void*)0))
12361 return false0;
12362
12363 /*
12364 * Is this field part of the raw frame tvbuff?
12365 * If not, we can't use "frame[N:M]" to match
12366 * it.
12367 *
12368 * XXX - should this be frame-relative, or
12369 * protocol-relative?
12370 *
12371 * XXX - does this fallback for non-registered
12372 * fields even make sense?
12373 */
12374 if (finfo->ds_tvb != edt->tvb)
12375 return false0; /* you lose */
12376
12377 /*
12378 * Don't go past the end of that tvbuff.
12379 */
12380 length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12381 if (length > length_remaining)
12382 length = length_remaining;
12383 if (length <= 0)
12384 return false0;
12385
12386 if (filter != NULL((void*)0)) {
12387 start = finfo->start;
12388 buf_len = 32 + length * 3;
12389 *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12390 ptr = *filter;
12391
12392 ptr += snprintf(ptr, buf_len-(ptr-*filter),
12393 "frame[%d:%d] == ", finfo->start, length);
12394 for (i=0; i<length; i++) {
12395 c = tvb_get_uint8(finfo->ds_tvb, start);
12396 start++;
12397 if (i == 0 ) {
12398 ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12399 }
12400 else {
12401 ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12402 }
12403 }
12404 }
12405 break;
12406
12407 /* By default, use the fvalue's "to_string_repr" method. */
12408 default:
12409 if (filter != NULL((void*)0)) {
12410 char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12411 *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12412 wmem_free(NULL((void*)0), str);
12413 }
12414 break;
12415 }
12416
12417 return true1;
12418}
12419
12420/*
12421 * Returns true if we can do a "match selected" on the field, false
12422 * otherwise.
12423 */
12424bool_Bool
12425proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12426{
12427 return construct_match_selected_string(finfo, edt, NULL((void*)0));
12428}
12429
12430/* This function attempts to construct a "match selected" display filter
12431 * string for the specified field; if it can do so, it returns a pointer
12432 * to the string, otherwise it returns NULL.
12433 *
12434 * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12435 */
12436char *
12437proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12438{
12439 char *filter = NULL((void*)0);
12440
12441 if (!construct_match_selected_string(finfo, edt, &filter))
12442 {
12443 wmem_free(NULL((void*)0), filter);
12444 return NULL((void*)0);
12445 }
12446 return filter;
12447}
12448
12449/* This function is common code for all proto_tree_add_bitmask... functions.
12450 */
12451
12452static bool_Bool
12453proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12454 const int len, const int ett, int * const *fields,
12455 const int flags, bool_Bool first,
12456 bool_Bool use_parent_tree,
12457 proto_tree* tree, uint64_t value)
12458{
12459 uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12460 uint64_t bitmask = 0;
12461 uint64_t tmpval;
12462 header_field_info *hf;
12463 uint32_t integer32;
12464 int bit_offset;
12465 int no_of_bits;
12466
12467 if (!*fields)
12468 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"
)
;
12469
12470 if (len < 0 || len > 8)
12471 REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12472 /**
12473 * packet-frame.c uses len=0 since the value is taken from the packet
12474 * metadata, not the packet bytes. In that case, assume that all bits
12475 * in the provided value are valid.
12476 */
12477 if (len > 0) {
12478 available_bits >>= (8 - (unsigned)len)*8;
12479 }
12480
12481 if (use_parent_tree == false0)
12482 tree = proto_item_add_subtree(item, ett);
12483
12484 while (*fields) {
12485 uint64_t present_bits;
12486 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", 12486, __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", 12486
, "**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", 12486, "gpa_hfinfo.hfi[**fields] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];
;
12487 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", 12487
, "hf->bitmask != 0", hf->abbrev))))
;
12488
12489 bitmask |= hf->bitmask;
12490
12491 /* Skip fields that aren't fully present */
12492 present_bits = available_bits & hf->bitmask;
12493 if (present_bits != hf->bitmask) {
12494 fields++;
12495 continue;
12496 }
12497
12498 switch (hf->type) {
12499 case FT_CHAR:
12500 case FT_UINT8:
12501 case FT_UINT16:
12502 case FT_UINT24:
12503 case FT_UINT32:
12504 proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12505 break;
12506
12507 case FT_INT8:
12508 case FT_INT16:
12509 case FT_INT24:
12510 case FT_INT32:
12511 proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12512 break;
12513
12514 case FT_UINT40:
12515 case FT_UINT48:
12516 case FT_UINT56:
12517 case FT_UINT64:
12518 proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12519 break;
12520
12521 case FT_INT40:
12522 case FT_INT48:
12523 case FT_INT56:
12524 case FT_INT64:
12525 proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12526 break;
12527
12528 case FT_BOOLEAN:
12529 proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12530 break;
12531
12532 default:
12533 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))
12534 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))
12535 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))
12536 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))
;
12537 break;
12538 }
12539 if (flags & BMT_NO_APPEND0x01) {
12540 fields++;
12541 continue;
12542 }
12543 tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12544
12545 /* XXX: README.developer and the comments have always defined
12546 * BMT_NO_INT as "only boolean flags are added to the title /
12547 * don't add non-boolean (integral) fields", but the
12548 * implementation has always added BASE_CUSTOM and fields with
12549 * value_strings, though not fields with unit_strings.
12550 * Possibly this is because some dissectors use a FT_UINT8
12551 * with a value_string for fields that should be a FT_BOOLEAN.
12552 */
12553 switch (hf->type) {
12554 case FT_CHAR:
12555 if (hf->display == BASE_CUSTOM) {
12556 char lbl[ITEM_LABEL_LENGTH240];
12557 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12558
12559 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12559, "fmtfunc"))))
;
12560 fmtfunc(lbl, (uint32_t) tmpval);
12561 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12562 hf->name, lbl);
12563 first = false0;
12564 }
12565 else if (hf->strings) {
12566 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12567 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12568 first = false0;
12569 }
12570 else if (!(flags & BMT_NO_INT0x02)) {
12571 char buf[32];
12572 const char *out;
12573
12574 if (!first) {
12575 proto_item_append_text(item, ", ");
12576 }
12577
12578 out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12579 proto_item_append_text(item, "%s: %s", hf->name, out);
12580 first = false0;
12581 }
12582
12583 break;
12584
12585 case FT_UINT8:
12586 case FT_UINT16:
12587 case FT_UINT24:
12588 case FT_UINT32:
12589 if (hf->display == BASE_CUSTOM) {
12590 char lbl[ITEM_LABEL_LENGTH240];
12591 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12592
12593 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12593, "fmtfunc"))))
;
12594 fmtfunc(lbl, (uint32_t) tmpval);
12595 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12596 hf->name, lbl);
12597 first = false0;
12598 }
12599 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12600 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12601 hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12602 first = false0;
12603 }
12604 else if (!(flags & BMT_NO_INT0x02)) {
12605 char buf[NUMBER_LABEL_LENGTH80];
12606 const char *out = NULL((void*)0);
12607
12608 if (!first) {
12609 proto_item_append_text(item, ", ");
12610 }
12611
12612 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12613 out = hf_try_val_to_str((uint32_t) tmpval, hf);
12614 }
12615 if (out == NULL((void*)0)) {
12616 out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12617 }
12618 proto_item_append_text(item, "%s: %s", hf->name, out);
12619 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12620 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12621 }
12622 first = false0;
12623 }
12624
12625 break;
12626
12627 case FT_INT8:
12628 case FT_INT16:
12629 case FT_INT24:
12630 case FT_INT32:
12631 integer32 = (uint32_t) tmpval;
12632 if (hf->bitmask) {
12633 no_of_bits = ws_count_ones(hf->bitmask);
12634 integer32 = ws_sign_ext32(integer32, no_of_bits);
12635 }
12636 if (hf->display == BASE_CUSTOM) {
12637 char lbl[ITEM_LABEL_LENGTH240];
12638 const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12639
12640 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12640, "fmtfunc"))))
;
12641 fmtfunc(lbl, (int32_t) integer32);
12642 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12643 hf->name, lbl);
12644 first = false0;
12645 }
12646 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12647 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12648 hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12649 first = false0;
12650 }
12651 else if (!(flags & BMT_NO_INT0x02)) {
12652 char buf[NUMBER_LABEL_LENGTH80];
12653 const char *out = NULL((void*)0);
12654
12655 if (!first) {
12656 proto_item_append_text(item, ", ");
12657 }
12658
12659 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12660 out = hf_try_val_to_str((int32_t) integer32, hf);
12661 }
12662 if (out == NULL((void*)0)) {
12663 out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12664 }
12665 proto_item_append_text(item, "%s: %s", hf->name, out);
12666 if (hf->display & BASE_UNIT_STRING0x00001000) {
12667 proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12668 }
12669 first = false0;
12670 }
12671
12672 break;
12673
12674 case FT_UINT40:
12675 case FT_UINT48:
12676 case FT_UINT56:
12677 case FT_UINT64:
12678 if (hf->display == BASE_CUSTOM) {
12679 char lbl[ITEM_LABEL_LENGTH240];
12680 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12681
12682 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12682, "fmtfunc"))))
;
12683 fmtfunc(lbl, tmpval);
12684 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12685 hf->name, lbl);
12686 first = false0;
12687 }
12688 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12689 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12690 hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12691 first = false0;
12692 }
12693 else if (!(flags & BMT_NO_INT0x02)) {
12694 char buf[NUMBER_LABEL_LENGTH80];
12695 const char *out = NULL((void*)0);
12696
12697 if (!first) {
12698 proto_item_append_text(item, ", ");
12699 }
12700
12701 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12702 out = hf_try_val64_to_str(tmpval, hf);
12703 }
12704 if (out == NULL((void*)0)) {
12705 out = hfinfo_number_value_format64(hf, buf, tmpval);
12706 }
12707 proto_item_append_text(item, "%s: %s", hf->name, out);
12708 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12709 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12710 }
12711 first = false0;
12712 }
12713
12714 break;
12715
12716 case FT_INT40:
12717 case FT_INT48:
12718 case FT_INT56:
12719 case FT_INT64:
12720 if (hf->bitmask) {
12721 no_of_bits = ws_count_ones(hf->bitmask);
12722 tmpval = ws_sign_ext64(tmpval, no_of_bits);
12723 }
12724 if (hf->display == BASE_CUSTOM) {
12725 char lbl[ITEM_LABEL_LENGTH240];
12726 const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12727
12728 DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\""
, "epan/proto.c", 12728, "fmtfunc"))))
;
12729 fmtfunc(lbl, (int64_t) tmpval);
12730 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12731 hf->name, lbl);
12732 first = false0;
12733 }
12734 else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12735 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12736 hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12737 first = false0;
12738 }
12739 else if (!(flags & BMT_NO_INT0x02)) {
12740 char buf[NUMBER_LABEL_LENGTH80];
12741 const char *out = NULL((void*)0);
12742
12743 if (!first) {
12744 proto_item_append_text(item, ", ");
12745 }
12746
12747 if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12748 out = hf_try_val64_to_str((int64_t) tmpval, hf);
12749 }
12750 if (out == NULL((void*)0)) {
12751 out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12752 }
12753 proto_item_append_text(item, "%s: %s", hf->name, out);
12754 if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12755 proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12756 }
12757 first = false0;
12758 }
12759
12760 break;
12761
12762 case FT_BOOLEAN:
12763 if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12764 /* If we have true/false strings, emit full - otherwise messages
12765 might look weird */
12766 const struct true_false_string *tfs =
12767 (const struct true_false_string *)hf->strings;
12768
12769 if (tmpval) {
12770 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12771 hf->name, tfs->true_string);
12772 first = false0;
12773 } else if (!(flags & BMT_NO_FALSE0x04)) {
12774 proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12775 hf->name, tfs->false_string);
12776 first = false0;
12777 }
12778 } else if (hf->bitmask & value) {
12779 /* If the flag is set, show the name */
12780 proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12781 first = false0;
12782 }
12783 break;
12784 default:
12785 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))
12786 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))
12787 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))
12788 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))
;
12789 break;
12790 }
12791
12792 fields++;
12793 }
12794
12795 /* XXX: We don't pass the hfi into this function. Perhaps we should,
12796 * but then again most dissectors don't set the bitmask field for
12797 * the higher level bitmask hfi, so calculate the bitmask from the
12798 * fields present. */
12799 if (item) {
12800 bit_offset = len*8 - 1 - ws_ilog2(bitmask);
12801 no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
12802 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)
;
12803 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)
;
12804 }
12805 return first;
12806}
12807
12808/* This function will dissect a sequence of bytes that describe a
12809 * bitmask and supply the value of that sequence through a pointer.
12810 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12811 * to be dissected.
12812 * This field will form an expansion under which the individual fields of the
12813 * bitmask is dissected and displayed.
12814 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12815 *
12816 * fields is an array of pointers to int that lists all the fields of the
12817 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12818 * or another integer of the same type/size as hf_hdr with a mask specified.
12819 * This array is terminated by a NULL entry.
12820 *
12821 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12822 * FT_integer fields that have a value_string attached will have the
12823 * matched string displayed on the expansion line.
12824 */
12825proto_item *
12826proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
12827 const unsigned offset, const int hf_hdr,
12828 const int ett, int * const *fields,
12829 const unsigned encoding, uint64_t *retval)
12830{
12831 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);
12832}
12833
12834/* This function will dissect a sequence of bytes that describe a
12835 * bitmask.
12836 * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
12837 * to be dissected.
12838 * This field will form an expansion under which the individual fields of the
12839 * bitmask is dissected and displayed.
12840 * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
12841 *
12842 * fields is an array of pointers to int that lists all the fields of the
12843 * bitmask. These fields can be either of the type FT_BOOLEAN for flags
12844 * or another integer of the same type/size as hf_hdr with a mask specified.
12845 * This array is terminated by a NULL entry.
12846 *
12847 * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
12848 * FT_integer fields that have a value_string attached will have the
12849 * matched string displayed on the expansion line.
12850 */
12851proto_item *
12852proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
12853 const unsigned offset, const int hf_hdr,
12854 const int ett, int * const *fields,
12855 const unsigned encoding)
12856{
12857 return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
12858}
12859
12860/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12861 * what data is appended to the header.
12862 */
12863proto_item *
12864proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12865 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
12866 uint64_t *retval)
12867{
12868 proto_item *item = NULL((void*)0);
12869 header_field_info *hf;
12870 int len;
12871 uint64_t value;
12872
12873 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", 12873, __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", 12873
, "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", 12873, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12874 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", 12874, (hf)->abbrev)))
;
12875 len = ftype_wire_size(hf->type);
12876 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12877
12878 if (parent_tree) {
12879 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12880 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12881 flags, false0, false0, NULL((void*)0), value);
12882 }
12883
12884 *retval = value;
12885 if (hf->bitmask) {
12886 /* Mask out irrelevant portions */
12887 *retval &= hf->bitmask;
12888 /* Shift bits */
12889 *retval >>= hfinfo_bitshift(hf);
12890 }
12891
12892 return item;
12893}
12894
12895/* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
12896 * what data is appended to the header.
12897 */
12898proto_item *
12899proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12900 const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
12901{
12902 proto_item *item = NULL((void*)0);
12903 header_field_info *hf;
12904 int len;
12905 uint64_t value;
12906
12907 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", 12907, __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", 12907
, "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", 12907, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12908 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", 12908, (hf)->abbrev)))
;
12909
12910 if (parent_tree) {
12911 len = ftype_wire_size(hf->type);
12912 item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
12913 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
12914 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12915 flags, false0, false0, NULL((void*)0), value);
12916 }
12917
12918 return item;
12919}
12920
12921/* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
12922 can't be retrieved directly from tvb) */
12923proto_item *
12924proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12925 const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
12926{
12927 return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
12928 hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
12929}
12930
12931/* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
12932WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
12933proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
12934 const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
12935{
12936 proto_item *item = NULL((void*)0);
12937 header_field_info *hf;
12938 int len;
12939
12940 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", 12940, __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", 12940
, "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", 12940, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
12941 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", 12941, (hf)->abbrev)))
;
12942 /* the proto_tree_add_uint/_uint64() calls below
12943 will fail if tvb==NULL and len!=0 */
12944 len = tvb ? ftype_wire_size(hf->type) : 0;
12945
12946 if (parent_tree) {
12947 if (len <= 4)
12948 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
12949 else
12950 item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
12951
12952 proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
12953 flags, false0, false0, NULL((void*)0), value);
12954 }
12955
12956 return item;
12957}
12958
12959/* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
12960void
12961proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
12962 const int len, int * const *fields, const unsigned encoding)
12963{
12964 uint64_t value;
12965
12966 if (tree) {
12967 value = get_uint64_value(tree, tvb, offset, len, encoding);
12968 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
12969 BMT_NO_APPEND0x01, false0, true1, tree, value);
12970 }
12971}
12972
12973WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
12974proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
12975 const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
12976{
12977 uint64_t value;
12978
12979 value = get_uint64_value(tree, tvb, offset, len, encoding);
12980 if (tree) {
12981 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
12982 BMT_NO_APPEND0x01, false0, true1, tree, value);
12983 }
12984 if (retval) {
12985 *retval = value;
12986 }
12987}
12988
12989WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
12990proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
12991 const int len, int * const *fields, const uint64_t value)
12992{
12993 if (tree) {
12994 proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
12995 BMT_NO_APPEND0x01, false0, true1, tree, value);
12996 }
12997}
12998
12999
13000/* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13001 * This is intended to support bitmask fields whose lengths can vary, perhaps
13002 * as the underlying standard evolves over time.
13003 * With this API there is the possibility of being called to display more or
13004 * less data than the dissector was coded to support.
13005 * In such cases, it is assumed that bitmasks are extended on the MSb end.
13006 * Thus when presented with "too much" or "too little" data, MSbits will be
13007 * ignored or MSfields sacrificed.
13008 *
13009 * Only fields for which all defined bits are available are displayed.
13010 */
13011proto_item *
13012proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13013 const unsigned offset, const unsigned len, const int hf_hdr,
13014 const int ett, int * const *fields, struct expert_field* exp,
13015 const unsigned encoding)
13016{
13017 proto_item *item = NULL((void*)0);
13018 header_field_info *hf;
13019 unsigned decodable_len;
13020 unsigned decodable_offset;
13021 uint32_t decodable_value;
13022 uint64_t value;
13023
13024 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", 13024, __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", 13024
, "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", 13024, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)"
, "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];
;
13025 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", 13025, (hf)->abbrev)))
;
13026
13027 decodable_offset = offset;
13028 decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len
) : ((unsigned) ftype_wire_size(hf->type)))
;
13029
13030 /* If we are ftype_wire_size-limited,
13031 * make sure we decode as many LSBs as possible.
13032 */
13033 if (encoding == ENC_BIG_ENDIAN0x00000000) {
13034 decodable_offset += (len - decodable_len);
13035 }
13036
13037 if (parent_tree) {
13038 decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13039 decodable_len, encoding);
13040
13041 /* The root item covers all the bytes even if we can't decode them all */
13042 item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13043 decodable_value);
13044 }
13045
13046 if (decodable_len < len) {
13047 /* Dissector likely requires updating for new protocol revision */
13048 expert_add_info_format(NULL((void*)0), item, exp,
13049 "Only least-significant %d of %d bytes decoded",
13050 decodable_len, len);
13051 }
13052
13053 if (item) {
13054 value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13055 proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13056 ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13057 }
13058
13059 return item;
13060}
13061
13062/* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13063proto_item *
13064proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13065 const unsigned offset, const unsigned len,
13066 const char *name, const char *fallback,
13067 const int ett, int * const *fields,
13068 const unsigned encoding, const int flags)
13069{
13070 proto_item *item = NULL((void*)0);
13071 uint64_t value;
13072
13073 if (parent_tree) {
13074 item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13075 value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13076 if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13077 flags, true1, false0, NULL((void*)0), value) && fallback) {
13078 /* Still at first item - append 'fallback' text if any */
13079 proto_item_append_text(item, "%s", fallback);
13080 }
13081 }
13082
13083 return item;
13084}
13085
13086proto_item *
13087proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13088 const unsigned bit_offset, const int no_of_bits,
13089 const unsigned encoding)
13090{
13091 header_field_info *hfinfo;
13092 int octet_length;
13093 int octet_offset;
13094
13095 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", 13095, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13095
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13095, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13096
13097 if (no_of_bits < 0) {
13098 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13099 }
13100 octet_length = (no_of_bits + 7) >> 3;
13101 octet_offset = bit_offset >> 3;
13102 test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13103
13104 /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13105 * but only after doing a bunch more work (which we can, in the common
13106 * case, shortcut here).
13107 */
13108 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13109 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", 13109
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13109, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13109, "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", 13109, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
13110
13111 return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13112}
13113
13114/*
13115 * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13116 * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13117 * Offset should be given in bits from the start of the tvb.
13118 */
13119
13120static proto_item *
13121_proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13122 const unsigned bit_offset, const int no_of_bits,
13123 uint64_t *return_value, const unsigned encoding)
13124{
13125 int offset;
13126 unsigned length;
13127 uint8_t tot_no_bits;
13128 char *bf_str;
13129 char lbl_str[ITEM_LABEL_LENGTH240];
13130 uint64_t value = 0;
13131 uint8_t *bytes = NULL((void*)0);
13132 size_t bytes_length = 0;
13133
13134 proto_item *pi;
13135 header_field_info *hf_field;
13136
13137 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13138 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", 13138, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13138
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13138, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex]
;
;
13139
13140 if (hf_field->bitmask != 0) {
13141 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)
13142 " 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)
13143 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)
;
13144 }
13145
13146 if (no_of_bits < 0) {
13147 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13148 } else if (no_of_bits == 0) {
13149 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)
13150 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)
;
13151 }
13152
13153 /* Byte align offset */
13154 offset = bit_offset>>3;
13155
13156 /*
13157 * Calculate the number of octets used to hold the bits
13158 */
13159 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13160 length = (tot_no_bits + 7) >> 3;
13161
13162 if (no_of_bits < 65) {
13163 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13164 } else if (hf_field->type != FT_BYTES) {
13165 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)
13166 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)
;
13167 return NULL((void*)0);
13168 }
13169
13170 /* Sign extend for signed types */
13171 switch (hf_field->type) {
13172 case FT_INT8:
13173 case FT_INT16:
13174 case FT_INT24:
13175 case FT_INT32:
13176 case FT_INT40:
13177 case FT_INT48:
13178 case FT_INT56:
13179 case FT_INT64:
13180 value = ws_sign_ext64(value, no_of_bits);
13181 break;
13182
13183 default:
13184 break;
13185 }
13186
13187 if (return_value) {
13188 *return_value = value;
13189 }
13190
13191 /* Coast clear. Try and fake it */
13192 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13193 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", 13193
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13193, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13193, "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", 13193, __func__, "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 tree; } } }
;
13194
13195 bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13196
13197 switch (hf_field->type) {
13198 case FT_BOOLEAN:
13199 /* Boolean field */
13200 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13201 "%s = %s: %s",
13202 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13203 break;
13204
13205 case FT_CHAR:
13206 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13207 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13208 break;
13209
13210 case FT_UINT8:
13211 case FT_UINT16:
13212 case FT_UINT24:
13213 case FT_UINT32:
13214 pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13215 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13216 break;
13217
13218 case FT_INT8:
13219 case FT_INT16:
13220 case FT_INT24:
13221 case FT_INT32:
13222 pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13223 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13224 break;
13225
13226 case FT_UINT40:
13227 case FT_UINT48:
13228 case FT_UINT56:
13229 case FT_UINT64:
13230 pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13231 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13232 break;
13233
13234 case FT_INT40:
13235 case FT_INT48:
13236 case FT_INT56:
13237 case FT_INT64:
13238 pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13239 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13240 break;
13241
13242 case FT_BYTES:
13243 bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13244 pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13245 proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13246 proto_item_set_text(pi, "%s", lbl_str);
13247 return pi;
13248
13249 /* TODO: should handle FT_UINT_BYTES ? */
13250
13251 default:
13252 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))
13253 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))
13254 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))
13255 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))
;
13256 return NULL((void*)0);
13257 }
13258
13259 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13260 return pi;
13261}
13262
13263proto_item *
13264proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13265 const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13266 uint64_t *return_value)
13267{
13268 proto_item *pi;
13269 int no_of_bits;
13270 int octet_offset;
13271 unsigned mask_initial_bit_offset;
13272 unsigned mask_greatest_bit_offset;
13273 unsigned octet_length;
13274 uint8_t i;
13275 char bf_str[256];
13276 char lbl_str[ITEM_LABEL_LENGTH240];
13277 uint64_t value;
13278 uint64_t composite_bitmask;
13279 uint64_t composite_bitmap;
13280
13281 header_field_info *hf_field;
13282
13283 /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13284 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", 13284, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13284
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13284, "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
13285
13286 if (hf_field->bitmask != 0) {
8
Assuming field 'bitmask' is equal to 0
9
Taking false branch
13287 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)
13288 " 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)
13289 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)
;
13290 }
13291
13292 mask_initial_bit_offset = bit_offset % 8;
13293
13294 no_of_bits = 0;
13295 value = 0;
13296 i = 0;
13297 mask_greatest_bit_offset = 0;
13298 composite_bitmask = 0;
13299 composite_bitmap = 0;
13300
13301 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
13302 uint64_t crumb_mask, crumb_value;
13303 uint8_t crumb_end_bit_offset;
13304
13305 crumb_value = tvb_get_bits64(tvb,
13306 bit_offset + crumb_spec[i].crumb_bit_offset,
13307 crumb_spec[i].crumb_bit_length,
13308 ENC_BIG_ENDIAN0x00000000);
13309 value += crumb_value;
13310 no_of_bits += crumb_spec[i].crumb_bit_length;
13311 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", 13311
, "no_of_bits <= 64", "a value larger than 64 bits cannot be represented"
))))
;
12
Assuming 'no_of_bits' is <= 64
13
'?' condition is true
13312
13313 /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13314 octet containing the initial offset.
13315 If the mask is beyond 32 bits, then give up on bit map display.
13316 This could be improved in future, probably showing a table
13317 of 32 or 64 bits per row */
13318 if (mask_greatest_bit_offset
13.1
'mask_greatest_bit_offset' is < 32
< 32) {
14
Taking true branch
13319 crumb_end_bit_offset = mask_initial_bit_offset
13320 + crumb_spec[i].crumb_bit_offset
13321 + crumb_spec[i].crumb_bit_length;
13322 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'
13323
13324 if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17
Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset'
18
Taking false branch
13325 mask_greatest_bit_offset = crumb_end_bit_offset;
13326 }
13327 /* Currently the bitmap of the crumbs are only shown if
13328 * smaller than 32 bits. Do not bother calculating the
13329 * mask if it is larger than that. */
13330 if (crumb_end_bit_offset
18.1
'crumb_end_bit_offset' is <= 32
<= 32) {
19
Taking true branch
13331 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'
13332 composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13333 }
13334 }
13335 /* Shift left for the next segment */
13336 value <<= crumb_spec[++i].crumb_bit_length;
13337 }
13338
13339 /* Sign extend for signed types */
13340 switch (hf_field->type) {
13341 case FT_INT8:
13342 case FT_INT16:
13343 case FT_INT24:
13344 case FT_INT32:
13345 case FT_INT40:
13346 case FT_INT48:
13347 case FT_INT56:
13348 case FT_INT64:
13349 value = ws_sign_ext64(value, no_of_bits);
13350 break;
13351 default:
13352 break;
13353 }
13354
13355 if (return_value) {
13356 *return_value = value;
13357 }
13358
13359 /* Coast clear. Try and fake it */
13360 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13361 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", 13361
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13361, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13361, "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", 13361, __func__, "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 tree; } } }
;
13362
13363 /* initialise the format string */
13364 bf_str[0] = '\0';
13365
13366 octet_offset = bit_offset >> 3;
13367
13368 /* Round up mask length to nearest octet */
13369 octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13370 mask_greatest_bit_offset = octet_length << 3;
13371
13372 /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13373 It would be a useful enhancement to eliminate this restriction. */
13374 if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13375 other_decode_bitfield_value(bf_str,
13376 (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13377 (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13378 mask_greatest_bit_offset);
13379 } else {
13380 /* If the bitmask is too large, try to describe its contents. */
13381 snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13382 }
13383
13384 switch (hf_field->type) {
13385 case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13386 /* Boolean field */
13387 return proto_tree_add_boolean_format(tree, hfindex,
13388 tvb, octet_offset, octet_length, value,
13389 "%s = %s: %s",
13390 bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13391 break;
13392
13393 case FT_CHAR:
13394 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13395 fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13396 break;
13397
13398 case FT_UINT8:
13399 case FT_UINT16:
13400 case FT_UINT24:
13401 case FT_UINT32:
13402 pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13403 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13404 break;
13405
13406 case FT_INT8:
13407 case FT_INT16:
13408 case FT_INT24:
13409 case FT_INT32:
13410 pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13411 fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13412 break;
13413
13414 case FT_UINT40:
13415 case FT_UINT48:
13416 case FT_UINT56:
13417 case FT_UINT64:
13418 pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13419 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13420 break;
13421
13422 case FT_INT40:
13423 case FT_INT48:
13424 case FT_INT56:
13425 case FT_INT64:
13426 pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13427 fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13428 break;
13429
13430 default:
13431 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))
13432 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))
13433 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))
13434 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))
;
13435 return NULL((void*)0);
13436 }
13437 proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13438 return pi;
13439}
13440
13441void
13442proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13443 const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13444{
13445 header_field_info *hfinfo;
13446 int start = bit_offset >> 3;
13447 int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13448
13449 /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13450 * so that we can use the tree's memory scope in calculating the string */
13451 if (length == -1) {
13452 tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13453 } else {
13454 tvb_ensure_bytes_exist(tvb, start, length);
13455 }
13456 if (!tree) return;
13457
13458 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", 13458, __func__, "Unregistered hf! index=%d"
, hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex
< gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13458
, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13458, "gpa_hfinfo.hfi[hfindex] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];
;
13459 proto_tree_add_text_internal(tree, tvb, start, length,
13460 "%s crumb %d of %s (decoded above)",
13461 decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13462 tvb_get_bits(tvb,
13463 bit_offset,
13464 crumb_spec[crumb_index].crumb_bit_length,
13465 ENC_BIG_ENDIAN0x00000000),
13466 ENC_BIG_ENDIAN0x00000000),
13467 crumb_index,
13468 hfinfo->name);
13469}
13470
13471proto_item *
13472proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13473 const unsigned bit_offset, const int no_of_bits,
13474 uint64_t *return_value, const unsigned encoding)
13475{
13476 proto_item *item;
13477
13478 if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13479 bit_offset, no_of_bits,
13480 return_value, encoding))) {
13481 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)
;
13482 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)
;
13483 }
13484 return item;
13485}
13486
13487static proto_item *
13488_proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13489 tvbuff_t *tvb, const unsigned bit_offset,
13490 const int no_of_bits, void *value_ptr,
13491 const unsigned encoding, char *value_str)
13492{
13493 int offset;
13494 unsigned length;
13495 uint8_t tot_no_bits;
13496 char *str;
13497 uint64_t value = 0;
13498 header_field_info *hf_field;
13499
13500 /* We do not have to return a value, try to fake it as soon as possible */
13501 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13502 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", 13502
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13502, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13502, "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", 13502, __func__, "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 tree; } } }
;
13503
13504 if (hf_field->bitmask != 0) {
13505 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)
13506 " 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)
13507 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)
;
13508 }
13509
13510 if (no_of_bits < 0) {
13511 THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13512 } else if (no_of_bits == 0) {
13513 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)
13514 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)
;
13515 }
13516
13517 /* Byte align offset */
13518 offset = bit_offset>>3;
13519
13520 /*
13521 * Calculate the number of octets used to hold the bits
13522 */
13523 tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13524 length = tot_no_bits>>3;
13525 /* If we are using part of the next octet, increase length by 1 */
13526 if (tot_no_bits & 0x07)
13527 length++;
13528
13529 if (no_of_bits < 65) {
13530 value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13531 } else {
13532 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)
13533 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)
;
13534 return NULL((void*)0);
13535 }
13536
13537 str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13538
13539 (void) g_strlcat(str, " = ", 256+64);
13540 (void) g_strlcat(str, hf_field->name, 256+64);
13541
13542 /*
13543 * This function does not receive an actual value but a dimensionless pointer to that value.
13544 * For this reason, the type of the header field is examined in order to determine
13545 * what kind of value we should read from this address.
13546 * The caller of this function must make sure that for the specific header field type the address of
13547 * a compatible value is provided.
13548 */
13549 switch (hf_field->type) {
13550 case FT_BOOLEAN:
13551 return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13552 "%s: %s", str, value_str);
13553 break;
13554
13555 case FT_CHAR:
13556 case FT_UINT8:
13557 case FT_UINT16:
13558 case FT_UINT24:
13559 case FT_UINT32:
13560 return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13561 "%s: %s", str, value_str);
13562 break;
13563
13564 case FT_UINT40:
13565 case FT_UINT48:
13566 case FT_UINT56:
13567 case FT_UINT64:
13568 return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13569 "%s: %s", str, value_str);
13570 break;
13571
13572 case FT_INT8:
13573 case FT_INT16:
13574 case FT_INT24:
13575 case FT_INT32:
13576 return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13577 "%s: %s", str, value_str);
13578 break;
13579
13580 case FT_INT40:
13581 case FT_INT48:
13582 case FT_INT56:
13583 case FT_INT64:
13584 return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13585 "%s: %s", str, value_str);
13586 break;
13587
13588 case FT_FLOAT:
13589 return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13590 "%s: %s", str, value_str);
13591 break;
13592
13593 default:
13594 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))
13595 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))
13596 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))
13597 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))
;
13598 return NULL((void*)0);
13599 }
13600}
13601
13602static proto_item *
13603proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13604 tvbuff_t *tvb, const unsigned bit_offset,
13605 const int no_of_bits, void *value_ptr,
13606 const unsigned encoding, char *value_str)
13607{
13608 proto_item *item;
13609
13610 if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13611 tvb, bit_offset, no_of_bits,
13612 value_ptr, encoding, value_str))) {
13613 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)
;
13614 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)
;
13615 }
13616 return item;
13617}
13618
13619#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);
\
13620 va_start(ap, format)__builtin_va_start(ap, format); \
13621 dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13622 va_end(ap)__builtin_va_end(ap);
13623
13624proto_item *
13625proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13626 tvbuff_t *tvb, const unsigned bit_offset,
13627 const int no_of_bits, uint32_t value,
13628 const unsigned encoding,
13629 const char *format, ...)
13630{
13631 va_list ap;
13632 char *dst;
13633 header_field_info *hf_field;
13634
13635 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13636
13637 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", 13637
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13637, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13637, "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", 13637, __func__, "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 tree; } } }
;
13638
13639 switch (hf_field->type) {
13640 case FT_UINT8:
13641 case FT_UINT16:
13642 case FT_UINT24:
13643 case FT_UINT32:
13644 break;
13645
13646 default:
13647 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)
13648 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)
;
13649 return NULL((void*)0);
13650 }
13651
13652 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);
;
13653
13654 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13655}
13656
13657proto_item *
13658proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13659 tvbuff_t *tvb, const unsigned bit_offset,
13660 const int no_of_bits, uint64_t value,
13661 const unsigned encoding,
13662 const char *format, ...)
13663{
13664 va_list ap;
13665 char *dst;
13666 header_field_info *hf_field;
13667
13668 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13669
13670 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", 13670
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13670, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13670, "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", 13670, __func__, "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 tree; } } }
;
13671
13672 switch (hf_field->type) {
13673 case FT_UINT40:
13674 case FT_UINT48:
13675 case FT_UINT56:
13676 case FT_UINT64:
13677 break;
13678
13679 default:
13680 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)
13681 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)
;
13682 return NULL((void*)0);
13683 }
13684
13685 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);
;
13686
13687 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13688}
13689
13690proto_item *
13691proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13692 tvbuff_t *tvb, const unsigned bit_offset,
13693 const int no_of_bits, float value,
13694 const unsigned encoding,
13695 const char *format, ...)
13696{
13697 va_list ap;
13698 char *dst;
13699 header_field_info *hf_field;
13700
13701 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13702
13703 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", 13703
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13703, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13703, "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", 13703, __func__, "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 tree; } } }
;
13704
13705 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",
13705, ((hf_field))->abbrev))))
;
13706
13707 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);
;
13708
13709 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13710}
13711
13712proto_item *
13713proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13714 tvbuff_t *tvb, const unsigned bit_offset,
13715 const int no_of_bits, int32_t value,
13716 const unsigned encoding,
13717 const char *format, ...)
13718{
13719 va_list ap;
13720 char *dst;
13721 header_field_info *hf_field;
13722
13723 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13724
13725 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", 13725
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13725, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13725, "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", 13725, __func__, "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 tree; } } }
;
13726
13727 switch (hf_field->type) {
13728 case FT_INT8:
13729 case FT_INT16:
13730 case FT_INT24:
13731 case FT_INT32:
13732 break;
13733
13734 default:
13735 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)
13736 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)
;
13737 return NULL((void*)0);
13738 }
13739
13740 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);
;
13741
13742 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13743}
13744
13745proto_item *
13746proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13747 tvbuff_t *tvb, const unsigned bit_offset,
13748 const int no_of_bits, int64_t value,
13749 const unsigned encoding,
13750 const char *format, ...)
13751{
13752 va_list ap;
13753 char *dst;
13754 header_field_info *hf_field;
13755
13756 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13757
13758 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", 13758
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13758, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13758, "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", 13758, __func__, "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 tree; } } }
;
13759
13760 switch (hf_field->type) {
13761 case FT_INT40:
13762 case FT_INT48:
13763 case FT_INT56:
13764 case FT_INT64:
13765 break;
13766
13767 default:
13768 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)
13769 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)
;
13770 return NULL((void*)0);
13771 }
13772
13773 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);
;
13774
13775 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13776}
13777
13778proto_item *
13779proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13780 tvbuff_t *tvb, const unsigned bit_offset,
13781 const int no_of_bits, uint64_t value,
13782 const unsigned encoding,
13783 const char *format, ...)
13784{
13785 va_list ap;
13786 char *dst;
13787 header_field_info *hf_field;
13788
13789 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13790
13791 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", 13791
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13791, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13791, "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", 13791, __func__, "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 tree; } } }
;
13792
13793 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"
, 13793, ((hf_field))->abbrev))))
;
13794
13795 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);
;
13796
13797 return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13798}
13799
13800proto_item *
13801proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13802 const unsigned bit_offset, const int no_of_chars)
13803{
13804 proto_item *pi;
13805 header_field_info *hfinfo;
13806 int byte_length;
13807 int byte_offset;
13808 char *string;
13809
13810 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13811
13812 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", 13812
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13812, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13812, "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", 13812, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
13813
13814 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"
, 13814, ((hfinfo))->abbrev))))
;
13815
13816 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13817 byte_offset = bit_offset >> 3;
13818
13819 string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13820
13821 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13822 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13822, "byte_length >= 0"
))))
;
13823 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13824
13825 return pi;
13826}
13827
13828proto_item *
13829proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13830 const unsigned bit_offset, const int no_of_chars)
13831{
13832 proto_item *pi;
13833 header_field_info *hfinfo;
13834 int byte_length;
13835 int byte_offset;
13836 char *string;
13837
13838 CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13839
13840 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", 13840
, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((
hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len
) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13840, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len"
, "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] !=
((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)"
, "epan/proto.c", 13840, "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", 13840, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data
)->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree
)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)"
, hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree
)->tree_data)->visible)) { if (proto_item_is_hidden((tree
))) { 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 tree; } } }
;
13841
13842 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"
, 13842, ((hfinfo))->abbrev))))
;
13843
13844 byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
13845 byte_offset = bit_offset >> 3;
13846
13847 string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
13848
13849 pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
13850 DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug
("%s:%u: failed assertion \"%s\"", "epan/proto.c", 13850, "byte_length >= 0"
))))
;
13851 proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
13852
13853 return pi;
13854}
13855
13856const value_string proto_checksum_vals[] = {
13857 { PROTO_CHECKSUM_E_BAD, "Bad" },
13858 { PROTO_CHECKSUM_E_GOOD, "Good" },
13859 { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
13860 { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
13861 { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
13862
13863 { 0, NULL((void*)0) }
13864};
13865
13866proto_item *
13867proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13868 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
13869 packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
13870{
13871 header_field_info *hfinfo;
13872 uint32_t checksum;
13873 uint32_t len;
13874 proto_item* ti = NULL((void*)0);
13875 proto_item* ti2;
13876 bool_Bool incorrect_checksum = true1;
13877
13878 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", 13878, __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", 13878
, "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", 13878, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
13879
13880 switch (hfinfo->type) {
13881 case FT_UINT8:
13882 len = 1;
13883 break;
13884 case FT_UINT16:
13885 len = 2;
13886 break;
13887 case FT_UINT24:
13888 len = 3;
13889 break;
13890 case FT_UINT32:
13891 len = 4;
13892 break;
13893 default:
13894 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)
13895 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32"
, hfinfo->abbrev)
;
13896 }
13897
13898 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
13899 ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
13900 proto_item_set_generated(ti);
13901 if (hf_checksum_status != -1) {
13902 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
13903 proto_item_set_generated(ti2);
13904 }
13905 return ti;
13906 }
13907
13908 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
13909 ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
13910 proto_item_set_generated(ti);
13911 } else {
13912 ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
13913 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
13914 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
13915 if (computed_checksum == 0) {
13916 proto_item_append_text(ti, " [correct]");
13917 if (hf_checksum_status != -1) {
13918 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13919 proto_item_set_generated(ti2);
13920 }
13921 incorrect_checksum = false0;
13922 } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
13923 computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
13924 }
13925 } else {
13926 if (checksum == computed_checksum) {
13927 proto_item_append_text(ti, " [correct]");
13928 if (hf_checksum_status != -1) {
13929 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
13930 proto_item_set_generated(ti2);
13931 }
13932 incorrect_checksum = false0;
13933 }
13934 }
13935
13936 if (incorrect_checksum) {
13937 if (hf_checksum_status != -1) {
13938 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
13939 proto_item_set_generated(ti2);
13940 }
13941 if (flags & PROTO_CHECKSUM_ZERO0x08) {
13942 proto_item_append_text(ti, " [incorrect]");
13943 if (bad_checksum_expert != NULL((void*)0))
13944 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
13945 } else {
13946 proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
13947 if (bad_checksum_expert != NULL((void*)0))
13948 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);
13949 }
13950 }
13951 } else {
13952 if (hf_checksum_status != -1) {
13953 proto_item_append_text(ti, " [unverified]");
13954 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
13955 proto_item_set_generated(ti2);
13956 }
13957 }
13958 }
13959
13960 return ti;
13961}
13962
13963proto_item *
13964proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13965 const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
13966 packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
13967{
13968 header_field_info *hfinfo;
13969 uint8_t *checksum = NULL((void*)0);
13970 proto_item* ti = NULL((void*)0);
13971 proto_item* ti2;
13972 bool_Bool incorrect_checksum = true1;
13973
13974 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", 13974, __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", 13974
, "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", 13974, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)"
, "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum
];
;
13975
13976 if (hfinfo->type != FT_BYTES) {
13977 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)
13978 hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES"
, hfinfo->abbrev)
;
13979 }
13980
13981 if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
13982 ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
13983 proto_item_set_generated(ti);
13984 if (hf_checksum_status != -1) {
13985 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
13986 proto_item_set_generated(ti2);
13987 }
13988 return ti;
13989 }
13990
13991 if (flags & PROTO_CHECKSUM_GENERATED0x02) {
13992 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
13993 proto_item_set_generated(ti);
13994 } else {
13995 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
))))))
;
13996 tvb_memcpy(tvb, checksum, offset, checksum_len);
13997 ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
13998 if (flags & PROTO_CHECKSUM_VERIFY0x01) {
13999 if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14000 if (computed_checksum == 0) {
14001 proto_item_append_text(ti, " [correct]");
14002 if (hf_checksum_status != -1) {
14003 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14004 proto_item_set_generated(ti2);
14005 }
14006 incorrect_checksum = false0;
14007 }
14008 } else {
14009 if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14010 proto_item_append_text(ti, " [correct]");
14011 if (hf_checksum_status != -1) {
14012 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14013 proto_item_set_generated(ti2);
14014 }
14015 incorrect_checksum = false0;
14016 }
14017 }
14018
14019 if (incorrect_checksum) {
14020 if (hf_checksum_status != -1) {
14021 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14022 proto_item_set_generated(ti2);
14023 }
14024 if (flags & PROTO_CHECKSUM_ZERO0x08) {
14025 proto_item_append_text(ti, " [incorrect]");
14026 if (bad_checksum_expert != NULL((void*)0))
14027 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14028 } else {
14029 size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14030 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))))))
;
14031 for (size_t counter = 0; counter < checksum_len; ++counter) {
14032 snprintf(
14033 /* On ecah iteration inserts two characters */
14034 (char*)&computed_checksum_str[counter << 1],
14035 computed_checksum_str_len - (counter << 1),
14036 "%02x",
14037 computed_checksum[counter]);
14038 }
14039 proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14040 if (bad_checksum_expert != NULL((void*)0))
14041 expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14042 }
14043 }
14044 } else {
14045 if (hf_checksum_status != -1) {
14046 proto_item_append_text(ti, " [unverified]");
14047 ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14048 proto_item_set_generated(ti2);
14049 }
14050 }
14051 }
14052
14053 return ti;
14054}
14055
14056unsigned char
14057proto_check_field_name(const char *field_name)
14058{
14059 return module_check_valid_name(field_name, false0);
14060}
14061
14062unsigned char
14063proto_check_field_name_lower(const char *field_name)
14064{
14065 return module_check_valid_name(field_name, true1);
14066}
14067
14068bool_Bool
14069tree_expanded(int tree_type)
14070{
14071 if (tree_type <= 0) {
14072 return false0;
14073 }
14074 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", 14074, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14075 return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14076}
14077
14078void
14079tree_expanded_set(int tree_type, bool_Bool value)
14080{
14081 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", 14081, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types"
); } while (0)
;
14082
14083 if (value)
14084 tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14085 else
14086 tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14087}
14088
14089/*
14090 * Editor modelines - https://www.wireshark.org/tools/modelines.html
14091 *
14092 * Local variables:
14093 * c-basic-offset: 8
14094 * tab-width: 8
14095 * indent-tabs-mode: t
14096 * End:
14097 *
14098 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14099 * :indentSize=8:tabSize=8:noTabs=false:
14100 */