### Bug Summary

File: | builds/wireshark/wireshark/epan/proto.c
Warning: | line 3393, column 3 3rd function call argument is an uninitialized value

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
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-22/lib/clang/22 -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/mit-krb5 -isystem /usr/include/lua5.5 -isystem /usr/include/libxml2 -D CARES_NO_DEPRECATED -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-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../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-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -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 -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-07-18-100301-3641-1 -x c /builds/wireshark/wireshark/epan/proto.c

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

1 | /* proto.c
2 | * Routines for protocol tree
3 | *
4 | * Wireshark - Network traffic analyzer
5 | * By Gerald Combs <gerald@wireshark.org>
6 | * Copyright 1998 Gerald Combs
7 | *
8 | * SPDX-License-Identifier: GPL-2.0-or-later
9 | */
10 |
11 | #include "config.h"
12 | #define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13 | #include "wireshark.h"
14 |
15 | #include <float.h>
16 | #include <errno(*__errno_location ()).h>
17 |
18 | #include <epan/tfs.h>
19 | #include <epan/unit_strings.h>
20 |
21 | #include <wsutil/array.h>
22 | #include <wsutil/bits_ctz.h>
23 | #include <wsutil/bits_count_ones.h>
24 | #include <wsutil/sign_ext.h>
25 | #include <wsutil/utf8_entities.h>
26 | #include <wsutil/json_dumper.h>
27 | #include <wsutil/pint.h>
28 | #include <wsutil/unicode-utils.h>
29 | #include <wsutil/dtoa.h>
30 | #include <wsutil/filesystem.h>
31 | #ifdef HAVE_UNISTD_H1
32 | #include <unistd.h>
33 | #endif
34 |
35 | #include <ftypes/ftypes.h>
36 | #include <ftypes/ftypes-int.h>
37 |
38 | #include <epan/packet.h>
39 | #include "exceptions.h"
40 | #include "ptvcursor.h"
41 | #include "strutil.h"
42 | #include "addr_resolv.h"
43 | #include "address_types.h"
44 | #include "oids.h"
45 | #include "proto.h"
46 | #include "epan_dissect.h"
47 | #include "dfilter/dfilter.h"
48 | #include "tvbuff.h"
49 | #include "charsets.h"
50 | #include "column-info.h"
51 | #include "to_str.h"
52 | #include "osi-utils.h"
53 | #include "expert.h"
54 | #include "show_exception.h"
55 | #include "in_cksum.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 |
64 | typedef struct __subtree_lvl {
65 | unsigned cursor_offset;
66 | proto_item *it;
67 | proto_tree *tree;
68 | } subtree_lvl;
69 |
70 | struct 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 | unsigned 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 | @return NULL if 'tree' is null */
95 | #define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 | CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97 |
98 | /** See inlined comments.
99 | @param length the length of this item
100 | @param cleanup_block a code block to call to free resources if this returns
101 | @return NULL if 'length' is equal to 0 */
102 | #define CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, cleanup_block)if (length == 0) { cleanup_block; return ((void*)0); } \
103 | if (length == 0) { \
104 | cleanup_block; \
105 | return NULL((void*)0); \
106 | }
107 |
108 | /** See inlined comments.
109 | @param length the length of this item
110 | @return NULL if 'length' is equal to 0 */
111 | #define CHECK_FOR_ZERO_LENGTH(length)if (length == 0) { ((void)0); return ((void*)0); } \
112 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length, ((void)0))if (length == 0) { ((void)0); return ((void*)0); }
113 |
114 | /** See inlined comments.
115 | @param tree the tree to append this item to
116 | @param hfindex field index
117 | @param hfinfo header_field
118 | @param free_block a code block to call to free resources if this returns
119 | @return the header field matching 'hfinfo' */
120 | #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", 120 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 120, "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", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { free_block; return proto_tree_add_fake_node(tree, hfinfo ); } } } \
121 | /* If the tree is not visible and this item is not referenced \
122 | we don't have to do much work at all but we should still \
123 | return a node so that referenced field items below this node \
124 | (think proto_item_add_subtree()) will still have somewhere \
125 | to attach to or else filtering will not work (they would be \
126 | ignored since tree would be NULL). \
127 | DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 | because that means we can change its length or repr, and we \
129 | don't want to do so with calls intended for this faked new \
130 | item, so this item needs a new (hidden) child node. \
131 | We fake FT_PROTOCOL unless some clients have requested us \
132 | not to do so. \
133 | */ \
134 | PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 | 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", 135, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; \
136 | if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 | free_block; \
138 | if (wireshark_abort_on_too_many_items) \
139 | 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", 140 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)
140 | hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); \
141 | /* Let the exception handler add items to the tree */ \
142 | PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 | 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)))
144 | 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)))
145 | "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)))
146 | 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))); \
147 | } \
148 | if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 | if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 | if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 | && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 | && (hfinfo->type != FT_PROTOCOL || \
153 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 | free_block; \
155 | /* return fake node with no field info */\
156 | return proto_tree_add_fake_node(tree, hfinfo); \
157 | } \
158 | } \
159 | }
160 |
161 | /** See inlined comments.
162 | @param tree the tree to append this item to
163 | @param hfindex field index
164 | @param hfinfo header_field
165 | @return the header field matching 'hfinfo' */
166 | #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", 166 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 166, "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", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } } \
167 | 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", 167 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } }
168 |
169 |
170 | /** See inlined comments.
171 | @param pi the created protocol item we're about to return */
172 | #define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 172, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; } \
173 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 173, __func__, "assertion failed: %s", "pi" ); } while (0); \
174 | if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 | return pi; \
176 | if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 | /* If the tree (GUI) or item isn't visible it's pointless for \
179 | * us to generate the protocol item's string representation */ \
180 | return pi; \
181 | }
182 | /* Same as above but returning void */
183 | #define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; } \
184 | if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 | return; \
186 | if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 | /* If the tree (GUI) or item isn't visible it's pointless for \
189 | * us to generate the protocol item's string representation */ \
190 | return; \
191 | }
192 | /* Similar to above, but allows a NULL tree */
193 | #define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) || (!(((pi)->tree_data)->visible) && proto_item_is_hidden ((pi)))) { return pi; } \
194 | if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 | /* If the tree (GUI) or item isn't visible it's pointless for \
197 | * us to generate the protocol item's string representation */ \
198 | return pi; \
199 | }
200 |
201 | #ifdef ENABLE_CHECK_FILTER
202 | #define CHECK_HF_VALUE(type, spec, start_values) \
203 | { \
204 | const type *current; \
205 | int n, m; \
206 | current = start_values; \
207 | for (n=0; current; n++, current++) { \
208 | /* Drop out if we reached the end. */ \
209 | if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 | break; \
211 | } \
212 | /* Check value against all previous */ \
213 | for (m=0; m < n; m++) { \
214 | /* There are lots of duplicates with the same string, \
215 | so only report if different... */ \
216 | if ((start_values[m].value == current->value) && \
217 | (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 | ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __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)
219 | " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __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)
220 | hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __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)
221 | current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __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); \
222 | } \
223 | } \
224 | } \
225 | }
226 | #endif
227 |
228 | /* The longest NUMBER-like field label we have is for BASE_OUI, which
229 | * can have up to 64 bytes for the manufacturer name if resolved plus
230 | * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 | */
232 | #define NUMBER_LABEL_LENGTH80 80
233 |
234 | static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235 | static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236 | static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237 | static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238 | static int hfinfo_bitoffset(const header_field_info *hfinfo);
239 | static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240 | static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241 |
242 | #define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 | ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244 |
245 | static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246 | static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247 |
248 | static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249 | static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250 | static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251 | static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252 | static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253 | static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254 | static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255 |
256 | static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257 | static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258 | static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259 | static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260 |
261 | static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262 | static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263 | static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264 | static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265 | static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266 | static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267 | static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268 | static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269 | static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270 | static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271 | static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272 |
273 | static void proto_cleanup_base(void);
274 |
275 | static proto_item *
276 | proto_tree_add_node(proto_tree *tree, field_info *fi);
277 |
278 | static proto_item *
279 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280 |
281 | static void
282 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
283 | int *item_length, const unsigned encoding);
284 |
285 | static void
286 | get_hfi_length_unsigned(header_field_info * hfinfo, tvbuff_t * tvb, const unsigned start, unsigned* length,
287 | unsigned* item_length, const unsigned encoding);
288 |
289 | static int
290 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
291 | int length, unsigned item_length, const int encoding);
292 |
293 | static field_info *
294 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 | const unsigned start, const int item_length);
296 |
297 | static proto_item *
298 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
299 | unsigned start, int *length);
300 |
301 | static proto_item *
302 | proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
303 | unsigned start, unsigned *length);
304 |
305 | static void
306 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
307 | static void
308 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
309 |
310 | static void
311 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
312 | static void
313 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
314 | static void
315 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length);
316 | static void
317 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
318 | static void
319 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
320 | static void
321 | proto_tree_set_string(field_info *fi, const char* value);
322 | static void
323 | proto_tree_set_ax25(field_info *fi, const uint8_t* value);
324 | static void
325 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
326 | static void
327 | proto_tree_set_vines(field_info *fi, const uint8_t* value);
328 | static void
329 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
330 | static void
331 | proto_tree_set_ether(field_info *fi, const uint8_t* value);
332 | static void
333 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start);
334 | static void
335 | proto_tree_set_ipxnet(field_info *fi, uint32_t value);
336 | static void
337 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
338 | static void
339 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
340 | static void
341 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
342 | static void
343 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
344 | static void
345 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
346 | static void
347 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
348 | static void
349 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length);
350 | static void
351 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
352 | static void
353 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length);
354 | static void
355 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length);
356 | static void
357 | proto_tree_set_boolean(field_info *fi, uint64_t value);
358 | static void
359 | proto_tree_set_float(field_info *fi, float value);
360 | static void
361 | proto_tree_set_double(field_info *fi, double value);
362 | static void
363 | proto_tree_set_uint(field_info *fi, uint32_t value);
364 | static void
365 | proto_tree_set_int(field_info *fi, int32_t value);
366 | static void
367 | proto_tree_set_uint64(field_info *fi, uint64_t value);
368 | static void
369 | proto_tree_set_int64(field_info *fi, int64_t value);
370 | static void
371 | proto_tree_set_eui64(field_info *fi, const uint64_t value);
372 | static void
373 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding);
374 |
375 | /* Handle type length mismatch (now filterable) expert info */
376 | static int proto_type_length_mismatch;
377 | static expert_field ei_type_length_mismatch_error;
378 | static expert_field ei_type_length_mismatch_warn;
379 | static void register_type_length_mismatch(void);
380 |
381 | /* Handle byte array string decoding errors with expert info */
382 | static int proto_byte_array_string_decoding_error;
383 | static expert_field ei_byte_array_string_decoding_failed_error;
384 | static void register_byte_array_string_decodinws_error(void);
385 |
386 | /* Handle date and time string decoding errors with expert info */
387 | static int proto_date_time_string_decoding_error;
388 | static expert_field ei_date_time_string_decoding_failed_error;
389 | static void register_date_time_string_decodinws_error(void);
390 |
391 | /* Handle string errors expert info */
392 | static int proto_string_errors;
393 | static expert_field ei_string_trailing_characters;
394 | static void register_string_errors(void);
395 |
396 | /* Handle varint errors expert info */
397 | static int proto_varint_errors;
398 | static expert_field ei_varint_decoding_failed_error;
399 | static void register_varint_errors(void);
400 |
401 | static int proto_register_field_init(header_field_info *hfinfo, const int parent);
402 |
403 | /* special-case header field used within proto.c */
404 | static header_field_info hfi_text_only =
405 | { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
406 | int hf_text_only;
407 |
408 | /* Structure for information about a protocol */
409 | struct _protocol {
410 | const char *name; /* long description */
411 | const char *short_name; /* short description */
412 | const char *filter_name; /* name of this protocol in filters */
413 | GPtrArray *fields; /* fields for this protocol */
414 | int proto_id; /* field ID for this protocol */
415 | bool_Bool is_enabled; /* true if protocol is enabled */
416 | bool_Bool enabled_by_default; /* true if protocol is enabled by default */
417 | bool_Bool can_toggle; /* true if is_enabled can be changed */
418 | int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
419 | For dissectors that need a protocol name so they
420 | can be added to a dissector table, but use the
421 | parent_proto_id for things like enable/disable */
422 | GList *heur_list; /* Heuristic dissectors associated with this protocol */
423 | };
424 |
425 | /* List of all protocols */
426 | static GList *protocols;
427 |
428 | /* Structure stored for deregistered g_slice */
429 | struct g_slice_data {
430 | size_t block_size;
431 | void *mem_block;
432 | };
433 |
434 | /* Deregistered fields */
435 | static GPtrArray *deregistered_fields;
436 | static GPtrArray *deregistered_data;
437 | static GPtrArray *deregistered_slice;
438 |
439 | /* indexed by prefix, contains initializers */
440 | static GHashTable* prefixes;
441 |
442 | /* Contains information about a field when a dissector calls
443 | * proto_tree_add_item. */
444 | #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)))
445 | #define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
446 |
447 | /* Contains the space for proto_nodes. */
448 | #define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void *)0); node->next = ((void*)0); \
449 | node->first_child = NULL((void*)0); \
450 | node->last_child = NULL((void*)0); \
451 | node->next = NULL((void*)0);
452 |
453 | #define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
454 | wmem_free(pool, node)
455 |
456 | /* String space for protocol and field items for the GUI */
457 | #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; \
458 | il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
459 | il->value_pos = 0; \
460 | il->value_len = 0;
461 | #define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
462 | wmem_free(pool, il);
463 |
464 | #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", 464, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 464, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 464, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex]; \
465 | if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
466 | ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 466 , __func__, "Unregistered hf! index=%d", hfindex); \
467 | 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", 467, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))); \
468 | 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", 468, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))); \
469 | hfinfo = gpa_hfinfo.hfi[hfindex];
470 |
471 | #define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
472 |
473 | /* List which stores protocols and fields that have been registered */
474 | typedef struct _gpa_hfinfo_t {
475 | uint32_t len;
476 | uint32_t allocated_len;
477 | header_field_info **hfi;
478 | } gpa_hfinfo_t;
479 |
480 | static gpa_hfinfo_t gpa_hfinfo;
481 |
482 | /* Hash table of abbreviations and IDs */
483 | static wmem_map_t *gpa_name_map;
484 | static header_field_info *same_name_hfinfo;
485 |
486 | /* Hash table protocol aliases. const char * -> const char * */
487 | static GHashTable *gpa_protocol_aliases;
488 |
489 | /*
490 | * We're called repeatedly with the same field name when sorting a column.
491 | * Cache our last gpa_name_map hit for faster lookups.
492 | */
493 | static char *last_field_name;
494 | static header_field_info *last_hfinfo;
495 |
496 | /* Points to the first element of an array of bits, indexed by
497 | a subtree item type; that array element is true if subtrees of
498 | an item of that type are to be expanded. */
499 | static uint32_t *tree_is_expanded;
500 |
501 | /* Number of elements in that array. The entry with index 0 is not used. */
502 | int num_tree_types = 1;
503 |
504 | /* Name hashtables for fast detection of duplicate names */
505 | static GHashTable* proto_names;
506 | static GHashTable* proto_short_names;
507 | static GHashTable* proto_filter_names;
508 |
509 | static const char * const reserved_filter_names[] = {
510 | /* Display filter keywords. */
511 | "eq",
512 | "ne",
513 | "all_eq",
514 | "any_eq",
515 | "all_ne",
516 | "any_ne",
517 | "gt",
518 | "ge",
519 | "lt",
520 | "le",
521 | "bitand",
522 | "bitwise_and",
523 | "contains",
524 | "matches",
525 | "not",
526 | "and",
527 | "or",
528 | "xor",
529 | "in",
530 | "any",
531 | "all",
532 | "true",
533 | "false",
534 | "nan",
535 | "inf",
536 | "infinity",
537 | NULL((void*)0)
538 | };
539 |
540 | static GHashTable *proto_reserved_filter_names;
541 | static GQueue* saved_dir_queue;
542 |
543 | static int
544 | proto_compare_name(const void *p1_arg, const void *p2_arg)
545 | {
546 | const protocol_t *p1 = (const protocol_t *)p1_arg;
547 | const protocol_t *p2 = (const protocol_t *)p2_arg;
548 |
549 | return g_ascii_strcasecmp(p1->short_name, p2->short_name);
550 | }
551 |
552 | static GSList *dissector_plugins;
553 |
554 | #ifdef HAVE_PLUGINS1
555 | void
556 | proto_register_plugin(const proto_plugin *plug)
557 | {
558 | dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
559 | }
560 | #else /* HAVE_PLUGINS */
561 | void
562 | proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
563 | {
564 | ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 564, __func__, "proto_register_plugin: built without support for binary plugins" ); } } while (0);
565 | }
566 | #endif /* HAVE_PLUGINS */
567 |
568 | static void
569 | call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
570 | {
571 | proto_plugin *plug = (proto_plugin *)data;
572 |
573 | if (plug->register_protoinfo) {
574 | plug->register_protoinfo();
575 | }
576 | }
577 |
578 | static void
579 | call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
580 | {
581 | proto_plugin *plug = (proto_plugin *)data;
582 |
583 | if (plug->register_handoff) {
584 | plug->register_handoff();
585 | }
586 | }
587 |
588 | void proto_pre_init(void)
589 | {
590 | saved_dir_queue = g_queue_new();
591 |
592 | proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
593 | proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
594 | proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
595 |
596 | proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
597 | for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
598 | /* GHashTable has no key destructor so the cast is safe. */
599 | g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
600 | }
601 |
602 | gpa_hfinfo.len = 0;
603 | gpa_hfinfo.allocated_len = 0;
604 | gpa_hfinfo.hfi = NULL((void*)0);
605 | gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
606 | wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
607 | gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
608 | deregistered_fields = g_ptr_array_new();
609 | deregistered_data = g_ptr_array_new();
610 | deregistered_slice = g_ptr_array_new();
611 | }
612 |
613 | /* initialize data structures and register protocols and fields */
614 | void
615 | proto_init(GSList *register_all_plugin_protocols_list,
616 | GSList *register_all_plugin_handoffs_list,
617 | register_entity_func register_func, register_entity_func handoff_func,
618 | register_cb cb,
619 | void *client_data)
620 | {
621 | /* Initialize the ftype subsystem */
622 | ftypes_initialize();
623 |
624 | /* Initialize the address type subsystem */
625 | address_types_initialize();
626 |
627 | /* Register one special-case FT_TEXT_ONLY field for use when
628 | converting wireshark to new-style proto_tree. These fields
629 | are merely strings on the GUI tree; they are not filterable */
630 | hf_text_only = proto_register_field_init(&hfi_text_only, -1);
631 |
632 | /* Register the pseudo-protocols used for exceptions. */
633 | register_show_exception();
634 | register_type_length_mismatch();
635 | register_byte_array_string_decodinws_error();
636 | register_date_time_string_decodinws_error();
637 | register_string_errors();
638 | register_varint_errors();
639 | ftypes_register_pseudofields();
640 | col_register_protocol();
641 |
642 | /* Have each built-in dissector register its protocols, fields,
643 | dissector tables, and dissectors to be called through a
644 | handle, and do whatever one-time initialization it needs to
645 | do. */
646 | if (register_func != NULL((void*)0))
647 | register_func(cb, client_data);
648 |
649 | /* Now call the registration routines for all epan plugins. */
650 | for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
651 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
652 | }
653 |
654 | /* Now call the registration routines for all dissector plugins. */
655 | if (cb)
656 | (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
657 | g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
658 |
659 | /* Now call the "handoff registration" routines of all built-in
660 | dissectors; those routines register the dissector in other
661 | dissectors' handoff tables, and fetch any dissector handles
662 | they need. */
663 | if (handoff_func != NULL((void*)0))
664 | handoff_func(cb, client_data);
665 |
666 | /* Now do the same with epan plugins. */
667 | for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
668 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
669 | }
670 |
671 | /* Now do the same with dissector plugins. */
672 | if (cb)
673 | (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
674 | g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
675 |
676 | /* sort the protocols by protocol name */
677 | protocols = g_list_sort(protocols, proto_compare_name);
678 |
679 | /* sort the dissector handles in dissector tables (for -G reports
680 | * and -d error messages. The GUI sorts the handles itself.) */
681 | packet_all_tables_sort_handles();
682 |
683 | /* We've assigned all the subtree type values; allocate the array
684 | for them, and zero it out. */
685 | 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 )));
686 | }
687 |
688 | static void
689 | proto_cleanup_base(void)
690 | {
691 | protocol_t *protocol;
692 | header_field_info *hfinfo;
693 |
694 | /* Free the abbrev/ID hash table */
695 | if (gpa_name_map) {
696 | // XXX - We don't have a wmem_map_destroy, but
697 | // it does get cleaned up when epan scope is
698 | // destroyed
699 | //g_hash_table_destroy(gpa_name_map);
700 | gpa_name_map = NULL((void*)0);
701 | }
702 | if (gpa_protocol_aliases) {
703 | g_hash_table_destroy(gpa_protocol_aliases);
704 | gpa_protocol_aliases = NULL((void*)0);
705 | }
706 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
707 | last_field_name = NULL((void*)0);
708 |
709 | while (protocols) {
710 | protocol = (protocol_t *)protocols->data;
711 | 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", 711 , __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", 711, "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", 711, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol-> proto_id];;
712 | 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", 712, "protocol->proto_id == hfinfo->id" ))));
713 |
714 | 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);
715 | if (protocol->parent_proto_id != -1) {
716 | // pino protocol
717 | DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 717, "protocol->fields == ((void*)0)" )))); //helpers should not have any registered fields
718 | 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" , 718, "protocol->heur_list == ((void*)0)")))); //helpers should not have a heuristic list
719 | } else {
720 | if (protocol->fields) {
721 | g_ptr_array_free(protocol->fields, true1);
722 | }
723 | g_list_free(protocol->heur_list);
724 | }
725 | protocols = g_list_remove(protocols, protocol);
726 | g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized (protocol, __builtin_object_size ((protocol), 0)) : (g_free) (protocol);
727 | }
728 |
729 | if (proto_names) {
730 | g_hash_table_destroy(proto_names);
731 | proto_names = NULL((void*)0);
732 | }
733 |
734 | if (proto_short_names) {
735 | g_hash_table_destroy(proto_short_names);
736 | proto_short_names = NULL((void*)0);
737 | }
738 |
739 | if (proto_filter_names) {
740 | g_hash_table_destroy(proto_filter_names);
741 | proto_filter_names = NULL((void*)0);
742 | }
743 |
744 | if (proto_reserved_filter_names) {
745 | g_hash_table_destroy(proto_reserved_filter_names);
746 | proto_reserved_filter_names = NULL((void*)0);
747 | }
748 |
749 | if (gpa_hfinfo.allocated_len) {
750 | gpa_hfinfo.len = 0;
751 | gpa_hfinfo.allocated_len = 0;
752 | g_free(gpa_hfinfo.hfi)(__builtin_object_size ((gpa_hfinfo.hfi), 0) != ((size_t) - 1 )) ? g_free_sized (gpa_hfinfo.hfi, __builtin_object_size ((gpa_hfinfo .hfi), 0)) : (g_free) (gpa_hfinfo.hfi);
753 | gpa_hfinfo.hfi = NULL((void*)0);
754 | }
755 |
756 | if (deregistered_fields) {
757 | g_ptr_array_free(deregistered_fields, true1);
758 | deregistered_fields = NULL((void*)0);
759 | }
760 |
761 | if (deregistered_data) {
762 | g_ptr_array_free(deregistered_data, true1);
763 | deregistered_data = NULL((void*)0);
764 | }
765 |
766 | if (deregistered_slice) {
767 | g_ptr_array_free(deregistered_slice, true1);
768 | deregistered_slice = NULL((void*)0);
769 | }
770 |
771 | g_free(tree_is_expanded)(__builtin_object_size ((tree_is_expanded), 0) != ((size_t) - 1)) ? g_free_sized (tree_is_expanded, __builtin_object_size ( (tree_is_expanded), 0)) : (g_free) (tree_is_expanded);
772 | tree_is_expanded = NULL((void*)0);
773 |
774 | if (prefixes)
775 | g_hash_table_destroy(prefixes);
776 |
777 | if (saved_dir_queue != NULL((void*)0)) {
778 | g_queue_clear_full(saved_dir_queue, g_free);
779 | g_queue_free(saved_dir_queue);
780 | saved_dir_queue = NULL((void*)0);
781 | }
782 | }
783 |
784 | void
785 | proto_cleanup(void)
786 | {
787 | proto_free_deregistered_fields();
788 | proto_cleanup_base();
789 |
790 | g_slist_free(dissector_plugins);
791 | dissector_plugins = NULL((void*)0);
792 | }
793 |
794 | static bool_Bool
795 | ws_pushd(const char* dir)
796 | {
797 | //Save the current working directory
798 | const char* save_wd = get_current_working_dir();
799 | if (save_wd != NULL((void*)0))
800 | g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
801 |
802 | //Change to the new one
803 | #ifdef _WIN32
804 | SetCurrentDirectory(utf_8to16(dir));
805 | return true1;
806 | #else
807 | return (chdir(dir) == 0);
808 | #endif
809 | }
810 |
811 | static bool_Bool
812 | ws_popd(void)
813 | {
814 | int ret = 0;
815 | char* saved_wd = g_queue_pop_head(saved_dir_queue);
816 | if (saved_wd == NULL((void*)0))
817 | return false0;
818 |
819 | //Restore the previous one
820 | #ifdef _WIN32
821 | SetCurrentDirectory(utf_8to16(saved_wd));
822 | #else
823 | ret = chdir(saved_wd);
824 | #endif
825 | g_free(saved_wd)(__builtin_object_size ((saved_wd), 0) != ((size_t) - 1)) ? g_free_sized (saved_wd, __builtin_object_size ((saved_wd), 0)) : (g_free) (saved_wd);
826 | return (ret == 0);
827 | }
828 |
829 | void
830 | proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
831 | {
832 | if (ws_pushd(dir))
833 | {
834 | func(param);
835 | ws_popd();
836 | }
837 | }
838 |
839 | static bool_Bool
840 | // NOLINTNEXTLINE(misc-no-recursion)
841 | proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
842 | void *data)
843 | {
844 | proto_node *pnode = tree;
845 | proto_node *child;
846 | proto_node *current;
847 |
848 | if (func(pnode, data))
849 | return true1;
850 |
851 | child = pnode->first_child;
852 | while (child != NULL((void*)0)) {
853 | /*
854 | * The routine we call might modify the child, e.g. by
855 | * freeing it, so we get the child's successor before
856 | * calling that routine.
857 | */
858 | current = child;
859 | child = current->next;
860 | // We recurse here, but we're limited by prefs.gui_max_tree_depth
861 | if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
862 | return true1;
863 | }
864 |
865 | return false0;
866 | }
867 |
868 | void
869 | proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
870 | void *data)
871 | {
872 | proto_node *node = tree;
873 | proto_node *current;
874 |
875 | if (!node)
876 | return;
877 |
878 | node = node->first_child;
879 | while (node != NULL((void*)0)) {
880 | current = node;
881 | node = current->next;
882 | func((proto_tree *)current, data);
883 | }
884 | }
885 |
886 | static void
887 | free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
888 | {
889 | GPtrArray *ptrs = (GPtrArray *)value;
890 | int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
891 | header_field_info *hfinfo;
892 |
893 | 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", 893, __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", 893, "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", 893, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
894 | if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
895 | /* when a field is referenced by a filter this also
896 | affects the refcount for the parent protocol so we need
897 | to adjust the refcount for the parent as well
898 | */
899 | if (hfinfo->parent != -1) {
900 | header_field_info *parent_hfinfo;
901 | 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", 901 , __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", 901, "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", 901, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)" , "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo ->parent];;
902 | parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
903 | }
904 | hfinfo->ref_type = HF_REF_TYPE_NONE;
905 | }
906 |
907 | g_ptr_array_free(ptrs, true1);
908 | }
909 |
910 | static void
911 | proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
912 | {
913 | field_info *finfo = PNODE_FINFO(node)((node)->finfo);
914 |
915 | proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
916 |
917 | if (finfo) {
918 | // The fvalue_t structure was allocated using fvalue_new_pool()
919 | // (see new_field_info()) and will be reclaimed when the pool is
920 | // freed, so we only release the type-specific data it owns here.
921 | fvalue_cleanup(finfo->value);
922 | finfo->value = NULL((void*)0);
923 | }
924 | }
925 |
926 | void
927 | proto_tree_reset(proto_tree *tree)
928 | {
929 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
930 |
931 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
932 |
933 | /* free tree data */
934 | if (tree_data->interesting_hfids) {
935 | /* Free all the GPtrArray's in the interesting_hfids hash. */
936 | g_hash_table_foreach(tree_data->interesting_hfids,
937 | free_GPtrArray_value, NULL((void*)0));
938 |
939 | /* And then remove all values. */
940 | g_hash_table_remove_all(tree_data->interesting_hfids);
941 | }
942 |
943 | /* Reset track of the number of children */
944 | tree_data->count = 0;
945 |
946 | /* Reset our loop checks */
947 | tree_data->idle_count_ds_tvb = NULL((void*)0);
948 | tree_data->max_start = 0;
949 | tree_data->start_idle_count = 0;
950 |
951 | PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void *)0); tree->next = ((void*)0);;
952 | }
953 |
954 | /* frees the resources that the dissection a proto_tree uses */
955 | void
956 | proto_tree_free(proto_tree *tree)
957 | {
958 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
959 |
960 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
961 |
962 | /* free tree data */
963 | if (tree_data->interesting_hfids) {
964 | /* Free all the GPtrArray's in the interesting_hfids hash. */
965 | g_hash_table_foreach(tree_data->interesting_hfids,
966 | free_GPtrArray_value, NULL((void*)0));
967 |
968 | /* And then destroy the hash. */
969 | g_hash_table_destroy(tree_data->interesting_hfids);
970 | }
971 |
972 | 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);
973 |
974 | g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else (void) ((proto_tree*) 0 == (tree)); } while (0);
975 | }
976 |
977 | /* Is the parsing being done for a visible proto_tree or an invisible one?
978 | * By setting this correctly, the proto_tree creation is sped up by not
979 | * having to call vsnprintf and copy strings around.
980 | */
981 | bool_Bool
982 | proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
983 | {
984 | bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
985 |
986 | PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
987 |
988 | return old_visible;
989 | }
990 |
991 | void
992 | proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
993 | {
994 | if (tree)
995 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
996 | }
997 |
998 | /* Assume dissector set only its protocol fields.
999 | This function is called by dissectors and allows the speeding up of filtering
1000 | in wireshark; if this function returns false it is safe to reset tree to NULL
1001 | and thus skip calling most of the expensive proto_tree_add_...()
1002 | functions.
1003 | If the tree is visible we implicitly assume the field is referenced.
1004 | */
1005 | bool_Bool
1006 | proto_field_is_referenced(proto_tree *tree, int proto_id)
1007 | {
1008 | register header_field_info *hfinfo;
1009 |
1010 |
1011 | if (!tree)
1012 | return false0;
1013 |
1014 | if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1015 | return true1;
1016 |
1017 | 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", 1017, __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", 1017, "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", 1017, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
1018 | if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1019 | return true1;
1020 |
1021 | if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1022 | return true1;
1023 |
1024 | return false0;
1025 | }
1026 |
1027 |
1028 | /* Finds a record in the hfinfo array by id. */
1029 | header_field_info *
1030 | proto_registrar_get_nth(unsigned hfindex)
1031 | {
1032 | register header_field_info *hfinfo;
1033 |
1034 | 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", 1034, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1034, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1034, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
1035 | return hfinfo;
1036 | }
1037 |
1038 |
1039 | /* Prefix initialization
1040 | * this allows for a dissector to register a display filter name prefix
1041 | * so that it can delay the initialization of the hf array as long as
1042 | * possible.
1043 | */
1044 |
1045 | /* compute a hash for the part before the dot of a display filter */
1046 | static unsigned
1047 | prefix_hash (const void *key) {
1048 | /* end the string at the dot and compute its hash */
1049 | char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1050 | char* c = copy;
1051 | unsigned tmp;
1052 |
1053 | for (; *c; c++) {
1054 | if (*c == '.') {
1055 | *c = 0;
1056 | break;
1057 | }
1058 | }
1059 |
1060 | tmp = wmem_str_hash(copy);
1061 | g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized (copy, __builtin_object_size ((copy), 0)) : (g_free) (copy);
1062 | return tmp;
1063 | }
1064 |
1065 | /* are both strings equal up to the end or the dot? */
1066 | static gboolean
1067 | prefix_equal (const void *ap, const void *bp) {
1068 | const char* a = (const char *)ap;
1069 | const char* b = (const char *)bp;
1070 |
1071 | do {
1072 | char ac = *a++;
1073 | char bc = *b++;
1074 |
1075 | if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1076 |
1077 | if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1078 | if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1079 |
1080 | if (ac != bc) return FALSE(0);
1081 | } while (1);
1082 |
1083 | return FALSE(0);
1084 | }
1085 |
1086 | /* Register a new prefix for "delayed" initialization of field arrays */
1087 | void
1088 | proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1089 | if (! prefixes ) {
1090 | prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1091 | }
1092 |
1093 | g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1094 | }
1095 |
1096 | /* helper to call all prefix initializers */
1097 | static gboolean
1098 | initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1099 | ((prefix_initializer_t)v)((const char *)k);
1100 | return TRUE(!(0));
1101 | }
1102 |
1103 | /** Initialize every remaining uninitialized prefix. */
1104 | void
1105 | proto_initialize_all_prefixes(void) {
1106 | g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1107 | }
1108 |
1109 | /* Finds a record in the hfinfo array by name.
1110 | * If it fails to find it in the already registered fields,
1111 | * it tries to find and call an initializer in the prefixes
1112 | * table and if so it looks again.
1113 | */
1114 |
1115 | header_field_info *
1116 | proto_registrar_get_byname(const char *field_name)
1117 | {
1118 | header_field_info *hfinfo;
1119 | prefix_initializer_t pi;
1120 |
1121 | if (!field_name)
1122 | return NULL((void*)0);
1123 |
1124 | if (g_strcmp0(field_name, last_field_name) == 0) {
1125 | return last_hfinfo;
1126 | }
1127 |
1128 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1129 |
1130 | if (hfinfo) {
1131 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
1132 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1133 | last_hfinfo = hfinfo;
1134 | return hfinfo;
1135 | }
1136 |
1137 | if (!prefixes)
1138 | return NULL((void*)0);
1139 |
1140 | if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1141 | pi(field_name);
1142 | g_hash_table_remove(prefixes, field_name);
1143 | } else {
1144 | return NULL((void*)0);
1145 | }
1146 |
1147 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1148 |
1149 | if (hfinfo) {
1150 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
1151 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1152 | last_hfinfo = hfinfo;
1153 | }
1154 | return hfinfo;
1155 | }
1156 |
1157 | header_field_info*
1158 | proto_registrar_get_byalias(const char *alias_name)
1159 | {
1160 | if (!alias_name) {
1161 | return NULL((void*)0);
1162 | }
1163 |
1164 | /* Find our aliased protocol. */
1165 | char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1166 | char *dot = strchr(an_copy, '.');
1167 | if (dot) {
1168 | *dot = '\0';
1169 | }
1170 | const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1171 | if (!proto_pfx) {
1172 | g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized (an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) ( an_copy);
1173 | return NULL((void*)0);
1174 | }
1175 |
1176 | /* Construct our aliased field and look it up. */
1177 | GString *filter_name = g_string_new(proto_pfx);
1178 | if (dot) {
1179 | g_string_append_printf(filter_name, ".%s", dot+1);
1180 | }
1181 | header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1182 | g_free(an_copy)(__builtin_object_size ((an_copy), 0) != ((size_t) - 1)) ? g_free_sized (an_copy, __builtin_object_size ((an_copy), 0)) : (g_free) ( an_copy);
1183 | 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)))));
1184 |
1185 | return hfinfo;
1186 | }
1187 |
1188 | int
1189 | proto_registrar_get_id_byname(const char *field_name)
1190 | {
1191 | header_field_info *hfinfo;
1192 |
1193 | hfinfo = proto_registrar_get_byname(field_name);
1194 |
1195 | if (!hfinfo)
1196 | return -1;
1197 |
1198 | return hfinfo->id;
1199 | }
1200 |
1201 | static int
1202 | label_strcat_flags(const header_field_info *hfinfo)
1203 | {
1204 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1205 | return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1206 |
1207 | return 0;
1208 | }
1209 |
1210 | static char *
1211 | format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1212 | const uint8_t *bytes, unsigned length, size_t max_str_len)
1213 | {
1214 | char *str = NULL((void*)0);
1215 | const uint8_t *p;
1216 | bool_Bool is_printable;
1217 |
1218 | if (bytes) {
1219 | if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1220 | /*
1221 | * If all bytes are valid and printable UTF-8, show the
1222 | * bytes as a string - in quotes to indicate that it's
1223 | * a string.
1224 | */
1225 | if (isprint_utf8_string((const char*)bytes, length)) {
1226 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1227 | (int)length, bytes);
1228 | return str;
1229 | }
1230 | } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1231 | /*
1232 | * Check whether all bytes are printable.
1233 | */
1234 | is_printable = true1;
1235 | for (p = bytes; p < bytes+length; p++) {
1236 | if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1237 | /* Not printable. */
1238 | is_printable = false0;
1239 | break;
1240 | }
1241 | }
1242 |
1243 | /*
1244 | * If all bytes are printable ASCII, show the bytes
1245 | * as a string - in quotes to indicate that it's
1246 | * a string.
1247 | */
1248 | if (is_printable) {
1249 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1250 | (int)length, bytes);
1251 | return str;
1252 | }
1253 | }
1254 |
1255 | /*
1256 | * Either it's not printable ASCII, or we don't care whether
1257 | * it's printable ASCII; show it as hex bytes.
1258 | */
1259 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1260 | case SEP_DOT:
1261 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1262 | break;
1263 | case SEP_DASH:
1264 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1265 | break;
1266 | case SEP_COLON:
1267 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1268 | break;
1269 | case SEP_SPACE:
1270 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1271 | break;
1272 | case BASE_NONE:
1273 | default:
1274 | if (prefs.display_byte_fields_with_spaces) {
1275 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1276 | } else {
1277 | str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1278 | }
1279 | break;
1280 | }
1281 | }
1282 | else {
1283 | if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1284 | str = wmem_strdup(scope, "<none>");
1285 | } else {
1286 | str = wmem_strdup(scope, "<MISSING>");
1287 | }
1288 | }
1289 | return str;
1290 | }
1291 |
1292 | static char *
1293 | format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1294 | const uint8_t *bytes, unsigned length)
1295 | {
1296 | return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1297 | }
1298 |
1299 | static void
1300 | ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1301 | {
1302 | subtree_lvl *pushed_tree;
1303 |
1304 | 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" , 1304, "ptvc->pushed_tree_max <= 256-8"))));
1305 | ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1306 |
1307 | pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1308 | DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1308, "pushed_tree != ((void*)0)" ))));
1309 | ptvc->pushed_tree = pushed_tree;
1310 | }
1311 |
1312 | static void
1313 | ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1314 | {
1315 | ptvc->pushed_tree = NULL((void*)0);
1316 | ptvc->pushed_tree_max = 0;
1317 | 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", 1317, "ptvc->pushed_tree_index == 0" ))));
1318 | ptvc->pushed_tree_index = 0;
1319 | }
1320 |
1321 | /* Allocates an initializes a ptvcursor_t with 3 variables:
1322 | * proto_tree, tvbuff, and offset. */
1323 | ptvcursor_t *
1324 | ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1325 | {
1326 | ptvcursor_t *ptvc;
1327 |
1328 | ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1329 | ptvc->scope = scope;
1330 | ptvc->tree = tree;
1331 | ptvc->tvb = tvb;
1332 | ptvc->offset = offset;
1333 | ptvc->pushed_tree = NULL((void*)0);
1334 | ptvc->pushed_tree_max = 0;
1335 | ptvc->pushed_tree_index = 0;
1336 | return ptvc;
1337 | }
1338 |
1339 |
1340 | /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1341 | void
1342 | ptvcursor_free(ptvcursor_t *ptvc)
1343 | {
1344 | ptvcursor_free_subtree_levels(ptvc);
1345 | wmem_free(ptvc->scope, ptvc);
1346 | }
1347 |
1348 | /* Returns tvbuff. */
1349 | tvbuff_t *
1350 | ptvcursor_tvbuff(ptvcursor_t *ptvc)
1351 | {
1352 | return ptvc->tvb;
1353 | }
1354 |
1355 | /* Returns current offset. */
1356 | unsigned
1357 | ptvcursor_current_offset(ptvcursor_t *ptvc)
1358 | {
1359 | return ptvc->offset;
1360 | }
1361 |
1362 | proto_tree *
1363 | ptvcursor_tree(ptvcursor_t *ptvc)
1364 | {
1365 | if (!ptvc)
1366 | return NULL((void*)0);
1367 |
1368 | return ptvc->tree;
1369 | }
1370 |
1371 | void
1372 | ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1373 | {
1374 | ptvc->tree = tree;
1375 | }
1376 |
1377 | /* creates a subtree, sets it as the working tree and pushes the old working tree */
1378 | proto_tree *
1379 | ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1380 | {
1381 | subtree_lvl *subtree;
1382 | if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1383 | ptvcursor_new_subtree_levels(ptvc);
1384 |
1385 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1386 | subtree->tree = ptvc->tree;
1387 | subtree->it= NULL((void*)0);
1388 | ptvc->pushed_tree_index++;
1389 | return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1390 | }
1391 |
1392 | /* pops a subtree */
1393 | void
1394 | ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1395 | {
1396 | subtree_lvl *subtree;
1397 |
1398 | if (ptvc->pushed_tree_index <= 0)
1399 | return;
1400 |
1401 | ptvc->pushed_tree_index--;
1402 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1403 | if (subtree->it != NULL((void*)0))
1404 | proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1405 |
1406 | ptvc->tree = subtree->tree;
1407 | }
1408 |
1409 | /* saves the current tvb offset and the item in the current subtree level */
1410 | static void
1411 | ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1412 | {
1413 | subtree_lvl *subtree;
1414 |
1415 | 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", 1415, "ptvc->pushed_tree_index > 0" ))));
1416 |
1417 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1418 | subtree->it = it;
1419 | subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1420 | }
1421 |
1422 | /* Creates a subtree and adds it to the cursor as the working tree but does not
1423 | * save the old working tree */
1424 | proto_tree *
1425 | ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1426 | {
1427 | ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1428 | return ptvc->tree;
1429 | }
1430 |
1431 | static proto_tree *
1432 | ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1433 | {
1434 | ptvcursor_push_subtree(ptvc, it, ett_subtree);
1435 | if (length == SUBTREE_UNDEFINED_LENGTH-1)
1436 | ptvcursor_subtree_set_item(ptvc, it);
1437 | return ptvcursor_tree(ptvc);
1438 | }
1439 |
1440 | /* Add an item to the tree and create a subtree
1441 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1442 | * In this case, when the subtree will be closed, the parent item length will
1443 | * be equal to the advancement of the cursor since the creation of the subtree.
1444 | */
1445 | proto_tree *
1446 | ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1447 | const unsigned encoding, int ett_subtree)
1448 | {
1449 | proto_item *it;
1450 |
1451 | it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1452 | return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1453 | }
1454 |
1455 | static proto_item *
1456 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1457 |
1458 | /* Add a text node to the tree and create a subtree
1459 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1460 | * In this case, when the subtree will be closed, the item length will be equal
1461 | * to the advancement of the cursor since the creation of the subtree.
1462 | */
1463 | proto_tree *
1464 | ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1465 | int ett_subtree, const char *format, ...)
1466 | {
1467 | proto_item *pi;
1468 | va_list ap;
1469 | header_field_info *hfinfo;
1470 | proto_tree *tree;
1471 |
1472 | tree = ptvcursor_tree(ptvc);
1473 |
1474 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1475 |
1476 | 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", 1476 , __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", 1476, "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", 1476, "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", 1476, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
1477 |
1478 | pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1479 | ptvcursor_current_offset(ptvc), length);
1480 |
1481 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1481, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1482 |
1483 | va_start(ap, format)__builtin_va_start(ap, format);
1484 | proto_tree_set_representation(pi, format, ap);
1485 | va_end(ap)__builtin_va_end(ap);
1486 |
1487 | return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1488 | }
1489 |
1490 | /* Add a text-only node, leaving it to our caller to fill the text in */
1491 | static proto_item *
1492 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1493 | {
1494 | proto_item *pi;
1495 |
1496 | if (tree == NULL((void*)0))
1497 | return NULL((void*)0);
1498 |
1499 | pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1500 |
1501 | return pi;
1502 | }
1503 |
1504 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1505 | proto_item *
1506 | proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length,
1507 | const char *format, ...)
1508 | {
1509 | proto_item *pi;
1510 | va_list ap;
1511 | header_field_info *hfinfo;
1512 |
1513 | tvb_ensure_bytes_exist(tvb, start, length);
1514 |
1515 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1516 |
1517 | 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", 1517 , __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", 1517, "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", 1517, "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", 1517, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
1518 |
1519 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1520 |
1521 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1521, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1522 |
1523 | va_start(ap, format)__builtin_va_start(ap, format);
1524 | proto_tree_set_representation(pi, format, ap);
1525 | va_end(ap)__builtin_va_end(ap);
1526 |
1527 | return pi;
1528 | }
1529 |
1530 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1531 | proto_item *
1532 | proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1533 | unsigned length, const char *format, va_list ap)
1534 | {
1535 | proto_item *pi;
1536 | header_field_info *hfinfo;
1537 |
1538 | /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1539 | * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1540 | * the length to be what's in the tvbuff if length is -1, and the
1541 | * minimum of length and what's in the tvbuff if not.
1542 | */
1543 |
1544 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1545 |
1546 | TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || ( unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1546 , __func__, "Unregistered hf! index=%d", hf_text_only); ((void ) ((hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1546, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only ] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1546, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only ];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1546, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
1547 |
1548 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1549 |
1550 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1550, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1551 |
1552 | proto_tree_set_representation(pi, format, ap);
1553 |
1554 | return pi;
1555 | }
1556 |
1557 | /* Add a text-only node that creates a subtree underneath.
1558 | */
1559 | proto_tree *
1560 | proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1561 | {
1562 | return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1563 | }
1564 |
1565 | /* Add a text-only node that creates a subtree underneath.
1566 | */
1567 | proto_tree *
1568 | proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1569 | {
1570 | proto_tree *pt;
1571 | proto_item *pi;
1572 | va_list ap;
1573 |
1574 | if (length == -1) {
1575 | length = tvb_captured_length_remaining(tvb, start);
1576 | }
1577 |
1578 | va_start(ap, format)__builtin_va_start(ap, format);
1579 | pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1580 | va_end(ap)__builtin_va_end(ap);
1581 |
1582 | if (tree_item != NULL((void*)0))
1583 | *tree_item = pi;
1584 |
1585 | pt = proto_item_add_subtree(pi, idx);
1586 |
1587 | return pt;
1588 | }
1589 |
1590 | /* Add a text-only node for debugging purposes. The caller doesn't need
1591 | * to worry about tvbuff, start, or length. Debug message gets sent to
1592 | * STDOUT, too */
1593 | proto_item *
1594 | proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1595 | {
1596 | proto_item *pi;
1597 | va_list ap;
1598 |
1599 | pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1600 |
1601 | if (pi) {
1602 | va_start(ap, format)__builtin_va_start(ap, format);
1603 | proto_tree_set_representation(pi, format, ap);
1604 | va_end(ap)__builtin_va_end(ap);
1605 | }
1606 | va_start(ap, format)__builtin_va_start(ap, format);
1607 | vprintf(format, ap);
1608 | va_end(ap)__builtin_va_end(ap);
1609 | printf("\n");
1610 |
1611 | return pi;
1612 | }
1613 |
1614 | proto_item *
1615 | proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1616 | {
1617 | proto_item *pi;
1618 | header_field_info *hfinfo;
1619 |
1620 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1621 |
1622 | 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", 1622 , __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", 1622, "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", 1622, "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", 1622, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
1623 |
1624 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1625 |
1626 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1626, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1627 |
1628 | proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1629 |
1630 | return pi;
1631 | }
1632 |
1633 | proto_item *
1634 | proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1635 | {
1636 | proto_item *pi;
1637 | header_field_info *hfinfo;
1638 | char *str;
1639 |
1640 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1641 |
1642 | 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", 1642 , __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", 1642, "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", 1642, "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", 1642, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
1643 |
1644 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1645 |
1646 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1646, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1647 |
1648 | str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1649 | proto_item_set_text(pi, "%s", str);
1650 | wmem_free(NULL((void*)0), str);
1651 |
1652 | return pi;
1653 | }
1654 |
1655 | void proto_report_dissector_bug(const char *format, ...)
1656 | {
1657 | va_list args;
1658 |
1659 | if (wireshark_abort_on_dissector_bug) {
1660 | /*
1661 | * Try to have the error message show up in the crash
1662 | * information.
1663 | */
1664 | va_start(args, format)__builtin_va_start(args, format);
1665 | ws_vadd_crash_info(format, args);
1666 | va_end(args)__builtin_va_end(args);
1667 |
1668 | /*
1669 | * Print the error message.
1670 | */
1671 | va_start(args, format)__builtin_va_start(args, format);
1672 | vfprintf(stderrstderr, format, args);
1673 | va_end(args)__builtin_va_end(args);
1674 | putc('\n', stderrstderr);
1675 |
1676 | /*
1677 | * And crash.
1678 | */
1679 | abort();
1680 | } else {
1681 | va_start(args, format)__builtin_va_start(args, format);
1682 | VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1683 | va_end(args)__builtin_va_end(args);
1684 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1684 , __func__, "assertion \"not reached\" failed"); /* GCC 12 with ASAN needs this. */
1685 | }
1686 | }
1687 |
1688 | /* We could probably get away with changing is_error to a minimum length value. */
1689 | static void
1690 | report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1691 | {
1692 | if (is_error) {
1693 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1694 | } else {
1695 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1696 | }
1697 |
1698 | if (is_error) {
1699 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1700 | }
1701 | }
1702 |
1703 | static uint32_t
1704 | get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1705 | {
1706 | uint32_t value;
1707 | bool_Bool length_error;
1708 |
1709 | switch (length) {
1710 |
1711 | case 1:
1712 | value = tvb_get_uint8(tvb, offset);
1713 | if (encoding & ENC_ZIGBEE0x40000000) {
1714 | if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1715 | value = 0;
1716 | }
1717 | }
1718 | break;
1719 |
1720 | case 2:
1721 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1722 | : tvb_get_ntohs(tvb, offset);
1723 | if (encoding & ENC_ZIGBEE0x40000000) {
1724 | if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1725 | value = 0;
1726 | }
1727 | }
1728 | break;
1729 |
1730 | case 3:
1731 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1732 | : tvb_get_ntoh24(tvb, offset);
1733 | break;
1734 |
1735 | case 4:
1736 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1737 | : tvb_get_ntohl(tvb, offset);
1738 | break;
1739 |
1740 | default:
1741 | if (length < 1) {
1742 | length_error = true1;
1743 | value = 0;
1744 | } else {
1745 | length_error = false0;
1746 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1747 | : tvb_get_ntohl(tvb, offset);
1748 | }
1749 | report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1750 | break;
1751 | }
1752 | return value;
1753 | }
1754 |
1755 | static inline uint64_t
1756 | get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1757 | {
1758 | uint64_t value;
1759 |
1760 | value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1761 |
1762 | if (length < 1 || length > 8) {
1763 | report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1764 | }
1765 |
1766 | return value;
1767 | }
1768 |
1769 | static int32_t
1770 | get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1771 | {
1772 | int32_t value;
1773 | bool_Bool length_error;
1774 |
1775 | switch (length) {
1776 |
1777 | case 1:
1778 | value = tvb_get_int8(tvb, offset);
1779 | break;
1780 |
1781 | case 2:
1782 | value = encoding ? tvb_get_letohis(tvb, offset)
1783 | : tvb_get_ntohis(tvb, offset);
1784 | break;
1785 |
1786 | case 3:
1787 | value = encoding ? tvb_get_letohi24(tvb, offset)
1788 | : tvb_get_ntohi24(tvb, offset);
1789 | break;
1790 |
1791 | case 4:
1792 | value = encoding ? tvb_get_letohil(tvb, offset)
1793 | : tvb_get_ntohil(tvb, offset);
1794 | break;
1795 |
1796 | default:
1797 | if (length < 1) {
1798 | length_error = true1;
1799 | value = 0;
1800 | } else {
1801 | length_error = false0;
1802 | value = encoding ? tvb_get_letohil(tvb, offset)
1803 | : tvb_get_ntohil(tvb, offset);
1804 | }
1805 | report_type_length_mismatch(tree, "a signed integer", length, length_error);
1806 | break;
1807 | }
1808 | return value;
1809 | }
1810 |
1811 | /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1812 | * be cast-able as a int64_t. This is weird, but what the code has always done.
1813 | */
1814 | static inline uint64_t
1815 | get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1816 | {
1817 | uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1818 |
1819 | switch (length) {
1820 | case 7:
1821 | value = ws_sign_ext64(value, 56);
1822 | break;
1823 | case 6:
1824 | value = ws_sign_ext64(value, 48);
1825 | break;
1826 | case 5:
1827 | value = ws_sign_ext64(value, 40);
1828 | break;
1829 | case 4:
1830 | value = ws_sign_ext64(value, 32);
1831 | break;
1832 | case 3:
1833 | value = ws_sign_ext64(value, 24);
1834 | break;
1835 | case 2:
1836 | value = ws_sign_ext64(value, 16);
1837 | break;
1838 | case 1:
1839 | value = ws_sign_ext64(value, 8);
1840 | break;
1841 | }
1842 |
1843 | return value;
1844 | }
1845 |
1846 | /* For FT_STRING */
1847 | static inline const uint8_t *
1848 | get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1849 | int length, unsigned *ret_length, const unsigned encoding)
1850 | {
1851 | if (length == -1) {
1852 | *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1853 | } else {
1854 | *ret_length = length;
1855 | }
1856 | return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1857 | }
1858 |
1859 | /* For FT_STRINGZ */
1860 | static inline const uint8_t *
1861 | get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1862 | unsigned start, int length, unsigned *ret_length, const unsigned encoding)
1863 | {
1864 | const uint8_t *value;
1865 |
1866 | if (length < -1) {
1867 | report_type_length_mismatch(tree, "a string", length, true1);
1868 | }
1869 |
1870 | /* XXX - Ideally, every "null-terminated string which fits into a
1871 | * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1872 | * as appropriate, not a FT_STRINGZ. If so, then we could always call
1873 | * tvb_get_stringz_enc here. Failing that, we could treat length 0
1874 | * as unknown length as well (since there is a trailing '\0', the real
1875 | * length is never zero), allowing switching to unsigned lengths.
1876 | */
1877 | if (length == -1) {
1878 | /* This can throw an exception */
1879 | value = tvb_get_stringz_enc(scope, tvb, start, ret_length, encoding);
1880 | } else {
1881 | /* In this case, length signifies the length of the string.
1882 | *
1883 | * This could either be a null-padded string, which doesn't
1884 | * necessarily have a '\0' at the end, or a null-terminated
1885 | * string, with a trailing '\0'. (Yes, there are cases
1886 | * where you have a string that's both counted and null-
1887 | * terminated.)
1888 | *
1889 | * In the first case, we must allocate a buffer of length
1890 | * "length+1", to make room for a trailing '\0'.
1891 | *
1892 | * In the second case, we don't assume that there is a
1893 | * trailing '\0' there, as the packet might be malformed.
1894 | * (XXX - should we throw an exception if there's no
1895 | * trailing '\0'?) Therefore, we allocate a buffer of
1896 | * length "length+1", and put in a trailing '\0', just to
1897 | * be safe.
1898 | *
1899 | * (XXX - this would change if we made string values counted
1900 | * rather than null-terminated.)
1901 | */
1902 | *ret_length = length;
1903 | value = tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1904 | }
1905 | return value;
1906 | }
1907 |
1908 | /* For FT_UINT_STRING */
1909 | static inline const uint8_t *
1910 | get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1911 | tvbuff_t *tvb, unsigned start, int length, unsigned *ret_length,
1912 | const unsigned encoding)
1913 | {
1914 | uint32_t n;
1915 | const uint8_t *value;
1916 |
1917 | /* I believe it's ok if this is called with a NULL tree */
1918 | n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1919 | value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1920 | *ret_length = length + n;
1921 | return value;
1922 | }
1923 |
1924 | /* For FT_STRINGZPAD */
1925 | static inline const uint8_t *
1926 | get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1927 | int length, unsigned *ret_length, const unsigned encoding)
1928 | {
1929 | /*
1930 | * XXX - currently, string values are null-
1931 | * terminated, so a "zero-padded" string
1932 | * isn't special. If we represent string
1933 | * values as something that includes a counted
1934 | * array of bytes, we'll need to strip the
1935 | * trailing NULs.
1936 | */
1937 | if (length == -1) {
1938 | *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1939 | } else {
1940 | *ret_length = length;
1941 | }
1942 | return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1943 | }
1944 |
1945 | /* For FT_STRINGZTRUNC */
1946 | static inline const uint8_t *
1947 | get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1948 | int length, unsigned *ret_length, const unsigned encoding)
1949 | {
1950 | /*
1951 | * XXX - currently, string values are null-
1952 | * terminated, so a "zero-truncated" string
1953 | * isn't special. If we represent string
1954 | * values as something that includes a counted
1955 | * array of bytes, we'll need to strip everything
1956 | * starting with the terminating NUL.
1957 | */
1958 | if (length == -1) {
1959 | *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1960 | } else {
1961 | *ret_length = length;
1962 | }
1963 | return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1964 | }
1965 |
1966 | /*
1967 | * Deltas between the epochs for various non-UN*X time stamp formats and
1968 | * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1969 | * stamp format.
1970 | */
1971 |
1972 | /*
1973 | * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1974 | * XXX - if it's OK if this is unsigned, can we just use
1975 | * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1976 | */
1977 | #define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1978 |
1979 | /*
1980 | * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1981 | */
1982 | #define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1983 |
1984 | /* this can be called when there is no tree, so tree may be null */
1985 | static void
1986 | get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1987 | const int length, const unsigned encoding, nstime_t *time_stamp,
1988 | const bool_Bool is_relative)
1989 | {
1990 | uint32_t tmpsecs;
1991 | uint64_t tmp64secs;
1992 | uint64_t todusecs;
1993 |
1994 | switch (encoding) {
1995 |
1996 | case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1997 | /*
1998 | * If the length is 16, 8-byte seconds, followed
1999 | * by 8-byte fractional time in nanoseconds,
2000 | * both big-endian.
2001 | *
2002 | * If the length is 12, 8-byte seconds, followed
2003 | * by 4-byte fractional time in nanoseconds,
2004 | * both big-endian.
2005 | *
2006 | * If the length is 8, 4-byte seconds, followed
2007 | * by 4-byte fractional time in nanoseconds,
2008 | * both big-endian.
2009 | *
2010 | * For absolute times, the seconds are seconds
2011 | * since the UN*X epoch.
2012 | */
2013 | if (length == 16) {
2014 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2015 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2016 | } else if (length == 12) {
2017 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2018 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2019 | } else if (length == 8) {
2020 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2021 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2022 | } else if (length == 4) {
2023 | /*
2024 | * Backwards compatibility.
2025 | * ENC_TIME_SECS_NSECS is 0; using
2026 | * ENC_BIG_ENDIAN by itself with a 4-byte
2027 | * time-in-seconds value was done in the
2028 | * past.
2029 | */
2030 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2031 | time_stamp->nsecs = 0;
2032 | } else {
2033 | time_stamp->secs = 0;
2034 | time_stamp->nsecs = 0;
2035 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2036 | }
2037 | break;
2038 |
2039 | case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2040 | /*
2041 | * If the length is 16, 8-byte seconds, followed
2042 | * by 8-byte fractional time in nanoseconds,
2043 | * both little-endian.
2044 | *
2045 | * If the length is 12, 8-byte seconds, followed
2046 | * by 4-byte fractional time in nanoseconds,
2047 | * both little-endian.
2048 | *
2049 | * If the length is 8, 4-byte seconds, followed
2050 | * by 4-byte fractional time in nanoseconds,
2051 | * both little-endian.
2052 | *
2053 | * For absolute times, the seconds are seconds
2054 | * since the UN*X epoch.
2055 | */
2056 | if (length == 16) {
2057 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2058 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2059 | } else if (length == 12) {
2060 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2061 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2062 | } else if (length == 8) {
2063 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2064 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2065 | } else if (length == 4) {
2066 | /*
2067 | * Backwards compatibility.
2068 | * ENC_TIME_SECS_NSECS is 0; using
2069 | * ENC_LITTLE_ENDIAN by itself with a 4-byte
2070 | * time-in-seconds value was done in the
2071 | * past.
2072 | */
2073 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2074 | time_stamp->nsecs = 0;
2075 | } else {
2076 | time_stamp->secs = 0;
2077 | time_stamp->nsecs = 0;
2078 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2079 | }
2080 | break;
2081 |
2082 | case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2083 | /*
2084 | * NTP time stamp, big-endian.
2085 | * Only supported for absolute times.
2086 | */
2087 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2087, "!is_relative" ))));
2088 |
2089 | /* We need a temporary variable here so the unsigned math
2090 | * works correctly (for years > 2036 according to RFC 2030
2091 | * chapter 3).
2092 | *
2093 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2094 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2095 | * If bit 0 is not set, the time is in the range 2036-2104 and
2096 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2097 | */
2098 | tmpsecs = tvb_get_ntohl(tvb, start);
2099 | if ((tmpsecs & 0x80000000) != 0)
2100 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2101 | else
2102 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2103 |
2104 | if (length == 8) {
2105 | tmp64secs = tvb_get_ntoh64(tvb, start);
2106 | if (tmp64secs == 0) {
2107 | //This is "NULL" time
2108 | time_stamp->secs = 0;
2109 | time_stamp->nsecs = 0;
2110 | } else {
2111 | /*
2112 | * Convert 1/2^32s of a second to
2113 | * nanoseconds.
2114 | */
2115 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2116 | }
2117 | } else if (length == 4) {
2118 | /*
2119 | * Backwards compatibility.
2120 | */
2121 | if (tmpsecs == 0) {
2122 | //This is "NULL" time
2123 | time_stamp->secs = 0;
2124 | }
2125 | time_stamp->nsecs = 0;
2126 | } else {
2127 | time_stamp->secs = 0;
2128 | time_stamp->nsecs = 0;
2129 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2130 | }
2131 | break;
2132 |
2133 | case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2134 | /*
2135 | * NTP time stamp, little-endian.
2136 | * Only supported for absolute times.
2137 | *
2138 | * NTP doesn't use this, because it's an Internet format
2139 | * and hence big-endian. Any implementation must decide
2140 | * whether the NTP timestamp is a 64-bit unsigned fixed
2141 | * point number (RFC 1305, RFC 4330) or a 64-bit struct
2142 | * with a 32-bit unsigned seconds field followed by a
2143 | * 32-bit fraction field (cf. RFC 5905, which obsoletes
2144 | * the previous two).
2145 | *
2146 | * XXX: We do the latter, but no dissector uses this format.
2147 | * OTOH, ERF timestamps do the former, so perhaps we
2148 | * should switch the interpretation so that packet-erf.c
2149 | * could use this directly? (ENC_TIME_RTPS is this 64-bit
2150 | * struct with two 32-bit fields, but with the UN*X epoch.)
2151 | */
2152 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2152, "!is_relative" ))));
2153 |
2154 | /* We need a temporary variable here so the unsigned math
2155 | * works correctly (for years > 2036 according to RFC 2030
2156 | * chapter 3).
2157 | *
2158 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2159 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2160 | * If bit 0 is not set, the time is in the range 2036-2104 and
2161 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2162 | */
2163 | tmpsecs = tvb_get_letohl(tvb, start);
2164 | if ((tmpsecs & 0x80000000) != 0)
2165 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2166 | else
2167 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2168 |
2169 | if (length == 8) {
2170 | tmp64secs = tvb_get_letoh64(tvb, start);
2171 | if (tmp64secs == 0) {
2172 | //This is "NULL" time
2173 | time_stamp->secs = 0;
2174 | time_stamp->nsecs = 0;
2175 | } else {
2176 | /*
2177 | * Convert 1/2^32s of a second to
2178 | * nanoseconds.
2179 | */
2180 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2181 | }
2182 | } else if (length == 4) {
2183 | /*
2184 | * Backwards compatibility.
2185 | */
2186 | if (tmpsecs == 0) {
2187 | //This is "NULL" time
2188 | time_stamp->secs = 0;
2189 | }
2190 | time_stamp->nsecs = 0;
2191 | } else {
2192 | time_stamp->secs = 0;
2193 | time_stamp->nsecs = 0;
2194 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2195 | }
2196 | break;
2197 |
2198 | case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2199 | /*
2200 | * S/3x0 and z/Architecture TOD clock time stamp,
2201 | * big-endian. The epoch is January 1, 1900,
2202 | * 00:00:00 (proleptic?) UTC.
2203 | *
2204 | * Only supported for absolute times.
2205 | */
2206 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2206, "!is_relative" ))));
2207 | DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2207, "length == 8" ))));
2208 |
2209 | if (length == 8) {
2210 | todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2211 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2212 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2213 | } else {
2214 | time_stamp->secs = 0;
2215 | time_stamp->nsecs = 0;
2216 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2217 | }
2218 | break;
2219 |
2220 | case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2221 | /*
2222 | * S/3x0 and z/Architecture TOD clock time stamp,
2223 | * little-endian. The epoch is January 1, 1900,
2224 | * 00:00:00 (proleptic?) UTC.
2225 | *
2226 | * Only supported for absolute times.
2227 | */
2228 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2228, "!is_relative" ))));
2229 |
2230 | if (length == 8) {
2231 | todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2232 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2233 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2234 | } else {
2235 | time_stamp->secs = 0;
2236 | time_stamp->nsecs = 0;
2237 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2238 | }
2239 | break;
2240 |
2241 | case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2242 | /*
2243 | * Time stamp using the same seconds/fraction format
2244 | * as NTP, but with the origin of the time stamp being
2245 | * the UNIX epoch rather than the NTP epoch; big-
2246 | * endian.
2247 | *
2248 | * Only supported for absolute times.
2249 | */
2250 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2250, "!is_relative" ))));
2251 |
2252 | if (length == 8) {
2253 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2254 | /*
2255 | * Convert 1/2^32s of a second to nanoseconds.
2256 | */
2257 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2258 | } else {
2259 | time_stamp->secs = 0;
2260 | time_stamp->nsecs = 0;
2261 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2262 | }
2263 | break;
2264 |
2265 | case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2266 | /*
2267 | * Time stamp using the same seconds/fraction format
2268 | * as NTP, but with the origin of the time stamp being
2269 | * the UNIX epoch rather than the NTP epoch; little-
2270 | * endian.
2271 | *
2272 | * Only supported for absolute times.
2273 | *
2274 | * The RTPS specification explicitly supports Little
2275 | * Endian encoding. In one place, it states that its
2276 | * Time_t representation "is the one defined by ...
2277 | * RFC 1305", but in another explicitly defines it as
2278 | * a struct consisting of an 32 bit unsigned seconds
2279 | * field and a 32 bit unsigned fraction field, not a 64
2280 | * bit fixed point, so we do that here.
2281 | * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2282 | */
2283 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2283, "!is_relative" ))));
2284 |
2285 | if (length == 8) {
2286 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2287 | /*
2288 | * Convert 1/2^32s of a second to nanoseconds.
2289 | */
2290 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2291 | } else {
2292 | time_stamp->secs = 0;
2293 | time_stamp->nsecs = 0;
2294 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2295 | }
2296 | break;
2297 |
2298 | case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2299 | /*
2300 | * MIP6 time stamp, big-endian.
2301 | * A 64-bit unsigned integer field containing a timestamp. The
2302 | * value indicates the number of seconds since January 1, 1970,
2303 | * 00:00 UTC, by using a fixed point format. In this format, the
2304 | * integer number of seconds is contained in the first 48 bits of
2305 | * the field, and the remaining 16 bits indicate the number of
2306 | * 1/65536 fractions of a second.
2307 |
2308 | * Only supported for absolute times.
2309 | */
2310 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2310, "!is_relative" ))));
2311 |
2312 | if (length == 8) {
2313 | /* We need a temporary variable here so the casting and fractions
2314 | * of a second work correctly.
2315 | */
2316 | tmp64secs = tvb_get_ntoh48(tvb, start);
2317 | tmpsecs = tvb_get_ntohs(tvb, start + 6);
2318 | tmpsecs <<= 16;
2319 |
2320 | if ((tmp64secs == 0) && (tmpsecs == 0)) {
2321 | //This is "NULL" time
2322 | time_stamp->secs = 0;
2323 | time_stamp->nsecs = 0;
2324 | } else {
2325 | time_stamp->secs = (time_t)tmp64secs;
2326 | time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2327 | }
2328 | } else {
2329 | time_stamp->secs = 0;
2330 | time_stamp->nsecs = 0;
2331 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2332 | }
2333 | break;
2334 |
2335 | case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2336 | /*
2337 | * If the length is 16, 8-byte seconds, followed
2338 | * by 8-byte fractional time in microseconds,
2339 | * both big-endian.
2340 | *
2341 | * If the length is 12, 8-byte seconds, followed
2342 | * by 4-byte fractional time in microseconds,
2343 | * both big-endian.
2344 | *
2345 | * If the length is 8, 4-byte seconds, followed
2346 | * by 4-byte fractional time in microseconds,
2347 | * both big-endian.
2348 | *
2349 | * For absolute times, the seconds are seconds
2350 | * since the UN*X epoch.
2351 | */
2352 | if (length == 16) {
2353 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2354 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2355 | } else if (length == 12) {
2356 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2357 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2358 | } else if (length == 8) {
2359 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2360 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2361 | } else {
2362 | time_stamp->secs = 0;
2363 | time_stamp->nsecs = 0;
2364 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2365 | }
2366 | break;
2367 |
2368 | case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2369 | /*
2370 | * If the length is 16, 8-byte seconds, followed
2371 | * by 8-byte fractional time in microseconds,
2372 | * both little-endian.
2373 | *
2374 | * If the length is 12, 8-byte seconds, followed
2375 | * by 4-byte fractional time in microseconds,
2376 | * both little-endian.
2377 | *
2378 | * If the length is 8, 4-byte seconds, followed
2379 | * by 4-byte fractional time in microseconds,
2380 | * both little-endian.
2381 | *
2382 | * For absolute times, the seconds are seconds
2383 | * since the UN*X epoch.
2384 | */
2385 | if (length == 16) {
2386 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2387 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2388 | } else if (length == 12) {
2389 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2390 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2391 | } else if (length == 8) {
2392 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2393 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2394 | } else {
2395 | time_stamp->secs = 0;
2396 | time_stamp->nsecs = 0;
2397 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2398 | }
2399 | break;
2400 |
2401 | case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2402 | case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2403 | /*
2404 | * Seconds, 1 to 8 bytes.
2405 | * For absolute times, it's seconds since the
2406 | * UN*X epoch.
2407 | */
2408 | if (length >= 1 && length <= 8) {
2409 | time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2410 | time_stamp->nsecs = 0;
2411 | } else {
2412 | time_stamp->secs = 0;
2413 | time_stamp->nsecs = 0;
2414 | report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2415 | }
2416 | break;
2417 |
2418 | case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2419 | case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2420 | /*
2421 | * Milliseconds, 1 to 8 bytes.
2422 | * For absolute times, it's milliseconds since the
2423 | * UN*X epoch.
2424 | */
2425 | if (length >= 1 && length <= 8) {
2426 | uint64_t msecs;
2427 |
2428 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2429 | time_stamp->secs = (time_t)(msecs / 1000);
2430 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2431 | } else {
2432 | time_stamp->secs = 0;
2433 | time_stamp->nsecs = 0;
2434 | report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2435 | }
2436 | break;
2437 |
2438 | case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2439 | case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2440 | /*
2441 | * Microseconds, 1 to 8 bytes.
2442 | * For absolute times, it's microseconds since the
2443 | * UN*X epoch.
2444 | */
2445 | if (length >= 1 && length <= 8) {
2446 | uint64_t usecs;
2447 |
2448 | usecs = get_uint64_value(tree, tvb, start, length, encoding);
2449 | time_stamp->secs = (time_t)(usecs / 1000000);
2450 | time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2451 | } else {
2452 | time_stamp->secs = 0;
2453 | time_stamp->nsecs = 0;
2454 | report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2455 | }
2456 | break;
2457 |
2458 | case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2459 | case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2460 | /*
2461 | * nanoseconds, 1 to 8 bytes.
2462 | * For absolute times, it's nanoseconds since the
2463 | * UN*X epoch.
2464 | */
2465 |
2466 | if (length >= 1 && length <= 8) {
2467 | uint64_t nsecs;
2468 |
2469 | nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2470 | time_stamp->secs = (time_t)(nsecs / 1000000000);
2471 | time_stamp->nsecs = (int)(nsecs % 1000000000);
2472 | } else {
2473 | time_stamp->secs = 0;
2474 | time_stamp->nsecs = 0;
2475 | report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2476 | }
2477 | break;
2478 |
2479 | case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2480 | /*
2481 | * 1/64ths of a second since the UN*X epoch,
2482 | * big-endian.
2483 | *
2484 | * Only supported for absolute times.
2485 | */
2486 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2486, "!is_relative" ))));
2487 |
2488 | if (length == 8) {
2489 | /*
2490 | * The upper 48 bits are seconds since the
2491 | * UN*X epoch.
2492 | */
2493 | time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2494 | /*
2495 | * The lower 16 bits are 1/2^16s of a second;
2496 | * convert them to nanoseconds.
2497 | *
2498 | * XXX - this may give the impression of higher
2499 | * precision than you actually get.
2500 | */
2501 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2502 | } else {
2503 | time_stamp->secs = 0;
2504 | time_stamp->nsecs = 0;
2505 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2506 | }
2507 | break;
2508 |
2509 | case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2510 | /*
2511 | * 1/64ths of a second since the UN*X epoch,
2512 | * little-endian.
2513 | *
2514 | * Only supported for absolute times.
2515 | */
2516 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2516, "!is_relative" ))));
2517 |
2518 | if (length == 8) {
2519 | /*
2520 | * XXX - this is assuming that, if anybody
2521 | * were ever to use this format - RFC 3971
2522 | * doesn't, because that's an Internet
2523 | * protocol, and those use network byte
2524 | * order, i.e. big-endian - they'd treat it
2525 | * as a 64-bit count of 1/2^16s of a second,
2526 | * putting the upper 48 bits at the end.
2527 | *
2528 | * The lower 48 bits are seconds since the
2529 | * UN*X epoch.
2530 | */
2531 | time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2532 | /*
2533 | * The upper 16 bits are 1/2^16s of a second;
2534 | * convert them to nanoseconds.
2535 | *
2536 | * XXX - this may give the impression of higher
2537 | * precision than you actually get.
2538 | */
2539 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2540 | } else {
2541 | time_stamp->secs = 0;
2542 | time_stamp->nsecs = 0;
2543 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2544 | }
2545 | break;
2546 |
2547 | case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2548 | /*
2549 | * NTP time stamp, with 1-second resolution (i.e.,
2550 | * seconds since the NTP epoch), big-endian.
2551 | * Only supported for absolute times.
2552 | */
2553 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2553, "!is_relative" ))));
2554 |
2555 | if (length == 4) {
2556 | /*
2557 | * We need a temporary variable here so the unsigned math
2558 | * works correctly (for years > 2036 according to RFC 2030
2559 | * chapter 3).
2560 | *
2561 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2562 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2563 | * If bit 0 is not set, the time is in the range 2036-2104 and
2564 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2565 | */
2566 | tmpsecs = tvb_get_ntohl(tvb, start);
2567 | if ((tmpsecs & 0x80000000) != 0)
2568 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2569 | else
2570 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2571 | time_stamp->nsecs = 0;
2572 | } else {
2573 | time_stamp->secs = 0;
2574 | time_stamp->nsecs = 0;
2575 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2576 | }
2577 | break;
2578 |
2579 | case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2580 | /*
2581 | * NTP time stamp, with 1-second resolution (i.e.,
2582 | * seconds since the NTP epoch), little-endian.
2583 | * Only supported for absolute times.
2584 | */
2585 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2585, "!is_relative" ))));
2586 |
2587 | /*
2588 | * We need a temporary variable here so the unsigned math
2589 | * works correctly (for years > 2036 according to RFC 2030
2590 | * chapter 3).
2591 | *
2592 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2593 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2594 | * If bit 0 is not set, the time is in the range 2036-2104 and
2595 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2596 | */
2597 | if (length == 4) {
2598 | tmpsecs = tvb_get_letohl(tvb, start);
2599 | if ((tmpsecs & 0x80000000) != 0)
2600 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2601 | else
2602 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2603 | time_stamp->nsecs = 0;
2604 | } else {
2605 | time_stamp->secs = 0;
2606 | time_stamp->nsecs = 0;
2607 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2608 | }
2609 | break;
2610 |
2611 | case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2612 | /*
2613 | * Milliseconds, 6 to 8 bytes.
2614 | * For absolute times, it's milliseconds since the
2615 | * NTP epoch.
2616 | *
2617 | * ETSI TS 129.274 8.119 defines this as:
2618 | * "a 48 bit unsigned integer in network order format
2619 | * ...encoded as the number of milliseconds since
2620 | * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2621 | * rounded value of 1000 x the value of the 64-bit
2622 | * timestamp (Seconds + (Fraction / (1<<32))) defined
2623 | * in clause 6 of IETF RFC 5905."
2624 | *
2625 | * Taken literally, the part after "i.e." would
2626 | * mean that the value rolls over before reaching
2627 | * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2628 | * when the 64 bit timestamp rolls over, and we have
2629 | * to pick an NTP Era equivalence class to support
2630 | * (such as 1968-01-20 to 2104-02-06).
2631 | *
2632 | * OTOH, the extra room might be used to store Era
2633 | * information instead, in which case times until
2634 | * 10819-08-03 can be represented with 6 bytes without
2635 | * ambiguity. We handle both implementations, and assume
2636 | * that times before 1968-01-20 are not represented.
2637 | *
2638 | * Only 6 bytes or more makes sense as an absolute
2639 | * time. 5 bytes or fewer could express a span of
2640 | * less than 35 years, either 1900-1934 or 2036-2070.
2641 | */
2642 | if (length >= 6 && length <= 8) {
2643 | uint64_t msecs;
2644 |
2645 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2646 | tmp64secs = (msecs / 1000);
2647 | /*
2648 | * Assume that times in the first half of NTP
2649 | * Era 0 really represent times in the NTP
2650 | * Era 1.
2651 | */
2652 | if (tmp64secs >= 0x80000000)
2653 | time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2654 | else
2655 | time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2656 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2657 | }
2658 | else {
2659 | time_stamp->secs = 0;
2660 | time_stamp->nsecs = 0;
2661 | report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2662 | }
2663 | break;
2664 |
2665 | case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2666 | /*
2667 | * MP4 file time stamps, big-endian.
2668 | * Only supported for absolute times.
2669 | */
2670 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2670, "!is_relative" ))));
2671 |
2672 | if (length == 8) {
2673 | tmp64secs = tvb_get_ntoh64(tvb, start);
2674 | time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2675 | time_stamp->nsecs = 0;
2676 | } else if (length == 4) {
2677 | tmpsecs = tvb_get_ntohl(tvb, start);
2678 | time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2679 | time_stamp->nsecs = 0;
2680 | } else {
2681 | time_stamp->secs = 0;
2682 | time_stamp->nsecs = 0;
2683 | report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2684 | }
2685 | break;
2686 |
2687 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2688 | /*
2689 | * Zigbee ZCL time stamps, big-endian.
2690 | * Only supported for absolute times.
2691 | */
2692 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2692, "!is_relative" ))));
2693 |
2694 | if (length == 8) {
2695 | tmp64secs = tvb_get_ntoh64(tvb, start);
2696 | if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmp64secs), (((3*365 + 366)*7 + 2*365 )*24*3600UL), (&time_stamp->secs))) {
2697 | /* There are several other possible choices for what to do
2698 | * with overflow; make sure to coordinate with whatever
2699 | * packet-zbee-zcl.h does. */
2700 | time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) - 1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8 - 1))))));
2701 | }
2702 | time_stamp->nsecs = 0;
2703 | } else if (length == 4) {
2704 | tmpsecs = tvb_get_ntohl(tvb, start);
2705 | if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmpsecs), (((3*365 + 366)*7 + 2*365)* 24*3600UL), (&time_stamp->secs))) {
2706 | time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) - 1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8 - 1))))));
2707 | }
2708 | time_stamp->nsecs = 0;
2709 | } else {
2710 | time_stamp->secs = 0;
2711 | time_stamp->nsecs = 0;
2712 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2713 | }
2714 | break;
2715 |
2716 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2717 | /*
2718 | * Zigbee ZCL time stamps, little-endian.
2719 | * Only supported for absolute times.
2720 | */
2721 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2721, "!is_relative" ))));
2722 |
2723 | if (length == 8) {
2724 | tmp64secs = tvb_get_letoh64(tvb, start);
2725 | if (ckd_add(&time_stamp->secs, tmp64secs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmp64secs), (((3*365 + 366)*7 + 2*365 )*24*3600UL), (&time_stamp->secs))) {
2726 | time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) - 1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8 - 1))))));
2727 | }
2728 | time_stamp->nsecs = 0;
2729 | } else if (length == 4) {
2730 | tmpsecs = tvb_get_letohl(tvb, start);
2731 | if (ckd_add(&time_stamp->secs, tmpsecs, EPOCH_DELTA_2000_01_01_00_00_00_UTC)__builtin_add_overflow((tmpsecs), (((3*365 + 366)*7 + 2*365)* 24*3600UL), (&time_stamp->secs))) {
2732 | time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) - 1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8 - 1))))));
2733 | }
2734 | time_stamp->nsecs = 0;
2735 | } else {
2736 | time_stamp->secs = 0;
2737 | time_stamp->nsecs = 0;
2738 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2739 | }
2740 | break;
2741 |
2742 | case ENC_TIME_WINDOWS0x00000034 | ENC_BIG_ENDIAN0x00000000:
2743 | /*
2744 | * WINDOWS FILETIME, big-endian.
2745 | * Only supported for absolute times.
2746 | * A FILETIME is a struct with the low 32-bits followed
2747 | * by the high 32-bits:
2748 | * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2749 | * There exist cases where the value is stored in a
2750 | * 64-bit integer:
2751 | * (See epan/dissectors/pidl/samr/samr.idl "NTTIME_hyper last_password_change;"
2752 | * which is confirmed as "LARGE_INTEGER PasswordLastSet;" in
2753 | * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/1cd138b9-cc1b-4706-b115-49e53189e32e
2754 | * That doesn't make a difference when retrieving little-endian,
2755 | * because tvb_get_letoh64 handles unaligned accesses and it's
2756 | * otherwise the same. However, for big-endian, it does matter,
2757 | * analogous to the ENC_TIME_NTP little-endian case. We use the
2758 | * struct version, but that means that this MUST NOT be used
2759 | * for dissect_nttime_hyper in packet-windows-common.h, at
2760 | * least
2761 | */
2762 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2762, "!is_relative" ))));
2763 |
2764 | if (length == 8) {
2765 | tmp64secs = tvb_get_ntoh64(tvb, start); // Really 100-ns units
2766 | if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2767 | // With 32-bit time_t, this could overflow in
2768 | // either direction. We should probably add some
2769 | // kind of time overflow expert item to all
2770 | // encodings.
2771 | time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) - 1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8 - 1))))));
2772 | time_stamp->nsecs = 0;
2773 | }
2774 | } else {
2775 | time_stamp->secs = 0;
2776 | time_stamp->nsecs = 0;
2777 | report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2778 | }
2779 | break;
2780 |
2781 | case ENC_TIME_WINDOWS0x00000034 | ENC_LITTLE_ENDIAN0x80000000:
2782 | /*
2783 | * WINDOWS FILETIME, big-endian.
2784 | * Only supported for absolute times.
2785 | * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2786 | */
2787 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2787, "!is_relative" ))));
2788 |
2789 | if (length == 8) {
2790 | tmp64secs = tvb_get_letoh64(tvb, start); // Really 100-ns units
2791 | if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2792 | // With 32-bit time_t, this could overflow in
2793 | // either direction. We should probably add some
2794 | // kind of time overflow expert item to all
2795 | // encodings.
2796 | time_stamp->secs = TIME_T_MAX((time_t) (~ (time_t) 0 - ((time_t) ((time_t)0 < (time_t) - 1 ? (time_t) 0 : (time_t) (~0ULL << (sizeof (time_t) * 8 - 1))))));
2797 | time_stamp->nsecs = 0;
2798 | }
2799 | } else {
2800 | time_stamp->secs = 0;
2801 | time_stamp->nsecs = 0;
2802 | report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2803 | }
2804 | break;
2805 | default:
2806 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 2806));
2807 | break;
2808 | }
2809 | }
2810 |
2811 | static void
2812 | tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2813 | {
2814 | const header_field_info *hfinfo = fi->hfinfo;
2815 |
2816 | if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2817 | GPtrArray *ptrs = NULL((void*)0);
2818 |
2819 | if (tree_data->interesting_hfids == NULL((void*)0)) {
2820 | /* Initialize the hash because we now know that it is needed */
2821 | tree_data->interesting_hfids =
2822 | g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2823 | } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2824 | ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2825 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2826 | }
2827 |
2828 | if (!ptrs) {
2829 | /* First element triggers the creation of pointer array */
2830 | ptrs = g_ptr_array_new();
2831 | g_hash_table_insert(tree_data->interesting_hfids,
2832 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2833 | }
2834 |
2835 | g_ptr_array_add(ptrs, fi);
2836 | }
2837 | }
2838 |
2839 |
2840 | /*
2841 | * Validates that field length bytes are available starting from
2842 | * start (pos/neg). Throws an exception if they aren't.
2843 | */
2844 | static void
2845 | test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2846 | unsigned start, int length, const unsigned encoding)
2847 | {
2848 | int size = length;
2849 |
2850 | if (!tvb)
2851 | return;
2852 |
2853 | if ((hfinfo->type == FT_STRINGZ) ||
2854 | ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2855 | (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 ))))) {
2856 | /* If we're fetching until the end of the TVB, only validate
2857 | * that the offset is within range.
2858 | */
2859 | if (length == -1)
2860 | size = 0;
2861 | }
2862 |
2863 | tvb_ensure_bytes_exist(tvb, start, size);
2864 | }
2865 |
2866 | static void
2867 | detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2868 | {
2869 | bool_Bool found_stray_character = false0;
2870 |
2871 | if (!string)
2872 | return;
2873 |
2874 | switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2875 | case ENC_ASCII0x00000000:
2876 | case ENC_UTF_80x00000002:
2877 | for (int i = (int)strlen(string); i < length; i++) {
2878 | if (string[i] != '\0') {
2879 | found_stray_character = true1;
2880 | break;
2881 | }
2882 | }
2883 | break;
2884 |
2885 | default:
2886 | break;
2887 | }
2888 |
2889 | if (found_stray_character) {
2890 | expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2891 | }
2892 | }
2893 |
2894 | /* Add an item to a proto_tree, using the text label registered to that item;
2895 | the item is extracted from the tvbuff handed to it. */
2896 | static proto_item *
2897 | proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2898 | tvbuff_t *tvb, unsigned start, int length,
2899 | unsigned encoding)
2900 | {
2901 | proto_item *pi;
2902 | uint32_t value, n;
2903 | uint64_t value64;
2904 | ws_in4_addr ipv4_value;
2905 | float floatval;
2906 | double doubleval;
2907 | const char *stringval = NULL((void*)0);
2908 | nstime_t time_stamp;
2909 | bool_Bool length_error;
2910 | unsigned item_length;
1 | 'item_length' declared without an initial value | →
2911 |
2912 | // new_fi->value is allocated from the packet-scoped pool (see
2913 | // new_field_info()), so if a tvbuff accessor below throws before the
2914 | // node is added to the tree the fvalue_t structure is still reclaimed
2915 | // when the pool is freed; no explicit cleanup handler is needed. This
2916 | // relies on the invariant that the type-specific data an fvalue owns
2917 | // (byte arrays, string buffers, ...) is only allocated *after* the
2918 | // throwing tvbuff read that produced it succeeds, so nothing that would
2919 | // need fvalue_cleanup() is ever leaked on the exception path.
2920 | switch (new_fi->hfinfo->type) {
2 | ← | Control jumps to 'case FT_NONE:' at line 2921 | →
2921 | case FT_NONE:
2922 | /* no value to set for FT_NONE */
2923 | break;
2924 |
2925 | case FT_PROTOCOL:
2926 | /* Set the protocol_tvb via the start offset, but include
2927 | * rest of the ds_tvb so that if finfo_set_len is called
2928 | * later it can be lengthened as much as possible. */
2929 | proto_tree_set_protocol_tvb(new_fi, new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0), new_fi->hfinfo->name, length);
2930 | break;
2931 |
2932 | case FT_BYTES:
2933 | proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2934 | break;
2935 |
2936 | case FT_UINT_BYTES:
2937 | n = get_uint_value(tree, tvb, start, length, encoding);
2938 | proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2939 |
2940 | /* Instead of calling proto_item_set_len(), since we don't yet
2941 | * have a proto_item, we set the field_info's length ourselves. */
2942 | new_fi->length = n + length;
2943 | break;
2944 |
2945 | case FT_BOOLEAN:
2946 | /*
2947 | * Map all non-zero values to little-endian for
2948 | * backwards compatibility.
2949 | */
2950 | if (encoding)
2951 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2952 | proto_tree_set_boolean(new_fi,
2953 | get_uint64_value(tree, tvb, start, length, encoding));
2954 | break;
2955 |
2956 | case FT_CHAR:
2957 | /* XXX - make these just FT_UINT? */
2958 | case FT_UINT8:
2959 | case FT_UINT16:
2960 | case FT_UINT24:
2961 | case FT_UINT32:
2962 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2963 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2964 | value = (uint32_t)value64;
2965 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2966 | new_fi->flags |= FI_VARINT0x00040000;
2967 | }
2968 | }
2969 | else {
2970 | /*
2971 | * Map all non-zero values to little-endian for
2972 | * backwards compatibility.
2973 | */
2974 | if (encoding)
2975 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2976 |
2977 | value = get_uint_value(tree, tvb, start, length, encoding);
2978 | }
2979 | proto_tree_set_uint(new_fi, value);
2980 | break;
2981 |
2982 | case FT_UINT40:
2983 | case FT_UINT48:
2984 | case FT_UINT56:
2985 | case FT_UINT64:
2986 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2987 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2988 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2989 | new_fi->flags |= FI_VARINT0x00040000;
2990 | }
2991 | }
2992 | else {
2993 | /*
2994 | * Map all other non-zero values to little-endian for
2995 | * backwards compatibility.
2996 | */
2997 | if (encoding)
2998 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2999 |
3000 | value64 = get_uint64_value(tree, tvb, start, length, encoding);
3001 | }
3002 | proto_tree_set_uint64(new_fi, value64);
3003 | break;
3004 |
3005 | /* XXX - make these just FT_INT? */
3006 | case FT_INT8:
3007 | case FT_INT16:
3008 | case FT_INT24:
3009 | case FT_INT32:
3010 | /*
3011 | * Map all non-zero values to little-endian for
3012 | * backwards compatibility.
3013 | */
3014 | if (encoding)
3015 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3016 | proto_tree_set_int(new_fi,
3017 | get_int_value(tree, tvb, start, length, encoding));
3018 | break;
3019 |
3020 | case FT_INT40:
3021 | case FT_INT48:
3022 | case FT_INT56:
3023 | case FT_INT64:
3024 | /*
3025 | * Map all non-zero values to little-endian for
3026 | * backwards compatibility.
3027 | */
3028 | if (encoding)
3029 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3030 | proto_tree_set_int64(new_fi,
3031 | get_int64_value(tree, tvb, start, length, encoding));
3032 | break;
3033 |
3034 | case FT_IPv4:
3035 | /*
3036 | * Map all non-zero values to little-endian for
3037 | * backwards compatibility.
3038 | */
3039 | if (encoding)
3040 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3041 | if (length != FT_IPv4_LEN4) {
3042 | length_error = length < FT_IPv4_LEN4 ? true1 : false0;
3043 | report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
3044 | }
3045 | ipv4_value = tvb_get_ipv4(tvb, start);
3046 | /*
3047 | * NOTE: to support code written when
3048 | * proto_tree_add_item() took a bool as its
3049 | * last argument, with false meaning "big-endian"
3050 | * and true meaning "little-endian", we treat any
3051 | * non-zero value of "encoding" as meaning
3052 | * "little-endian".
3053 | */
3054 | 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);
3055 | break;
3056 |
3057 | case FT_IPXNET:
3058 | if (length != FT_IPXNET_LEN4) {
3059 | length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
3060 | report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
3061 | }
3062 | proto_tree_set_ipxnet(new_fi,
3063 | get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
3064 | break;
3065 |
3066 | case FT_IPv6:
3067 | if (length != FT_IPv6_LEN16) {
3068 | length_error = length < FT_IPv6_LEN16 ? true1 : false0;
3069 | report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3070 | }
3071 | proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3072 | break;
3073 |
3074 | case FT_FCWWN:
3075 | if (length != FT_FCWWN_LEN8) {
3076 | length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
3077 | report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3078 | }
3079 | proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3080 | break;
3081 |
3082 | case FT_AX25:
3083 | if (length != 7) {
3084 | length_error = length < 7 ? true1 : false0;
3085 | report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3086 | }
3087 | proto_tree_set_ax25_tvb(new_fi, tvb, start);
3088 | break;
3089 |
3090 | case FT_VINES:
3091 | if (length != VINES_ADDR_LEN6) {
3092 | length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3093 | report_type_length_mismatch(tree, "a Vines address", length, length_error);
3094 | }
3095 | proto_tree_set_vines_tvb(new_fi, tvb, start);
3096 | break;
3097 |
3098 | case FT_ETHER:
3099 | if (length != FT_ETHER_LEN6) {
3100 | length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3101 | report_type_length_mismatch(tree, "a MAC address", length, length_error);
3102 | }
3103 | proto_tree_set_ether_tvb(new_fi, tvb, start);
3104 | break;
3105 |
3106 | case FT_EUI64:
3107 | /*
3108 | * Map all non-zero values to little-endian for
3109 | * backwards compatibility.
3110 | */
3111 | if (encoding)
3112 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3113 | if (length != FT_EUI64_LEN8) {
3114 | length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3115 | report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3116 | }
3117 | proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3118 | break;
3119 | case FT_GUID:
3120 | /*
3121 | * Map all non-zero values to little-endian for
3122 | * backwards compatibility.
3123 | */
3124 | if (encoding)
3125 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3126 | if (length != FT_GUID_LEN16) {
3127 | length_error = length < FT_GUID_LEN16 ? true1 : false0;
3128 | report_type_length_mismatch(tree, "a GUID", length, length_error);
3129 | }
3130 | proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3131 | break;
3132 |
3133 | case FT_OID:
3134 | case FT_REL_OID:
3135 | proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3136 | break;
3137 |
3138 | case FT_SYSTEM_ID:
3139 | proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3140 | break;
3141 |
3142 | case FT_FLOAT:
3143 | /*
3144 | * NOTE: to support code written when
3145 | * proto_tree_add_item() took a bool as its
3146 | * last argument, with false meaning "big-endian"
3147 | * and true meaning "little-endian", we treat any
3148 | * non-zero value of "encoding" as meaning
3149 | * "little-endian".
3150 | *
3151 | * At some point in the future, we might
3152 | * support non-IEEE-binary floating-point
3153 | * formats in the encoding as well
3154 | * (IEEE decimal, System/3x0, VAX).
3155 | */
3156 | if (encoding)
3157 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3158 | if (length != 4) {
3159 | length_error = length < 4 ? true1 : false0;
3160 | report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3161 | }
3162 | if (encoding)
3163 | floatval = tvb_get_letohieee_float(tvb, start);
3164 | else
3165 | floatval = tvb_get_ntohieee_float(tvb, start);
3166 | proto_tree_set_float(new_fi, floatval);
3167 | break;
3168 |
3169 | case FT_DOUBLE:
3170 | /*
3171 | * NOTE: to support code written when
3172 | * proto_tree_add_item() took a bool as its
3173 | * last argument, with false meaning "big-endian"
3174 | * and true meaning "little-endian", we treat any
3175 | * non-zero value of "encoding" as meaning
3176 | * "little-endian".
3177 | *
3178 | * At some point in the future, we might
3179 | * support non-IEEE-binary floating-point
3180 | * formats in the encoding as well
3181 | * (IEEE decimal, System/3x0, VAX).
3182 | */
3183 | if (encoding == true1)
3184 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3185 | if (length != 8) {
3186 | length_error = length < 8 ? true1 : false0;
3187 | report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3188 | }
3189 | if (encoding)
3190 | doubleval = tvb_get_letohieee_double(tvb, start);
3191 | else
3192 | doubleval = tvb_get_ntohieee_double(tvb, start);
3193 | proto_tree_set_double(new_fi, doubleval);
3194 | break;
3195 |
3196 | case FT_STRING:
3197 | stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3198 | tvb, start, length, &item_length, encoding);
3199 | proto_tree_set_string(new_fi, stringval);
3200 |
3201 | /* Instead of calling proto_item_set_len(), since we
3202 | * don't yet have a proto_item, we set the
3203 | * field_info's length ourselves.
3204 | *
3205 | * XXX - our caller can't use that length to
3206 | * advance an offset unless they arrange that
3207 | * there always be a protocol tree into which
3208 | * we're putting this item.
3209 | */
3210 | new_fi->length = item_length;
3211 | break;
3212 |
3213 | case FT_STRINGZ:
3214 | stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3215 | tree, tvb, start, length, &item_length, encoding);
3216 | proto_tree_set_string(new_fi, stringval);
3217 |
3218 | /* Instead of calling proto_item_set_len(),
3219 | * since we don't yet have a proto_item, we
3220 | * set the field_info's length ourselves.
3221 | *
3222 | * XXX - our caller can't use that length to
3223 | * advance an offset unless they arrange that
3224 | * there always be a protocol tree into which
3225 | * we're putting this item.
3226 | */
3227 | new_fi->length = item_length;
3228 | break;
3229 |
3230 | case FT_UINT_STRING:
3231 | /*
3232 | * NOTE: to support code written when
3233 | * proto_tree_add_item() took a bool as its
3234 | * last argument, with false meaning "big-endian"
3235 | * and true meaning "little-endian", if the
3236 | * encoding value is true, treat that as
3237 | * ASCII with a little-endian length.
3238 | *
3239 | * This won't work for code that passes
3240 | * arbitrary non-zero values; that code
3241 | * will need to be fixed.
3242 | */
3243 | if (encoding == true1)
3244 | encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3245 | stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3246 | tree, tvb, start, length, &item_length, encoding);
3247 | proto_tree_set_string(new_fi, stringval);
3248 |
3249 | /* Instead of calling proto_item_set_len(), since we
3250 | * don't yet have a proto_item, we set the
3251 | * field_info's length ourselves.
3252 | *
3253 | * XXX - our caller can't use that length to
3254 | * advance an offset unless they arrange that
3255 | * there always be a protocol tree into which
3256 | * we're putting this item.
3257 | */
3258 | new_fi->length = item_length;
3259 | break;
3260 |
3261 | case FT_STRINGZPAD:
3262 | stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3263 | tvb, start, length, &item_length, encoding);
3264 | proto_tree_set_string(new_fi, stringval);
3265 |
3266 | /* Instead of calling proto_item_set_len(), since we
3267 | * don't yet have a proto_item, we set the
3268 | * field_info's length ourselves.
3269 | *
3270 | * XXX - our caller can't use that length to
3271 | * advance an offset unless they arrange that
3272 | * there always be a protocol tree into which
3273 | * we're putting this item.
3274 | */
3275 | new_fi->length = item_length;
3276 | break;
3277 |
3278 | case FT_STRINGZTRUNC:
3279 | stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3280 | tvb, start, length, &item_length, encoding);
3281 | proto_tree_set_string(new_fi, stringval);
3282 |
3283 | /* Instead of calling proto_item_set_len(), since we
3284 | * don't yet have a proto_item, we set the
3285 | * field_info's length ourselves.
3286 | *
3287 | * XXX - our caller can't use that length to
3288 | * advance an offset unless they arrange that
3289 | * there always be a protocol tree into which
3290 | * we're putting this item.
3291 | */
3292 | new_fi->length = item_length;
3293 | break;
3294 |
3295 | case FT_ABSOLUTE_TIME:
3296 | /*
3297 | * Absolute times can be in any of a number of
3298 | * formats, and they can be big-endian or
3299 | * little-endian.
3300 | *
3301 | * Historically FT_TIMEs were only timespecs;
3302 | * the only question was whether they were stored
3303 | * in big- or little-endian format.
3304 | *
3305 | * For backwards compatibility, we interpret an
3306 | * encoding of 1 as meaning "little-endian timespec",
3307 | * so that passing true is interpreted as that.
3308 | */
3309 | if (encoding == true1)
3310 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3311 |
3312 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3313 |
3314 | proto_tree_set_time(new_fi, &time_stamp);
3315 | break;
3316 |
3317 | case FT_RELATIVE_TIME:
3318 | /*
3319 | * Relative times can be in any of a number of
3320 | * formats, and they can be big-endian or
3321 | * little-endian.
3322 | *
3323 | * Historically FT_TIMEs were only timespecs;
3324 | * the only question was whether they were stored
3325 | * in big- or little-endian format.
3326 | *
3327 | * For backwards compatibility, we interpret an
3328 | * encoding of 1 as meaning "little-endian timespec",
3329 | * so that passing true is interpreted as that.
3330 | */
3331 | if (encoding == true1)
3332 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3333 |
3334 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3335 |
3336 | proto_tree_set_time(new_fi, &time_stamp);
3337 | break;
3338 | case FT_IEEE_11073_SFLOAT:
3339 | if (encoding)
3340 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3341 | if (length != 2) {
3342 | length_error = length < 2 ? true1 : false0;
3343 | report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3344 | }
3345 |
3346 | fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3347 |
3348 | break;
3349 | case FT_IEEE_11073_FLOAT:
3350 | if (encoding)
3351 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3352 | if (length != 4) {
3353 | length_error = length < 4 ? true1 : false0;
3354 | report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3355 | }
3356 | fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3357 |
3358 | break;
3359 | default:
3360 | 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))
3361 | 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))
3362 | 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))
3363 | 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));
3364 | break;
3365 | }
3366 | 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);
3 | ← | Execution continues on line 3366 | →
4 | ← | Taking true branch | →
5 | ← | Assuming the condition is false | →
6 | ← | '?' condition is false | →
7 | ← | Loop condition is false. Exiting loop | →
3367 |
3368 | /* Don't add new node to proto_tree until now so that any exceptions
3369 | * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3370 | /* XXX. wouldn't be better to add this item to tree, with some special
3371 | * flag (FI_EXCEPTION?) to know which item caused exception? For
3372 | * strings and bytes, we would have to set new_fi->value to something
3373 | * non-NULL, or otherwise ensure that proto_item_fill_display_label
3374 | * could handle NULL values. */
3375 | pi = proto_tree_add_node(tree, new_fi);
3376 |
3377 | switch (new_fi->hfinfo->type) {
8 | ← | Control jumps to 'case FT_STRING:' at line 3379 | →
3378 |
3379 | case FT_STRING:
3380 | /* XXX: trailing stray character detection should be done
3381 | * _before_ conversion to UTF-8, because conversion can change
3382 | * the length, or else get_string_length should return a value
3383 | * for the "length in bytes of the string after conversion
3384 | * including internal nulls." (Noting that we do, for other
3385 | * reasons, still need the "length in bytes in the field",
3386 | * especially for FT_STRINGZ.)
3387 | *
3388 | * This is true even for ASCII and UTF-8, because
3389 | * substituting REPLACEMENT CHARACTERS for illegal characters
3390 | * can also do so (and for UTF-8 possibly even make the
3391 | * string _shorter_).
3392 | */
3393 | detect_trailing_stray_characters(encoding, stringval, item_length, pi);
9 | ← | 3rd function call argument is an uninitialized value
3394 | break;
3395 |
3396 | default:
3397 | break;
3398 | }
3399 |
3400 | return pi;
3401 | }
3402 |
3403 | proto_item *
3404 | proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3405 | const unsigned start, unsigned length,
3406 | const unsigned encoding, int32_t *retval)
3407 | {
3408 | header_field_info *hfinfo;
3409 | field_info *new_fi;
3410 | int32_t value;
3411 |
3412 | 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", 3412, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3412, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3412, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3413 |
3414 | switch (hfinfo->type) {
3415 | case FT_INT8:
3416 | case FT_INT16:
3417 | case FT_INT24:
3418 | case FT_INT32:
3419 | break;
3420 | case FT_INT64:
3421 | 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)
3422 | hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3423 | default:
3424 | 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)
3425 | hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3426 | }
3427 |
3428 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3429 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3430 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3431 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3432 | *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3433 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3434 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3435 |
3436 | if (encoding & ENC_STRING0x07000000) {
3437 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3438 | }
3439 | /* I believe it's ok if this is called with a NULL tree */
3440 | value = get_int_value(tree, tvb, start, length, encoding);
3441 |
3442 | if (retval) {
3443 | int no_of_bits;
3444 | *retval = value;
3445 | if (hfinfo->bitmask) {
3446 | /* Mask out irrelevant portions */
3447 | *retval &= (uint32_t)(hfinfo->bitmask);
3448 | /* Shift bits */
3449 | *retval >>= hfinfo_bitshift(hfinfo);
3450 | }
3451 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3452 | *retval = ws_sign_ext32(*retval, no_of_bits);
3453 | }
3454 |
3455 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3456 |
3457 | 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", 3457 , __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", 3457, "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", 3457, "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", 3457, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
3458 |
3459 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3460 |
3461 | proto_tree_set_int(new_fi, value);
3462 |
3463 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3464 |
3465 | return proto_tree_add_node(tree, new_fi);
3466 | }
3467 |
3468 | proto_item *
3469 | proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3470 | const unsigned start, unsigned length,
3471 | const unsigned encoding, uint32_t *retval)
3472 | {
3473 | header_field_info *hfinfo;
3474 | field_info *new_fi;
3475 | uint32_t value;
3476 |
3477 | 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", 3477, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3477, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3477, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3478 |
3479 | switch (hfinfo->type) {
3480 | case FT_CHAR:
3481 | case FT_UINT8:
3482 | case FT_UINT16:
3483 | case FT_UINT24:
3484 | case FT_UINT32:
3485 | break;
3486 | default:
3487 | 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)
3488 | 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);
3489 | }
3490 |
3491 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3492 | {if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3493 | if (retval) {if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3494 | *retval = 0;if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3495 | }if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3496 | return NULL;if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3497 | }if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3498 | )if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); };
3499 |
3500 | if (encoding & ENC_STRING0x07000000) {
3501 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3502 | }
3503 | /* I believe it's ok if this is called with a NULL tree */
3504 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3505 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3506 | uint64_t temp64;
3507 | tvb_get_varint(tvb, start, length, &temp64, encoding);
3508 | value = (uint32_t)temp64;
3509 | } else {
3510 | value = get_uint_value(tree, tvb, start, length, encoding);
3511 | }
3512 |
3513 | if (retval) {
3514 | *retval = value;
3515 | if (hfinfo->bitmask) {
3516 | /* Mask out irrelevant portions */
3517 | *retval &= (uint32_t)(hfinfo->bitmask);
3518 | /* Shift bits */
3519 | *retval >>= hfinfo_bitshift(hfinfo);
3520 | }
3521 | }
3522 |
3523 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3524 |
3525 | 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", 3525 , __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", 3525, "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", 3525, "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", 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); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
3526 |
3527 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3528 |
3529 | proto_tree_set_uint(new_fi, value);
3530 |
3531 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3532 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3533 | new_fi->flags |= FI_VARINT0x00040000;
3534 | }
3535 | return proto_tree_add_node(tree, new_fi);
3536 | }
3537 |
3538 | proto_item *
3539 | proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3540 | const unsigned start, unsigned length,
3541 | const unsigned encoding, uint32_t *retval)
3542 | {
3543 | return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3544 | }
3545 |
3546 | proto_item *
3547 | proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3548 | const unsigned start, unsigned length,
3549 | const unsigned encoding, uint8_t *retval)
3550 | {
3551 | /* TODO: further restrict by hfinfo->type ? */
3552 | uint32_t val32;
3553 | proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3554 | *retval = (uint8_t)val32;
3555 | return item;
3556 | }
3557 |
3558 | proto_item *
3559 | proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3560 | const unsigned start, unsigned length,
3561 | const unsigned encoding, uint16_t *retval)
3562 | {
3563 | /* TODO: further restrict by hfinfo->type ? */
3564 | uint32_t val32;
3565 | proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3566 | *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3567 | return item;
3568 | }
3569 |
3570 |
3571 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3572 | * and returns proto_item* and uint value retrieved*/
3573 | proto_item *
3574 | ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3575 | const unsigned encoding, uint32_t *retval)
3576 | {
3577 | field_info *new_fi;
3578 | header_field_info *hfinfo;
3579 | unsigned item_length;
3580 | unsigned offset;
3581 | uint32_t value;
3582 |
3583 | offset = ptvc->offset;
3584 | 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", 3584, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3584, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3584, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3585 |
3586 | switch (hfinfo->type) {
3587 | case FT_CHAR:
3588 | case FT_UINT8:
3589 | case FT_UINT16:
3590 | case FT_UINT24:
3591 | case FT_UINT32:
3592 | break;
3593 | default:
3594 | 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)
3595 | 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);
3596 | }
3597 |
3598 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3599 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3600 |
3601 | /* I believe it's ok if this is called with a NULL tree */
3602 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3603 | value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3604 |
3605 | if (retval) {
3606 | *retval = value;
3607 | if (hfinfo->bitmask) {
3608 | /* Mask out irrelevant portions */
3609 | *retval &= (uint32_t)(hfinfo->bitmask);
3610 | /* Shift bits */
3611 | *retval >>= hfinfo_bitshift(hfinfo);
3612 | }
3613 | }
3614 |
3615 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3616 |
3617 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3618 |
3619 | /* Coast clear. Try and fake it */
3620 | 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", 3620 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3620, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3620, "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", 3620, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree )->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc ->tree)->tree_data)->visible)) { if (proto_item_is_hidden ((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT ) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data )->fake_protocols)) { ((void)0); return proto_tree_add_fake_node (ptvc->tree, hfinfo); } } };
3621 |
3622 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3623 |
3624 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3625 | offset, length, encoding);
3626 | }
3627 |
3628 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3629 | * and returns proto_item* and int value retrieved*/
3630 | proto_item *
3631 | ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3632 | const unsigned encoding, int32_t *retval)
3633 | {
3634 | field_info *new_fi;
3635 | header_field_info *hfinfo;
3636 | unsigned item_length;
3637 | unsigned offset;
3638 | uint32_t value;
3639 |
3640 | offset = ptvc->offset;
3641 | 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", 3641, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3641, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3641, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3642 |
3643 | switch (hfinfo->type) {
3644 | case FT_INT8:
3645 | case FT_INT16:
3646 | case FT_INT24:
3647 | case FT_INT32:
3648 | break;
3649 | default:
3650 | 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)
3651 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
3652 | }
3653 |
3654 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3655 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3656 |
3657 | /* I believe it's ok if this is called with a NULL tree */
3658 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3659 | value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3660 |
3661 | if (retval) {
3662 | int no_of_bits;
3663 | *retval = value;
3664 | if (hfinfo->bitmask) {
3665 | /* Mask out irrelevant portions */
3666 | *retval &= (uint32_t)(hfinfo->bitmask);
3667 | /* Shift bits */
3668 | *retval >>= hfinfo_bitshift(hfinfo);
3669 | }
3670 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3671 | *retval = ws_sign_ext32(*retval, no_of_bits);
3672 | }
3673 |
3674 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3675 |
3676 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3677 |
3678 | /* Coast clear. Try and fake it */
3679 | 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", 3679 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3679, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3679, "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", 3679, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree )->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc ->tree)->tree_data)->visible)) { if (proto_item_is_hidden ((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT ) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data )->fake_protocols)) { ((void)0); return proto_tree_add_fake_node (ptvc->tree, hfinfo); } } };
3680 |
3681 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3682 |
3683 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3684 | offset, length, encoding);
3685 | }
3686 |
3687 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3688 | * and returns proto_item* and string value retrieved */
3689 | proto_item*
3690 | ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3691 | {
3692 | header_field_info *hfinfo;
3693 | field_info *new_fi;
3694 | const uint8_t *value;
3695 | unsigned item_length;
3696 | unsigned offset;
3697 |
3698 | offset = ptvc->offset;
3699 |
3700 | 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", 3700 , __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", 3700, "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", 3700, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hf];;
3701 |
3702 | switch (hfinfo->type) {
3703 | case FT_STRING:
3704 | value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3705 | break;
3706 | case FT_STRINGZ:
3707 | value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3708 | break;
3709 | case FT_UINT_STRING:
3710 | value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3711 | break;
3712 | case FT_STRINGZPAD:
3713 | value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3714 | break;
3715 | case FT_STRINGZTRUNC:
3716 | value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3717 | break;
3718 | default:
3719 | 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)
3720 | 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);
3721 | }
3722 |
3723 | if (retval)
3724 | *retval = value;
3725 |
3726 | ptvcursor_advance(ptvc, item_length);
3727 |
3728 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3729 |
3730 | 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", 3730, __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", 3730, "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", 3730, "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", 3730 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree )->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc ->tree)->tree_data)->visible)) { if (proto_item_is_hidden ((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT ) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data )->fake_protocols)) { ((void)0); return proto_tree_add_fake_node (ptvc->tree, hfinfo); } } };
3731 |
3732 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3733 |
3734 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3735 | offset, length, encoding);
3736 | }
3737 |
3738 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3739 | * and returns proto_item* and boolean value retrieved */
3740 | proto_item*
3741 | ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3742 | {
3743 | header_field_info *hfinfo;
3744 | field_info *new_fi;
3745 | unsigned item_length;
3746 | unsigned offset;
3747 | uint64_t value, bitval;
3748 |
3749 | offset = ptvc->offset;
3750 | 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", 3750, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3750, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3750, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3751 |
3752 | if (hfinfo->type != FT_BOOLEAN) {
3753 | 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)
3754 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3755 | }
3756 |
3757 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3758 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3759 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3760 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3761 | *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3762 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3763 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3764 |
3765 | if (encoding & ENC_STRING0x07000000) {
3766 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3767 | }
3768 |
3769 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3770 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3771 |
3772 | /* I believe it's ok if this is called with a NULL tree */
3773 | value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3774 |
3775 | if (retval) {
3776 | bitval = value;
3777 | if (hfinfo->bitmask) {
3778 | /* Mask out irrelevant portions */
3779 | bitval &= hfinfo->bitmask;
3780 | }
3781 | *retval = (bitval != 0);
3782 | }
3783 |
3784 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3785 |
3786 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3787 |
3788 | 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", 3788, __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", 3788, "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", 3788, "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", 3788 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree )->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc ->tree)->tree_data)->visible)) { if (proto_item_is_hidden ((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT ) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data )->fake_protocols)) { ((void)0); return proto_tree_add_fake_node (ptvc->tree, hfinfo); } } };
3789 |
3790 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3791 |
3792 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3793 | offset, length, encoding);
3794 | }
3795 |
3796 | proto_item *
3797 | proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3798 | const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval)
3799 | {
3800 | header_field_info *hfinfo;
3801 | field_info *new_fi;
3802 | uint64_t value;
3803 |
3804 | 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", 3804, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3804, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3804, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3805 |
3806 | switch (hfinfo->type) {
3807 | case FT_UINT40:
3808 | case FT_UINT48:
3809 | case FT_UINT56:
3810 | case FT_UINT64:
3811 | break;
3812 | default:
3813 | 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)
3814 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64" , hfinfo->abbrev);
3815 | }
3816 |
3817 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3818 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3819 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3820 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3821 | *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3822 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3823 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3824 |
3825 | if (encoding & ENC_STRING0x07000000) {
3826 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3827 | }
3828 | /* I believe it's ok if this is called with a NULL tree */
3829 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3830 | tvb_get_varint(tvb, start, length, &value, encoding);
3831 | } else {
3832 | value = get_uint64_value(tree, tvb, start, length, encoding);
3833 | }
3834 |
3835 | if (retval) {
3836 | *retval = value;
3837 | if (hfinfo->bitmask) {
3838 | /* Mask out irrelevant portions */
3839 | *retval &= hfinfo->bitmask;
3840 | /* Shift bits */
3841 | *retval >>= hfinfo_bitshift(hfinfo);
3842 | }
3843 | }
3844 |
3845 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3846 |
3847 | 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", 3847 , __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", 3847, "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", 3847, "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", 3847, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
3848 |
3849 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3850 |
3851 | proto_tree_set_uint64(new_fi, value);
3852 |
3853 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3854 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3855 | new_fi->flags |= FI_VARINT0x00040000;
3856 | }
3857 |
3858 | return proto_tree_add_node(tree, new_fi);
3859 | }
3860 |
3861 | proto_item *
3862 | proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3863 | const unsigned start, unsigned length, const unsigned encoding, int64_t *retval)
3864 | {
3865 | header_field_info *hfinfo;
3866 | field_info *new_fi;
3867 | int64_t value;
3868 |
3869 | 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", 3869, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3869, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3869, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3870 |
3871 | switch (hfinfo->type) {
3872 | case FT_INT40:
3873 | case FT_INT48:
3874 | case FT_INT56:
3875 | case FT_INT64:
3876 | break;
3877 | default:
3878 | 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)
3879 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
3880 | }
3881 |
3882 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3883 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3884 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3885 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3886 | *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3887 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3888 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3889 |
3890 | if (encoding & ENC_STRING0x07000000) {
3891 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3892 | }
3893 | /* I believe it's ok if this is called with a NULL tree */
3894 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3895 | tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3896 | }
3897 | else {
3898 | value = get_int64_value(tree, tvb, start, length, encoding);
3899 | }
3900 |
3901 | if (retval) {
3902 | *retval = value;
3903 | }
3904 |
3905 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3906 |
3907 | 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", 3907 , __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", 3907, "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", 3907, "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", 3907, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
3908 |
3909 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3910 |
3911 | proto_tree_set_int64(new_fi, value);
3912 |
3913 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3914 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3915 | new_fi->flags |= FI_VARINT0x00040000;
3916 | }
3917 |
3918 | return proto_tree_add_node(tree, new_fi);
3919 | }
3920 |
3921 | proto_item *
3922 | proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3923 | const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval, unsigned *lenretval)
3924 | {
3925 | header_field_info *hfinfo;
3926 | field_info *new_fi;
3927 | uint64_t value;
3928 |
3929 | 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", 3929, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3929, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3929, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3930 |
3931 | 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 )))) {
3932 | 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)
3933 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT" , hfinfo->abbrev);
3934 | }
3935 |
3936 | if (!(encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3937 | REPORT_DISSECTOR_BUG("Encoding must be a VARINT")proto_report_dissector_bug("Encoding must be a VARINT");
3938 | }
3939 |
3940 | if (encoding & ENC_STRING0x07000000) {
3941 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3942 | }
3943 |
3944 | /* tvb_get_varint clamps the max length to FT_VARINT_MAX_LEN (10)
3945 | * It also handles length 0, setting both return values to 0.
3946 | * XXX - Should the max length be affected by the field type and/or
3947 | * encoding, e.g. 5 for FT_[U]INT32?
3948 | * XXX - Should there be separate _varint and _varuint versions to
3949 | * avoid the changing the sign when casting the return value?
3950 | * XXX - Do we even need the length parameter? Every user of this
3951 | * function passes in -1 or FT_VARINT_MAX_LEN. We could have a
3952 | * separate function, but unlike some field types, variable length
3953 | * is the typical case here, not the exception, and the typical
3954 | * case should have the shorter, more convenient function name.
3955 | * Having the length makes the signature more similar to other
3956 | * functions, though. */
3957 | length = tvb_get_varint(tvb, start, length, &value, encoding);
3958 |
3959 | if (length == 0) {
3960 | expert_add_info(NULL((void*)0), tree, &ei_varint_decoding_failed_error);
3961 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
3962 | }
3963 |
3964 | if (retval) {
3965 | *retval = value;
3966 | if (hfinfo->bitmask) {
3967 | /* Mask out irrelevant portions */
3968 | *retval &= hfinfo->bitmask;
3969 | /* Shift bits */
3970 | *retval >>= hfinfo_bitshift(hfinfo);
3971 | }
3972 | }
3973 |
3974 | if (lenretval) {
3975 | *lenretval = length;
3976 | }
3977 |
3978 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3979 |
3980 | 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", 3980 , __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", 3980, "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", 3980, "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", 3980, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
3981 |
3982 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3983 |
3984 | proto_tree_set_uint64(new_fi, value);
3985 |
3986 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3987 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3988 | new_fi->flags |= FI_VARINT0x00040000;
3989 | }
3990 |
3991 | return proto_tree_add_node(tree, new_fi);
3992 |
3993 | }
3994 |
3995 | proto_item *
3996 | proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3997 | const unsigned start, unsigned length,
3998 | const unsigned encoding, bool_Bool *retval)
3999 | {
4000 | header_field_info *hfinfo;
4001 | field_info *new_fi;
4002 | uint64_t value, bitval;
4003 |
4004 | 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", 4004, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4004, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4004, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4005 |
4006 | if (hfinfo->type != FT_BOOLEAN) {
4007 | 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)
4008 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
4009 | }
4010 |
4011 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
4012 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
4013 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
4014 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
4015 | *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
4016 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
4017 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
4018 |
4019 | if (encoding & ENC_STRING0x07000000) {
4020 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4021 | }
4022 | /* I believe it's ok if this is called with a NULL tree */
4023 | value = get_uint64_value(tree, tvb, start, length, encoding);
4024 |
4025 | if (retval) {
4026 | bitval = value;
4027 | if (hfinfo->bitmask) {
4028 | /* Mask out irrelevant portions */
4029 | bitval &= hfinfo->bitmask;
4030 | }
4031 | *retval = (bitval != 0);
4032 | }
4033 |
4034 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4035 |
4036 | 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", 4036 , __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", 4036, "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", 4036, "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", 4036, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4037 |
4038 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4039 |
4040 | proto_tree_set_boolean(new_fi, value);
4041 |
4042 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4043 |
4044 | return proto_tree_add_node(tree, new_fi);
4045 | }
4046 |
4047 | proto_item *
4048 | proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4049 | const unsigned start, unsigned length,
4050 | const unsigned encoding, float *retval)
4051 | {
4052 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4053 | field_info *new_fi;
4054 | float value;
4055 |
4056 | 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", 4056, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4057 |
4058 | if (hfinfo->type != FT_FLOAT) {
4059 | 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);
4060 | }
4061 |
4062 | if (length != 4) {
4063 | report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
4064 | }
4065 |
4066 | /* treat any nonzero encoding as little endian for backwards compatibility */
4067 | value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
4068 | if (retval) {
4069 | *retval = value;
4070 | }
4071 |
4072 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4073 |
4074 | 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", 4074 , __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", 4074, "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", 4074, "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", 4074, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4075 |
4076 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4077 | if (encoding) {
4078 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4079 | }
4080 |
4081 | proto_tree_set_float(new_fi, value);
4082 |
4083 | return proto_tree_add_node(tree, new_fi);
4084 | }
4085 |
4086 | proto_item *
4087 | proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4088 | const unsigned start, unsigned length,
4089 | const unsigned encoding, double *retval)
4090 | {
4091 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4092 | field_info *new_fi;
4093 | double value;
4094 |
4095 | 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", 4095, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4096 |
4097 | if (hfinfo->type != FT_DOUBLE) {
4098 | 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);
4099 | }
4100 |
4101 | if (length != 8) {
4102 | report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4103 | }
4104 |
4105 | /* treat any nonzero encoding as little endian for backwards compatibility */
4106 | value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4107 | if (retval) {
4108 | *retval = value;
4109 | }
4110 |
4111 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4112 |
4113 | 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", 4113 , __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", 4113, "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", 4113, "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", 4113, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4114 |
4115 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4116 | if (encoding) {
4117 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4118 | }
4119 |
4120 | proto_tree_set_double(new_fi, value);
4121 |
4122 | return proto_tree_add_node(tree, new_fi);
4123 | }
4124 |
4125 | proto_item *
4126 | proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4127 | const unsigned start, unsigned length,
4128 | const unsigned encoding, ws_in4_addr *retval)
4129 | {
4130 | header_field_info *hfinfo;
4131 | field_info *new_fi;
4132 | ws_in4_addr value;
4133 |
4134 | 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", 4134, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4134, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4134, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4135 |
4136 | switch (hfinfo->type) {
4137 | case FT_IPv4:
4138 | break;
4139 | default:
4140 | 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)
4141 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4", hfinfo->abbrev);
4142 | }
4143 |
4144 | if (length != FT_IPv4_LEN4)
4145 | 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)
4146 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4" , length);
4147 |
4148 | if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4149 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4150 | }
4151 |
4152 | /*
4153 | * NOTE: to support code written when proto_tree_add_item() took
4154 | * a bool as its last argument, with false meaning "big-endian"
4155 | * and true meaning "little-endian", we treat any non-zero value
4156 | * of "encoding" as meaning "little-endian".
4157 | */
4158 | value = tvb_get_ipv4(tvb, start);
4159 | if (encoding)
4160 | 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))));
4161 |
4162 | if (retval) {
4163 | *retval = value;
4164 | }
4165 |
4166 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4167 |
4168 | 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", 4168 , __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", 4168, "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", 4168, "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", 4168, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4169 |
4170 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4171 |
4172 | proto_tree_set_ipv4(new_fi, value);
4173 |
4174 | new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4175 | return proto_tree_add_node(tree, new_fi);
4176 | }
4177 |
4178 | proto_item *
4179 | proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4180 | const unsigned start, unsigned length,
4181 | const unsigned encoding, ws_in6_addr *addr)
4182 | {
4183 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4184 | field_info *new_fi;
4185 |
4186 | 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", 4186, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4187 |
4188 | switch (hfinfo->type) {
4189 | case FT_IPv6:
4190 | break;
4191 | default:
4192 | 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)
4193 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6", hfinfo->abbrev);
4194 | }
4195 |
4196 | if (length != FT_IPv6_LEN16)
4197 | 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)
4198 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6" , length);
4199 |
4200 | if (encoding) {
4201 | 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" );
4202 | }
4203 |
4204 | tvb_get_ipv6(tvb, start, addr);
4205 |
4206 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4207 |
4208 | 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", 4208 , __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", 4208, "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", 4208, "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", 4208, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4209 |
4210 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4211 |
4212 | proto_tree_set_ipv6(new_fi, addr);
4213 |
4214 | return proto_tree_add_node(tree, new_fi);
4215 | }
4216 |
4217 | proto_item *
4218 | proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4219 | const unsigned start, unsigned length, const unsigned encoding, uint8_t *retval) {
4220 |
4221 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4222 | field_info *new_fi;
4223 |
4224 | 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", 4224, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4225 |
4226 | switch (hfinfo->type) {
4227 | case FT_ETHER:
4228 | break;
4229 | default:
4230 | 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)
4231 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER" , hfinfo->abbrev);
4232 | }
4233 |
4234 | if (length != FT_ETHER_LEN6)
4235 | 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)
4236 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether" , length);
4237 |
4238 | if (encoding) {
4239 | 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" );
4240 | }
4241 |
4242 | tvb_memcpy(tvb, retval, start, length);
4243 |
4244 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4245 |
4246 | 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", 4246 , __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", 4246, "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", 4246, "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", 4246, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4247 |
4248 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4249 |
4250 | proto_tree_set_ether(new_fi, retval);
4251 |
4252 | return proto_tree_add_node(tree, new_fi);
4253 | }
4254 |
4255 |
4256 | proto_item *
4257 | proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4258 | tvbuff_t *tvb,
4259 | const unsigned start, int length,
4260 | const unsigned encoding,
4261 | wmem_allocator_t *scope,
4262 | const uint8_t **retval,
4263 | unsigned *lenretval)
4264 | {
4265 | proto_item *pi;
4266 | header_field_info *hfinfo;
4267 | field_info *new_fi;
4268 | const uint8_t *value;
4269 |
4270 | 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", 4270, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4270, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4270, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4271 |
4272 | switch (hfinfo->type) {
4273 | case FT_STRING:
4274 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4275 | break;
4276 | case FT_STRINGZ:
4277 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4278 | break;
4279 | case FT_UINT_STRING:
4280 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4281 | break;
4282 | case FT_STRINGZPAD:
4283 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4284 | break;
4285 | case FT_STRINGZTRUNC:
4286 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4287 | break;
4288 | default:
4289 | 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)
4290 | 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);
4291 | }
4292 |
4293 | if (retval)
4294 | *retval = value;
4295 |
4296 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4297 |
4298 | 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", 4298 , __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", 4298, "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", 4298, "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", 4298, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4299 |
4300 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4301 |
4302 | proto_tree_set_string(new_fi, (const char*)value);
4303 |
4304 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4305 |
4306 | pi = proto_tree_add_node(tree, new_fi);
4307 |
4308 | switch (hfinfo->type) {
4309 |
4310 | case FT_STRINGZ:
4311 | case FT_STRINGZPAD:
4312 | case FT_STRINGZTRUNC:
4313 | case FT_UINT_STRING:
4314 | break;
4315 |
4316 | case FT_STRING:
4317 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4318 | break;
4319 |
4320 | default:
4321 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4321 , __func__, "assertion \"not reached\" failed");
4322 | }
4323 |
4324 | return pi;
4325 | }
4326 |
4327 | proto_item *
4328 | proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4329 | const unsigned start, int length,
4330 | const unsigned encoding, wmem_allocator_t *scope,
4331 | const uint8_t **retval)
4332 | {
4333 | unsigned item_length; // Param cannot be NULL in function below
4334 | return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4335 | tvb, start, length, encoding, scope, retval, &item_length);
4336 | }
4337 |
4338 | proto_item *
4339 | proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4340 | tvbuff_t *tvb,
4341 | const unsigned start, int length,
4342 | const unsigned encoding,
4343 | wmem_allocator_t *scope,
4344 | char **retval,
4345 | unsigned *lenretval)
4346 | {
4347 | proto_item *pi;
4348 | header_field_info *hfinfo;
4349 | field_info *new_fi;
4350 | const uint8_t *value;
4351 | uint32_t n = 0;
4352 |
4353 | 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", 4353, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4353, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4353, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4354 |
4355 | switch (hfinfo->type) {
4356 | case FT_STRING:
4357 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4358 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4359 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4360 | break;
4361 | case FT_STRINGZ:
4362 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4363 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4364 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4365 | break;
4366 | case FT_UINT_STRING:
4367 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4368 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4369 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4370 | break;
4371 | case FT_STRINGZPAD:
4372 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4373 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4374 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4375 | break;
4376 | case FT_STRINGZTRUNC:
4377 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4378 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4379 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4380 | break;
4381 | case FT_BYTES:
4382 | tvb_ensure_bytes_exist(tvb, start, length);
4383 | value = tvb_get_ptr(tvb, start, length);
4384 | *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4385 | *lenretval = length;
4386 | break;
4387 | case FT_UINT_BYTES:
4388 | n = get_uint_value(tree, tvb, start, length, encoding);
4389 | tvb_ensure_bytes_exist(tvb, start + length, n);
4390 | value = tvb_get_ptr(tvb, start + length, n);
4391 | *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4392 | *lenretval = length + n;
4393 | break;
4394 | default:
4395 | 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)
4396 | 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);
4397 | }
4398 |
4399 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4400 |
4401 | 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", 4401 , __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", 4401, "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", 4401, "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", 4401, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4402 |
4403 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4404 |
4405 | switch (hfinfo->type) {
4406 |
4407 | case FT_STRING:
4408 | case FT_STRINGZ:
4409 | case FT_UINT_STRING:
4410 | case FT_STRINGZPAD:
4411 | case FT_STRINGZTRUNC:
4412 | proto_tree_set_string(new_fi, (const char*)value);
4413 | break;
4414 |
4415 | case FT_BYTES:
4416 | proto_tree_set_bytes(new_fi, value, length);
4417 | break;
4418 |
4419 | case FT_UINT_BYTES:
4420 | proto_tree_set_bytes(new_fi, value, n);
4421 | break;
4422 |
4423 | default:
4424 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4424 , __func__, "assertion \"not reached\" failed");
4425 | }
4426 |
4427 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4428 |
4429 | pi = proto_tree_add_node(tree, new_fi);
4430 |
4431 | switch (hfinfo->type) {
4432 |
4433 | case FT_STRINGZ:
4434 | case FT_STRINGZPAD:
4435 | case FT_STRINGZTRUNC:
4436 | case FT_UINT_STRING:
4437 | break;
4438 |
4439 | case FT_STRING:
4440 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4441 | break;
4442 |
4443 | case FT_BYTES:
4444 | case FT_UINT_BYTES:
4445 | break;
4446 |
4447 | default:
4448 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4448 , __func__, "assertion \"not reached\" failed");
4449 | }
4450 |
4451 | return pi;
4452 | }
4453 |
4454 | proto_item *
4455 | proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4456 | tvbuff_t *tvb,
4457 | const unsigned start, int length,
4458 | const unsigned encoding,
4459 | wmem_allocator_t *scope,
4460 | char **retval)
4461 | {
4462 | unsigned item_length; // Param cannot be NULL in function below
4463 | return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4464 | tvb, start, length, encoding, scope, retval, &item_length);
4465 | }
4466 |
4467 | proto_item *
4468 | proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4469 | tvbuff_t *tvb,
4470 | const unsigned start, int length, const unsigned encoding,
4471 | wmem_allocator_t *scope, char **retval)
4472 | {
4473 | header_field_info *hfinfo;
4474 | field_info *new_fi;
4475 | nstime_t time_stamp;
4476 | int flags;
4477 |
4478 | 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", 4478, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4478, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4478, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4479 |
4480 | switch (hfinfo->type) {
4481 | case FT_ABSOLUTE_TIME:
4482 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4483 | flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4484 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4485 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4486 | }
4487 | *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4488 | break;
4489 | case FT_RELATIVE_TIME:
4490 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4491 | *retval = rel_time_to_secs_str(scope, &time_stamp);
4492 | break;
4493 | default:
4494 | 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)
4495 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME" , hfinfo->abbrev);
4496 | }
4497 |
4498 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4499 |
4500 | 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", 4500 , __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", 4500, "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", 4500, "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", 4500, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4501 |
4502 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4503 |
4504 | switch (hfinfo->type) {
4505 |
4506 | case FT_ABSOLUTE_TIME:
4507 | case FT_RELATIVE_TIME:
4508 | proto_tree_set_time(new_fi, &time_stamp);
4509 | break;
4510 | default:
4511 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4511 , __func__, "assertion \"not reached\" failed");
4512 | }
4513 |
4514 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4515 |
4516 | return proto_tree_add_node(tree, new_fi);
4517 | }
4518 |
4519 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
4520 | and returns proto_item* */
4521 | proto_item *
4522 | ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4523 | const unsigned encoding)
4524 | {
4525 | field_info *new_fi;
4526 | header_field_info *hfinfo;
4527 | int item_length;
4528 | unsigned offset;
4529 |
4530 | offset = ptvc->offset;
4531 | 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", 4531, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4531, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4531, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4532 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4533 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4534 |
4535 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4536 |
4537 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4538 |
4539 | /* Coast clear. Try and fake it */
4540 | 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", 4540 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4540, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4540, "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", 4540, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree )->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc ->tree)->tree_data)->visible)) { if (proto_item_is_hidden ((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT ) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data )->fake_protocols)) { ((void)0); return proto_tree_add_fake_node (ptvc->tree, hfinfo); } } };
4541 |
4542 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4543 |
4544 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4545 | offset, length, encoding);
4546 | }
4547 |
4548 | /* Add an item to a proto_tree, using the text label registered to that item;
4549 | the item is extracted from the tvbuff handed to it. */
4550 | proto_item *
4551 | proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4552 | const unsigned start, int length, const unsigned encoding)
4553 | {
4554 | field_info *new_fi;
4555 | int item_length;
4556 |
4557 | 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", 4557, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4558 |
4559 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4560 | test_length(hfinfo, tvb, start, item_length, encoding);
4561 |
4562 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4563 |
4564 | 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", 4564 , __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", 4564, "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", 4564, "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", 4564, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4565 |
4566 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4567 |
4568 | return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4569 | }
4570 |
4571 | proto_item *
4572 | proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4573 | const unsigned start, int length, const unsigned encoding)
4574 | {
4575 | register header_field_info *hfinfo;
4576 |
4577 | 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", 4577, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4577, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4577, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4578 | return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4579 | }
4580 |
4581 | /* Add an item to a proto_tree, using the text label registered to that item;
4582 | the item is extracted from the tvbuff handed to it.
4583 |
4584 | Return the length of the item through the pointer. */
4585 | proto_item *
4586 | proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4587 | tvbuff_t *tvb, const unsigned start,
4588 | int length, const unsigned encoding,
4589 | unsigned *lenretval)
4590 | {
4591 | field_info *new_fi;
4592 | int item_length;
4593 | proto_item *item;
4594 |
4595 | 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", 4595, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4596 |
4597 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4598 | test_length(hfinfo, tvb, start, item_length, encoding);
4599 |
4600 | if (!tree) {
4601 | /*
4602 | * We need to get the correct item length here.
4603 | * That's normally done by proto_tree_new_item(),
4604 | * but we won't be calling it.
4605 | */
4606 | *lenretval = get_full_length(hfinfo, tvb, start, length,
4607 | item_length, encoding);
4608 | return NULL((void*)0);
4609 | }
4610 |
4611 | 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", 4618 , __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", 4618, "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", 4618, "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", 4618 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4612 | /*((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", 4618 , __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", 4618, "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", 4618, "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", 4618 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4613 | * 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", 4618 , __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", 4618, "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", 4618, "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", 4618 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4614 | * 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", 4618 , __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", 4618, "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", 4618, "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", 4618 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4615 | */((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", 4618 , __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", 4618, "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", 4618, "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", 4618 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4616 | *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", 4618 , __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", 4618, "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", 4618, "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", 4618 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4617 | 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", 4618 , __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", 4618, "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", 4618, "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", 4618 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4618 | })((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", 4618 , __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", 4618, "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", 4618, "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", 4618 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } };
4619 |
4620 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4621 |
4622 | item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4623 | *lenretval = new_fi->length;
4624 | return item;
4625 | }
4626 |
4627 | proto_item *
4628 | proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4629 | const unsigned start, int length,
4630 | const unsigned encoding, unsigned *lenretval)
4631 | {
4632 | register header_field_info *hfinfo;
4633 |
4634 | 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", 4634, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4634, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4634, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4635 | return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4636 | }
4637 |
4638 | /* which FT_ types can use proto_tree_add_bytes_item() */
4639 | static inline bool_Bool
4640 | validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4641 | {
4642 | return (type == FT_BYTES ||
4643 | type == FT_UINT_BYTES ||
4644 | type == FT_OID ||
4645 | type == FT_REL_OID ||
4646 | type == FT_SYSTEM_ID );
4647 | }
4648 |
4649 | /* Note: this does no validation that the byte array of an FT_OID or
4650 | FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4651 | so I think it's ok to continue not validating it?
4652 | */
4653 | proto_item *
4654 | proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4655 | const unsigned start, unsigned length,
4656 | const unsigned encoding,
4657 | GByteArray *retval, unsigned *endoff, int *err)
4658 | {
4659 | field_info *new_fi;
4660 | GByteArray *bytes = retval;
4661 | GByteArray *created_bytes = NULL((void*)0);
4662 | bool_Bool failed = false0;
4663 | uint32_t n = 0;
4664 | header_field_info *hfinfo;
4665 | bool_Bool generate = (bytes || tree) ? true1 : false0;
4666 |
4667 | 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", 4667, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4667, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4667, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4668 |
4669 | 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", 4669, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4670 |
4671 | 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", 4672, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))))
4672 | "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", 4672, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))));
4673 |
4674 | if (length == 0) {
4675 | return NULL((void*)0);
4676 | }
4677 |
4678 | if (encoding & ENC_STR_NUM0x01000000) {
4679 | 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" );
4680 | }
4681 |
4682 | if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4683 | if (hfinfo->type == FT_UINT_BYTES) {
4684 | /* can't decode FT_UINT_BYTES from strings */
4685 | 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")
4686 | "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");
4687 | }
4688 |
4689 | unsigned hex_encoding = encoding;
4690 | if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4691 | /* If none of the separator values are used,
4692 | * assume no separator (the common case). */
4693 | hex_encoding |= ENC_SEP_NONE0x00010000;
4694 | #if 0
4695 | REPORT_DISSECTOR_BUG("proto_tree_add_bytes_item called "proto_report_dissector_bug("proto_tree_add_bytes_item called " "with ENC_STR_HEX but no ENC_SEP_XXX value")
4696 | "with ENC_STR_HEX but no ENC_SEP_XXX value")proto_report_dissector_bug("proto_tree_add_bytes_item called " "with ENC_STR_HEX but no ENC_SEP_XXX value");
4697 | #endif
4698 | }
4699 |
4700 | if (!bytes) {
4701 | /* caller doesn't care about return value, but we need it to
4702 | call tvb_get_string_bytes() and set the tree later */
4703 | bytes = created_bytes = g_byte_array_new();
4704 | }
4705 |
4706 | /*
4707 | * bytes might be NULL after this, but can't add expert
4708 | * error until later; if it's NULL, just note that
4709 | * it failed.
4710 | */
4711 | bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4712 | if (bytes == NULL((void*)0))
4713 | failed = true1;
4714 | }
4715 | else if (generate) {
4716 | tvb_ensure_bytes_exist(tvb, start, length);
4717 |
4718 | if (hfinfo->type == FT_UINT_BYTES) {
4719 | n = length; /* n is now the "header" length */
4720 | length = get_uint_value(tree, tvb, start, n, encoding);
4721 | /* length is now the value's length; only store the value in the array */
4722 | tvb_ensure_bytes_exist(tvb, start + n, length);
4723 | if (!bytes) {
4724 | /* caller doesn't care about return value, but
4725 | * we may need it to set the tree later */
4726 | bytes = created_bytes = g_byte_array_new();
4727 | }
4728 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4729 | }
4730 | else if (length > 0) {
4731 | if (!bytes) {
4732 | /* caller doesn't care about return value, but
4733 | * we may need it to set the tree later */
4734 | bytes = created_bytes = g_byte_array_new();
4735 | }
4736 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4737 | }
4738 |
4739 | if (endoff)
4740 | *endoff = start + n + length;
4741 | }
4742 |
4743 | if (err)
4744 | *err = failed ? EINVAL22 : 0;
4745 |
4746 | 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); }
4747 | {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4748 | 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); }
4749 | 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); }
4750 | 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); }
4751 | bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4752 | } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); };
4753 |
4754 | 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", 4760 , __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", 4760, "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", 4760, "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", 4760 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { if (created_bytes) g_byte_array_free(created_bytes, 1) ; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node (tree, hfinfo); } } }
4755 | {((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", 4760 , __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", 4760, "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", 4760, "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", 4760 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { if (created_bytes) g_byte_array_free(created_bytes, 1) ; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node (tree, hfinfo); } } }
4756 | 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", 4760 , __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", 4760, "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", 4760, "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", 4760 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { if (created_bytes) g_byte_array_free(created_bytes, 1) ; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node (tree, hfinfo); } } }
4757 | 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", 4760 , __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", 4760, "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", 4760, "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", 4760 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { if (created_bytes) g_byte_array_free(created_bytes, 1) ; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node (tree, hfinfo); } } }
4758 | 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", 4760 , __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", 4760, "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", 4760, "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", 4760 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { if (created_bytes) g_byte_array_free(created_bytes, 1) ; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node (tree, hfinfo); } } }
4759 | 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", 4760 , __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", 4760, "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", 4760, "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", 4760 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { if (created_bytes) g_byte_array_free(created_bytes, 1) ; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node (tree, hfinfo); } } }
4760 | } )((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", 4760 , __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", 4760, "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", 4760, "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", 4760 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { if (created_bytes) g_byte_array_free(created_bytes, 1) ; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node (tree, hfinfo); } } };
4761 |
4762 | /* n will be zero except when it's a FT_UINT_BYTES */
4763 | new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4764 |
4765 | if (encoding & ENC_STRING0x07000000) {
4766 | if (failed)
4767 | expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4768 |
4769 | if (bytes)
4770 | proto_tree_set_bytes_gbytearray(new_fi, bytes);
4771 | else
4772 | proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4773 |
4774 | if (created_bytes)
4775 | g_byte_array_free(created_bytes, true1);
4776 | }
4777 | else {
4778 | /* n will be zero except when it's a FT_UINT_BYTES */
4779 | proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4780 |
4781 | /* XXX: If we have a non-NULL tree but NULL retval, we don't
4782 | * use the byte array created above in this case.
4783 | */
4784 | if (created_bytes)
4785 | g_byte_array_free(created_bytes, true1);
4786 |
4787 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4788 | (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);
4789 | }
4790 |
4791 | return proto_tree_add_node(tree, new_fi);
4792 | }
4793 |
4794 |
4795 | proto_item *
4796 | proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4797 | const unsigned start, const unsigned length,
4798 | const unsigned encoding,
4799 | nstime_t *retval, unsigned *endoff, int *err)
4800 | {
4801 | field_info *new_fi;
4802 | nstime_t time_stamp;
4803 | int saved_err = 0;
4804 | header_field_info *hfinfo;
4805 |
4806 | 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", 4806, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4806, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4806, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4807 |
4808 | 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", 4808, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4809 |
4810 | if (length == 0) {
4811 | if(retval) {
4812 | nstime_set_zero(retval);
4813 | }
4814 | return NULL((void*)0);
4815 | }
4816 |
4817 | nstime_set_zero(&time_stamp);
4818 |
4819 | if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4820 | 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", 4820, ((hfinfo))->abbrev))));
4821 | /* The only string format that could be a relative time is
4822 | * ENC_ISO_8601_TIME, and that is treated as an absolute time
4823 | * relative to "now" currently.
4824 | */
4825 | if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4826 | saved_err = EINVAL22;
4827 | }
4828 | else {
4829 | 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", 4829, ((hfinfo))->abbrev))));
4830 | const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4831 |
4832 | tvb_ensure_bytes_exist(tvb, start, length);
4833 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4834 | if (endoff) *endoff = start + length;
4835 | }
4836 |
4837 | if (err) *err = saved_err;
4838 |
4839 | if (retval) {
4840 | retval->secs = time_stamp.secs;
4841 | retval->nsecs = time_stamp.nsecs;
4842 | }
4843 |
4844 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4845 |
4846 | 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", 4846 , __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", 4846, "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", 4846, "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", 4846, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4847 |
4848 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4849 |
4850 | proto_tree_set_time(new_fi, &time_stamp);
4851 |
4852 | if (encoding & ENC_STRING0x07000000) {
4853 | if (saved_err)
4854 | expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4855 | }
4856 | else {
4857 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4858 | (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);
4859 | }
4860 |
4861 | return proto_tree_add_node(tree, new_fi);
4862 | }
4863 |
4864 | /* Add a FT_NONE to a proto_tree */
4865 | proto_item *
4866 | proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4867 | const unsigned start, int length, const char *format,
4868 | ...)
4869 | {
4870 | proto_item *pi;
4871 | va_list ap;
4872 | header_field_info *hfinfo;
4873 |
4874 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4875 |
4876 | TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4876 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4876, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4876, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4876, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4877 |
4878 | DISSECTOR_ASSERT_FIELD_TYPE(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", 4878 , ((hfinfo))->abbrev))));
4879 |
4880 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4881 |
4882 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4882, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4883 |
4884 | va_start(ap, format)__builtin_va_start(ap, format);
4885 | proto_tree_set_representation(pi, format, ap);
4886 | va_end(ap)__builtin_va_end(ap);
4887 |
4888 | /* no value to set for FT_NONE */
4889 | return pi;
4890 | }
4891 |
4892 | /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4893 | * offset, and returns proto_item* */
4894 | proto_item *
4895 | ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4896 | const unsigned encoding)
4897 | {
4898 | proto_item *item;
4899 |
4900 | item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4901 | length, encoding);
4902 |
4903 | return item;
4904 | }
4905 |
4906 | /* Advance the ptvcursor's offset within its tvbuff without
4907 | * adding anything to the proto_tree. */
4908 | void
4909 | ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4910 | {
4911 | if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc ->offset))) {
4912 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4913 | }
4914 | }
4915 |
4916 |
4917 | static void
4918 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4919 | {
4920 | ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full( "Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4920, __func__, "assertion failed: %s" , "length >= 0"); } while (0);
4921 | fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4922 | }
4923 |
4924 | /* Add a FT_PROTOCOL to a proto_tree */
4925 | proto_item *
4926 | proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4927 | unsigned start, int length, const char *format, ...)
4928 | {
4929 | proto_item *pi;
4930 | field_info *new_fi;
4931 | tvbuff_t *protocol_tvb;
4932 | va_list ap;
4933 | header_field_info *hfinfo;
4934 | char* protocol_rep;
4935 |
4936 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4937 |
4938 | 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", 4938 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4938, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4938, "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", 4938, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4939 |
4940 | 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" , 4940, ((hfinfo))->abbrev))));
4941 |
4942 | /*
4943 | * This can throw an exception when it calls get_hfi_length before
4944 | * it allocates anything, if length is nonzero and start is past
4945 | * the end of the tvb. Afterwards it can't throw an exception,
4946 | * as length is clamped to the captured length remaining.
4947 | */
4948 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4949 | new_fi = PNODE_FINFO(pi)((pi)->finfo);
4950 | /* Start the protocol_tvb at the correct start offset, but allow it
4951 | * to be lengthened later via finfo_set_len. */
4952 | protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4953 |
4954 | va_start(ap, format)__builtin_va_start(ap, format);
4955 | protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4956 | proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4957 | g_free(protocol_rep)(__builtin_object_size ((protocol_rep), 0) != ((size_t) - 1)) ? g_free_sized (protocol_rep, __builtin_object_size ((protocol_rep ), 0)) : (g_free) (protocol_rep);
4958 | va_end(ap)__builtin_va_end(ap);
4959 |
4960 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4960, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4961 |
4962 | va_start(ap, format)__builtin_va_start(ap, format);
4963 | proto_tree_set_representation(pi, format, ap);
4964 | va_end(ap)__builtin_va_end(ap);
4965 |
4966 | return pi;
4967 | }
4968 |
4969 | /* Add a FT_BYTES to a proto_tree */
4970 | proto_item *
4971 | proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4972 | int length, const uint8_t *start_ptr)
4973 | {
4974 | proto_item *pi;
4975 | header_field_info *hfinfo;
4976 | int item_length;
4977 |
4978 | 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", 4978, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4978, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4978, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4979 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4980 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4981 |
4982 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4983 |
4984 | 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", 4984 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4984, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4984, "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", 4984, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4985 |
4986 | 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", 4986, ((hfinfo))->abbrev))));
4987 |
4988 | if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4989 | start_ptr = tvb_get_ptr(tvb, start, length);
4990 |
4991 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4992 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4993 |
4994 | return pi;
4995 | }
4996 |
4997 | /* Add a FT_BYTES to a proto_tree */
4998 | proto_item *
4999 | proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5000 | int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
5001 | {
5002 | proto_item *pi;
5003 | header_field_info *hfinfo;
5004 | int item_length;
5005 |
5006 | 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", 5006, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5006, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5006, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
5007 | get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
5008 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5009 |
5010 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5011 |
5012 | 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", 5012 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5012, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5012, "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", 5012, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5013 |
5014 | 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", 5014, ((hfinfo))->abbrev))));
5015 |
5016 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
5017 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
5018 |
5019 | return pi;
5020 | }
5021 |
5022 | proto_item *
5023 | proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5024 | unsigned start, int length,
5025 | const uint8_t *start_ptr,
5026 | const char *format, ...)
5027 | {
5028 | proto_item *pi;
5029 | va_list ap;
5030 |
5031 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5032 |
5033 | TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) || (!(((pi)->tree_data)->visible) && proto_item_is_hidden ((pi)))) { return pi; };
5034 |
5035 | va_start(ap, format)__builtin_va_start(ap, format);
5036 | proto_tree_set_representation_value(pi, format, ap);
5037 | va_end(ap)__builtin_va_end(ap);
5038 |
5039 | return pi;
5040 | }
5041 |
5042 | proto_item *
5043 | proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5044 | unsigned start, int length, const uint8_t *start_ptr,
5045 | const char *format, ...)
5046 | {
5047 | proto_item *pi;
5048 | va_list ap;
5049 |
5050 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5051 |
5052 | TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) || (!(((pi)->tree_data)->visible) && proto_item_is_hidden ((pi)))) { return pi; };
5053 |
5054 | va_start(ap, format)__builtin_va_start(ap, format);
5055 | proto_tree_set_representation(pi, format, ap);
5056 | va_end(ap)__builtin_va_end(ap);
5057 |
5058 | return pi;
5059 | }
5060 |
5061 | static void
5062 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
5063 | {
5064 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5064, "length >= 0" ))));
5065 | 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", 5065, "start_ptr != ((void*)0) || length == 0" ))));
5066 |
5067 | fvalue_set_bytes_data(fi->value, start_ptr, length);
5068 | }
5069 |
5070 |
5071 | static void
5072 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
5073 | {
5074 | tvb_ensure_bytes_exist(tvb, offset, length);
5075 | proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
5076 | }
5077 |
5078 | static void
5079 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
5080 | {
5081 | GByteArray *bytes;
5082 |
5083 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5083, "value != ((void*)0)" ))));
5084 |
5085 | bytes = byte_array_dup(value);
5086 |
5087 | fvalue_set_byte_array(fi->value, bytes);
5088 | }
5089 |
5090 | /* Add a FT_*TIME to a proto_tree */
5091 | proto_item *
5092 | proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5093 | unsigned length, const nstime_t *value_ptr)
5094 | {
5095 | proto_item *pi;
5096 | header_field_info *hfinfo;
5097 |
5098 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5099 |
5100 | 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", 5100 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5100, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5100, "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", 5100, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5101 |
5102 | 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", 5102, ((hfinfo))->abbrev))));
5103 |
5104 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5105 | proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5106 |
5107 | return pi;
5108 | }
5109 |
5110 | proto_item *
5111 | proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5112 | unsigned start, unsigned length, nstime_t *value_ptr,
5113 | const char *format, ...)
5114 | {
5115 | proto_item *pi;
5116 | va_list ap;
5117 |
5118 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5119 | if (pi != tree) {
5120 | va_start(ap, format)__builtin_va_start(ap, format);
5121 | proto_tree_set_representation_value(pi, format, ap);
5122 | va_end(ap)__builtin_va_end(ap);
5123 | }
5124 |
5125 | return pi;
5126 | }
5127 |
5128 | proto_item *
5129 | proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5130 | unsigned start, unsigned length, nstime_t *value_ptr,
5131 | const char *format, ...)
5132 | {
5133 | proto_item *pi;
5134 | va_list ap;
5135 |
5136 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5137 | if (pi != tree) {
5138 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5138, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5139 |
5140 | va_start(ap, format)__builtin_va_start(ap, format);
5141 | proto_tree_set_representation(pi, format, ap);
5142 | va_end(ap)__builtin_va_end(ap);
5143 | }
5144 |
5145 | return pi;
5146 | }
5147 |
5148 | /* Set the FT_*TIME value */
5149 | static void
5150 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5151 | {
5152 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5152, "value_ptr != ((void*)0)" ))));
5153 |
5154 | fvalue_set_time(fi->value, value_ptr);
5155 | }
5156 |
5157 | /* Add a FT_IPXNET to a proto_tree */
5158 | proto_item *
5159 | proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5160 | unsigned length, uint32_t value)
5161 | {
5162 | proto_item *pi;
5163 | header_field_info *hfinfo;
5164 |
5165 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5166 |
5167 | 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", 5167 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5167, "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", 5167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5168 |
5169 | 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" , 5169, ((hfinfo))->abbrev))));
5170 |
5171 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5172 | proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5173 |
5174 | return pi;
5175 | }
5176 |
5177 | proto_item *
5178 | proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5179 | unsigned start, unsigned length, uint32_t value,
5180 | const char *format, ...)
5181 | {
5182 | proto_item *pi;
5183 | va_list ap;
5184 |
5185 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5186 | if (pi != tree) {
5187 | va_start(ap, format)__builtin_va_start(ap, format);
5188 | proto_tree_set_representation_value(pi, format, ap);
5189 | va_end(ap)__builtin_va_end(ap);
5190 | }
5191 |
5192 | return pi;
5193 | }
5194 |
5195 | proto_item *
5196 | proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5197 | unsigned start, unsigned length, uint32_t value,
5198 | const char *format, ...)
5199 | {
5200 | proto_item *pi;
5201 | va_list ap;
5202 |
5203 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5204 | if (pi != tree) {
5205 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5205, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5206 |
5207 | va_start(ap, format)__builtin_va_start(ap, format);
5208 | proto_tree_set_representation(pi, format, ap);
5209 | va_end(ap)__builtin_va_end(ap);
5210 | }
5211 |
5212 | return pi;
5213 | }
5214 |
5215 | /* Set the FT_IPXNET value */
5216 | static void
5217 | proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5218 | {
5219 | fvalue_set_uinteger(fi->value, value);
5220 | }
5221 |
5222 | /* Add a FT_IPv4 to a proto_tree */
5223 | proto_item *
5224 | proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5225 | unsigned length, ws_in4_addr value)
5226 | {
5227 | proto_item *pi;
5228 | header_field_info *hfinfo;
5229 |
5230 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5231 |
5232 | 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", 5232 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5232, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5232, "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", 5232, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5233 |
5234 | 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", 5234 , ((hfinfo))->abbrev))));
5235 |
5236 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5237 | proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5238 |
5239 | return pi;
5240 | }
5241 |
5242 | proto_item *
5243 | proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5244 | unsigned start, unsigned length, ws_in4_addr value,
5245 | const char *format, ...)
5246 | {
5247 | proto_item *pi;
5248 | va_list ap;
5249 |
5250 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5251 | if (pi != tree) {
5252 | va_start(ap, format)__builtin_va_start(ap, format);
5253 | proto_tree_set_representation_value(pi, format, ap);
5254 | va_end(ap)__builtin_va_end(ap);
5255 | }
5256 |
5257 | return pi;
5258 | }
5259 |
5260 | proto_item *
5261 | proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5262 | unsigned start, unsigned length, ws_in4_addr value,
5263 | const char *format, ...)
5264 | {
5265 | proto_item *pi;
5266 | va_list ap;
5267 |
5268 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5269 | if (pi != tree) {
5270 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5270, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5271 |
5272 | va_start(ap, format)__builtin_va_start(ap, format);
5273 | proto_tree_set_representation(pi, format, ap);
5274 | va_end(ap)__builtin_va_end(ap);
5275 | }
5276 |
5277 | return pi;
5278 | }
5279 |
5280 | /* Set the FT_IPv4 value */
5281 | static void
5282 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5283 | {
5284 | ipv4_addr_and_mask ipv4;
5285 | ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5286 | fvalue_set_ipv4(fi->value, &ipv4);
5287 | }
5288 |
5289 | /* Add a FT_IPv6 to a proto_tree */
5290 | proto_item *
5291 | proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5292 | unsigned length, const ws_in6_addr *value)
5293 | {
5294 | proto_item *pi;
5295 | header_field_info *hfinfo;
5296 |
5297 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5298 |
5299 | 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", 5299 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5299, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5299, "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", 5299, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5300 |
5301 | 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", 5301 , ((hfinfo))->abbrev))));
5302 |
5303 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5304 | proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5305 |
5306 | return pi;
5307 | }
5308 |
5309 | proto_item *
5310 | proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5311 | unsigned start, unsigned length,
5312 | const ws_in6_addr *value_ptr,
5313 | const char *format, ...)
5314 | {
5315 | proto_item *pi;
5316 | va_list ap;
5317 |
5318 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5319 | if (pi != tree) {
5320 | va_start(ap, format)__builtin_va_start(ap, format);
5321 | proto_tree_set_representation_value(pi, format, ap);
5322 | va_end(ap)__builtin_va_end(ap);
5323 | }
5324 |
5325 | return pi;
5326 | }
5327 |
5328 | proto_item *
5329 | proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5330 | unsigned start, unsigned length,
5331 | const ws_in6_addr *value_ptr,
5332 | const char *format, ...)
5333 | {
5334 | proto_item *pi;
5335 | va_list ap;
5336 |
5337 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5338 | if (pi != tree) {
5339 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5339, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5340 |
5341 | va_start(ap, format)__builtin_va_start(ap, format);
5342 | proto_tree_set_representation(pi, format, ap);
5343 | va_end(ap)__builtin_va_end(ap);
5344 | }
5345 |
5346 | return pi;
5347 | }
5348 |
5349 | /* Set the FT_IPv6 value */
5350 | static void
5351 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5352 | {
5353 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5353, "value != ((void*)0)" ))));
5354 | ipv6_addr_and_prefix ipv6;
5355 | ipv6.addr = *value;
5356 | ipv6.prefix = 128;
5357 | fvalue_set_ipv6(fi->value, &ipv6);
5358 | }
5359 |
5360 | static void
5361 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5362 | {
5363 | proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5364 | }
5365 |
5366 | /* Set the FT_FCWWN value */
5367 | static void
5368 | proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5369 | {
5370 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5370, "value_ptr != ((void*)0)" ))));
5371 | fvalue_set_fcwwn(fi->value, value_ptr);
5372 | }
5373 |
5374 | static void
5375 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5376 | {
5377 | proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5378 | }
5379 |
5380 | /* Add a FT_GUID to a proto_tree */
5381 | proto_item *
5382 | proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5383 | unsigned length, const e_guid_t *value_ptr)
5384 | {
5385 | proto_item *pi;
5386 | header_field_info *hfinfo;
5387 |
5388 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5389 |
5390 | 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", 5390 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5390, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5390, "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", 5390, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5391 |
5392 | 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", 5392 , ((hfinfo))->abbrev))));
5393 |
5394 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5395 | proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5396 |
5397 | return pi;
5398 | }
5399 |
5400 | proto_item *
5401 | proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5402 | unsigned start, unsigned length,
5403 | const e_guid_t *value_ptr,
5404 | const char *format, ...)
5405 | {
5406 | proto_item *pi;
5407 | va_list ap;
5408 |
5409 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5410 | if (pi != tree) {
5411 | va_start(ap, format)__builtin_va_start(ap, format);
5412 | proto_tree_set_representation_value(pi, format, ap);
5413 | va_end(ap)__builtin_va_end(ap);
5414 | }
5415 |
5416 | return pi;
5417 | }
5418 |
5419 | proto_item *
5420 | proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5421 | unsigned start, unsigned length, const e_guid_t *value_ptr,
5422 | const char *format, ...)
5423 | {
5424 | proto_item *pi;
5425 | va_list ap;
5426 |
5427 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5428 | if (pi != tree) {
5429 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5429, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5430 |
5431 | va_start(ap, format)__builtin_va_start(ap, format);
5432 | proto_tree_set_representation(pi, format, ap);
5433 | va_end(ap)__builtin_va_end(ap);
5434 | }
5435 |
5436 | return pi;
5437 | }
5438 |
5439 | /* Set the FT_GUID value */
5440 | static void
5441 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5442 | {
5443 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5443, "value_ptr != ((void*)0)" ))));
5444 | fvalue_set_guid(fi->value, value_ptr);
5445 | }
5446 |
5447 | static void
5448 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5449 | const unsigned encoding)
5450 | {
5451 | e_guid_t guid;
5452 |
5453 | tvb_get_guid(tvb, start, &guid, encoding);
5454 | proto_tree_set_guid(fi, &guid);
5455 | }
5456 |
5457 | /* Add a FT_OID to a proto_tree */
5458 | proto_item *
5459 | proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5460 | unsigned length, const uint8_t* value_ptr)
5461 | {
5462 | proto_item *pi;
5463 | header_field_info *hfinfo;
5464 |
5465 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5466 |
5467 | 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", 5467 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5467, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5467, "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", 5467, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5468 |
5469 | 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", 5469 , ((hfinfo))->abbrev))));
5470 |
5471 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5472 | proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5473 |
5474 | return pi;
5475 | }
5476 |
5477 | proto_item *
5478 | proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5479 | unsigned start, unsigned length,
5480 | const uint8_t* value_ptr,
5481 | const char *format, ...)
5482 | {
5483 | proto_item *pi;
5484 | va_list ap;
5485 |
5486 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5487 | if (pi != tree) {
5488 | va_start(ap, format)__builtin_va_start(ap, format);
5489 | proto_tree_set_representation_value(pi, format, ap);
5490 | va_end(ap)__builtin_va_end(ap);
5491 | }
5492 |
5493 | return pi;
5494 | }
5495 |
5496 | proto_item *
5497 | proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5498 | unsigned start, unsigned length, const uint8_t* value_ptr,
5499 | const char *format, ...)
5500 | {
5501 | proto_item *pi;
5502 | va_list ap;
5503 |
5504 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5505 | if (pi != tree) {
5506 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5506, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5507 |
5508 | va_start(ap, format)__builtin_va_start(ap, format);
5509 | proto_tree_set_representation(pi, format, ap);
5510 | va_end(ap)__builtin_va_end(ap);
5511 | }
5512 |
5513 | return pi;
5514 | }
5515 |
5516 | /* Set the FT_OID value */
5517 | static void
5518 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5519 | {
5520 | GByteArray *bytes;
5521 |
5522 | 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", 5522, "value_ptr != ((void*)0) || length == 0" ))));
5523 |
5524 | bytes = g_byte_array_new();
5525 | if (length > 0) {
5526 | g_byte_array_append(bytes, value_ptr, length);
5527 | }
5528 | fvalue_set_byte_array(fi->value, bytes);
5529 | }
5530 |
5531 | static void
5532 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5533 | {
5534 | proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5535 | }
5536 |
5537 | /* Set the FT_SYSTEM_ID value */
5538 | static void
5539 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5540 | {
5541 | GByteArray *bytes;
5542 |
5543 | 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", 5543, "value_ptr != ((void*)0) || length == 0" ))));
5544 |
5545 | bytes = g_byte_array_new();
5546 | if (length > 0) {
5547 | g_byte_array_append(bytes, value_ptr, length);
5548 | }
5549 | fvalue_set_byte_array(fi->value, bytes);
5550 | }
5551 |
5552 | static void
5553 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5554 | {
5555 | proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5556 | }
5557 |
5558 | /* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5559 | * proto_tree. Creates own copy of string, and frees it when the proto_tree
5560 | * is destroyed. */
5561 | proto_item *
5562 | proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5563 | int length, const char* value)
5564 | {
5565 | proto_item *pi;
5566 | header_field_info *hfinfo;
5567 | int item_length;
5568 |
5569 | 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", 5569, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5569, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5569, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
5570 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5571 | /*
5572 | * Special case - if the length is 0, skip the test, so that
5573 | * we can have an empty string right after the end of the
5574 | * packet. (This handles URL-encoded forms where the last field
5575 | * has no value so the form ends right after the =.)
5576 | *
5577 | * XXX - length zero makes sense for FT_STRING, and more or less
5578 | * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5579 | * for FT_STRINGZ (except that a number of fields that should be
5580 | * one of the others are actually registered as FT_STRINGZ.)
5581 | */
5582 | if (item_length != 0)
5583 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5584 |
5585 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5586 |
5587 | 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", 5587 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5587, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5587, "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", 5587, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5588 |
5589 | 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", 5589, ((hfinfo))->abbrev))));
5590 |
5591 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5592 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5592, "length >= 0" ))));
5593 |
5594 | 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", 5594, __func__, value, -1, __uni_endptr); } } while (0); } } while (0);
5595 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5596 |
5597 | return pi;
5598 | }
5599 |
5600 | proto_item *
5601 | proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5602 | unsigned start, int length, const char* value,
5603 | const char *format,
5604 | ...)
5605 | {
5606 | proto_item *pi;
5607 | va_list ap;
5608 |
5609 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5610 | if (pi != tree) {
5611 | va_start(ap, format)__builtin_va_start(ap, format);
5612 | proto_tree_set_representation_value(pi, format, ap);
5613 | va_end(ap)__builtin_va_end(ap);
5614 | }
5615 |
5616 | return pi;
5617 | }
5618 |
5619 | proto_item *
5620 | proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5621 | unsigned start, int length, const char* value,
5622 | const char *format, ...)
5623 | {
5624 | proto_item *pi;
5625 | va_list ap;
5626 |
5627 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5628 | if (pi != tree) {
5629 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5629, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5630 |
5631 | va_start(ap, format)__builtin_va_start(ap, format);
5632 | proto_tree_set_representation(pi, format, ap);
5633 | va_end(ap)__builtin_va_end(ap);
5634 | }
5635 |
5636 | return pi;
5637 | }
5638 |
5639 | /* Set the FT_STRING value */
5640 | static void
5641 | proto_tree_set_string(field_info *fi, const char* value)
5642 | {
5643 | if (value) {
5644 | fvalue_set_string(fi->value, value);
5645 | } else {
5646 | /*
5647 | * XXX - why is a null value for a string field
5648 | * considered valid?
5649 | */
5650 | fvalue_set_string(fi->value, "[ Null ]");
5651 | }
5652 | }
5653 |
5654 | /* Set the FT_AX25 value */
5655 | static void
5656 | proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5657 | {
5658 | fvalue_set_ax25(fi->value, value);
5659 | }
5660 |
5661 | static void
5662 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5663 | {
5664 | proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5665 | }
5666 |
5667 | /* Set the FT_VINES value */
5668 | static void
5669 | proto_tree_set_vines(field_info *fi, const uint8_t* value)
5670 | {
5671 | fvalue_set_vines(fi->value, value);
5672 | }
5673 |
5674 | static void
5675 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5676 | {
5677 | proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5678 | }
5679 |
5680 | /* Add a FT_ETHER to a proto_tree */
5681 | proto_item *
5682 | proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5683 | unsigned length, const uint8_t* value)
5684 | {
5685 | proto_item *pi;
5686 | header_field_info *hfinfo;
5687 |
5688 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5689 |
5690 | 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", 5690 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5690, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5690, "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", 5690, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5691 |
5692 | 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", 5692, ((hfinfo))->abbrev))));
5693 |
5694 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5695 | proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5696 |
5697 | return pi;
5698 | }
5699 |
5700 | proto_item *
5701 | proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5702 | unsigned start, unsigned length, const uint8_t* value,
5703 | const char *format, ...)
5704 | {
5705 | proto_item *pi;
5706 | va_list ap;
5707 |
5708 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5709 | if (pi != tree) {
5710 | va_start(ap, format)__builtin_va_start(ap, format);
5711 | proto_tree_set_representation_value(pi, format, ap);
5712 | va_end(ap)__builtin_va_end(ap);
5713 | }
5714 |
5715 | return pi;
5716 | }
5717 |
5718 | proto_item *
5719 | proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5720 | unsigned start, unsigned length, const uint8_t* value,
5721 | const char *format, ...)
5722 | {
5723 | proto_item *pi;
5724 | va_list ap;
5725 |
5726 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5727 | if (pi != tree) {
5728 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5728, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5729 |
5730 | va_start(ap, format)__builtin_va_start(ap, format);
5731 | proto_tree_set_representation(pi, format, ap);
5732 | va_end(ap)__builtin_va_end(ap);
5733 | }
5734 |
5735 | return pi;
5736 | }
5737 |
5738 | /* Set the FT_ETHER value */
5739 | static void
5740 | proto_tree_set_ether(field_info *fi, const uint8_t* value)
5741 | {
5742 | fvalue_set_ether(fi->value, value);
5743 | }
5744 |
5745 | static void
5746 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5747 | {
5748 | proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5749 | }
5750 |
5751 | /* Add a FT_BOOLEAN to a proto_tree */
5752 | proto_item *
5753 | proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5754 | unsigned length, uint64_t value)
5755 | {
5756 | proto_item *pi;
5757 | header_field_info *hfinfo;
5758 |
5759 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5760 |
5761 | TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5761 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5761, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5761, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5761, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5762 |
5763 | DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_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" , 5763, ((hfinfo))->abbrev))));
5764 |
5765 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5766 | proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5767 |
5768 | return pi;
5769 | }
5770 |
5771 | proto_item *
5772 | proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5773 | tvbuff_t *tvb, unsigned start, unsigned length,
5774 | uint64_t value, const char *format, ...)
5775 | {
5776 | proto_item *pi;
5777 | va_list ap;
5778 |
5779 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5780 | if (pi != tree) {
5781 | va_start(ap, format)__builtin_va_start(ap, format);
5782 | proto_tree_set_representation_value(pi, format, ap);
5783 | va_end(ap)__builtin_va_end(ap);
5784 | }
5785 |
5786 | return pi;
5787 | }
5788 |
5789 | proto_item *
5790 | proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5791 | unsigned start, unsigned length, uint64_t value,
5792 | const char *format, ...)
5793 | {
5794 | proto_item *pi;
5795 | va_list ap;
5796 |
5797 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5798 | if (pi != tree) {
5799 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5799, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5800 |
5801 | va_start(ap, format)__builtin_va_start(ap, format);
5802 | proto_tree_set_representation(pi, format, ap);
5803 | va_end(ap)__builtin_va_end(ap);
5804 | }
5805 |
5806 | return pi;
5807 | }
5808 |
5809 | /* Set the FT_BOOLEAN value */
5810 | static void
5811 | proto_tree_set_boolean(field_info *fi, uint64_t value)
5812 | {
5813 | proto_tree_set_uint64(fi, value);
5814 | }
5815 |
5816 | /* Generate, into "buf", a string showing the bits of a bitfield.
5817 | Return a pointer to the character after that string. */
5818 | static char *
5819 | other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5820 | {
5821 | int i = 0;
5822 | uint64_t bit;
5823 | char *p;
5824 |
5825 | p = buf;
5826 |
5827 | /* This is a devel error. It is safer to stop here. */
5828 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5828, "width >= 1" ))));
5829 |
5830 | bit = UINT64_C(1)1UL << (width - 1);
5831 | for (;;) {
5832 | if (mask & bit) {
5833 | /* This bit is part of the field. Show its value. */
5834 | if (val & bit)
5835 | *p++ = '1';
5836 | else
5837 | *p++ = '0';
5838 | } else {
5839 | /* This bit is not part of the field. */
5840 | *p++ = '.';
5841 | }
5842 | bit >>= 1;
5843 | i++;
5844 | if (i >= width)
5845 | break;
5846 | if (i % 4 == 0)
5847 | *p++ = ' ';
5848 | }
5849 | *p = '\0';
5850 | return p;
5851 | }
5852 |
5853 | static char *
5854 | decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5855 | {
5856 | char *p;
5857 |
5858 | p = other_decode_bitfield_value(buf, val, mask, width);
5859 | p = g_stpcpy(p, " = ");
5860 |
5861 | return p;
5862 | }
5863 |
5864 | static char *
5865 | other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5866 | {
5867 | int i = 0;
5868 | uint64_t bit;
5869 | char *p;
5870 |
5871 | p = buf;
5872 |
5873 | /* This is a devel error. It is safer to stop here. */
5874 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5874, "width >= 1" ))));
5875 |
5876 | bit = UINT64_C(1)1UL << (width - 1);
5877 | for (;;) {
5878 | if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5879 | (mask & bit)) {
5880 | /* This bit is part of the field. Show its value. */
5881 | if (val & bit)
5882 | *p++ = '1';
5883 | else
5884 | *p++ = '0';
5885 | } else {
5886 | /* This bit is not part of the field. */
5887 | *p++ = '.';
5888 | }
5889 | bit >>= 1;
5890 | i++;
5891 | if (i >= width)
5892 | break;
5893 | if (i % 4 == 0)
5894 | *p++ = ' ';
5895 | }
5896 |
5897 | *p = '\0';
5898 | return p;
5899 | }
5900 |
5901 | static char *
5902 | decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5903 | {
5904 | char *p;
5905 |
5906 | p = other_decode_bitfield_varint_value(buf, val, mask, width);
5907 | p = g_stpcpy(p, " = ");
5908 |
5909 | return p;
5910 | }
5911 |
5912 | /* Add a FT_FLOAT to a proto_tree */
5913 | proto_item *
5914 | proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5915 | unsigned length, float value)
5916 | {
5917 | proto_item *pi;
5918 | header_field_info *hfinfo;
5919 |
5920 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5921 |
5922 | 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", 5922 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5922, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5922, "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", 5922, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5923 |
5924 | 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", 5924, ((hfinfo))->abbrev))));
5925 |
5926 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5927 | proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5928 |
5929 | return pi;
5930 | }
5931 |
5932 | proto_item *
5933 | proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5934 | unsigned start, unsigned length, float value,
5935 | const char *format, ...)
5936 | {
5937 | proto_item *pi;
5938 | va_list ap;
5939 |
5940 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5941 | if (pi != tree) {
5942 | va_start(ap, format)__builtin_va_start(ap, format);
5943 | proto_tree_set_representation_value(pi, format, ap);
5944 | va_end(ap)__builtin_va_end(ap);
5945 | }
5946 |
5947 | return pi;
5948 | }
5949 |
5950 | proto_item *
5951 | proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5952 | unsigned start, unsigned length, float value,
5953 | const char *format, ...)
5954 | {
5955 | proto_item *pi;
5956 | va_list ap;
5957 |
5958 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5959 | if (pi != tree) {
5960 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5960, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5961 |
5962 | va_start(ap, format)__builtin_va_start(ap, format);
5963 | proto_tree_set_representation(pi, format, ap);
5964 | va_end(ap)__builtin_va_end(ap);
5965 | }
5966 |
5967 | return pi;
5968 | }
5969 |
5970 | /* Set the FT_FLOAT value */
5971 | static void
5972 | proto_tree_set_float(field_info *fi, float value)
5973 | {
5974 | fvalue_set_floating(fi->value, value);
5975 | }
5976 |
5977 | /* Add a FT_DOUBLE to a proto_tree */
5978 | proto_item *
5979 | proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5980 | unsigned length, double value)
5981 | {
5982 | proto_item *pi;
5983 | header_field_info *hfinfo;
5984 |
5985 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5986 |
5987 | 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", 5987 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5987, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5987, "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", 5987, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5988 |
5989 | 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" , 5989, ((hfinfo))->abbrev))));
5990 |
5991 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5992 | proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5993 |
5994 | return pi;
5995 | }
5996 |
5997 | proto_item *
5998 | proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5999 | unsigned start, unsigned length, double value,
6000 | const char *format, ...)
6001 | {
6002 | proto_item *pi;
6003 | va_list ap;
6004 |
6005 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6006 | if (pi != tree) {
6007 | va_start(ap, format)__builtin_va_start(ap, format);
6008 | proto_tree_set_representation_value(pi, format, ap);
6009 | va_end(ap)__builtin_va_end(ap);
6010 | }
6011 |
6012 | return pi;
6013 | }
6014 |
6015 | proto_item *
6016 | proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6017 | unsigned start, unsigned length, double value,
6018 | const char *format, ...)
6019 | {
6020 | proto_item *pi;
6021 | va_list ap;
6022 |
6023 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6024 | if (pi != tree) {
6025 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6025, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6026 |
6027 | va_start(ap, format)__builtin_va_start(ap, format);
6028 | proto_tree_set_representation(pi, format, ap);
6029 | va_end(ap)__builtin_va_end(ap);
6030 | }
6031 |
6032 | return pi;
6033 | }
6034 |
6035 | /* Set the FT_DOUBLE value */
6036 | static void
6037 | proto_tree_set_double(field_info *fi, double value)
6038 | {
6039 | fvalue_set_floating(fi->value, value);
6040 | }
6041 |
6042 | /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
6043 | proto_item *
6044 | proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6045 | unsigned length, uint32_t value)
6046 | {
6047 | proto_item *pi = NULL((void*)0);
6048 | header_field_info *hfinfo;
6049 |
6050 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6051 |
6052 | 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", 6052 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6052, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6052, "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", 6052, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
6053 |
6054 | switch (hfinfo->type) {
6055 | case FT_CHAR:
6056 | case FT_UINT8:
6057 | case FT_UINT16:
6058 | case FT_UINT24:
6059 | case FT_UINT32:
6060 | case FT_FRAMENUM:
6061 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6062 | proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
6063 | break;
6064 |
6065 | default:
6066 | 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)
6067 | 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);
6068 | }
6069 |
6070 | return pi;
6071 | }
6072 |
6073 | proto_item *
6074 | proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6075 | unsigned start, unsigned length, uint32_t value,
6076 | const char *format, ...)
6077 | {
6078 | proto_item *pi;
6079 | va_list ap;
6080 |
6081 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6082 | if (pi != tree) {
6083 | va_start(ap, format)__builtin_va_start(ap, format);
6084 | proto_tree_set_representation_value(pi, format, ap);
6085 | va_end(ap)__builtin_va_end(ap);
6086 | }
6087 |
6088 | return pi;
6089 | }
6090 |
6091 | proto_item *
6092 | proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6093 | unsigned start, unsigned length, uint32_t value,
6094 | const char *format, ...)
6095 | {
6096 | proto_item *pi;
6097 | va_list ap;
6098 |
6099 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6100 | if (pi != tree) {
6101 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6101, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6102 |
6103 | va_start(ap, format)__builtin_va_start(ap, format);
6104 | proto_tree_set_representation(pi, format, ap);
6105 | va_end(ap)__builtin_va_end(ap);
6106 | }
6107 |
6108 | return pi;
6109 | }
6110 |
6111 | /* Set the FT_UINT{8,16,24,32} value */
6112 | static void
6113 | proto_tree_set_uint(field_info *fi, uint32_t value)
6114 | {
6115 | const header_field_info *hfinfo;
6116 | uint32_t integer;
6117 |
6118 | hfinfo = fi->hfinfo;
6119 | integer = value;
6120 |
6121 | if (hfinfo->bitmask) {
6122 | /* Mask out irrelevant portions */
6123 | integer &= (uint32_t)(hfinfo->bitmask);
6124 |
6125 | /* Shift bits */
6126 | integer >>= hfinfo_bitshift(hfinfo);
6127 |
6128 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6129 | FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth (hfinfo)) & 63) << 12)); } while(0);
6130 | }
6131 |
6132 | fvalue_set_uinteger(fi->value, integer);
6133 | }
6134 |
6135 | /* Add FT_UINT{40,48,56,64} to a proto_tree */
6136 | proto_item *
6137 | proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6138 | unsigned length, uint64_t value)
6139 | {
6140 | proto_item *pi = NULL((void*)0);
6141 | header_field_info *hfinfo;
6142 |
6143 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6144 |
6145 | 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", 6145 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6145, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6145, "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", 6145, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
6146 |
6147 | switch (hfinfo->type) {
6148 | case FT_UINT40:
6149 | case FT_UINT48:
6150 | case FT_UINT56:
6151 | case FT_UINT64:
6152 | case FT_FRAMENUM:
6153 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6154 | proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6155 | break;
6156 |
6157 | default:
6158 | 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)
6159 | 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);
6160 | }
6161 |
6162 | return pi;
6163 | }
6164 |
6165 | proto_item *
6166 | proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6167 | unsigned start, unsigned length, uint64_t value,
6168 | const char *format, ...)
6169 | {
6170 | proto_item *pi;
6171 | va_list ap;
6172 |
6173 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6174 | if (pi != tree) {
6175 | va_start(ap, format)__builtin_va_start(ap, format);
6176 | proto_tree_set_representation_value(pi, format, ap);
6177 | va_end(ap)__builtin_va_end(ap);
6178 | }
6179 |
6180 | return pi;
6181 | }
6182 |
6183 | proto_item *
6184 | proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6185 | unsigned start, unsigned length, uint64_t value,
6186 | const char *format, ...)
6187 | {
6188 | proto_item *pi;
6189 | va_list ap;
6190 |
6191 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6192 | if (pi != tree) {
6193 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6193, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6194 |
6195 | va_start(ap, format)__builtin_va_start(ap, format);
6196 | proto_tree_set_representation(pi, format, ap);
6197 | va_end(ap)__builtin_va_end(ap);
6198 | }
6199 |
6200 | return pi;
6201 | }
6202 |
6203 | /* Set the FT_UINT{40,48,56,64} value */
6204 | static void
6205 | proto_tree_set_uint64(field_info *fi, uint64_t value)
6206 | {
6207 | const header_field_info *hfinfo;
6208 | uint64_t integer;
6209 |
6210 | hfinfo = fi->hfinfo;
6211 | integer = value;
6212 |
6213 | if (hfinfo->bitmask) {
6214 | /* Mask out irrelevant portions */
6215 | integer &= hfinfo->bitmask;
6216 |
6217 | /* Shift bits */
6218 | integer >>= hfinfo_bitshift(hfinfo);
6219 |
6220 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6221 | FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth (hfinfo)) & 63) << 12)); } while(0);
6222 | }
6223 |
6224 | fvalue_set_uinteger64(fi->value, integer);
6225 | }
6226 |
6227 | /* Add FT_INT{8,16,24,32} to a proto_tree */
6228 | proto_item *
6229 | proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6230 | unsigned length, int32_t value)
6231 | {
6232 | proto_item *pi = NULL((void*)0);
6233 | header_field_info *hfinfo;
6234 |
6235 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6236 |
6237 | 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", 6237 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6237, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6237, "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", 6237, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
6238 |
6239 | switch (hfinfo->type) {
6240 | case FT_INT8:
6241 | case FT_INT16:
6242 | case FT_INT24:
6243 | case FT_INT32:
6244 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6245 | proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6246 | break;
6247 |
6248 | default:
6249 | 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)
6250 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
6251 | }
6252 |
6253 | return pi;
6254 | }
6255 |
6256 | proto_item *
6257 | proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6258 | unsigned start, unsigned length, int32_t value,
6259 | const char *format, ...)
6260 | {
6261 | proto_item *pi;
6262 | va_list ap;
6263 |
6264 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6265 | if (pi != tree) {
6266 | va_start(ap, format)__builtin_va_start(ap, format);
6267 | proto_tree_set_representation_value(pi, format, ap);
6268 | va_end(ap)__builtin_va_end(ap);
6269 | }
6270 |
6271 | return pi;
6272 | }
6273 |
6274 | proto_item *
6275 | proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6276 | unsigned start, unsigned length, int32_t value,
6277 | const char *format, ...)
6278 | {
6279 | proto_item *pi;
6280 | va_list ap;
6281 |
6282 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6283 | if (pi != tree) {
6284 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6284, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6285 |
6286 | va_start(ap, format)__builtin_va_start(ap, format);
6287 | proto_tree_set_representation(pi, format, ap);
6288 | va_end(ap)__builtin_va_end(ap);
6289 | }
6290 |
6291 | return pi;
6292 | }
6293 |
6294 | /* Set the FT_INT{8,16,24,32} value */
6295 | static void
6296 | proto_tree_set_int(field_info *fi, int32_t value)
6297 | {
6298 | const header_field_info *hfinfo;
6299 | uint32_t integer;
6300 | int no_of_bits;
6301 |
6302 | hfinfo = fi->hfinfo;
6303 | integer = (uint32_t) value;
6304 |
6305 | if (hfinfo->bitmask) {
6306 | /* Mask out irrelevant portions */
6307 | integer &= (uint32_t)(hfinfo->bitmask);
6308 |
6309 | /* Shift bits */
6310 | integer >>= hfinfo_bitshift(hfinfo);
6311 |
6312 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6313 | integer = ws_sign_ext32(integer, no_of_bits);
6314 |
6315 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6316 | FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth (hfinfo)) & 63) << 12)); } while(0);
6317 | }
6318 |
6319 | fvalue_set_sinteger(fi->value, integer);
6320 | }
6321 |
6322 | /* Add FT_INT{40,48,56,64} to a proto_tree */
6323 | proto_item *
6324 | proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6325 | unsigned length, int64_t value)
6326 | {
6327 | proto_item *pi = NULL((void*)0);
6328 | header_field_info *hfinfo;
6329 |
6330 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6331 |
6332 | 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", 6332 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6332, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6332, "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", 6332, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
6333 |
6334 | switch (hfinfo->type) {
6335 | case FT_INT40:
6336 | case FT_INT48:
6337 | case FT_INT56:
6338 | case FT_INT64:
6339 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6340 | proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6341 | break;
6342 |
6343 | default:
6344 | 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)
6345 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
6346 | }
6347 |
6348 | return pi;
6349 | }
6350 |
6351 | proto_item *
6352 | proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6353 | unsigned start, unsigned length, int64_t value,
6354 | const char *format, ...)
6355 | {
6356 | proto_item *pi;
6357 | va_list ap;
6358 |
6359 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6360 | if (pi != tree) {
6361 | va_start(ap, format)__builtin_va_start(ap, format);
6362 | proto_tree_set_representation_value(pi, format, ap);
6363 | va_end(ap)__builtin_va_end(ap);
6364 | }
6365 |
6366 | return pi;
6367 | }
6368 |
6369 | /* Set the FT_INT{40,48,56,64} value */
6370 | static void
6371 | proto_tree_set_int64(field_info *fi, int64_t value)
6372 | {
6373 | const header_field_info *hfinfo;
6374 | uint64_t integer;
6375 | int no_of_bits;
6376 |
6377 | hfinfo = fi->hfinfo;
6378 | integer = value;
6379 |
6380 | if (hfinfo->bitmask) {
6381 | /* Mask out irrelevant portions */
6382 | integer &= hfinfo->bitmask;
6383 |
6384 | /* Shift bits */
6385 | integer >>= hfinfo_bitshift(hfinfo);
6386 |
6387 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6388 | integer = ws_sign_ext64(integer, no_of_bits);
6389 |
6390 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6391 | FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth (hfinfo)) & 63) << 12)); } while(0);
6392 | }
6393 |
6394 | fvalue_set_sinteger64(fi->value, integer);
6395 | }
6396 |
6397 | proto_item *
6398 | proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6399 | unsigned start, unsigned length, int64_t value,
6400 | const char *format, ...)
6401 | {
6402 | proto_item *pi;
6403 | va_list ap;
6404 |
6405 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6406 | if (pi != tree) {
6407 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6407, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6408 |
6409 | va_start(ap, format)__builtin_va_start(ap, format);
6410 | proto_tree_set_representation(pi, format, ap);
6411 | va_end(ap)__builtin_va_end(ap);
6412 | }
6413 |
6414 | return pi;
6415 | }
6416 |
6417 | /* Add a FT_EUI64 to a proto_tree */
6418 | proto_item *
6419 | proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6420 | unsigned length, const uint64_t value)
6421 | {
6422 | proto_item *pi;
6423 | header_field_info *hfinfo;
6424 |
6425 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6426 |
6427 | 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", 6427 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6427, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6427, "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", 6427, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
6428 |
6429 | 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", 6429, ((hfinfo))->abbrev))));
6430 |
6431 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6432 | proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6433 |
6434 | return pi;
6435 | }
6436 |
6437 | proto_item *
6438 | proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6439 | unsigned start, unsigned length, const uint64_t value,
6440 | const char *format, ...)
6441 | {
6442 | proto_item *pi;
6443 | va_list ap;
6444 |
6445 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6446 | if (pi != tree) {
6447 | va_start(ap, format)__builtin_va_start(ap, format);
6448 | proto_tree_set_representation_value(pi, format, ap);
6449 | va_end(ap)__builtin_va_end(ap);
6450 | }
6451 |
6452 | return pi;
6453 | }
6454 |
6455 | proto_item *
6456 | proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6457 | unsigned start, unsigned length, const uint64_t value,
6458 | const char *format, ...)
6459 | {
6460 | proto_item *pi;
6461 | va_list ap;
6462 |
6463 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6464 | if (pi != tree) {
6465 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6465, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6466 |
6467 | va_start(ap, format)__builtin_va_start(ap, format);
6468 | proto_tree_set_representation(pi, format, ap);
6469 | va_end(ap)__builtin_va_end(ap);
6470 | }
6471 |
6472 | return pi;
6473 | }
6474 |
6475 | /* Set the FT_EUI64 value */
6476 | static void
6477 | proto_tree_set_eui64(field_info *fi, const uint64_t value)
6478 | {
6479 | uint8_t v[FT_EUI64_LEN8];
6480 | phtonu64(v, value);
6481 | fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6482 | }
6483 |
6484 | static void
6485 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6486 | {
6487 | if (encoding)
6488 | {
6489 | proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6490 | } else {
6491 | proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6492 | }
6493 | }
6494 |
6495 | proto_item *
6496 | proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6497 | const mac_hf_list_t *list_generic,
6498 | int idx, tvbuff_t *tvb,
6499 | proto_tree *tree, unsigned offset)
6500 | {
6501 | uint8_t addr[6];
6502 | const char *addr_name = NULL((void*)0);
6503 | const char *oui_name = NULL((void*)0);
6504 | proto_item *addr_item = NULL((void*)0);
6505 | proto_tree *addr_tree = NULL((void*)0);
6506 | proto_item *ret_val = NULL((void*)0);
6507 |
6508 | if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6509 | return NULL((void*)0);
6510 | }
6511 |
6512 | /* Resolve what we can of the address */
6513 | tvb_memcpy(tvb, addr, offset, sizeof addr);
6514 | if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6515 | addr_name = get_ether_name(addr);
6516 | }
6517 | if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6518 | oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6519 | }
6520 |
6521 | /* Add the item for the specific address type */
6522 | ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6523 | if (idx >= 0) {
6524 | addr_tree = proto_item_add_subtree(ret_val, idx);
6525 | }
6526 | else {
6527 | addr_tree = tree;
6528 | }
6529 |
6530 | if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6531 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6532 | tvb, offset, 6, addr_name);
6533 | proto_item_set_generated(addr_item);
6534 | proto_item_set_hidden(addr_item);
6535 | }
6536 |
6537 | if (list_specific->hf_oui != NULL((void*)0)) {
6538 | addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6539 | proto_item_set_generated(addr_item);
6540 | proto_item_set_hidden(addr_item);
6541 |
6542 | if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6543 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6544 | proto_item_set_generated(addr_item);
6545 | proto_item_set_hidden(addr_item);
6546 | }
6547 | }
6548 |
6549 | if (list_specific->hf_lg != NULL((void*)0)) {
6550 | proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6551 | }
6552 | if (list_specific->hf_ig != NULL((void*)0)) {
6553 | proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6554 | }
6555 |
6556 | /* Were we given a list for generic address fields? If not, stop here */
6557 | if (list_generic == NULL((void*)0)) {
6558 | return ret_val;
6559 | }
6560 |
6561 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6562 | proto_item_set_hidden(addr_item);
6563 |
6564 | if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6565 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6566 | tvb, offset, 6, addr_name);
6567 | proto_item_set_generated(addr_item);
6568 | proto_item_set_hidden(addr_item);
6569 | }
6570 |
6571 | if (list_generic->hf_oui != NULL((void*)0)) {
6572 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6573 | proto_item_set_generated(addr_item);
6574 | proto_item_set_hidden(addr_item);
6575 |
6576 | if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6577 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6578 | proto_item_set_generated(addr_item);
6579 | proto_item_set_hidden(addr_item);
6580 | }
6581 | }
6582 |
6583 | if (list_generic->hf_lg != NULL((void*)0)) {
6584 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6585 | proto_item_set_hidden(addr_item);
6586 | }
6587 | if (list_generic->hf_ig != NULL((void*)0)) {
6588 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6589 | proto_item_set_hidden(addr_item);
6590 | }
6591 | return ret_val;
6592 | }
6593 |
6594 | static proto_item *
6595 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6596 | {
6597 | proto_node *pnode, *tnode, *sibling;
6598 | field_info *tfi;
6599 | unsigned depth = 1;
6600 |
6601 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6601, __func__, "assertion failed: %s", "tree" ); } while (0);
6602 |
6603 | /*
6604 | * Restrict our depth. proto_tree_traverse_pre_order and
6605 | * proto_tree_traverse_post_order (and possibly others) are recursive
6606 | * so we need to be mindful of our stack size.
6607 | */
6608 | if (tree->first_child == NULL((void*)0)) {
6609 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6610 | depth++;
6611 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6612 | THROW_MESSAGE(DissectorError, wmem_strdup_printf(PNODE_POOL(tree),except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)" , prefs.gui_max_tree_depth, hfinfo->name, hfinfo->abbrev , ((const char*) (__func__)), 6615)))
6613 | "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)",except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)" , prefs.gui_max_tree_depth, hfinfo->name, hfinfo->abbrev , ((const char*) (__func__)), 6615)))
6614 | prefs.gui_max_tree_depth,except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)" , prefs.gui_max_tree_depth, hfinfo->name, hfinfo->abbrev , ((const char*) (__func__)), 6615)))
6615 | hfinfo->name, hfinfo->abbrev, G_STRFUNC, __LINE__))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Maximum tree depth %d exceeded for \"%s\" - \"%s\" (%s:%u) (Maximum depth can be increased in advanced preferences)" , prefs.gui_max_tree_depth, hfinfo->name, hfinfo->abbrev , ((const char*) (__func__)), 6615)));
6616 | }
6617 | }
6618 | }
6619 |
6620 | /*
6621 | * Make sure "tree" is ready to have subtrees under it, by
6622 | * checking whether it's been given an ett_ value.
6623 | *
6624 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6625 | * node of the protocol tree. That node is not displayed,
6626 | * so it doesn't need an ett_ value to remember whether it
6627 | * was expanded.
6628 | */
6629 | tnode = tree;
6630 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6631 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6632 | REPORT_DISSECTOR_BUG("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)",proto_report_dissector_bug("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)" , hfinfo->name, hfinfo->abbrev, tfi->tree_type, "epan/proto.c" , 6633)
6633 | hfinfo->name, hfinfo->abbrev, tfi->tree_type, __FILE__, __LINE__)proto_report_dissector_bug("\"%s\" - \"%s\" tfi->tree_type: %d invalid (%s:%u)" , hfinfo->name, hfinfo->abbrev, tfi->tree_type, "epan/proto.c" , 6633);
6634 | /* XXX - is it safe to continue here? */
6635 | }
6636 |
6637 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6638 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6639 | pnode->parent = tnode;
6640 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6641 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6642 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6643 |
6644 | if (tnode->last_child != NULL((void*)0)) {
6645 | sibling = tnode->last_child;
6646 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6646, "sibling->next == ((void*)0)" ))));
6647 | sibling->next = pnode;
6648 | } else
6649 | tnode->first_child = pnode;
6650 | tnode->last_child = pnode;
6651 |
6652 | /* We should not be adding a fake node for an interesting field */
6653 | ws_assert(hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT)do { if ((1) && !(hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT)) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6653, __func__, "assertion failed: %s" , "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT" ); } while (0);
6654 |
6655 | /* XXX - Should the proto_item have a header_field_info member, at least
6656 | * for faked items, to know what hfi was faked? (Some dissectors look at
6657 | * the tree items directly.)
6658 | */
6659 | return (proto_item *)pnode;
6660 | }
6661 |
6662 | /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6663 | static proto_item *
6664 | proto_tree_add_node(proto_tree *tree, field_info *fi)
6665 | {
6666 | proto_node *pnode, *tnode, *sibling;
6667 | field_info *tfi;
6668 | unsigned depth = 1;
6669 |
6670 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6670, __func__, "assertion failed: %s", "tree" ); } while (0);
6671 |
6672 | /*
6673 | * Restrict our depth. proto_tree_traverse_pre_order and
6674 | * proto_tree_traverse_post_order (and possibly others) are recursive
6675 | * so we need to be mindful of our stack size.
6676 | */
6677 | if (tree->first_child == NULL((void*)0)) {
6678 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6679 | depth++;
6680 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6681 | /* The fvalue_t is pool-allocated; just release the
6682 | * type-specific data it owns (see new_field_info()). */
6683 | fvalue_cleanup(fi->value);
6684 | fi->value = NULL((void*)0);
6685 | 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__)), 6688)))
6686 | "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__)), 6688)))
6687 | 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__)), 6688)))
6688 | 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__)), 6688)));
6689 | }
6690 | }
6691 | }
6692 |
6693 | /*
6694 | * Make sure "tree" is ready to have subtrees under it, by
6695 | * checking whether it's been given an ett_ value.
6696 | *
6697 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6698 | * node of the protocol tree. That node is not displayed,
6699 | * so it doesn't need an ett_ value to remember whether it
6700 | * was expanded.
6701 | */
6702 | tnode = tree;
6703 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6704 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6705 | /* Since we are not adding fi to a node, its fvalue won't get
6706 | * cleaned up by proto_tree_free_node(), so release the
6707 | * type-specific data it owns now. The fvalue_t structure itself
6708 | * is pool-allocated (see new_field_info()).
6709 | */
6710 | fvalue_cleanup(fi->value);
6711 | fi->value = NULL((void*)0);
6712 | 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", 6713)
6713 | 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", 6713);
6714 | /* XXX - is it safe to continue here? */
6715 | }
6716 |
6717 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6718 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6719 | pnode->parent = tnode;
6720 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6721 | PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6722 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6723 |
6724 | if (tnode->last_child != NULL((void*)0)) {
6725 | sibling = tnode->last_child;
6726 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6726, "sibling->next == ((void*)0)" ))));
6727 | sibling->next = pnode;
6728 | } else
6729 | tnode->first_child = pnode;
6730 | tnode->last_child = pnode;
6731 |
6732 | tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6733 |
6734 | return (proto_item *)pnode;
6735 | }
6736 |
6737 |
6738 | /* Generic way to allocate field_info and add to proto_tree.
6739 | * Sets *pfi to address of newly-allocated field_info struct */
6740 | static proto_item *
6741 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6742 | int *length)
6743 | {
6744 | proto_item *pi;
6745 | field_info *fi;
6746 | int item_length;
6747 |
6748 | get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6749 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6750 | pi = proto_tree_add_node(tree, fi);
6751 |
6752 | return pi;
6753 | }
6754 |
6755 | /* Generic way to allocate field_info and add to proto_tree with unsigned length.
6756 | * Eventually this should replace the other function.
6757 | * Sets *pfi to address of newly-allocated field_info struct */
6758 | static proto_item *
6759 | proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6760 | unsigned *length)
6761 | {
6762 | proto_item *pi;
6763 | field_info *fi;
6764 | unsigned item_length;
6765 |
6766 | get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6767 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6768 | pi = proto_tree_add_node(tree, fi);
6769 |
6770 | return pi;
6771 | }
6772 |
6773 | static void
6774 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6775 | int *item_length, const unsigned encoding)
6776 | {
6777 | int length_remaining;
6778 |
6779 | /*
6780 | * We only allow a null tvbuff if the item has a zero length,
6781 | * i.e. if there's no data backing it.
6782 | */
6783 | 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", 6783, "tvb != ((void*)0) || *length == 0" ))));
6784 |
6785 | /*
6786 | * XXX - in some protocols, there are 32-bit unsigned length
6787 | * fields, so lengths in protocol tree and tvbuff routines
6788 | * should really be unsigned. We should have, for those
6789 | * field types for which "to the end of the tvbuff" makes sense,
6790 | * additional routines that take no length argument and
6791 | * add fields that run to the end of the tvbuff.
6792 | */
6793 | if (*length == -1) {
6794 | /*
6795 | * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6796 | * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6797 | * of -1 means "set the length to what remains in the
6798 | * tvbuff".
6799 | *
6800 | * The assumption is either that
6801 | *
6802 | * 1) the length of the item can only be determined
6803 | * by dissection (typically true of items with
6804 | * subitems, which are probably FT_NONE or
6805 | * FT_PROTOCOL)
6806 | *
6807 | * or
6808 | *
6809 | * 2) if the tvbuff is "short" (either due to a short
6810 | * snapshot length or due to lack of reassembly of
6811 | * fragments/segments/whatever), we want to display
6812 | * what's available in the field (probably FT_BYTES
6813 | * or FT_STRING) and then throw an exception later
6814 | *
6815 | * or
6816 | *
6817 | * 3) the field is defined to be "what's left in the
6818 | * packet"
6819 | *
6820 | * so we set the length to what remains in the tvbuff so
6821 | * that, if we throw an exception while dissecting, it
6822 | * has what is probably the right value.
6823 | *
6824 | * For FT_STRINGZ, it means "the string is null-terminated,
6825 | * not null-padded; set the length to the actual length
6826 | * of the string", and if the tvbuff if short, we just
6827 | * throw an exception.
6828 | *
6829 | * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6830 | * it means "find the end of the string",
6831 | * and if the tvbuff if short, we just throw an exception.
6832 | *
6833 | * It's not valid for any other type of field. For those
6834 | * fields, we treat -1 the same way we treat other
6835 | * negative values - we assume the length is a Really
6836 | * Big Positive Number, and throw a ReportedBoundsError
6837 | * exception, under the assumption that the Really Big
6838 | * Length would run past the end of the packet.
6839 | */
6840 | 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 )))) {
6841 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6842 | /*
6843 | * Leave the length as -1, so our caller knows
6844 | * it was -1.
6845 | */
6846 | *item_length = *length;
6847 | return;
6848 | } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6849 | switch (tvb_get_uint8(tvb, start) >> 6)
6850 | {
6851 | case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6852 | *item_length = 1;
6853 | break;
6854 | case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6855 | *item_length = 2;
6856 | break;
6857 | case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6858 | *item_length = 4;
6859 | break;
6860 | case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6861 | *item_length = 8;
6862 | break;
6863 | }
6864 | }
6865 | }
6866 |
6867 | switch (hfinfo->type) {
6868 |
6869 | case FT_PROTOCOL:
6870 | case FT_NONE:
6871 | case FT_BYTES:
6872 | case FT_STRING:
6873 | case FT_STRINGZPAD:
6874 | case FT_STRINGZTRUNC:
6875 | /*
6876 | * We allow FT_PROTOCOLs to be zero-length -
6877 | * for example, an ONC RPC NULL procedure has
6878 | * neither arguments nor reply, so the
6879 | * payload for that protocol is empty.
6880 | *
6881 | * We also allow the others to be zero-length -
6882 | * because that's the way the code has been for a
6883 | * long, long time.
6884 | *
6885 | * However, we want to ensure that the start
6886 | * offset is not *past* the byte past the end
6887 | * of the tvbuff: we throw an exception in that
6888 | * case.
6889 | */
6890 | *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6891 | DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6891, "*length >= 0" ))));
6892 | break;
6893 |
6894 | case FT_STRINGZ:
6895 | /*
6896 | * Leave the length as -1, so our caller knows
6897 | * it was -1.
6898 | */
6899 | break;
6900 |
6901 | default:
6902 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6903 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 6903));
6904 | }
6905 | *item_length = *length;
6906 | } else {
6907 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6908 | /*
6909 | * These types are for interior nodes of the
6910 | * tree, and don't have data associated with
6911 | * them; if the length is negative (XXX - see
6912 | * above) or goes past the end of the tvbuff,
6913 | * cut it short at the end of the tvbuff.
6914 | * That way, if this field is selected in
6915 | * Wireshark, we don't highlight stuff past
6916 | * the end of the data.
6917 | *
6918 | * If we don't have a tvb, then length must be zero,
6919 | * per the DISSECTOR_ASSERT() above.
6920 | *
6921 | * If we do have a tvb, and the length requested is
6922 | * nonzero, we want to ensure that the start offset
6923 | * is not *past* the byte past the end of the tvbuff
6924 | * data: we throw an exception in that case as above.
6925 | */
6926 | if (tvb && *length) {
6927 | length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6928 | if (*length < 0 ||
6929 | (*length > 0 &&
6930 | (length_remaining < *length)))
6931 | *length = length_remaining;
6932 | }
6933 | }
6934 | *item_length = *length;
6935 | if (*item_length < 0) {
6936 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6937 | }
6938 | }
6939 | }
6940 |
6941 | static void
6942 | get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6943 | unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6944 | {
6945 | unsigned length_remaining;
6946 |
6947 | /*
6948 | * We only allow a null tvbuff if the item has a zero length,
6949 | * i.e. if there's no data backing it.
6950 | */
6951 | 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", 6951, "tvb != ((void*)0) || *length == 0" ))));
6952 |
6953 |
6954 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6955 | /*
6956 | * These types are for interior nodes of the
6957 | * tree, and don't have data associated with
6958 | * them; if the length is negative (XXX - see
6959 | * above) or goes past the end of the tvbuff,
6960 | * cut it short at the end of the tvbuff.
6961 | * That way, if this field is selected in
6962 | * Wireshark, we don't highlight stuff past
6963 | * the end of the data.
6964 | *
6965 | * If we don't have a tvb, then length must be zero,
6966 | * per the DISSECTOR_ASSERT() above.
6967 | *
6968 | * If we do have a tvb, and the length requested is
6969 | * nonzero, we want to ensure that the start offset
6970 | * is not *past* the byte past the end of the tvbuff
6971 | * data: we throw an exception in that case as above.
6972 | * (If the length requested is zero, then it's quite
6973 | * likely that the start offset is the byte past the
6974 | * end, but that's ok.)
6975 | */
6976 | if (tvb && *length) {
6977 | length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6978 | if (length_remaining < *length) {
6979 | *length = length_remaining;
6980 | }
6981 | }
6982 | }
6983 | *item_length = *length;
6984 | }
6985 |
6986 | static int
6987 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6988 | int length, unsigned item_length, const int encoding)
6989 | {
6990 | uint32_t n;
6991 |
6992 | /*
6993 | * We need to get the correct item length here.
6994 | * That's normally done by proto_tree_new_item(),
6995 | * but we won't be calling it.
6996 | */
6997 | switch (hfinfo->type) {
6998 |
6999 | case FT_NONE:
7000 | case FT_PROTOCOL:
7001 | case FT_BYTES:
7002 | /*
7003 | * The length is the specified length.
7004 | */
7005 | break;
7006 |
7007 | case FT_UINT_BYTES:
7008 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
7009 | item_length += n;
7010 | if ((int)item_length < length) {
7011 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7012 | }
7013 | break;
7014 |
7015 | /* XXX - make these just FT_UINT? */
7016 | case FT_UINT8:
7017 | case FT_UINT16:
7018 | case FT_UINT24:
7019 | case FT_UINT32:
7020 | case FT_UINT40:
7021 | case FT_UINT48:
7022 | case FT_UINT56:
7023 | case FT_UINT64:
7024 | /* XXX - make these just FT_INT? */
7025 | case FT_INT8:
7026 | case FT_INT16:
7027 | case FT_INT24:
7028 | case FT_INT32:
7029 | case FT_INT40:
7030 | case FT_INT48:
7031 | case FT_INT56:
7032 | case FT_INT64:
7033 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
7034 | if (length < -1) {
7035 | report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
7036 | }
7037 | if (length == -1) {
7038 | uint64_t dummy;
7039 | /* This can throw an exception */
7040 | /* XXX - do this without fetching the varint? */
7041 | length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
7042 | if (length == 0) {
7043 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7044 | }
7045 | }
7046 | item_length = length;
7047 | break;
7048 | }
7049 |
7050 | /*
7051 | * The length is the specified length.
7052 | */
7053 | break;
7054 |
7055 | case FT_BOOLEAN:
7056 | case FT_CHAR:
7057 | case FT_IPv4:
7058 | case FT_IPXNET:
7059 | case FT_IPv6:
7060 | case FT_FCWWN:
7061 | case FT_AX25:
7062 | case FT_VINES:
7063 | case FT_ETHER:
7064 | case FT_EUI64:
7065 | case FT_GUID:
7066 | case FT_OID:
7067 | case FT_REL_OID:
7068 | case FT_SYSTEM_ID:
7069 | case FT_FLOAT:
7070 | case FT_DOUBLE:
7071 | case FT_STRING:
7072 | /*
7073 | * The length is the specified length.
7074 | */
7075 | break;
7076 |
7077 | case FT_STRINGZ:
7078 | if (length < -1) {
7079 | report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
7080 | }
7081 | if (length == -1) {
7082 | /* This can throw an exception */
7083 | item_length = tvb_strsize_enc(tvb, start, encoding);
7084 | }
7085 | break;
7086 |
7087 | case FT_UINT_STRING:
7088 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
7089 | item_length += n;
7090 | if ((int)item_length < length) {
7091 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7092 | }
7093 | break;
7094 |
7095 | case FT_STRINGZPAD:
7096 | case FT_STRINGZTRUNC:
7097 | case FT_ABSOLUTE_TIME:
7098 | case FT_RELATIVE_TIME:
7099 | case FT_IEEE_11073_SFLOAT:
7100 | case FT_IEEE_11073_FLOAT:
7101 | /*
7102 | * The length is the specified length.
7103 | */
7104 | break;
7105 |
7106 | default:
7107 | 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 ))
7108 | 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 ))
7109 | 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 ))
7110 | 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 ));
7111 | break;
7112 | }
7113 | return item_length;
7114 | }
7115 |
7116 | // This was arbitrarily chosen, but if you're adding 50K items to the tree
7117 | // without advancing the offset you should probably take a long, hard look
7118 | // at what you're doing.
7119 | // We *could* make this a configurable option, but I (Gerald) would like to
7120 | // avoid adding yet another nerd knob.
7121 | # define PROTO_TREE_MAX_IDLE50000 50000
7122 | static field_info *
7123 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7124 | const unsigned start, const int item_length)
7125 | {
7126 | field_info *fi;
7127 |
7128 | FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo ->pool)), sizeof(field_info)));
7129 |
7130 | fi->hfinfo = hfinfo;
7131 | fi->start = start;
7132 | fi->start += (tvb)?tvb_raw_offset(tvb):0;
7133 | /* add the data source tvbuff */
7134 | fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7135 |
7136 | // If our start offset hasn't advanced after adding many items it probably
7137 | // means we're in a large or infinite loop.
7138 | if (fi->start > 0) {
7139 | if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7140 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7141 | if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7142 | if (wireshark_abort_on_too_many_items) {
7143 | ws_error("Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7144 , __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)
7144 | hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7144 , __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000);
7145 | }
7146 | /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7147 | * but if not, we should hit the max item error earlier,
7148 | * so we shouldn't need to reset the tree count to
7149 | * ensure that the exception handler can add the item. */
7150 | THROW_MESSAGE(DissectorError,except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)))
7151 | wmem_strdup_printf(PNODE_POOL(tree),except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)))
7152 | "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop",except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)))
7153 | hfinfo->abbrev, PROTO_TREE_MAX_IDLE))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)));
7154 | }
7155 | } else {
7156 | PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7157 | PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7158 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7159 | }
7160 | }
7161 | fi->length = item_length;
7162 | fi->tree_type = -1;
7163 | fi->flags = 0;
7164 | if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7165 | /* If the tree is not visible, set the item hidden, unless we
7166 | * need the representation or length and can't fake them.
7167 | */
7168 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7169 | FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); } while(0);
7170 | }
7171 | }
7172 | fi->value = fvalue_new_pool(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), fi->hfinfo->type);
7173 | fi->rep = NULL((void*)0);
7174 |
7175 | fi->appendix_start = 0;
7176 | fi->appendix_length = 0;
7177 |
7178 | fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7179 | fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7180 |
7181 | return fi;
7182 | }
7183 |
7184 | static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7185 | {
7186 | if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7187 | return 0;
7188 | }
7189 |
7190 | /* Search for field name */
7191 | char *ptr = strstr(representation, hfinfo->name);
7192 | if (!ptr) {
7193 | return 0;
7194 | }
7195 |
7196 | /* Check if field name ends with the ": " delimiter */
7197 | ptr += strlen(hfinfo->name);
7198 | if (strncmp(ptr, ": ", 2) == 0) {
7199 | ptr += 2;
7200 | }
7201 |
7202 | /* Return offset to after field name */
7203 | return ptr - representation;
7204 | }
7205 |
7206 | static size_t label_find_name_pos(const item_label_t *rep)
7207 | {
7208 | size_t name_pos = 0;
7209 |
7210 | /* If the value_pos is too small or too large, we can't find the expected format */
7211 | if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7212 | return 0;
7213 | }
7214 |
7215 | /* Check if the format looks like "label: value", then set name_pos before ':'. */
7216 | if (rep->representation[rep->value_pos-2] == ':') {
7217 | name_pos = rep->value_pos - 2;
7218 | }
7219 |
7220 | return name_pos;
7221 | }
7222 |
7223 | /* If the protocol tree is to be visible, set the representation of a
7224 | proto_tree entry with the name of the field for the item and with
7225 | the value formatted with the supplied printf-style format and
7226 | argument list. */
7227 | static void
7228 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7229 | {
7230 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 7230, __func__, "assertion failed: %s", "pi" ); } while (0);
7231 |
7232 | /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7233 | * items string representation */
7234 | if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7235 | size_t name_pos, ret = 0;
7236 | char *str;
7237 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7238 | const header_field_info *hf;
7239 |
7240 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7240, "fi"))));
7241 |
7242 | hf = fi->hfinfo;
7243 |
7244 | 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;;
7245 | 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)))) {
7246 | uint64_t val;
7247 | char *p;
7248 |
7249 | 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))
7250 | val = fvalue_get_uinteger(fi->value);
7251 | else
7252 | val = fvalue_get_uinteger64(fi->value);
7253 |
7254 | val <<= hfinfo_bitshift(hf);
7255 |
7256 | p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7257 | ret = (p - fi->rep->representation);
7258 | }
7259 |
7260 | /* put in the hf name */
7261 | name_pos = ret = label_concat(fi->rep->representation, ret, (const uint8_t*)hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, (const uint8_t*)hf->name, 0);
7262 |
7263 | ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const uint8_t*)": ", 0);
7264 | /* If possible, Put in the value of the string */
7265 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7266 | 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" , 7266, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7267 | fi->rep->value_pos = ret;
7268 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7269 | if (ret >= ITEM_LABEL_LENGTH240) {
7270 | /* Uh oh, we don't have enough room. Tell the user
7271 | * that the field is truncated.
7272 | */
7273 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7274 | }
7275 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7276 | }
7277 | }
7278 |
7279 | /* If the protocol tree is to be visible, set the representation of a
7280 | proto_tree entry with the representation formatted with the supplied
7281 | printf-style format and argument list. */
7282 | static void
7283 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7284 | {
7285 | size_t ret; /*tmp return value */
7286 | char *str;
7287 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7288 |
7289 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7289, "fi"))));
7290 |
7291 | if (!proto_item_is_hidden(pi)) {
7292 | 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;;
7293 |
7294 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7295 | 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" , 7295, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7296 | fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7297 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7298 | if (ret >= ITEM_LABEL_LENGTH240) {
7299 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7300 | size_t name_pos = label_find_name_pos(fi->rep);
7301 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7302 | }
7303 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7304 | }
7305 | }
7306 |
7307 | static int
7308 | proto_strlcpy(char *dest, const char *src, size_t dest_size)
7309 | {
7310 | if (dest_size == 0) return 0;
7311 |
7312 | size_t res = g_strlcpy(dest, src, dest_size);
7313 |
7314 | /* At most dest_size - 1 characters will be copied
7315 | * (unless dest_size is 0). */
7316 | if (res >= dest_size)
7317 | res = dest_size - 1;
7318 | return (int) res;
7319 | }
7320 |
7321 | static header_field_info *
7322 | hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7323 | {
7324 | header_field_info *dup_hfinfo;
7325 |
7326 | if (hfinfo->same_name_prev_id == -1)
7327 | return NULL((void*)0);
7328 | 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", 7328 , __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", 7328, "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", 7328, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo ->same_name_prev_id];;
7329 | return dup_hfinfo;
7330 | }
7331 |
7332 | static void
7333 | hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7334 | {
7335 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
7336 | last_field_name = NULL((void*)0);
7337 |
7338 | if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7339 | /* No hfinfo with the same name */
7340 | wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7341 | return;
7342 | }
7343 |
7344 | if (hfinfo->same_name_next) {
7345 | hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7346 | }
7347 |
7348 | if (hfinfo->same_name_prev_id != -1) {
7349 | header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7350 | same_name_prev->same_name_next = hfinfo->same_name_next;
7351 | if (!hfinfo->same_name_next) {
7352 | /* It's always the latest added hfinfo which is stored in gpa_name_map */
7353 | wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7354 | }
7355 | }
7356 | }
7357 |
7358 | int
7359 | proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7360 | {
7361 | const header_field_info *hfinfo = finfo->hfinfo;
7362 | int label_len = 0;
7363 | char *tmp_str;
7364 | const char *str;
7365 | const uint8_t *bytes;
7366 | uint32_t number;
7367 | uint64_t number64;
7368 | const char *hf_str_val;
7369 | char number_buf[NUMBER_LABEL_LENGTH80];
7370 | const char *number_out;
7371 | address addr;
7372 | const ipv4_addr_and_mask *ipv4;
7373 | const ipv6_addr_and_prefix *ipv6;
7374 |
7375 | switch (hfinfo->type) {
7376 |
7377 | case FT_NONE:
7378 | case FT_PROTOCOL:
7379 | return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7380 |
7381 | case FT_UINT_BYTES:
7382 | case FT_BYTES:
7383 | tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7384 | hfinfo,
7385 | fvalue_get_bytes_data(finfo->value),
7386 | (unsigned)fvalue_length2(finfo->value),
7387 | label_str_size);
7388 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7389 | wmem_free(NULL((void*)0), tmp_str);
7390 | break;
7391 |
7392 | case FT_ABSOLUTE_TIME:
7393 | {
7394 | const nstime_t *value = fvalue_get_time(finfo->value);
7395 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7396 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7397 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7398 | }
7399 | if (hfinfo->strings) {
7400 | const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7401 | if (time_string != NULL((void*)0)) {
7402 | label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7403 | break;
7404 | }
7405 | }
7406 | tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7407 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7408 | wmem_free(NULL((void*)0), tmp_str);
7409 | break;
7410 | }
7411 |
7412 | case FT_RELATIVE_TIME:
7413 | tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7414 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7415 | wmem_free(NULL((void*)0), tmp_str);
7416 | break;
7417 |
7418 | case FT_BOOLEAN:
7419 | number64 = fvalue_get_uinteger64(finfo->value);
7420 | label_len = proto_strlcpy(display_label_str,
7421 | tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7422 | break;
7423 |
7424 | case FT_CHAR:
7425 | number = fvalue_get_uinteger(finfo->value);
7426 |
7427 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7428 | char tmp[ITEM_LABEL_LENGTH240];
7429 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7430 |
7431 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7431, "fmtfunc"))));
7432 | fmtfunc(tmp, number);
7433 |
7434 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7435 |
7436 | } else if (hfinfo->strings) {
7437 | number_out = hf_try_val_to_str(number, hfinfo);
7438 |
7439 | if (!number_out) {
7440 | number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7441 | }
7442 |
7443 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7444 |
7445 | } else {
7446 | number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7447 |
7448 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7449 | }
7450 |
7451 | break;
7452 |
7453 | /* XXX - make these just FT_NUMBER? */
7454 | case FT_INT8:
7455 | case FT_INT16:
7456 | case FT_INT24:
7457 | case FT_INT32:
7458 | case FT_UINT8:
7459 | case FT_UINT16:
7460 | case FT_UINT24:
7461 | case FT_UINT32:
7462 | case FT_FRAMENUM:
7463 | hf_str_val = NULL((void*)0);
7464 | 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 )) ?
7465 | (uint32_t) fvalue_get_sinteger(finfo->value) :
7466 | fvalue_get_uinteger(finfo->value);
7467 |
7468 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7469 | char tmp[ITEM_LABEL_LENGTH240];
7470 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7471 |
7472 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7472, "fmtfunc"))));
7473 | fmtfunc(tmp, number);
7474 |
7475 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7476 |
7477 | } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7478 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7479 | number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7480 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7481 | hf_str_val = hf_try_val_to_str(number, hfinfo);
7482 | if (hf_str_val)
7483 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7484 | } else {
7485 | number_out = hf_try_val_to_str(number, hfinfo);
7486 |
7487 | if (!number_out) {
7488 | number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7489 | }
7490 |
7491 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7492 | }
7493 | } else {
7494 | number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7495 |
7496 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7497 | }
7498 |
7499 | break;
7500 |
7501 | case FT_INT40:
7502 | case FT_INT48:
7503 | case FT_INT56:
7504 | case FT_INT64:
7505 | case FT_UINT40:
7506 | case FT_UINT48:
7507 | case FT_UINT56:
7508 | case FT_UINT64:
7509 | hf_str_val = NULL((void*)0);
7510 | 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 )) ?
7511 | (uint64_t) fvalue_get_sinteger64(finfo->value) :
7512 | fvalue_get_uinteger64(finfo->value);
7513 |
7514 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7515 | char tmp[ITEM_LABEL_LENGTH240];
7516 | custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7517 |
7518 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 7518, "fmtfunc64" ))));
7519 | fmtfunc64(tmp, number64);
7520 |
7521 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7522 | } else if (hfinfo->strings) {
7523 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7524 | number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7525 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7526 | hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7527 | if (hf_str_val)
7528 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7529 | } else {
7530 | number_out = hf_try_val64_to_str(number64, hfinfo);
7531 |
7532 | if (!number_out)
7533 | number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7534 |
7535 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7536 | }
7537 | } else {
7538 | number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7539 |
7540 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7541 | }
7542 |
7543 | break;
7544 |
7545 | case FT_EUI64:
7546 | set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7547 | tmp_str = address_to_display(NULL((void*)0), &addr);
7548 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7549 | wmem_free(NULL((void*)0), tmp_str);
7550 | break;
7551 |
7552 | case FT_IPv4:
7553 | ipv4 = fvalue_get_ipv4(finfo->value);
7554 | //XXX: Should we ignore the mask?
7555 | set_address_ipv4(&addr, ipv4);
7556 | tmp_str = address_to_display(NULL((void*)0), &addr);
7557 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7558 | wmem_free(NULL((void*)0), tmp_str);
7559 | free_address(&addr);
7560 | break;
7561 |
7562 | case FT_IPv6:
7563 | ipv6 = fvalue_get_ipv6(finfo->value);
7564 | set_address_ipv6(&addr, ipv6);
7565 | tmp_str = address_to_display(NULL((void*)0), &addr);
7566 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7567 | wmem_free(NULL((void*)0), tmp_str);
7568 | free_address(&addr);
7569 | break;
7570 |
7571 | case FT_FCWWN:
7572 | set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7573 | tmp_str = address_to_display(NULL((void*)0), &addr);
7574 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7575 | wmem_free(NULL((void*)0), tmp_str);
7576 | break;
7577 |
7578 | case FT_ETHER:
7579 | set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7580 | tmp_str = address_to_display(NULL((void*)0), &addr);
7581 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7582 | wmem_free(NULL((void*)0), tmp_str);
7583 | break;
7584 |
7585 | case FT_GUID:
7586 | tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7587 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7588 | wmem_free(NULL((void*)0), tmp_str);
7589 | break;
7590 |
7591 | case FT_REL_OID:
7592 | bytes = fvalue_get_bytes_data(finfo->value);
7593 | tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7594 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7595 | wmem_free(NULL((void*)0), tmp_str);
7596 | break;
7597 |
7598 | case FT_OID:
7599 | bytes = fvalue_get_bytes_data(finfo->value);
7600 | tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7601 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7602 | wmem_free(NULL((void*)0), tmp_str);
7603 | break;
7604 |
7605 | case FT_SYSTEM_ID:
7606 | bytes = fvalue_get_bytes_data(finfo->value);
7607 | tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7608 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7609 | wmem_free(NULL((void*)0), tmp_str);
7610 | break;
7611 |
7612 | case FT_FLOAT:
7613 | case FT_DOUBLE:
7614 | label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7615 | break;
7616 |
7617 | case FT_IEEE_11073_SFLOAT:
7618 | case FT_IEEE_11073_FLOAT:
7619 | label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7620 | break;
7621 |
7622 | case FT_STRING:
7623 | case FT_STRINGZ:
7624 | case FT_UINT_STRING:
7625 | case FT_STRINGZPAD:
7626 | case FT_STRINGZTRUNC:
7627 | str = fvalue_get_string(finfo->value);
7628 | label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7629 | if (label_len >= label_str_size) {
7630 | /* Truncation occurred. Get the real length
7631 | * copied (not including '\0') */
7632 | label_len = label_str_size ? label_str_size - 1 : 0;
7633 | }
7634 | break;
7635 |
7636 | default:
7637 | /* First try ftype string representation */
7638 | tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7639 | if (!tmp_str) {
7640 | /* Default to show as bytes */
7641 | bytes = fvalue_get_bytes_data(finfo->value);
7642 | tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo-> value), 36);
7643 | }
7644 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7645 | wmem_free(NULL((void*)0), tmp_str);
7646 | break;
7647 | }
7648 | return label_len;
7649 | }
7650 |
7651 | const char *
7652 | proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7653 | char *result, char *expr, const int size)
7654 | {
7655 | int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7656 | GPtrArray *finfos;
7657 | field_info *finfo = NULL((void*)0);
7658 | header_field_info* hfinfo;
7659 | const char *abbrev = NULL((void*)0);
7660 |
7661 | char *str;
7662 | col_custom_t *field_idx;
7663 | int field_id;
7664 | int ii = 0;
7665 |
7666 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7666, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7667 | while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7668 | field_id = field_idx->field_id;
7669 | if (field_id == 0) {
7670 | GPtrArray *fvals = NULL((void*)0);
7671 | bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7672 | if (fvals != NULL((void*)0)) {
7673 |
7674 | // XXX - Handling occurrences is unusual when more
7675 | // than one field is involved, e.g. there's four
7676 | // results for tcp.port + tcp.port. We may really
7677 | // want to apply it to the operands, not the output.
7678 | // Note that occurrences are not quite the same as
7679 | // the layer operator (should the grammar support
7680 | // both?)
7681 | /* Calculate single index or set outer boundaries */
7682 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7683 | if (occurrence < 0) {
7684 | i = occurrence + len;
7685 | last = i;
7686 | } else if (occurrence > 0) {
7687 | i = occurrence - 1;
7688 | last = i;
7689 | } else {
7690 | i = 0;
7691 | last = len - 1;
7692 | }
7693 | if (i < 0 || i >= len) {
7694 | g_ptr_array_unref(fvals);
7695 | continue;
7696 | }
7697 | for (; i <= last; i++) {
7698 | /* XXX - We could have a "resolved" result
7699 | * for types where the value depends only
7700 | * on the type, e.g. FT_IPv4, and not on
7701 | * hfinfo->strings. Supporting the latter
7702 | * requires knowing which hfinfo matched
7703 | * if there are multiple with the same
7704 | * abbreviation. In any case, we need to
7705 | * know the expected return type of the
7706 | * field expression.
7707 | */
7708 | str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7709 | if (offset_r && (offset_r < (size - 1)))
7710 | result[offset_r++] = ',';
7711 | if (offset_e && (offset_e < (size - 1)))
7712 | expr[offset_e++] = ',';
7713 | offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7714 | // col_{add,append,set}_* calls ws_label_strcpy
7715 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7716 |
7717 | g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized (str, __builtin_object_size ((str), 0)) : (g_free) (str);
7718 | }
7719 | g_ptr_array_unref(fvals);
7720 | } else if (passed) {
7721 | // XXX - Occurrence doesn't make sense for a test
7722 | // output, it should be applied to the operands.
7723 | if (offset_r && (offset_r < (size - 1)))
7724 | result[offset_r++] = ',';
7725 | if (offset_e && (offset_e < (size - 1)))
7726 | expr[offset_e++] = ',';
7727 | /* Prevent multiple check marks */
7728 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7729 | offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7730 | } else {
7731 | result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7732 | }
7733 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7734 | offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7735 | } else {
7736 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7737 | }
7738 | }
7739 | continue;
7740 | }
7741 | 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", 7741 , __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", 7741, "(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", 7741, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7742 |
7743 | /* do we need to rewind ? */
7744 | if (!hfinfo)
7745 | return "";
7746 |
7747 | if (occurrence < 0) {
7748 | /* Search other direction */
7749 | while (hfinfo->same_name_prev_id != -1) {
7750 | 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", 7750 , __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", 7750, "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", 7750, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7751 | }
7752 | }
7753 |
7754 | prev_len = 0; /* Reset handled occurrences */
7755 |
7756 | while (hfinfo) {
7757 | finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7758 |
7759 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7760 | if (occurrence < 0) {
7761 | hfinfo = hfinfo->same_name_next;
7762 | } else {
7763 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7764 | }
7765 | continue;
7766 | }
7767 |
7768 | /* Are there enough occurrences of the field? */
7769 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7770 | if (occurrence < 0) {
7771 | hfinfo = hfinfo->same_name_next;
7772 | } else {
7773 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7774 | }
7775 | prev_len += len;
7776 | continue;
7777 | }
7778 |
7779 | /* Calculate single index or set outer boundaries */
7780 | if (occurrence < 0) {
7781 | i = occurrence + len + prev_len;
7782 | last = i;
7783 | } else if (occurrence > 0) {
7784 | i = occurrence - 1 - prev_len;
7785 | last = i;
7786 | } else {
7787 | i = 0;
7788 | last = len - 1;
7789 | }
7790 |
7791 | prev_len += len; /* Count handled occurrences */
7792 |
7793 | while (i <= last) {
7794 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7795 |
7796 | if (offset_r && (offset_r < (size - 1)))
7797 | result[offset_r++] = ',';
7798 |
7799 | if (display_details) {
7800 | char representation[ITEM_LABEL_LENGTH240];
7801 | size_t offset = 0;
7802 |
7803 | if (finfo->rep && finfo->rep->value_len) {
7804 | (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7805 | MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo-> rep->value_len + 1) : (240)));
7806 | } else {
7807 | proto_item_fill_label(finfo, representation, &offset);
7808 | }
7809 | offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7810 | } else {
7811 | switch (hfinfo->type) {
7812 |
7813 | case FT_NONE:
7814 | case FT_PROTOCOL:
7815 | /* Prevent multiple check marks */
7816 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7817 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7818 | } else {
7819 | result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7820 | }
7821 | break;
7822 |
7823 | default:
7824 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7825 | break;
7826 | }
7827 | }
7828 |
7829 | if (offset_e && (offset_e < (size - 1)))
7830 | expr[offset_e++] = ',';
7831 |
7832 | 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 )))) {
7833 | const char *hf_str_val;
7834 | /* Integer types with BASE_NONE never get the numeric value. */
7835 | if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16 || (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32 )) {
7836 | hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7837 | } 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 )) {
7838 | hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7839 | } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48 || (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64 )) {
7840 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7841 | } else { // if (FT_IS_UINT64(hfinfo->type)) {
7842 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7843 | }
7844 | snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7845 | offset_e = (int)strlen(expr);
7846 | } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7847 | /* Prevent multiple check marks */
7848 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7849 | offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7850 | } else {
7851 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7852 | }
7853 | } else {
7854 | str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7855 | // col_{add,append,set}_* calls ws_label_strcpy
7856 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7857 | wmem_free(NULL((void*)0), str);
7858 | }
7859 | i++;
7860 | }
7861 |
7862 | /* XXX: Why is only the first abbreviation returned for a multifield
7863 | * custom column? */
7864 | if (!abbrev) {
7865 | /* Store abbrev for return value */
7866 | abbrev = hfinfo->abbrev;
7867 | }
7868 |
7869 | if (occurrence == 0) {
7870 | /* Fetch next hfinfo with same name (abbrev) */
7871 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7872 | } else {
7873 | hfinfo = NULL((void*)0);
7874 | }
7875 | }
7876 | }
7877 |
7878 | if (offset_r >= (size - 1)) {
7879 | mark_truncated(result, 0, size, NULL((void*)0));
7880 | }
7881 | if (offset_e >= (size - 1)) {
7882 | mark_truncated(expr, 0, size, NULL((void*)0));
7883 | }
7884 | return abbrev ? abbrev : "";
7885 | }
7886 |
7887 | char *
7888 | proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7889 | {
7890 | int len, prev_len, last, i;
7891 | GPtrArray *finfos;
7892 | field_info *finfo = NULL((void*)0);
7893 | header_field_info* hfinfo;
7894 |
7895 | char *filter = NULL((void*)0);
7896 | GPtrArray *filter_array;
7897 |
7898 | col_custom_t *col_custom;
7899 | int field_id;
7900 |
7901 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7901, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7902 | filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7903 | for (GSList *iter = field_ids; iter; iter = iter->next) {
7904 | col_custom = (col_custom_t*)iter->data;
7905 | field_id = col_custom->field_id;
7906 | if (field_id == 0) {
7907 | GPtrArray *fvals = NULL((void*)0);
7908 | bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7909 | if (fvals != NULL((void*)0)) {
7910 | // XXX - Handling occurrences is unusual when more
7911 | // than one field is involved, e.g. there's four
7912 | // results for tcp.port + tcp.port. We really
7913 | // want to apply it to the operands, not the output.
7914 | /* Calculate single index or set outer boundaries */
7915 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7916 | if (occurrence < 0) {
7917 | i = occurrence + len;
7918 | last = i;
7919 | } else if (occurrence > 0) {
7920 | i = occurrence - 1;
7921 | last = i;
7922 | } else {
7923 | i = 0;
7924 | last = len - 1;
7925 | }
7926 | if (i < 0 || i >= len) {
7927 | g_ptr_array_unref(fvals);
7928 | continue;
7929 | }
7930 | for (; i <= last; i++) {
7931 | /* XXX - Should multiple values for one
7932 | * field use set membership to reduce
7933 | * verbosity, here and below? */
7934 | char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7935 | filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7936 | wmem_free(NULL((void*)0), str);
7937 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7938 | g_ptr_array_add(filter_array, filter);
7939 | }
7940 | }
7941 | g_ptr_array_unref(fvals);
7942 | } else if (passed) {
7943 | filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7944 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7945 | g_ptr_array_add(filter_array, filter);
7946 | }
7947 | } else {
7948 | filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7949 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7950 | g_ptr_array_add(filter_array, filter);
7951 | }
7952 | }
7953 | continue;
7954 | }
7955 |
7956 | 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", 7956 , __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", 7956, "(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", 7956, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7957 |
7958 | /* do we need to rewind ? */
7959 | if (!hfinfo)
7960 | return NULL((void*)0);
7961 |
7962 | if (occurrence < 0) {
7963 | /* Search other direction */
7964 | while (hfinfo->same_name_prev_id != -1) {
7965 | 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", 7965 , __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", 7965, "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", 7965, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7966 | }
7967 | }
7968 |
7969 | prev_len = 0; /* Reset handled occurrences */
7970 |
7971 | while (hfinfo) {
7972 | finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7973 |
7974 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7975 | if (occurrence < 0) {
7976 | hfinfo = hfinfo->same_name_next;
7977 | } else {
7978 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7979 | }
7980 | continue;
7981 | }
7982 |
7983 | /* Are there enough occurrences of the field? */
7984 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7985 | if (occurrence < 0) {
7986 | hfinfo = hfinfo->same_name_next;
7987 | } else {
7988 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7989 | }
7990 | prev_len += len;
7991 | continue;
7992 | }
7993 |
7994 | /* Calculate single index or set outer boundaries */
7995 | if (occurrence < 0) {
7996 | i = occurrence + len + prev_len;
7997 | last = i;
7998 | } else if (occurrence > 0) {
7999 | i = occurrence - 1 - prev_len;
8000 | last = i;
8001 | } else {
8002 | i = 0;
8003 | last = len - 1;
8004 | }
8005 |
8006 | prev_len += len; /* Count handled occurrences */
8007 |
8008 | while (i <= last) {
8009 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
8010 |
8011 | filter = proto_construct_match_selected_string(finfo, edt);
8012 | if (filter) {
8013 | /* Only add the same expression once (especially for FT_PROTOCOL).
8014 | * The ptr array doesn't have NULL entries so g_str_equal is fine.
8015 | */
8016 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
8017 | g_ptr_array_add(filter_array, filter);
8018 | }
8019 | }
8020 | i++;
8021 | }
8022 |
8023 | if (occurrence == 0) {
8024 | /* Fetch next hfinfo with same name (abbrev) */
8025 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
8026 | } else {
8027 | hfinfo = NULL((void*)0);
8028 | }
8029 | }
8030 | }
8031 |
8032 | g_ptr_array_add(filter_array, NULL((void*)0));
8033 |
8034 | /* XXX: Should this be || or && ? */
8035 | char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
8036 |
8037 | g_ptr_array_free(filter_array, true1);
8038 |
8039 | return output;
8040 | }
8041 |
8042 | /* Set text of proto_item after having already been created. */
8043 | void
8044 | proto_item_set_text(proto_item *pi, const char *format, ...)
8045 | {
8046 | field_info *fi = NULL((void*)0);
8047 | va_list ap;
8048 |
8049 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
8050 |
8051 | fi = PITEM_FINFO(pi)((pi)->finfo);
8052 | if (fi == NULL((void*)0))
8053 | return;
8054 |
8055 | if (fi->rep) {
8056 | ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep );;
8057 | fi->rep = NULL((void*)0);
8058 | }
8059 |
8060 | va_start(ap, format)__builtin_va_start(ap, format);
8061 | proto_tree_set_representation(pi, format, ap);
8062 | va_end(ap)__builtin_va_end(ap);
8063 | }
8064 |
8065 | /* Append to text of proto_item after having already been created. */
8066 | void
8067 | proto_item_append_text(proto_item *pi, const char *format, ...)
8068 | {
8069 | field_info *fi = NULL((void*)0);
8070 | size_t curlen;
8071 | char *str;
8072 | va_list ap;
8073 |
8074 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
8075 |
8076 | fi = PITEM_FINFO(pi)((pi)->finfo);
8077 | if (fi == NULL((void*)0)) {
8078 | return;
8079 | }
8080 |
8081 | if (!proto_item_is_hidden(pi)) {
8082 | /*
8083 | * If we don't already have a representation,
8084 | * generate the default representation.
8085 | */
8086 | if (fi->rep == NULL((void*)0)) {
8087 | 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;;
8088 | proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
8089 | /* Check for special case append value to FT_NONE or FT_PROTOCOL */
8090 | if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
8091 | (strncmp(format, ": ", 2) == 0)) {
8092 | fi->rep->value_pos += 2;
8093 | }
8094 | }
8095 | if (fi->rep) {
8096 | curlen = strlen(fi->rep->representation);
8097 | /* curlen doesn't include the \0 byte.
8098 | * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8099 | * the representation has already been truncated (of an up
8100 | * to 4 byte UTF-8 character) or is just at the maximum length
8101 | * unless we search for " [truncated]" (which may not be
8102 | * at the start.)
8103 | * It's safer to do nothing.
8104 | */
8105 | if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8106 | va_start(ap, format)__builtin_va_start(ap, format);
8107 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8108 | va_end(ap)__builtin_va_end(ap);
8109 | 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" , 8109, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
8110 | /* Keep fi->rep->value_pos */
8111 | curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8112 | if (curlen >= ITEM_LABEL_LENGTH240) {
8113 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8114 | size_t name_pos = label_find_name_pos(fi->rep);
8115 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8116 | }
8117 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8118 | }
8119 | }
8120 | }
8121 | }
8122 |
8123 | /* Prepend to text of proto_item after having already been created. */
8124 | void
8125 | proto_item_prepend_text(proto_item *pi, const char *format, ...)
8126 | {
8127 | field_info *fi = NULL((void*)0);
8128 | size_t pos;
8129 | char representation[ITEM_LABEL_LENGTH240];
8130 | char *str;
8131 | va_list ap;
8132 |
8133 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
8134 |
8135 | fi = PITEM_FINFO(pi)((pi)->finfo);
8136 | if (fi == NULL((void*)0)) {
8137 | return;
8138 | }
8139 |
8140 | if (!proto_item_is_hidden(pi)) {
8141 | /*
8142 | * If we don't already have a representation,
8143 | * generate the default representation.
8144 | */
8145 | if (fi->rep == NULL((void*)0)) {
8146 | 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;;
8147 | proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8148 | } else
8149 | (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8150 |
8151 | va_start(ap, format)__builtin_va_start(ap, format);
8152 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8153 | va_end(ap)__builtin_va_end(ap);
8154 | 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" , 8154, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
8155 | fi->rep->value_pos += strlen(str);
8156 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8157 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8158 | /* XXX: As above, if the old representation is close to the label
8159 | * length, it might already be marked as truncated. */
8160 | if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8161 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8162 | size_t name_pos = label_find_name_pos(fi->rep);
8163 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8164 | }
8165 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8166 | }
8167 | }
8168 |
8169 | static void
8170 | finfo_set_len(field_info *fi, const unsigned length)
8171 | {
8172 | unsigned length_remaining;
8173 |
8174 | length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8175 | if (length > length_remaining)
8176 | fi->length = length_remaining;
8177 | else
8178 | fi->length = length;
8179 |
8180 | /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8181 | if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8182 | fvalue_set_protocol_length(fi->value, fi->length);
8183 | }
8184 |
8185 | /*
8186 | * You cannot just make the "len" field of a GByteArray
8187 | * larger, if there's no data to back that length;
8188 | * you can only make it smaller.
8189 | */
8190 | if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8191 | GBytes *bytes = fvalue_get_bytes(fi->value);
8192 | size_t size;
8193 | const void *data = g_bytes_get_data(bytes, &size);
8194 | if ((size_t)fi->length <= size) {
8195 | fvalue_set_bytes_data(fi->value, data, fi->length);
8196 | }
8197 | g_bytes_unref(bytes);
8198 | }
8199 | }
8200 |
8201 | void
8202 | proto_item_set_len(proto_item *pi, const unsigned length)
8203 | {
8204 | field_info *fi;
8205 |
8206 | if (pi == NULL((void*)0))
8207 | return;
8208 |
8209 | fi = PITEM_FINFO(pi)((pi)->finfo);
8210 | if (fi == NULL((void*)0))
8211 | return;
8212 |
8213 | finfo_set_len(fi, length);
8214 | }
8215 |
8216 | /*
8217 | * Sets the length of the item based on its start and on the specified
8218 | * offset, which is the offset past the end of the item; as the start
8219 | * in the item is relative to the beginning of the data source tvbuff,
8220 | * we need to pass in a tvbuff - the end offset is relative to the beginning
8221 | * of that tvbuff.
8222 | */
8223 | void
8224 | proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8225 | {
8226 | field_info *fi;
8227 | unsigned length;
8228 |
8229 | if (pi == NULL((void*)0))
8230 | return;
8231 |
8232 | fi = PITEM_FINFO(pi)((pi)->finfo);
8233 | if (fi == NULL((void*)0))
8234 | return;
8235 |
8236 | if (G_LIKELY(tvb)(tvb)) {
8237 | DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : ( proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c" , 8237, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))));
8238 | end += tvb_raw_offset(tvb);
8239 | } else {
8240 | DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8240, "((void*)0) == fi->ds_tvb" ))));
8241 | }
8242 | DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8242, "end >= fi->start" ))));
8243 | length = end - fi->start;
8244 |
8245 | finfo_set_len(fi, length);
8246 | }
8247 |
8248 | unsigned
8249 | proto_item_get_len(const proto_item *pi)
8250 | {
8251 | /* XXX - The only use case where this is really guaranteed to work is
8252 | * increasing the length of an item (which has no effect if the item
8253 | * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8254 | *
8255 | * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8256 | *
8257 | * Should there be a macro or function to do that, and possibly this
8258 | * be deprecated? As a bonus, we could handle overflow.
8259 | */
8260 | field_info *fi;
8261 |
8262 | if (!pi)
8263 | return 0;
8264 | fi = PITEM_FINFO(pi)((pi)->finfo);
8265 | if (fi) {
8266 | return fi->length;
8267 | }
8268 | return 0;
8269 | }
8270 |
8271 | void
8272 | proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8273 | if (!ti) {
8274 | return;
8275 | }
8276 | FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_OFFSET(bits_offset))do { if (((ti)->finfo)) (((ti)->finfo))->flags = ((( ti)->finfo))->flags | ((((bits_offset) & 63) << 5)); } while(0);
8277 | FI_SET_FLAG(PNODE_FINFO(ti), FI_BITS_SIZE(bits_len))do { if (((ti)->finfo)) (((ti)->finfo))->flags = ((( ti)->finfo))->flags | ((((bits_len) & 63) << 12 )); } while(0);
8278 | }
8279 |
8280 | char *
8281 | proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8282 | {
8283 | field_info *fi;
8284 |
8285 | if (!pi)
8286 | return wmem_strdup(scope, "");
8287 | fi = PITEM_FINFO(pi)((pi)->finfo);
8288 | if (!fi)
8289 | return wmem_strdup(scope, "");
8290 | DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8290, "fi->hfinfo != ((void*)0)" ))));
8291 | return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8292 | }
8293 |
8294 | proto_tree *
8295 | proto_tree_create_root(packet_info *pinfo)
8296 | {
8297 | proto_node *pnode;
8298 |
8299 | /* Initialize the proto_node */
8300 | pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof (proto_tree) : 1)));
8301 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
8302 | pnode->parent = NULL((void*)0);
8303 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8304 | pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc ((sizeof (tree_data_t) > 0 ? sizeof (tree_data_t) : 1)));
8305 |
8306 | /* Make sure we can access pinfo everywhere */
8307 | pnode->tree_data->pinfo = pinfo;
8308 |
8309 | /* Don't initialize the tree_data_t. Wait until we know we need it */
8310 | pnode->tree_data->interesting_hfids = NULL((void*)0);
8311 |
8312 | /* Set the default to false so it's easier to
8313 | * find errors; if we expect to see the protocol tree
8314 | * but for some reason the default 'visible' is not
8315 | * changed, then we'll find out very quickly. */
8316 | pnode->tree_data->visible = false0;
8317 |
8318 | /* Make sure that we fake protocols (if possible) */
8319 | pnode->tree_data->fake_protocols = true1;
8320 |
8321 | /* Keep track of the number of children */
8322 | pnode->tree_data->count = 0;
8323 |
8324 | /* Initialize our loop checks */
8325 | pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8326 | pnode->tree_data->max_start = 0;
8327 | pnode->tree_data->start_idle_count = 0;
8328 |
8329 | return (proto_tree *)pnode;
8330 | }
8331 |
8332 |
8333 | /* "prime" a proto_tree with a single hfid that a dfilter
8334 | * is interested in. */
8335 | void
8336 | proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8337 | {
8338 | header_field_info *hfinfo;
8339 |
8340 | 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", 8340, __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", 8340, "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", 8340, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8341 | /* this field is referenced by a filter so increase the refcount.
8342 | also increase the refcount for the parent, i.e the protocol.
8343 | Don't increase the refcount if we're already printing the
8344 | type, as that is a superset of direct reference.
8345 | */
8346 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8347 | hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8348 | }
8349 | /* only increase the refcount if there is a parent.
8350 | if this is a protocol and not a field then parent will be -1
8351 | and there is no parent to add any refcounting for.
8352 | */
8353 | if (hfinfo->parent != -1) {
8354 | header_field_info *parent_hfinfo;
8355 | 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", 8355 , __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", 8355, "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", 8355, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8356 |
8357 | /* Mark parent as indirectly referenced unless it is already directly
8358 | * referenced, i.e. the user has specified the parent in a filter.
8359 | */
8360 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8361 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8362 | }
8363 | }
8364 |
8365 | /* "prime" a proto_tree with a single hfid that a dfilter
8366 | * is interested in. */
8367 | void
8368 | proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8369 | {
8370 | header_field_info *hfinfo;
8371 |
8372 | 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", 8372, __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", 8372, "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", 8372, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8373 | /* this field is referenced by an (output) filter so increase the refcount.
8374 | also increase the refcount for the parent, i.e the protocol.
8375 | */
8376 | hfinfo->ref_type = HF_REF_TYPE_PRINT;
8377 | /* only increase the refcount if there is a parent.
8378 | if this is a protocol and not a field then parent will be -1
8379 | and there is no parent to add any refcounting for.
8380 | */
8381 | if (hfinfo->parent != -1) {
8382 | header_field_info *parent_hfinfo;
8383 | 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", 8383 , __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", 8383, "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", 8383, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8384 |
8385 | /* Mark parent as indirectly referenced unless it is already directly
8386 | * referenced, i.e. the user has specified the parent in a filter.
8387 | */
8388 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8389 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8390 | }
8391 | }
8392 |
8393 | proto_tree *
8394 | proto_item_add_subtree(proto_item *pi, const int idx) {
8395 | field_info *fi;
8396 |
8397 | if (!pi)
8398 | return NULL((void*)0);
8399 |
8400 | 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", 8400, "idx >= 0 && idx < num_tree_types" ))));
8401 |
8402 | fi = PITEM_FINFO(pi)((pi)->finfo);
8403 | if (!fi)
8404 | return (proto_tree *)pi;
8405 |
8406 | fi->tree_type = idx;
8407 |
8408 | return (proto_tree *)pi;
8409 | }
8410 |
8411 | proto_tree *
8412 | proto_item_get_subtree(proto_item *pi) {
8413 | field_info *fi;
8414 |
8415 | if (!pi)
8416 | return NULL((void*)0);
8417 | fi = PITEM_FINFO(pi)((pi)->finfo);
8418 | if ( (fi) && (fi->tree_type == -1) )
8419 | return NULL((void*)0);
8420 | return (proto_tree *)pi;
8421 | }
8422 |
8423 | proto_item *
8424 | proto_item_get_parent(const proto_item *ti) {
8425 | if (!ti)
8426 | return NULL((void*)0);
8427 | return ti->parent;
8428 | }
8429 |
8430 | proto_item *
8431 | proto_item_get_parent_nth(proto_item *ti, int gen) {
8432 | if (!ti)
8433 | return NULL((void*)0);
8434 | while (gen--) {
8435 | ti = ti->parent;
8436 | if (!ti)
8437 | return NULL((void*)0);
8438 | }
8439 | return ti;
8440 | }
8441 |
8442 |
8443 | proto_item *
8444 | proto_tree_get_parent(proto_tree *tree) {
8445 | if (!tree)
8446 | return NULL((void*)0);
8447 | return (proto_item *)tree;
8448 | }
8449 |
8450 | proto_tree *
8451 | proto_tree_get_parent_tree(proto_tree *tree) {
8452 | if (!tree)
8453 | return NULL((void*)0);
8454 |
8455 | /* we're the root tree, there's no parent
8456 | return ourselves so the caller has at least a tree to attach to */
8457 | if (!tree->parent)
8458 | return tree;
8459 |
8460 | return (proto_tree *)tree->parent;
8461 | }
8462 |
8463 | proto_tree *
8464 | proto_tree_get_root(proto_tree *tree) {
8465 | if (!tree)
8466 | return NULL((void*)0);
8467 | while (tree->parent) {
8468 | tree = tree->parent;
8469 | }
8470 | return tree;
8471 | }
8472 |
8473 | void
8474 | proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8475 | proto_item *item_to_move)
8476 | {
8477 | /* This function doesn't generate any values. It only reorganizes the protocol tree
8478 | * so we can bail out immediately if it isn't visible. */
8479 | if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8480 | return;
8481 |
8482 | 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", 8482, "item_to_move->parent == tree" ))));
8483 | 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", 8483, "fixed_item->parent == tree" ))));
8484 |
8485 | /*** cut item_to_move out ***/
8486 |
8487 | /* is item_to_move the first? */
8488 | if (tree->first_child == item_to_move) {
8489 | /* simply change first child to next */
8490 | tree->first_child = item_to_move->next;
8491 |
8492 | 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", 8492, "tree->last_child != item_to_move" ))));
8493 | } else {
8494 | proto_item *curr_item;
8495 | /* find previous and change it's next */
8496 | for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8497 | if (curr_item->next == item_to_move) {
8498 | break;
8499 | }
8500 | }
8501 |
8502 | DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 8502, "curr_item" ))));
8503 |
8504 | curr_item->next = item_to_move->next;
8505 |
8506 | /* fix last_child if required */
8507 | if (tree->last_child == item_to_move) {
8508 | tree->last_child = curr_item;
8509 | }
8510 | }
8511 |
8512 | /*** insert to_move after fixed ***/
8513 | item_to_move->next = fixed_item->next;
8514 | fixed_item->next = item_to_move;
8515 | if (tree->last_child == fixed_item) {
8516 | tree->last_child = item_to_move;
8517 | }
8518 | }
8519 |
8520 | void
8521 | proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8522 | const unsigned length)
8523 | {
8524 | field_info *fi;
8525 |
8526 | if (tree == NULL((void*)0))
8527 | return;
8528 |
8529 | fi = PTREE_FINFO(tree)((tree)->finfo);
8530 | if (fi == NULL((void*)0))
8531 | return;
8532 |
8533 | /* We don't store a separate data source tvb for the appendix, so
8534 | * it must be from the same data source. (XXX - Are there any
8535 | * situations where it makes sense to have an appendix from a
8536 | * different data source?) */
8537 | if (G_LIKELY(tvb)(tvb)) {
8538 | DISSECTOR_ASSERT(tvb_get_ds_tvb(tvb) == fi->ds_tvb)((void) ((tvb_get_ds_tvb(tvb) == fi->ds_tvb) ? (void)0 : ( proto_report_dissector_bug("%s:%u: failed assertion \"%s\"", "epan/proto.c" , 8538, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))));
8539 | start += tvb_raw_offset(tvb);
8540 | } else {
8541 | DISSECTOR_ASSERT(NULL == fi->ds_tvb)((void) ((((void*)0) == fi->ds_tvb) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8541, "((void*)0) == fi->ds_tvb" ))));
8542 | }
8543 |
8544 | /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8545 | * main body? */
8546 |
8547 | fi->appendix_start = start;
8548 | fi->appendix_length = length;
8549 | }
8550 |
8551 | static void
8552 | check_protocol_filter_name_or_fail(const char *filter_name)
8553 | {
8554 | /* Require at least two characters. */
8555 | if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8556 | 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);
8557 | }
8558 |
8559 | if (proto_check_field_name(filter_name) != '\0') {
8560 | 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)
8561 | " 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)
8562 | " 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);
8563 | }
8564 |
8565 | /* Check that it doesn't match some very common numeric forms. */
8566 | if (filter_name[0] == '0' &&
8567 | (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8568 | filter_name[1] == 'b' || filter_name[1] == 'B')) {
8569 | 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])
8570 | 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]);
8571 | }
8572 |
8573 | /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8574 |
8575 | /* Check that it contains at least one letter. */
8576 | bool_Bool have_letter = false0;
8577 | for (const char *s = filter_name; *s != '\0'; s++) {
8578 | if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8579 | have_letter = true1;
8580 | break;
8581 | }
8582 | }
8583 | if (!have_letter) {
8584 | 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)
8585 | filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z." , filter_name);
8586 | }
8587 |
8588 | /* Check for reserved keywords. */
8589 | if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8590 | 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)
8591 | " 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);
8592 | }
8593 | }
8594 |
8595 | int
8596 | proto_register_protocol(const char *name, const char *short_name,
8597 | const char *filter_name)
8598 | {
8599 | protocol_t *protocol;
8600 | header_field_info *hfinfo;
8601 |
8602 | check_protocol_filter_name_or_fail(filter_name);
8603 |
8604 | /*
8605 | * Add this protocol to the list of known protocols;
8606 | * the list is sorted by protocol short name.
8607 | */
8608 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8609 | protocol->name = name;
8610 | protocol->short_name = short_name;
8611 | protocol->filter_name = filter_name;
8612 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8613 | protocol->is_enabled = true1; /* protocol is enabled by default */
8614 | protocol->enabled_by_default = true1; /* see previous comment */
8615 | protocol->can_toggle = true1;
8616 | protocol->parent_proto_id = -1;
8617 | protocol->heur_list = NULL((void*)0);
8618 |
8619 | /* List will be sorted later by name, when all protocols completed registering */
8620 | protocols = g_list_prepend(protocols, protocol);
8621 | /*
8622 | * Make sure there's not already a protocol with any of those
8623 | * names. Crash if there is, as that's an error in the code
8624 | * or an inappropriate plugin.
8625 | * This situation has to be fixed to not register more than one
8626 | * protocol with the same name.
8627 | */
8628 | if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8629 | /* ws_error will terminate the program */
8630 | 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)
8631 | " 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);
8632 | }
8633 | if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8634 | 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)
8635 | " 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);
8636 | }
8637 | if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8638 | 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)
8639 | " 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);
8640 | }
8641 |
8642 | /* Here we allocate a new header_field_info struct */
8643 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info ) > 0 ? sizeof (header_field_info) : 1)));
8644 | hfinfo->name = name;
8645 | hfinfo->abbrev = filter_name;
8646 | hfinfo->type = FT_PROTOCOL;
8647 | hfinfo->display = BASE_NONE;
8648 | hfinfo->strings = protocol;
8649 | hfinfo->bitmask = 0;
8650 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8651 | hfinfo->blurb = NULL((void*)0);
8652 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8653 |
8654 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8655 | return protocol->proto_id;
8656 | }
8657 |
8658 | int
8659 | proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8660 | {
8661 | protocol_t *protocol;
8662 | header_field_info *hfinfo;
8663 |
8664 | /*
8665 | * Helper protocols don't need the strict rules as a "regular" protocol
8666 | * Just register it in a list and make a hf_ field from it
8667 | */
8668 | if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8669 | 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);
8670 | }
8671 |
8672 | if (parent_proto <= 0) {
8673 | 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)
8674 | " 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);
8675 | }
8676 |
8677 | check_protocol_filter_name_or_fail(filter_name);
8678 |
8679 | /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8680 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8681 | protocol->name = name;
8682 | protocol->short_name = short_name;
8683 | protocol->filter_name = filter_name;
8684 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8685 |
8686 | /* Enabling and toggling is really determined by parent protocol,
8687 | but provide default values here */
8688 | protocol->is_enabled = true1;
8689 | protocol->enabled_by_default = true1;
8690 | protocol->can_toggle = true1;
8691 |
8692 | protocol->parent_proto_id = parent_proto;
8693 | protocol->heur_list = NULL((void*)0);
8694 |
8695 | /* List will be sorted later by name, when all protocols completed registering */
8696 | protocols = g_list_prepend(protocols, protocol);
8697 |
8698 | /* Here we allocate a new header_field_info struct */
8699 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info ) > 0 ? sizeof (header_field_info) : 1)));
8700 | hfinfo->name = name;
8701 | hfinfo->abbrev = filter_name;
8702 | hfinfo->type = field_type;
8703 | hfinfo->display = BASE_NONE;
8704 | if (field_type == FT_BYTES) {
8705 | hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8706 | }
8707 | hfinfo->strings = protocol;
8708 | hfinfo->bitmask = 0;
8709 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8710 | hfinfo->blurb = NULL((void*)0);
8711 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8712 |
8713 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8714 | return protocol->proto_id;
8715 | }
8716 |
8717 | bool_Bool
8718 | proto_deregister_protocol(const char *short_name)
8719 | {
8720 | protocol_t *protocol;
8721 | header_field_info *hfinfo;
8722 | int proto_id;
8723 | unsigned i;
8724 |
8725 | proto_id = proto_get_id_by_short_name(short_name);
8726 | protocol = find_protocol_by_id(proto_id);
8727 | if (protocol == NULL((void*)0))
8728 | return false0;
8729 |
8730 | g_hash_table_remove(proto_names, protocol->name);
8731 | g_hash_table_remove(proto_short_names, (void *)short_name);
8732 | g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8733 |
8734 | if (protocol->fields) {
8735 | for (i = 0; i < protocol->fields->len; i++) {
8736 | hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8737 | hfinfo_remove_from_gpa_name_map(hfinfo);
8738 | expert_deregister_expertinfo(hfinfo->abbrev);
8739 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8740 | }
8741 | g_ptr_array_free(protocol->fields, true1);
8742 | protocol->fields = NULL((void*)0);
8743 | }
8744 |
8745 | g_list_free(protocol->heur_list);
8746 |
8747 | /* Remove this protocol from the list of known protocols */
8748 | protocols = g_list_remove(protocols, protocol);
8749 |
8750 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8751 | wmem_map_remove(gpa_name_map, protocol->filter_name);
8752 |
8753 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
8754 | last_field_name = NULL((void*)0);
8755 |
8756 | return true1;
8757 | }
8758 |
8759 | void
8760 | proto_register_alias(const int proto_id, const char *alias_name)
8761 | {
8762 | protocol_t *protocol;
8763 |
8764 | protocol = find_protocol_by_id(proto_id);
8765 | if (alias_name && protocol) {
8766 | g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8767 | }
8768 | }
8769 |
8770 | /*
8771 | * Routines to use to iterate over the protocols.
8772 | * The argument passed to the iterator routines is an opaque cookie to
8773 | * their callers; it's the GList pointer for the current element in
8774 | * the list.
8775 | * The ID of the protocol is returned, or -1 if there is no protocol.
8776 | */
8777 | int
8778 | proto_get_first_protocol(void **cookie)
8779 | {
8780 | protocol_t *protocol;
8781 |
8782 | if (protocols == NULL((void*)0))
8783 | return -1;
8784 | *cookie = protocols;
8785 | protocol = (protocol_t *)protocols->data;
8786 | return protocol->proto_id;
8787 | }
8788 |
8789 | int
8790 | proto_get_data_protocol(void *cookie)
8791 | {
8792 | GList *list_item = (GList *)cookie;
8793 |
8794 | protocol_t *protocol = (protocol_t *)list_item->data;
8795 | return protocol->proto_id;
8796 | }
8797 |
8798 | int
8799 | proto_get_next_protocol(void **cookie)
8800 | {
8801 | GList *list_item = (GList *)*cookie;
8802 | protocol_t *protocol;
8803 |
8804 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8805 | if (list_item == NULL((void*)0))
8806 | return -1;
8807 | *cookie = list_item;
8808 | protocol = (protocol_t *)list_item->data;
8809 | return protocol->proto_id;
8810 | }
8811 |
8812 | header_field_info *
8813 | proto_get_first_protocol_field(const int proto_id, void **cookie)
8814 | {
8815 | protocol_t *protocol = find_protocol_by_id(proto_id);
8816 |
8817 | if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8818 | return NULL((void*)0);
8819 |
8820 | *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8821 | return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8822 | }
8823 |
8824 | header_field_info *
8825 | proto_get_next_protocol_field(const int proto_id, void **cookie)
8826 | {
8827 | protocol_t *protocol = find_protocol_by_id(proto_id);
8828 | unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8829 |
8830 | i++;
8831 |
8832 | if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8833 | return NULL((void*)0);
8834 |
8835 | *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8836 | return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8837 | }
8838 |
8839 | protocol_t *
8840 | find_protocol_by_id(const int proto_id)
8841 | {
8842 | header_field_info *hfinfo;
8843 |
8844 | if (proto_id <= 0)
8845 | return NULL((void*)0);
8846 |
8847 | 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", 8847, __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", 8847, "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", 8847, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
8848 | if (hfinfo->type != FT_PROTOCOL) {
8849 | 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", 8849, "hfinfo->display & 0x00004000" ))));
8850 | }
8851 | return (protocol_t *)hfinfo->strings;
8852 | }
8853 |
8854 | int
8855 | proto_get_id(const protocol_t *protocol)
8856 | {
8857 | return protocol->proto_id;
8858 | }
8859 |
8860 | bool_Bool
8861 | proto_name_already_registered(const char *name)
8862 | {
8863 | DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 8863, "name", "No name present"))));
8864 |
8865 | if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8866 | return true1;
8867 | return false0;
8868 | }
8869 |
8870 | int
8871 | proto_get_id_by_filter_name(const char *filter_name)
8872 | {
8873 | const protocol_t *protocol = NULL((void*)0);
8874 |
8875 | 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", 8875, "filter_name", "No filter name present"))));
8876 |
8877 | protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8878 |
8879 | if (protocol == NULL((void*)0))
8880 | return -1;
8881 | return protocol->proto_id;
8882 | }
8883 |
8884 | int
8885 | proto_get_id_by_short_name(const char *short_name)
8886 | {
8887 | const protocol_t *protocol = NULL((void*)0);
8888 |
8889 | 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", 8889, "short_name", "No short name present"))));
8890 |
8891 | protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8892 |
8893 | if (protocol == NULL((void*)0))
8894 | return -1;
8895 | return protocol->proto_id;
8896 | }
8897 |
8898 | const char *
8899 | proto_get_protocol_name(const int proto_id)
8900 | {
8901 | protocol_t *protocol;
8902 |
8903 | protocol = find_protocol_by_id(proto_id);
8904 |
8905 | if (protocol == NULL((void*)0))
8906 | return NULL((void*)0);
8907 | return protocol->name;
8908 | }
8909 |
8910 | const char *
8911 | proto_get_protocol_short_name(const protocol_t *protocol)
8912 | {
8913 | if (protocol == NULL((void*)0))
8914 | return "(none)";
8915 | return protocol->short_name;
8916 | }
8917 |
8918 | const char *
8919 | proto_get_protocol_long_name(const protocol_t *protocol)
8920 | {
8921 | if (protocol == NULL((void*)0))
8922 | return "(none)";
8923 | return protocol->name;
8924 | }
8925 |
8926 | const char *
8927 | proto_get_protocol_filter_name(const int proto_id)
8928 | {
8929 | protocol_t *protocol;
8930 |
8931 | protocol = find_protocol_by_id(proto_id);
8932 | if (protocol == NULL((void*)0))
8933 | return "(none)";
8934 | return protocol->filter_name;
8935 | }
8936 |
8937 | void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8938 | {
8939 | heur_dtbl_entry_t* heuristic_dissector;
8940 |
8941 | if (protocol == NULL((void*)0))
8942 | return;
8943 |
8944 | heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8945 | if (heuristic_dissector != NULL((void*)0))
8946 | {
8947 | protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8948 | }
8949 | }
8950 |
8951 | void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8952 | {
8953 | if (protocol == NULL((void*)0))
8954 | return;
8955 |
8956 | g_list_foreach(protocol->heur_list, func, user_data);
8957 | }
8958 |
8959 | void
8960 | proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8961 | bool_Bool *is_tcp, bool_Bool *is_udp,
8962 | bool_Bool *is_sctp, bool_Bool *is_tls,
8963 | bool_Bool *is_rtp,
8964 | bool_Bool *is_lte_rlc)
8965 | {
8966 | wmem_list_frame_t *protos = wmem_list_head(layers);
8967 | int proto_id;
8968 | const char *proto_name;
8969 |
8970 | /* Walk the list of a available protocols in the packet and
8971 | attempt to find "major" ones. */
8972 | /* It might make more sense to assemble and return a bitfield. */
8973 | while (protos != NULL((void*)0))
8974 | {
8975 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8976 | proto_name = proto_get_protocol_filter_name(proto_id);
8977 |
8978 | if (is_ip && ((!strcmp(proto_name, "ip")) ||
8979 | (!strcmp(proto_name, "ipv6")))) {
8980 | *is_ip = true1;
8981 | } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8982 | *is_tcp = true1;
8983 | } else if (is_udp && !strcmp(proto_name, "udp")) {
8984 | *is_udp = true1;
8985 | } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8986 | *is_sctp = true1;
8987 | } else if (is_tls && !strcmp(proto_name, "tls")) {
8988 | *is_tls = true1;
8989 | } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8990 | *is_rtp = true1;
8991 | } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8992 | *is_lte_rlc = true1;
8993 | }
8994 |
8995 | protos = wmem_list_frame_next(protos);
8996 | }
8997 | }
8998 |
8999 | bool_Bool
9000 | proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
9001 | {
9002 | wmem_list_frame_t *protos = wmem_list_head(layers);
9003 | int proto_id;
9004 | const char *name;
9005 |
9006 | /* Walk the list of a available protocols in the packet and
9007 | attempt to find the specified protocol. */
9008 | while (protos != NULL((void*)0))
9009 | {
9010 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
9011 | name = proto_get_protocol_filter_name(proto_id);
9012 |
9013 | if (!strcmp(name, proto_name))
9014 | {
9015 | return true1;
9016 | }
9017 |
9018 | protos = wmem_list_frame_next(protos);
9019 | }
9020 |
9021 | return false0;
9022 | }
9023 |
9024 | char *
9025 | proto_list_layers(const packet_info *pinfo)
9026 | {
9027 | wmem_strbuf_t *buf;
9028 | wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
9029 |
9030 | buf = wmem_strbuf_new_sized(pinfo->pool, 128);
9031 |
9032 | /* Walk the list of layers in the packet and
9033 | return a string of all entries. */
9034 | while (layers != NULL((void*)0))
9035 | {
9036 | wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
9037 |
9038 | layers = wmem_list_frame_next(layers);
9039 | if (layers != NULL((void*)0)) {
9040 | wmem_strbuf_append_c(buf, ':');
9041 | }
9042 | }
9043 |
9044 | return wmem_strbuf_finalize(buf);
9045 | }
9046 |
9047 | uint8_t
9048 | proto_get_layer_num(const packet_info *pinfo, const int proto_id)
9049 | {
9050 | int *proto_layer_num_ptr;
9051 |
9052 | proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
9053 | if (proto_layer_num_ptr == NULL((void*)0)) {
9054 | return 0;
9055 | }
9056 |
9057 | return (uint8_t)*proto_layer_num_ptr;
9058 | }
9059 |
9060 | bool_Bool
9061 | proto_is_pino(const protocol_t *protocol)
9062 | {
9063 | return (protocol->parent_proto_id != -1);
9064 | }
9065 |
9066 | bool_Bool
9067 | proto_is_bytes_pino(const protocol_t *protocol)
9068 | {
9069 | header_field_info *hfinfo;
9070 |
9071 | if (!proto_is_pino(protocol))
9072 | return false0;
9073 |
9074 | 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", 9074 , __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", 9074, "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", 9074, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[protocol->proto_id];;
9075 | return hfinfo->type != FT_PROTOCOL;
9076 | }
9077 |
9078 | bool_Bool
9079 | // NOLINTNEXTLINE(misc-no-recursion)
9080 | proto_is_protocol_enabled(const protocol_t *protocol)
9081 | {
9082 | if (protocol == NULL((void*)0))
9083 | return false0;
9084 |
9085 | //parent protocol determines enable/disable for helper dissectors
9086 | if (proto_is_pino(protocol))
9087 | return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
9088 |
9089 | return protocol->is_enabled;
9090 | }
9091 |
9092 | bool_Bool
9093 | // NOLINTNEXTLINE(misc-no-recursion)
9094 | proto_is_protocol_enabled_by_default(const protocol_t *protocol)
9095 | {
9096 | //parent protocol determines enable/disable for helper dissectors
9097 | if (proto_is_pino(protocol))
9098 | return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
9099 |
9100 | return protocol->enabled_by_default;
9101 | }
9102 |
9103 | bool_Bool
9104 | // NOLINTNEXTLINE(misc-no-recursion)
9105 | proto_can_toggle_protocol(const int proto_id)
9106 | {
9107 | protocol_t *protocol;
9108 |
9109 | protocol = find_protocol_by_id(proto_id);
9110 | //parent protocol determines toggling for helper dissectors
9111 | if (proto_is_pino(protocol))
9112 | return proto_can_toggle_protocol(protocol->parent_proto_id);
9113 |
9114 | return protocol->can_toggle;
9115 | }
9116 |
9117 | void
9118 | proto_disable_by_default(const int proto_id)
9119 | {
9120 | protocol_t *protocol;
9121 |
9122 | protocol = find_protocol_by_id(proto_id);
9123 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9123, "protocol->can_toggle" ))));
9124 | 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", 9124, "proto_is_pino(protocol) == 0" ))));
9125 | protocol->is_enabled = false0;
9126 | protocol->enabled_by_default = false0;
9127 | }
9128 |
9129 | void
9130 | proto_set_decoding(const int proto_id, const bool_Bool enabled)
9131 | {
9132 | protocol_t *protocol;
9133 |
9134 | protocol = find_protocol_by_id(proto_id);
9135 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9135, "protocol->can_toggle" ))));
9136 | 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", 9136, "proto_is_pino(protocol) == 0" ))));
9137 | protocol->is_enabled = enabled;
9138 | }
9139 |
9140 | void
9141 | proto_disable_all(void)
9142 | {
9143 | /* This doesn't explicitly disable heuristic protocols,
9144 | * but the heuristic doesn't get called if the parent
9145 | * protocol isn't enabled.
9146 | */
9147 | protocol_t *protocol;
9148 | GList *list_item = protocols;
9149 |
9150 | if (protocols == NULL((void*)0))
9151 | return;
9152 |
9153 | while (list_item) {
9154 | protocol = (protocol_t *)list_item->data;
9155 | if (protocol->can_toggle) {
9156 | protocol->is_enabled = false0;
9157 | }
9158 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
9159 | }
9160 | }
9161 |
9162 | static void
9163 | heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9164 | {
9165 | heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9166 |
9167 | heur->enabled = heur->enabled_by_default;
9168 | }
9169 |
9170 | void
9171 | proto_reenable_all(void)
9172 | {
9173 | protocol_t *protocol;
9174 | GList *list_item = protocols;
9175 |
9176 | if (protocols == NULL((void*)0))
9177 | return;
9178 |
9179 | while (list_item) {
9180 | protocol = (protocol_t *)list_item->data;
9181 | if (protocol->can_toggle)
9182 | protocol->is_enabled = protocol->enabled_by_default;
9183 | proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9184 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
9185 | }
9186 | }
9187 |
9188 | void
9189 | proto_set_cant_toggle(const int proto_id)
9190 | {
9191 | protocol_t *protocol;
9192 |
9193 | protocol = find_protocol_by_id(proto_id);
9194 | protocol->can_toggle = false0;
9195 | }
9196 |
9197 | static int
9198 | proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9199 | {
9200 | g_ptr_array_add(proto->fields, hfi);
9201 |
9202 | return proto_register_field_init(hfi, parent);
9203 | }
9204 |
9205 | /* for use with static arrays only, since we don't allocate our own copies
9206 | of the header_field_info struct contained within the hf_register_info struct */
9207 | void
9208 | proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9209 | {
9210 | hf_register_info *ptr = hf;
9211 | protocol_t *proto;
9212 | int i;
9213 |
9214 | proto = find_protocol_by_id(parent);
9215 |
9216 | /* if (proto == NULL) - error or return? */
9217 |
9218 | if (proto->fields == NULL((void*)0)) {
9219 | /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9220 | * GLib introduced g_ptr_array_new_from_array, which might have
9221 | * given a reason to actually use it. (#17774)
9222 | */
9223 | proto->fields = g_ptr_array_sized_new(num_records);
9224 | }
9225 |
9226 | for (i = 0; i < num_records; i++, ptr++) {
9227 | /*
9228 | * Make sure we haven't registered this yet.
9229 | * Most fields have variables associated with them that
9230 | * are initialized to 0; some are initialized to -1 (which
9231 | * was the standard before 4.4).
9232 | *
9233 | * XXX - Since this is called almost 300000 times at startup,
9234 | * it might be nice to compare to only 0 and require
9235 | * dissectors to pass in zero for unregistered fields.
9236 | */
9237 | if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9238 | REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev)
9239 | "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)
9240 | ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev);
9241 | return;
9242 | }
9243 |
9244 | *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9245 | }
9246 | }
9247 |
9248 | /* deregister already registered fields */
9249 | void
9250 | proto_deregister_field (const int parent, int hf_id)
9251 | {
9252 | header_field_info *hfi;
9253 | protocol_t *proto;
9254 | unsigned i;
9255 |
9256 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
9257 | last_field_name = NULL((void*)0);
9258 |
9259 | if (hf_id == -1 || hf_id == 0)
9260 | return;
9261 |
9262 | proto = find_protocol_by_id (parent);
9263 | if (!proto || proto->fields == NULL((void*)0)) {
9264 | return;
9265 | }
9266 |
9267 | for (i = 0; i < proto->fields->len; i++) {
9268 | hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9269 | if (hfi->id == hf_id) {
9270 | /* Found the hf_id in this protocol */
9271 | wmem_map_remove(gpa_name_map, hfi->abbrev);
9272 | g_ptr_array_remove_index_fast(proto->fields, i);
9273 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9274 | return;
9275 | }
9276 | }
9277 | }
9278 |
9279 | /* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9280 | void
9281 | proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9282 | {
9283 | header_field_info *hfinfo;
9284 | protocol_t *proto;
9285 |
9286 | g_free(last_field_name)(__builtin_object_size ((last_field_name), 0) != ((size_t) - 1 )) ? g_free_sized (last_field_name, __builtin_object_size ((last_field_name ), 0)) : (g_free) (last_field_name);
9287 | last_field_name = NULL((void*)0);
9288 |
9289 | proto = find_protocol_by_id(parent);
9290 | if (proto && proto->fields && proto->fields->len > 0) {
9291 | unsigned i = proto->fields->len;
9292 | do {
9293 | i--;
9294 |
9295 | hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9296 | if (g_str_has_prefix(hfinfo->abbrev, prefix)(__builtin_constant_p (prefix)? __extension__ ({ const char * const __str = (hfinfo->abbrev); const char * const __prefix = (prefix); gboolean __result = (0); if (__str == ((void*)0) || __prefix == ((void*)0)) __result = (g_str_has_prefix) (__str , __prefix); else { const size_t __str_len = strlen (((__str) + !(__str))); const size_t __prefix_len = strlen (((__prefix ) + !(__prefix))); if (__str_len >= __prefix_len) __result = memcmp (((__str) + !(__str)), ((__prefix) + !(__prefix)), __prefix_len ) == 0; } __result; }) : (g_str_has_prefix) (hfinfo->abbrev , prefix) )) {
9297 | hfinfo_remove_from_gpa_name_map(hfinfo);
9298 | expert_deregister_expertinfo(hfinfo->abbrev);
9299 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9300 | g_ptr_array_remove_index_fast(proto->fields, i);
9301 | }
9302 | } while (i > 0);
9303 | }
9304 | }
9305 |
9306 | void
9307 | proto_add_deregistered_data (void *data)
9308 | {
9309 | g_ptr_array_add(deregistered_data, data);
9310 | }
9311 |
9312 | void
9313 | proto_add_deregistered_slice (size_t block_size, void *mem_block)
9314 | {
9315 | 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 ) > 0 ? sizeof (struct g_slice_data) : 1)));
9316 |
9317 | slice_data->block_size = block_size;
9318 | slice_data->mem_block = mem_block;
9319 |
9320 | g_ptr_array_add(deregistered_slice, slice_data);
9321 | }
9322 |
9323 | void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9324 | {
9325 | if (field_strings == NULL((void*)0)) {
9326 | return;
9327 | }
9328 |
9329 | switch (field_type) {
9330 | case FT_FRAMENUM:
9331 | /* This is just an integer represented as a pointer */
9332 | break;
9333 | case FT_PROTOCOL: {
9334 | protocol_t *protocol = (protocol_t *)field_strings;
9335 | g_free((char *)protocol->short_name)(__builtin_object_size (((char *)protocol->short_name), 0) != ((size_t) - 1)) ? g_free_sized ((char *)protocol->short_name , __builtin_object_size (((char *)protocol->short_name), 0 )) : (g_free) ((char *)protocol->short_name);
9336 | break;
9337 | }
9338 | case FT_BOOLEAN: {
9339 | true_false_string *tf = (true_false_string *)field_strings;
9340 | g_free((char *)tf->true_string)(__builtin_object_size (((char *)tf->true_string), 0) != ( (size_t) - 1)) ? g_free_sized ((char *)tf->true_string, __builtin_object_size (((char *)tf->true_string), 0)) : (g_free) ((char *)tf-> true_string);
9341 | g_free((char *)tf->false_string)(__builtin_object_size (((char *)tf->false_string), 0) != ( (size_t) - 1)) ? g_free_sized ((char *)tf->false_string, __builtin_object_size (((char *)tf->false_string), 0)) : (g_free) ((char *)tf-> false_string);
9342 | break;
9343 | }
9344 | case FT_UINT40:
9345 | case FT_INT40:
9346 | case FT_UINT48:
9347 | case FT_INT48:
9348 | case FT_UINT56:
9349 | case FT_INT56:
9350 | case FT_UINT64:
9351 | case FT_INT64: {
9352 | if (field_display & BASE_UNIT_STRING0x00001000) {
9353 | unit_name_string *unit = (unit_name_string *)field_strings;
9354 | g_free((char *)unit->singular)(__builtin_object_size (((char *)unit->singular), 0) != (( size_t) - 1)) ? g_free_sized ((char *)unit->singular, __builtin_object_size (((char *)unit->singular), 0)) : (g_free) ((char *)unit-> singular);
9355 | g_free((char *)unit->plural)(__builtin_object_size (((char *)unit->plural), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)unit->plural, __builtin_object_size (((char *)unit->plural), 0)) : (g_free) ((char *)unit-> plural);
9356 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9357 | range_string *rs = (range_string *)field_strings;
9358 | while (rs->strptr) {
9359 | g_free((char *)rs->strptr)(__builtin_object_size (((char *)rs->strptr), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)rs->strptr, __builtin_object_size (((char *)rs->strptr), 0)) : (g_free) ((char *)rs->strptr );
9360 | rs++;
9361 | }
9362 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9363 | val64_string_ext *vse = (val64_string_ext *)field_strings;
9364 | val64_string *vs = (val64_string *)vse->_vs_p;
9365 | while (vs->strptr) {
9366 | g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size (((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr );
9367 | vs++;
9368 | }
9369 | val64_string_ext_free(vse);
9370 | field_strings = NULL((void*)0);
9371 | } else if (field_display == BASE_CUSTOM) {
9372 | /* this will be a pointer to a function, don't free that */
9373 | field_strings = NULL((void*)0);
9374 | } else {
9375 | val64_string *vs64 = (val64_string *)field_strings;
9376 | while (vs64->strptr) {
9377 | g_free((char *)vs64->strptr)(__builtin_object_size (((char *)vs64->strptr), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)vs64->strptr, __builtin_object_size (((char *)vs64->strptr), 0)) : (g_free) ((char *)vs64-> strptr);
9378 | vs64++;
9379 | }
9380 | }
9381 | break;
9382 | }
9383 | case FT_CHAR:
9384 | case FT_UINT8:
9385 | case FT_INT8:
9386 | case FT_UINT16:
9387 | case FT_INT16:
9388 | case FT_UINT24:
9389 | case FT_INT24:
9390 | case FT_UINT32:
9391 | case FT_INT32:
9392 | case FT_FLOAT:
9393 | case FT_DOUBLE: {
9394 | if (field_display & BASE_UNIT_STRING0x00001000) {
9395 | unit_name_string *unit = (unit_name_string *)field_strings;
9396 | g_free((char *)unit->singular)(__builtin_object_size (((char *)unit->singular), 0) != (( size_t) - 1)) ? g_free_sized ((char *)unit->singular, __builtin_object_size (((char *)unit->singular), 0)) : (g_free) ((char *)unit-> singular);
9397 | g_free((char *)unit->plural)(__builtin_object_size (((char *)unit->plural), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)unit->plural, __builtin_object_size (((char *)unit->plural), 0)) : (g_free) ((char *)unit-> plural);
9398 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9399 | range_string *rs = (range_string *)field_strings;
9400 | while (rs->strptr) {
9401 | g_free((char *)rs->strptr)(__builtin_object_size (((char *)rs->strptr), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)rs->strptr, __builtin_object_size (((char *)rs->strptr), 0)) : (g_free) ((char *)rs->strptr );
9402 | rs++;
9403 | }
9404 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9405 | value_string_ext *vse = (value_string_ext *)field_strings;
9406 | value_string *vs = (value_string *)vse->_vs_p;
9407 | while (vs->strptr) {
9408 | g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size (((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr );
9409 | vs++;
9410 | }
9411 | value_string_ext_free(vse);
9412 | field_strings = NULL((void*)0);
9413 | } else if (field_display == BASE_CUSTOM) {
9414 | /* this will be a pointer to a function, don't free that */
9415 | field_strings = NULL((void*)0);
9416 | } else {
9417 | value_string *vs = (value_string *)field_strings;
9418 | while (vs->strptr) {
9419 | g_free((char *)vs->strptr)(__builtin_object_size (((char *)vs->strptr), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)vs->strptr, __builtin_object_size (((char *)vs->strptr), 0)) : (g_free) ((char *)vs->strptr );
9420 | vs++;
9421 | }
9422 | }
9423 | break;
9424 | default:
9425 | break;
9426 | }
9427 | }
9428 |
9429 | if (field_type != FT_FRAMENUM) {
9430 | g_free((void *)field_strings)(__builtin_object_size (((void *)field_strings), 0) != ((size_t ) - 1)) ? g_free_sized ((void *)field_strings, __builtin_object_size (((void *)field_strings), 0)) : (g_free) ((void *)field_strings );
9431 | }
9432 | }
9433 |
9434 | static void
9435 | free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9436 | {
9437 | header_field_info *hfi = (header_field_info *) data;
9438 | int hf_id = hfi->id;
9439 |
9440 | g_free((char *)hfi->name)(__builtin_object_size (((char *)hfi->name), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)hfi->name, __builtin_object_size (((char *)hfi->name), 0)) : (g_free) ((char *)hfi->name );
9441 | g_free((char *)hfi->abbrev)(__builtin_object_size (((char *)hfi->abbrev), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)hfi->abbrev, __builtin_object_size (((char *)hfi->abbrev), 0)) : (g_free) ((char *)hfi->abbrev );
9442 | g_free((char *)hfi->blurb)(__builtin_object_size (((char *)hfi->blurb), 0) != ((size_t ) - 1)) ? g_free_sized ((char *)hfi->blurb, __builtin_object_size (((char *)hfi->blurb), 0)) : (g_free) ((char *)hfi->blurb );
9443 |
9444 | proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9445 |
9446 | if (hfi->parent == -1)
9447 | 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);
9448 |
9449 | gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9450 | }
9451 |
9452 | static void
9453 | free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9454 | {
9455 | g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized (data, __builtin_object_size ((data), 0)) : (g_free) (data);
9456 | }
9457 |
9458 | static void
9459 | free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9460 | {
9461 | struct g_slice_data *slice_data = (struct g_slice_data *)data;
9462 |
9463 | g_slice_free1(slice_data->block_size, slice_data->mem_block);
9464 | 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);
9465 | }
9466 |
9467 | /* free deregistered fields and data */
9468 | void
9469 | proto_free_deregistered_fields (void)
9470 | {
9471 | expert_free_deregistered_expertinfos();
9472 |
9473 | g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9474 | g_ptr_array_free(deregistered_fields, true1);
9475 | deregistered_fields = g_ptr_array_new();
9476 |
9477 | g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9478 | g_ptr_array_free(deregistered_data, true1);
9479 | deregistered_data = g_ptr_array_new();
9480 |
9481 | g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9482 | g_ptr_array_free(deregistered_slice, true1);
9483 | deregistered_slice = g_ptr_array_new();
9484 | }
9485 |
9486 | static const value_string hf_display[] = {
9487 | { BASE_NONE, "BASE_NONE" },
9488 | { BASE_DEC, "BASE_DEC" },
9489 | { BASE_HEX, "BASE_HEX" },
9490 | { BASE_OCT, "BASE_OCT" },
9491 | { BASE_DEC_HEX, "BASE_DEC_HEX" },
9492 | { BASE_HEX_DEC, "BASE_HEX_DEC" },
9493 | { BASE_CUSTOM, "BASE_CUSTOM" },
9494 | { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9495 | { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9496 | { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9497 | { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9498 | { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9499 | { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9500 | { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9501 | { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9502 | { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9503 | { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9504 | { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9505 | { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9506 | { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9507 | { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9508 | { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9509 | { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9510 | { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9511 | { BASE_PT_UDP, "BASE_PT_UDP" },
9512 | { BASE_PT_TCP, "BASE_PT_TCP" },
9513 | { BASE_PT_DCCP, "BASE_PT_DCCP" },
9514 | { BASE_PT_SCTP, "BASE_PT_SCTP" },
9515 | { BASE_OUI, "BASE_OUI" },
9516 | { 0, NULL((void*)0) } };
9517 |
9518 | const char* proto_field_display_to_string(int field_display)
9519 | {
9520 | return val_to_str_const(field_display, hf_display, "Unknown");
9521 | }
9522 |
9523 | static inline port_type
9524 | display_to_port_type(field_display_e e)
9525 | {
9526 | switch (e) {
9527 | case BASE_PT_UDP:
9528 | return PT_UDP;
9529 | case BASE_PT_TCP:
9530 | return PT_TCP;
9531 | case BASE_PT_DCCP:
9532 | return PT_DCCP;
9533 | case BASE_PT_SCTP:
9534 | return PT_SCTP;
9535 | default:
9536 | break;
9537 | }
9538 | return PT_NONE;
9539 | }
9540 |
9541 | /* temporary function containing assert part for easier profiling */
9542 | static void
9543 | tmp_fld_check_assert(header_field_info *hfinfo)
9544 | {
9545 | char* tmp_str;
9546 |
9547 | /* The field must have a name (with length > 0) */
9548 | if (!hfinfo->name || !hfinfo->name[0]) {
9549 | if (hfinfo->abbrev)
9550 | /* Try to identify the field */
9551 | 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)
9552 | hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name" , hfinfo->abbrev);
9553 | else
9554 | /* Hum, no luck */
9555 | 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)" );
9556 | }
9557 |
9558 | /* fields with an empty string for an abbreviation aren't filterable */
9559 | if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9560 | 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);
9561 |
9562 | /* TODO: This check is a significant percentage of startup time (~10%),
9563 | although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9564 | It might be nice to have a way to disable this check when, e.g.,
9565 | running TShark many times with the same configuration. */
9566 | /* Check that the filter name (abbreviation) is legal;
9567 | * it must contain only alphanumerics, '-', "_", and ".". */
9568 | unsigned char c;
9569 | c = module_check_valid_name(hfinfo->abbrev, false0);
9570 | if (c) {
9571 | if (c == '.') {
9572 | 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);
9573 | } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9574 | 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);
9575 | } else {
9576 | 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);
9577 | }
9578 | }
9579 |
9580 | /* These types of fields are allowed to have value_strings,
9581 | * true_false_strings or a protocol_t struct
9582 | */
9583 | if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9584 | switch (hfinfo->type) {
9585 |
9586 | /*
9587 | * These types are allowed to support display value_strings,
9588 | * value64_strings, the extended versions of the previous
9589 | * two, range strings, or unit strings.
9590 | */
9591 | case FT_CHAR:
9592 | case FT_UINT8:
9593 | case FT_UINT16:
9594 | case FT_UINT24:
9595 | case FT_UINT32:
9596 | case FT_UINT40:
9597 | case FT_UINT48:
9598 | case FT_UINT56:
9599 | case FT_UINT64:
9600 | case FT_INT8:
9601 | case FT_INT16:
9602 | case FT_INT24:
9603 | case FT_INT32:
9604 | case FT_INT40:
9605 | case FT_INT48:
9606 | case FT_INT56:
9607 | case FT_INT64:
9608 | case FT_BOOLEAN:
9609 | case FT_PROTOCOL:
9610 | break;
9611 |
9612 | /*
9613 | * This is allowed to have a value of type
9614 | * enum ft_framenum_type to indicate what relationship
9615 | * the frame in question has to the frame in which
9616 | * the field is put.
9617 | */
9618 | case FT_FRAMENUM:
9619 | break;
9620 |
9621 | /*
9622 | * These types are allowed to support only unit strings.
9623 | */
9624 | case FT_FLOAT:
9625 | case FT_DOUBLE:
9626 | case FT_IEEE_11073_SFLOAT:
9627 | case FT_IEEE_11073_FLOAT:
9628 | if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9629 | 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))
9630 | " (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))
9631 | 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));
9632 | }
9633 | break;
9634 |
9635 | /*
9636 | * These types are allowed to support display
9637 | * time_value_strings.
9638 | */
9639 | case FT_ABSOLUTE_TIME:
9640 | if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9641 | hfinfo->display & BASE_EXT_STRING0x00000200 ||
9642 | hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9643 | hfinfo->display & BASE_UNIT_STRING0x00001000) {
9644 | REPORT_DISSECTOR_BUG("Field '%s' (%s) has a non-time-value-strings 'strings' value but is of type %s"proto_report_dissector_bug("Field '%s' (%s) has a non-time-value-strings 'strings' value but is of type %s" " (which is only allowed to have time-value strings)", hfinfo ->name, hfinfo->abbrev, ftype_name(hfinfo->type))
9645 | " (which is only allowed to have time-value strings)",proto_report_dissector_bug("Field '%s' (%s) has a non-time-value-strings 'strings' value but is of type %s" " (which is only allowed to have time-value strings)", hfinfo ->name, hfinfo->abbrev, ftype_name(hfinfo->type))
9646 | hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) has a non-time-value-strings 'strings' value but is of type %s" " (which is only allowed to have time-value strings)", hfinfo ->name, hfinfo->abbrev, ftype_name(hfinfo->type));
9647 | }
9648 | break;
9649 |
9650 | /*
9651 | * This type is only allowed to support a string if it's
9652 | * a protocol (for pinos).
9653 | */
9654 | case FT_BYTES:
9655 | if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9656 | 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))
9657 | " (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))
9658 | 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));
9659 | }
9660 | break;
9661 |
9662 | default:
9663 | 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))
9664 | " (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))
9665 | 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));
9666 | }
9667 | }
9668 |
9669 | /* TODO: This check may slow down startup, and output quite a few warnings.
9670 | It would be good to be able to enable this (and possibly other checks?)
9671 | in non-release builds. */
9672 | #ifdef ENABLE_CHECK_FILTER
9673 | /* Check for duplicate value_string values.
9674 | There are lots that have the same value *and* string, so for now only
9675 | report those that have same value but different string. */
9676 | if ((hfinfo->strings != NULL((void*)0)) &&
9677 | !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9678 | !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9679 | !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9680 | (
9681 | (hfinfo->type == FT_CHAR) ||
9682 | (hfinfo->type == FT_UINT8) ||
9683 | (hfinfo->type == FT_UINT16) ||
9684 | (hfinfo->type == FT_UINT24) ||
9685 | (hfinfo->type == FT_UINT32) ||
9686 | (hfinfo->type == FT_INT8) ||
9687 | (hfinfo->type == FT_INT16) ||
9688 | (hfinfo->type == FT_INT24) ||
9689 | (hfinfo->type == FT_INT32) )) {
9690 |
9691 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9692 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9693 | const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9694 | CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9695 | } else {
9696 | const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9697 | CHECK_HF_VALUE(value_string, "u", start_values);
9698 | }
9699 | } else {
9700 | const value_string *start_values = (const value_string*)hfinfo->strings;
9701 | CHECK_HF_VALUE(value_string, "u", start_values);
9702 | }
9703 | }
9704 |
9705 | if (hfinfo->type == FT_BOOLEAN) {
9706 | const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9707 | if (tfs) {
9708 | if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9709 | ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9711 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string)
9710 | hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9711 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string)
9711 | tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9711 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string);
9712 | }
9713 | }
9714 | }
9715 |
9716 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9717 | const range_string *rs = (const range_string*)(hfinfo->strings);
9718 | if (rs) {
9719 | const range_string *this_it = rs;
9720 |
9721 | do {
9722 | if (this_it->value_max < this_it->value_min) {
9723 | 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" , 9727, __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)
9724 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9727, __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)
9725 | this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9727, __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)
9726 | this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9727, __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)
9727 | this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9727, __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);
9728 | ++this_it;
9729 | continue;
9730 | }
9731 |
9732 | for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9733 | /* Not OK if this one is completely hidden by an earlier one! */
9734 | if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9735 | 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" , 9741, __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)
9736 | "(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" , 9741, __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)
9737 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9741, __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)
9738 | prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9741, __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)
9739 | prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9741, __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)
9740 | this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9741, __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)
9741 | this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9741, __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);
9742 | }
9743 | }
9744 | ++this_it;
9745 | } while (this_it->strptr);
9746 | }
9747 | }
9748 | #endif
9749 |
9750 | switch (hfinfo->type) {
9751 |
9752 | case FT_CHAR:
9753 | /* Require the char type to have BASE_HEX, BASE_OCT,
9754 | * BASE_CUSTOM, or BASE_NONE as its base.
9755 | *
9756 | * If the display value is BASE_NONE and there is a
9757 | * strings conversion then the dissector writer is
9758 | * telling us that the field's numerical value is
9759 | * meaningless; we'll avoid showing the value to the
9760 | * user.
9761 | */
9762 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9763 | case BASE_HEX:
9764 | case BASE_OCT:
9765 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9766 | break;
9767 | case BASE_NONE:
9768 | if (hfinfo->strings == NULL((void*)0))
9769 | 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 ))
9770 | " 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 ))
9771 | " 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 ))
9772 | 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 ))
9773 | 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 ));
9774 | break;
9775 | default:
9776 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9777 | 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)
9778 | " 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)
9779 | 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)
9780 | 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);
9781 | //wmem_free(NULL, tmp_str);
9782 | }
9783 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9784 | 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 ))
9785 | 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 ))
9786 | 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 ));
9787 | }
9788 | break;
9789 | case FT_INT8:
9790 | case FT_INT16:
9791 | case FT_INT24:
9792 | case FT_INT32:
9793 | case FT_INT40:
9794 | case FT_INT48:
9795 | case FT_INT56:
9796 | case FT_INT64:
9797 | /* Hexadecimal and octal are, in printf() and everywhere
9798 | * else, unsigned so don't allow dissectors to register a
9799 | * signed field to be displayed unsigned. (Else how would
9800 | * we display negative values?)
9801 | */
9802 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9803 | case BASE_HEX:
9804 | case BASE_OCT:
9805 | case BASE_DEC_HEX:
9806 | case BASE_HEX_DEC:
9807 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9808 | 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)
9809 | 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)
9810 | 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);
9811 | //wmem_free(NULL, tmp_str);
9812 | }
9813 | /* FALL THROUGH */
9814 | case FT_UINT8:
9815 | case FT_UINT16:
9816 | case FT_UINT24:
9817 | case FT_UINT32:
9818 | case FT_UINT40:
9819 | case FT_UINT48:
9820 | case FT_UINT56:
9821 | case FT_UINT64:
9822 | 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 ))) {
9823 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9824 | if (hfinfo->type != FT_UINT16) {
9825 | 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))
9826 | 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))
9827 | 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));
9828 | }
9829 | if (hfinfo->strings != NULL((void*)0)) {
9830 | 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)
9831 | 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)
9832 | 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);
9833 | }
9834 | if (hfinfo->bitmask != 0) {
9835 | 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)
9836 | 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)
9837 | 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);
9838 | }
9839 | wmem_free(NULL((void*)0), tmp_str);
9840 | break;
9841 | }
9842 |
9843 | if (hfinfo->display == BASE_OUI) {
9844 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9845 | if (!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 )) || ftype_wire_size(hfinfo->type) < 3) {
9846 | 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))
9847 | 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))
9848 | 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));
9849 | }
9850 | if (hfinfo->strings != NULL((void*)0)) {
9851 | 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)
9852 | 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)
9853 | 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);
9854 | }
9855 | /* It can be a FT_UINT24 with a 0 bitmask, or
9856 | * larger with a bitmask with 24 bits set. */
9857 | if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9858 | 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)
9859 | 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)
9860 | 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);
9861 | }
9862 | wmem_free(NULL((void*)0), tmp_str);
9863 | break;
9864 | }
9865 |
9866 | /* Require integral types (other than frame number,
9867 | * which is always displayed in decimal) to have a
9868 | * number base.
9869 | *
9870 | * If the display value is BASE_NONE and there is a
9871 | * strings conversion then the dissector writer is
9872 | * telling us that the field's numerical value is
9873 | * meaningless; we'll avoid showing the value to the
9874 | * user.
9875 | */
9876 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9877 | case BASE_DEC:
9878 | case BASE_HEX:
9879 | case BASE_OCT:
9880 | case BASE_DEC_HEX:
9881 | case BASE_HEX_DEC:
9882 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9883 | break;
9884 | case BASE_NONE:
9885 | if (hfinfo->strings == NULL((void*)0)) {
9886 | 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 ))
9887 | " 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 ))
9888 | " 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 ))
9889 | 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 ))
9890 | 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 ));
9891 | }
9892 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9893 | 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 ))
9894 | " 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 ))
9895 | " 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 ))
9896 | 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 ))
9897 | 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 ));
9898 | }
9899 | break;
9900 |
9901 | default:
9902 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9903 | 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)
9904 | " 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)
9905 | 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)
9906 | 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);
9907 | //wmem_free(NULL, tmp_str);
9908 | }
9909 | break;
9910 | case FT_BYTES:
9911 | case FT_UINT_BYTES:
9912 | /* Require bytes to have a "display type" that could
9913 | * add a character between displayed bytes.
9914 | */
9915 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9916 | case BASE_NONE:
9917 | case SEP_DOT:
9918 | case SEP_DASH:
9919 | case SEP_COLON:
9920 | case SEP_SPACE:
9921 | break;
9922 | default:
9923 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9924 | 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)
9925 | 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);
9926 | //wmem_free(NULL, tmp_str);
9927 | }
9928 | if (hfinfo->bitmask != 0)
9929 | 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 ))
9930 | 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 ))
9931 | 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 ));
9932 | //allowed to support string if its a protocol (for pinos)
9933 | if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9934 | 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 ))
9935 | 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 ))
9936 | 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 ));
9937 | break;
9938 |
9939 | case FT_PROTOCOL:
9940 | case FT_FRAMENUM:
9941 | if (hfinfo->display != BASE_NONE) {
9942 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9943 | 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)
9944 | 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)
9945 | 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);
9946 | //wmem_free(NULL, tmp_str);
9947 | }
9948 | if (hfinfo->bitmask != 0)
9949 | 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 ))
9950 | 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 ))
9951 | 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 ));
9952 | break;
9953 |
9954 | case FT_BOOLEAN:
9955 | break;
9956 |
9957 | case FT_ABSOLUTE_TIME:
9958 | if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL && ((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)) {
9959 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9960 | 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)
9961 | 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);
9962 | //wmem_free(NULL, tmp_str);
9963 | }
9964 | if (hfinfo->bitmask != 0)
9965 | 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 ))
9966 | 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 ))
9967 | 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 ));
9968 | break;
9969 |
9970 | case FT_STRING:
9971 | case FT_STRINGZ:
9972 | case FT_UINT_STRING:
9973 | case FT_STRINGZPAD:
9974 | case FT_STRINGZTRUNC:
9975 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9976 | case BASE_NONE:
9977 | case BASE_STR_WSP:
9978 | break;
9979 |
9980 | default:
9981 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9982 | 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)
9983 | " 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)
9984 | 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)
9985 | 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);
9986 | //wmem_free(NULL, tmp_str);
9987 | }
9988 |
9989 | if (hfinfo->bitmask != 0)
9990 | 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 ))
9991 | 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 ))
9992 | 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 ));
9993 | if (hfinfo->strings != NULL((void*)0))
9994 | 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 ))
9995 | 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 ))
9996 | 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 ));
9997 | break;
9998 |
9999 | case FT_IPv4:
10000 | switch (hfinfo->display) {
10001 | case BASE_NONE:
10002 | case BASE_NETMASK:
10003 | break;
10004 |
10005 | default:
10006 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10007 | 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)
10008 | " 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)
10009 | 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)
10010 | 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);
10011 | //wmem_free(NULL, tmp_str);
10012 | break;
10013 | }
10014 | break;
10015 | case FT_FLOAT:
10016 | case FT_DOUBLE:
10017 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
10018 | case BASE_NONE:
10019 | case BASE_DEC:
10020 | case BASE_HEX:
10021 | case BASE_EXP:
10022 | case BASE_CUSTOM:
10023 | break;
10024 | default:
10025 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10026 | 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)
10027 | " 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)
10028 | 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)
10029 | 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);
10030 | //wmem_free(NULL, tmp_str);
10031 | }
10032 | if (hfinfo->bitmask != 0)
10033 | 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 ))
10034 | 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 ))
10035 | 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 ));
10036 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
10037 | 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 ))
10038 | 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 ))
10039 | 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 ));
10040 | break;
10041 | case FT_IEEE_11073_SFLOAT:
10042 | case FT_IEEE_11073_FLOAT:
10043 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
10044 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10045 | 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)
10046 | 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)
10047 | 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)
10048 | 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);
10049 | //wmem_free(NULL, tmp_str);
10050 | }
10051 | if (hfinfo->bitmask != 0)
10052 | 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 ))
10053 | 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 ))
10054 | 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 ));
10055 | if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
10056 | 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 ))
10057 | 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 ))
10058 | 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 ));
10059 | break;
10060 | default:
10061 | if (hfinfo->display != BASE_NONE) {
10062 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10063 | 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)
10064 | 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)
10065 | 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)
10066 | 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);
10067 | //wmem_free(NULL, tmp_str);
10068 | }
10069 | if (hfinfo->bitmask != 0)
10070 | 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 ))
10071 | 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 ))
10072 | 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 ));
10073 | if (hfinfo->strings != NULL((void*)0))
10074 | 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 ))
10075 | 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 ))
10076 | 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 ));
10077 | break;
10078 | }
10079 | }
10080 |
10081 | static void
10082 | register_type_length_mismatch(void)
10083 | {
10084 | static ei_register_info ei[] = {
10085 | { &ei_type_length_mismatch_error, { "_ws.type_length.mismatch", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}} }},
10086 | { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch_warn", PI_MALFORMED0x07000000, PI_WARN0x00600000, "Trying to fetch X with length Y", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}} }},
10087 | };
10088 |
10089 | expert_module_t* expert_type_length_mismatch;
10090 |
10091 | proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
10092 |
10093 | expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
10094 | expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10095 |
10096 | /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
10097 | disabling them makes no sense. */
10098 | proto_set_cant_toggle(proto_type_length_mismatch);
10099 | }
10100 |
10101 | static void
10102 | register_byte_array_string_decodinws_error(void)
10103 | {
10104 | static ei_register_info ei[] = {
10105 | { &ei_byte_array_string_decoding_failed_error,
10106 | { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10107 | "Failed to decode byte array from string", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}
10108 | }
10109 | },
10110 | };
10111 |
10112 | expert_module_t* expert_byte_array_string_decoding_error;
10113 |
10114 | proto_byte_array_string_decoding_error =
10115 | proto_register_protocol("Byte Array-String Decoding Error",
10116 | "Byte Array-string decoding error",
10117 | "_ws.byte_array_string.decoding_error");
10118 |
10119 | expert_byte_array_string_decoding_error =
10120 | expert_register_protocol(proto_byte_array_string_decoding_error);
10121 | expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10122 |
10123 | /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10124 | disabling them makes no sense. */
10125 | proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10126 | }
10127 |
10128 | static void
10129 | register_date_time_string_decodinws_error(void)
10130 | {
10131 | static ei_register_info ei[] = {
10132 | { &ei_date_time_string_decoding_failed_error,
10133 | { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10134 | "Failed to decode date and time from string", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}}
10135 | }
10136 | },
10137 | };
10138 |
10139 | expert_module_t* expert_date_time_string_decoding_error;
10140 |
10141 | proto_date_time_string_decoding_error =
10142 | proto_register_protocol("Date and Time-String Decoding Error",
10143 | "Date and Time-string decoding error",
10144 | "_ws.date_time_string.decoding_error");
10145 |
10146 | expert_date_time_string_decoding_error =
10147 | expert_register_protocol(proto_date_time_string_decoding_error);
10148 | expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10149 |
10150 | /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10151 | disabling them makes no sense. */
10152 | proto_set_cant_toggle(proto_date_time_string_decoding_error);
10153 | }
10154 |
10155 | static void
10156 | register_string_errors(void)
10157 | {
10158 | static ei_register_info ei[] = {
10159 | { &ei_string_trailing_characters,
10160 | { "_ws.string.trailing_stray_characters", PI_UNDECODED0x05000000, PI_WARN0x00600000, "Trailing stray characters", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}} }
10161 | },
10162 | };
10163 |
10164 | expert_module_t* expert_string_errors;
10165 |
10166 | proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10167 |
10168 | expert_string_errors = expert_register_protocol(proto_string_errors);
10169 | expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10170 |
10171 | /* "String Errors" isn't really a protocol, it's an error indication;
10172 | disabling them makes no sense. */
10173 | proto_set_cant_toggle(proto_string_errors);
10174 | }
10175 |
10176 | static void
10177 | register_varint_errors(void)
10178 | {
10179 | static ei_register_info ei[] = {
10180 | { &ei_varint_decoding_failed_error,
10181 | { "_ws.varint.decoding_failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000, "Varint decoding failed", EXPFILL0, ((void*)0), 0, ((void*)0), {0, {((void*)0), ((void*)0), FT_NONE , BASE_NONE, ((void*)0), 0, ((void*)0), -1, 0, HF_REF_TYPE_NONE , -1, ((void*)0)}} }
10182 | },
10183 | };
10184 |
10185 | expert_module_t* expert_varint_errors;
10186 |
10187 | proto_varint_errors = proto_register_protocol("Varint Errors", "Varint errors", "_ws.varint");
10188 |
10189 | expert_varint_errors = expert_register_protocol(proto_varint_errors);
10190 | expert_register_field_array(expert_varint_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10191 |
10192 | /* "Varint Errors" isn't really a protocol, it's an error indication;
10193 | disabling them makes no sense. */
10194 | proto_set_cant_toggle(proto_varint_errors);
10195 | }
10196 |
10197 | static int
10198 | proto_register_field_init(header_field_info *hfinfo, const int parent)
10199 | {
10200 |
10201 | tmp_fld_check_assert(hfinfo);
10202 |
10203 | hfinfo->parent = parent;
10204 | hfinfo->same_name_next = NULL((void*)0);
10205 | hfinfo->same_name_prev_id = -1;
10206 |
10207 | /* if we always add and never delete, then id == len - 1 is correct */
10208 | if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10209 | if (!gpa_hfinfo.hfi) {
10210 | gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10211 | gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10212 | /* The entry with index 0 is not used. */
10213 | gpa_hfinfo.hfi[0] = NULL((void*)0);
10214 | gpa_hfinfo.len = 1;
10215 | } else {
10216 | gpa_hfinfo.allocated_len += 1000;
10217 | gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10218 | sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10219 | /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10220 | }
10221 | }
10222 | gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10223 | gpa_hfinfo.len++;
10224 | hfinfo->id = gpa_hfinfo.len - 1;
10225 |
10226 | /* if we have real names, enter this field in the name tree */
10227 | /* Already checked in tmp_fld_check_assert */
10228 | /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10229 | {
10230 |
10231 | header_field_info *same_name_next_hfinfo;
10232 |
10233 | /* We allow multiple hfinfo's to be registered under the same
10234 | * abbreviation. This was done for X.25, as, depending
10235 | * on whether it's modulo-8 or modulo-128 operation,
10236 | * some bitfield fields may be in different bits of
10237 | * a byte, and we want to be able to refer to that field
10238 | * with one name regardless of whether the packets
10239 | * are modulo-8 or modulo-128 packets. */
10240 |
10241 | /* wmem_map_insert - if key is already present the previous
10242 | * hfinfo with the same key/name is returned, otherwise NULL */
10243 | same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10244 | if (same_name_hfinfo) {
10245 | /* There's already a field with this name.
10246 | * Put the current field *before* that field
10247 | * in the list of fields with this name, Thus,
10248 | * we end up with an effectively
10249 | * doubly-linked-list of same-named hfinfo's,
10250 | * with the head of the list (stored in the
10251 | * hash) being the last seen hfinfo.
10252 | */
10253 | same_name_next_hfinfo =
10254 | same_name_hfinfo->same_name_next;
10255 |
10256 | hfinfo->same_name_next = same_name_next_hfinfo;
10257 | if (same_name_next_hfinfo)
10258 | same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10259 |
10260 | same_name_hfinfo->same_name_next = hfinfo;
10261 | hfinfo->same_name_prev_id = same_name_hfinfo->id;
10262 | #ifdef ENABLE_CHECK_FILTER
10263 | while (same_name_hfinfo) {
10264 | if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10265 | ws_error("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type))ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10265 , __func__, "'%s' exists multiple times with incompatible types: %s and %s" , hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name( same_name_hfinfo->type));
10266 | same_name_hfinfo = same_name_hfinfo->same_name_next;
10267 | }
10268 | #endif
10269 | }
10270 | }
10271 |
10272 | return hfinfo->id;
10273 | }
10274 |
10275 | void
10276 | proto_register_subtree_array(int * const *indices, const int num_indices)
10277 | {
10278 | int i;
10279 | int *const *ptr = indices;
10280 |
10281 | /*
10282 | * If we've already allocated the array of tree types, expand
10283 | * it; this lets plugins such as mate add tree types after
10284 | * the initial startup. (If we haven't already allocated it,
10285 | * we don't allocate it; on the first pass, we just assign
10286 | * ett values and keep track of how many we've assigned, and
10287 | * when we're finished registering all dissectors we allocate
10288 | * the array, so that we do only one allocation rather than
10289 | * wasting CPU time and memory by growing the array for each
10290 | * dissector that registers ett values.)
10291 | */
10292 | if (tree_is_expanded != NULL((void*)0)) {
10293 | tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10294 |
10295 | /* set new items to 0 */
10296 | /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10297 | for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10298 | tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10299 | }
10300 |
10301 | /*
10302 | * Assign "num_indices" subtree numbers starting at "num_tree_types",
10303 | * returning the indices through the pointers in the array whose
10304 | * first element is pointed to by "indices", and update
10305 | * "num_tree_types" appropriately.
10306 | */
10307 | for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10308 | if (**ptr != -1 && **ptr != 0) {
10309 | 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.")
10310 | " 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.")
10311 | " 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.")
10312 | " 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.");
10313 | }
10314 | **ptr = num_tree_types;
10315 | }
10316 | }
10317 |
10318 | static void
10319 | mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10320 | {
10321 | static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10322 | const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10323 | char *last_char;
10324 |
10325 | /* ..... field_name: dataaaaaaaaaaaaa
10326 | * |
10327 | * ^^^^^ name_pos
10328 | *
10329 | * ..... field_name […]: dataaaaaaaaaaaaa
10330 | *
10331 | * name_pos==0 means that we have only data or only a field_name
10332 | */
10333 |
10334 | ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10334, __func__, "assertion failed: %s" , "size > trunc_len"); } while (0);
10335 |
10336 | if (name_pos >= size - trunc_len) {
10337 | /* No room for trunc_str after the field_name, put it first. */
10338 | name_pos = 0;
10339 | }
10340 |
10341 | memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10342 | if (name_pos == 0) {
10343 | /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10344 | memcpy(label_str, trunc_str + 1, trunc_len);
10345 | } else {
10346 | memcpy(label_str + name_pos, trunc_str, trunc_len);
10347 | }
10348 | /* in general, label_str is UTF-8
10349 | we can truncate it only at the beginning of a new character
10350 | we go backwards from the byte right after our buffer and
10351 | find the next starting byte of a UTF-8 character, this is
10352 | where we cut
10353 | there's no need to use g_utf8_find_prev_char(), the search
10354 | will always succeed since we copied trunc_str into the
10355 | buffer */
10356 | /* g_utf8_prev_char does not deference the memory address
10357 | * passed in (until after decrementing it, so it is perfectly
10358 | * legal to pass in a pointer one past the last element.
10359 | */
10360 | last_char = g_utf8_prev_char(label_str + size);
10361 | *last_char = '\0';
10362 | /* This is unnecessary (above always terminates), but try to
10363 | * convince Coverity to avoid dozens of false positives. */
10364 | label_str[size - 1] = '\0';
10365 |
10366 | if (value_pos && *value_pos > 0) {
10367 | if (name_pos == 0) {
10368 | *value_pos += trunc_len;
10369 | } else {
10370 | /* Move one back to include trunc_str in the value. */
10371 | *value_pos -= 1;
10372 | }
10373 | }
10374 |
10375 | /* Check if value_pos is past label_str. */
10376 | if (value_pos && *value_pos >= size) {
10377 | *value_pos = size - 1;
10378 | }
10379 | }
10380 |
10381 | static void
10382 | label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10383 | {
10384 | mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10385 | }
10386 |
10387 | static size_t
10388 | label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10389 | {
10390 | size_t name_pos;
10391 |
10392 | /* "%s: %s", hfinfo->name, text */
10393 | name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hfinfo-> name, 0);
10394 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10395 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10396 | if (value_pos) {
10397 | *value_pos = pos;
10398 | }
10399 | pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10400 | }
10401 |
10402 | if (pos >= ITEM_LABEL_LENGTH240) {
10403 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10404 | label_mark_truncated(label_str, name_pos, value_pos);
10405 | }
10406 |
10407 | return pos;
10408 | }
10409 |
10410 | static size_t
10411 | label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10412 | {
10413 | size_t name_pos;
10414 |
10415 | /* "%s: %s (%s)", hfinfo->name, text, descr */
10416 | name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hfinfo-> name, 0);
10417 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10418 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10419 | if (value_pos) {
10420 | *value_pos = pos;
10421 | }
10422 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10423 | pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(descr ? descr : "(null)"), 0);
10424 | pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(text ? text : "(null)"), 0);
10425 | } else {
10426 | pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(text ? text : "(null)"), 0);
10427 | pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10428 | pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(descr ? descr : "(null)"), 0);
10429 | pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10430 | }
10431 | }
10432 |
10433 | if (pos >= ITEM_LABEL_LENGTH240) {
10434 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10435 | label_mark_truncated(label_str, name_pos, value_pos);
10436 | }
10437 |
10438 | return pos;
10439 | }
10440 |
10441 | void
10442 | proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10443 | {
10444 | const header_field_info *hfinfo;
10445 | const char *str;
10446 | const uint8_t *bytes;
10447 | uint32_t integer;
10448 | const ipv4_addr_and_mask *ipv4;
10449 | const ipv6_addr_and_prefix *ipv6;
10450 | const e_guid_t *guid;
10451 | char *name;
10452 | address addr;
10453 | char *addr_str;
10454 | char *tmp;
10455 |
10456 | if (!label_str) {
10457 | ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10457, __func__, "NULL label_str passed to proto_item_fill_label." ); } } while (0);
10458 | return;
10459 | }
10460 |
10461 | label_str[0]= '\0';
10462 |
10463 | if (!fi) {
10464 | return;
10465 | }
10466 |
10467 | hfinfo = fi->hfinfo;
10468 |
10469 | switch (hfinfo->type) {
10470 | case FT_NONE:
10471 | case FT_PROTOCOL:
10472 | (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10473 | if (value_pos) {
10474 | *value_pos = strlen(hfinfo->name);
10475 | }
10476 | break;
10477 |
10478 | case FT_BOOLEAN:
10479 | fill_label_boolean(fi, label_str, value_pos);
10480 | break;
10481 |
10482 | case FT_BYTES:
10483 | case FT_UINT_BYTES:
10484 | tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10485 | fvalue_get_bytes_data(fi->value),
10486 | (unsigned)fvalue_length2(fi->value));
10487 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10488 | wmem_free(NULL((void*)0), tmp);
10489 | break;
10490 |
10491 | case FT_CHAR:
10492 | if (hfinfo->bitmask) {
10493 | fill_label_bitfield_char(fi, label_str, value_pos);
10494 | } else {
10495 | fill_label_char(fi, label_str, value_pos);
10496 | }
10497 | break;
10498 |
10499 | /* Four types of integers to take care of:
10500 | * Bitfield, with val_string
10501 | * Bitfield, w/o val_string
10502 | * Non-bitfield, with val_string
10503 | * Non-bitfield, w/o val_string
10504 | */
10505 | case FT_UINT8:
10506 | case FT_UINT16:
10507 | case FT_UINT24:
10508 | case FT_UINT32:
10509 | if (hfinfo->bitmask) {
10510 | fill_label_bitfield(fi, label_str, value_pos, false0);
10511 | } else {
10512 | fill_label_number(fi, label_str, value_pos, false0);
10513 | }
10514 | break;
10515 |
10516 | case FT_FRAMENUM:
10517 | fill_label_number(fi, label_str, value_pos, false0);
10518 | break;
10519 |
10520 | case FT_UINT40:
10521 | case FT_UINT48:
10522 | case FT_UINT56:
10523 | case FT_UINT64:
10524 | if (hfinfo->bitmask) {
10525 | fill_label_bitfield64(fi, label_str, value_pos, false0);
10526 | } else {
10527 | fill_label_number64(fi, label_str, value_pos, false0);
10528 | }
10529 | break;
10530 |
10531 | case FT_INT8:
10532 | case FT_INT16:
10533 | case FT_INT24:
10534 | case FT_INT32:
10535 | if (hfinfo->bitmask) {
10536 | fill_label_bitfield(fi, label_str, value_pos, true1);
10537 | } else {
10538 | fill_label_number(fi, label_str, value_pos, true1);
10539 | }
10540 | break;
10541 |
10542 | case FT_INT40:
10543 | case FT_INT48:
10544 | case FT_INT56:
10545 | case FT_INT64:
10546 | if (hfinfo->bitmask) {
10547 | fill_label_bitfield64(fi, label_str, value_pos, true1);
10548 | } else {
10549 | fill_label_number64(fi, label_str, value_pos, true1);
10550 | }
10551 | break;
10552 |
10553 | case FT_FLOAT:
10554 | case FT_DOUBLE:
10555 | fill_label_float(fi, label_str, value_pos);
10556 | break;
10557 |
10558 | case FT_ABSOLUTE_TIME:
10559 | {
10560 | const nstime_t *value = fvalue_get_time(fi->value);
10561 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10562 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10563 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10564 | }
10565 | if (hfinfo->strings) {
10566 | /*
10567 | * Table of time values to be displayed
10568 | * specially.
10569 | *
10570 | * XXX - Initializing these time_value_strings can be a pain
10571 | * because the special times usually have special values in
10572 | * the original encoding, not when converted to a nstime_t
10573 | * relative to the UN*X epoch.
10574 | */
10575 | const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10576 | if (time_string != NULL((void*)0)) {
10577 | label_fill(label_str, 0, hfinfo, time_string, value_pos);
10578 | break;
10579 | }
10580 | }
10581 | tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10582 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10583 | wmem_free(NULL((void*)0), tmp);
10584 | break;
10585 | }
10586 | case FT_RELATIVE_TIME:
10587 | tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10588 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10589 | wmem_free(NULL((void*)0), tmp);
10590 | break;
10591 |
10592 | case FT_IPXNET:
10593 | integer = fvalue_get_uinteger(fi->value);
10594 | tmp = get_ipxnet_name(NULL((void*)0), integer);
10595 | addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10596 | label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10597 | wmem_free(NULL((void*)0), tmp);
10598 | wmem_free(NULL((void*)0), addr_str);
10599 | break;
10600 |
10601 | case FT_VINES:
10602 | addr.type = AT_VINES;
10603 | addr.len = VINES_ADDR_LEN6;
10604 | addr.data = fvalue_get_bytes_data(fi->value);
10605 |
10606 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10607 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10608 | wmem_free(NULL((void*)0), addr_str);
10609 | break;
10610 |
10611 | case FT_ETHER:
10612 | bytes = fvalue_get_bytes_data(fi->value);
10613 |
10614 | addr.type = AT_ETHER;
10615 | addr.len = 6;
10616 | addr.data = bytes;
10617 |
10618 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10619 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10620 | wmem_free(NULL((void*)0), addr_str);
10621 | break;
10622 |
10623 | case FT_IPv4:
10624 | ipv4 = fvalue_get_ipv4(fi->value);
10625 | set_address_ipv4(&addr, ipv4);
10626 |
10627 | if (hfinfo->display == BASE_NETMASK) {
10628 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10629 | } else {
10630 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10631 | }
10632 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10633 | wmem_free(NULL((void*)0), addr_str);
10634 | free_address(&addr);
10635 | break;
10636 |
10637 | case FT_IPv6:
10638 | ipv6 = fvalue_get_ipv6(fi->value);
10639 | set_address_ipv6(&addr, ipv6);
10640 |
10641 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10642 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10643 | wmem_free(NULL((void*)0), addr_str);
10644 | free_address(&addr);
10645 | break;
10646 |
10647 | case FT_FCWWN:
10648 | bytes = fvalue_get_bytes_data(fi->value);
10649 | addr.type = AT_FCWWN;
10650 | addr.len = FCWWN_ADDR_LEN8;
10651 | addr.data = bytes;
10652 |
10653 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10654 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10655 | wmem_free(NULL((void*)0), addr_str);
10656 | break;
10657 |
10658 | case FT_GUID:
10659 | guid = fvalue_get_guid(fi->value);
10660 | tmp = guid_to_str(NULL((void*)0), guid);
10661 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10662 | wmem_free(NULL((void*)0), tmp);
10663 | break;
10664 |
10665 | case FT_OID:
10666 | bytes = fvalue_get_bytes_data(fi->value);
10667 | name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10668 | tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10669 | if (name) {
10670 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10671 | wmem_free(NULL((void*)0), name);
10672 | } else {
10673 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10674 | }
10675 | wmem_free(NULL((void*)0), tmp);
10676 | break;
10677 |
10678 | case FT_REL_OID:
10679 | bytes = fvalue_get_bytes_data(fi->value);
10680 | name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10681 | tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10682 | if (name) {
10683 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10684 | wmem_free(NULL((void*)0), name);
10685 | } else {
10686 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10687 | }
10688 | wmem_free(NULL((void*)0), tmp);
10689 | break;
10690 |
10691 | case FT_SYSTEM_ID:
10692 | bytes = fvalue_get_bytes_data(fi->value);
10693 | tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10694 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10695 | wmem_free(NULL((void*)0), tmp);
10696 | break;
10697 |
10698 | case FT_EUI64:
10699 | bytes = fvalue_get_bytes_data(fi->value);
10700 | addr.type = AT_EUI64;
10701 | addr.len = EUI64_ADDR_LEN8;
10702 | addr.data = bytes;
10703 |
10704 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10705 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10706 | wmem_free(NULL((void*)0), addr_str);
10707 | break;
10708 | case FT_STRING:
10709 | case FT_STRINGZ:
10710 | case FT_UINT_STRING:
10711 | case FT_STRINGZPAD:
10712 | case FT_STRINGZTRUNC:
10713 | case FT_AX25:
10714 | str = fvalue_get_string(fi->value);
10715 | label_fill(label_str, 0, hfinfo, str, value_pos);
10716 | break;
10717 |
10718 | case FT_IEEE_11073_SFLOAT:
10719 | case FT_IEEE_11073_FLOAT:
10720 | fill_label_ieee_11073_float(fi, label_str, value_pos);
10721 | break;
10722 |
10723 | default:
10724 | 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 ))
10725 | 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 ))
10726 | 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 ))
10727 | 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 ));
10728 | break;
10729 | }
10730 | }
10731 |
10732 | static void
10733 | fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10734 | {
10735 | char *p;
10736 | unsigned bitfield_byte_length = 0;
10737 | int bitwidth;
10738 | uint64_t unshifted_value;
10739 | uint64_t value;
10740 |
10741 | const header_field_info *hfinfo = fi->hfinfo;
10742 |
10743 | value = fvalue_get_uinteger64(fi->value);
10744 | if (hfinfo->bitmask) {
10745 | /* Figure out the bit width */
10746 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10747 |
10748 | /* Un-shift bits */
10749 | unshifted_value = value;
10750 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10751 |
10752 | /* Create the bitfield first */
10753 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10754 | bitfield_byte_length = (unsigned) (p - label_str);
10755 | }
10756 |
10757 | /* Fill in the textual info */
10758 | label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10759 | }
10760 |
10761 | static const char *
10762 | hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10763 | {
10764 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10765 | return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10766 |
10767 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10768 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10769 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10770 | else
10771 | return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10772 | }
10773 |
10774 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10775 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10776 |
10777 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10778 | return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10779 |
10780 | return try_val_to_str(value, (const value_string *) hfinfo->strings);
10781 | }
10782 |
10783 | static const char *
10784 | hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10785 | {
10786 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10787 | if (hfinfo->display & BASE_EXT_STRING0x00000200)
10788 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10789 | else
10790 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10791 | }
10792 |
10793 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10794 | return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10795 |
10796 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10797 | return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10798 |
10799 | /* If this is reached somebody registered a 64-bit field with a 32-bit
10800 | * value-string, which isn't right. */
10801 | 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)
10802 | hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string" , hfinfo->abbrev);
10803 |
10804 | /* This is necessary to squelch MSVC errors; is there
10805 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10806 | never returns? */
10807 | return NULL((void*)0);
10808 | }
10809 |
10810 | static const char *
10811 | hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10812 | {
10813 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10814 | return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10815 |
10816 | 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);
10817 |
10818 | /* This is necessary to squelch MSVC errors; is there
10819 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10820 | never returns? */
10821 | return NULL((void*)0);
10822 | }
10823 |
10824 | static const char *
10825 | hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10826 | {
10827 | const char *str = hf_try_val_to_str(value, hfinfo);
10828 |
10829 | return (str) ? str : unknown_str;
10830 | }
10831 |
10832 | static const char *
10833 | hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10834 | {
10835 | const char *str = hf_try_val64_to_str(value, hfinfo);
10836 |
10837 | return (str) ? str : unknown_str;
10838 | }
10839 |
10840 | /* Fills data for bitfield chars with val_strings */
10841 | static void
10842 | fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10843 | {
10844 | char *p;
10845 | unsigned bitfield_byte_length;
10846 | int bitwidth;
10847 | uint32_t unshifted_value;
10848 | uint32_t value;
10849 |
10850 | char buf[32];
10851 | const char *out;
10852 |
10853 | const header_field_info *hfinfo = fi->hfinfo;
10854 |
10855 | /* Figure out the bit width */
10856 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10857 |
10858 | /* Un-shift bits */
10859 | value = fvalue_get_uinteger(fi->value);
10860 |
10861 | unshifted_value = value;
10862 | if (hfinfo->bitmask) {
10863 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10864 | }
10865 |
10866 | /* Create the bitfield first */
10867 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10868 | bitfield_byte_length = (unsigned) (p - label_str);
10869 |
10870 | /* Fill in the textual info using stored (shifted) value */
10871 | if (hfinfo->display == BASE_CUSTOM) {
10872 | char tmp[ITEM_LABEL_LENGTH240];
10873 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10874 |
10875 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10875, "fmtfunc"))));
10876 | fmtfunc(tmp, value);
10877 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10878 | }
10879 | else if (hfinfo->strings) {
10880 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10881 |
10882 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10883 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10884 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10885 | else
10886 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10887 | }
10888 | else {
10889 | out = hfinfo_char_value_format(hfinfo, buf, value);
10890 |
10891 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10892 | }
10893 | }
10894 |
10895 | /* Fills data for bitfield ints with val_strings */
10896 | static void
10897 | fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10898 | {
10899 | char *p;
10900 | unsigned bitfield_byte_length;
10901 | int bitwidth;
10902 | uint32_t value, unshifted_value;
10903 | char buf[NUMBER_LABEL_LENGTH80];
10904 | const char *out;
10905 |
10906 | const header_field_info *hfinfo = fi->hfinfo;
10907 |
10908 | /* Figure out the bit width */
10909 | if (fi->flags & FI_VARINT0x00040000)
10910 | bitwidth = fi->length*8;
10911 | else
10912 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10913 |
10914 | /* Un-shift bits */
10915 | if (is_signed)
10916 | value = fvalue_get_sinteger(fi->value);
10917 | else
10918 | value = fvalue_get_uinteger(fi->value);
10919 |
10920 | unshifted_value = value;
10921 | if (hfinfo->bitmask) {
10922 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10923 | }
10924 |
10925 | /* Create the bitfield first */
10926 | if (fi->flags & FI_VARINT0x00040000)
10927 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10928 | else
10929 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10930 | bitfield_byte_length = (unsigned) (p - label_str);
10931 |
10932 | /* Fill in the textual info using stored (shifted) value */
10933 | if (hfinfo->display == BASE_CUSTOM) {
10934 | char tmp[ITEM_LABEL_LENGTH240];
10935 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10936 |
10937 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10937, "fmtfunc"))));
10938 | fmtfunc(tmp, value);
10939 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10940 | }
10941 | else if (hfinfo->strings) {
10942 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10943 |
10944 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10945 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10946 | /*
10947 | * Unique values only display value_string string
10948 | * if there is a match. Otherwise it's just a number
10949 | */
10950 | if (val_str) {
10951 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10952 | } else {
10953 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10954 | }
10955 | } else {
10956 | if (val_str == NULL((void*)0))
10957 | val_str = "Unknown";
10958 |
10959 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10960 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10961 | else
10962 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10963 | }
10964 | }
10965 | else {
10966 | out = hfinfo_number_value_format(hfinfo, buf, value);
10967 |
10968 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10969 | }
10970 | }
10971 |
10972 | static void
10973 | fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10974 | {
10975 | char *p;
10976 | unsigned bitfield_byte_length;
10977 | int bitwidth;
10978 | uint64_t value, unshifted_value;
10979 | char buf[NUMBER_LABEL_LENGTH80];
10980 | const char *out;
10981 |
10982 | const header_field_info *hfinfo = fi->hfinfo;
10983 |
10984 | /* Figure out the bit width */
10985 | if (fi->flags & FI_VARINT0x00040000)
10986 | bitwidth = fi->length*8;
10987 | else
10988 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10989 |
10990 | /* Un-shift bits */
10991 | if (is_signed)
10992 | value = fvalue_get_sinteger64(fi->value);
10993 | else
10994 | value = fvalue_get_uinteger64(fi->value);
10995 |
10996 | unshifted_value = value;
10997 | if (hfinfo->bitmask) {
10998 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10999 | }
11000 |
11001 | /* Create the bitfield first */
11002 | if (fi->flags & FI_VARINT0x00040000)
11003 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11004 | else
11005 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11006 | bitfield_byte_length = (unsigned) (p - label_str);
11007 |
11008 | /* Fill in the textual info using stored (shifted) value */
11009 | if (hfinfo->display == BASE_CUSTOM) {
11010 | char tmp[ITEM_LABEL_LENGTH240];
11011 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11012 |
11013 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 11013, "fmtfunc64" ))));
11014 | fmtfunc64(tmp, value);
11015 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
11016 | }
11017 | else if (hfinfo->strings) {
11018 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
11019 |
11020 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
11021 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11022 | /*
11023 | * Unique values only display value_string string
11024 | * if there is a match. Otherwise it's just a number
11025 | */
11026 | if (val_str) {
11027 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11028 | } else {
11029 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11030 | }
11031 | } else {
11032 | if (val_str == NULL((void*)0))
11033 | val_str = "Unknown";
11034 |
11035 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11036 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
11037 | else
11038 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11039 | }
11040 | }
11041 | else {
11042 | out = hfinfo_number_value_format64(hfinfo, buf, value);
11043 |
11044 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11045 | }
11046 | }
11047 |
11048 | static void
11049 | fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
11050 | {
11051 | const header_field_info *hfinfo = fi->hfinfo;
11052 | uint32_t value;
11053 |
11054 | char buf[32];
11055 | const char *out;
11056 |
11057 | value = fvalue_get_uinteger(fi->value);
11058 |
11059 | /* Fill in the textual info */
11060 | if (hfinfo->display == BASE_CUSTOM) {
11061 | char tmp[ITEM_LABEL_LENGTH240];
11062 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11063 |
11064 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 11064, "fmtfunc"))));
11065 | fmtfunc(tmp, value);
11066 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
11067 | }
11068 | else if (hfinfo->strings) {
11069 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
11070 |
11071 | out = hfinfo_char_vals_format(hfinfo, buf, value);
11072 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11073 | }
11074 | else {
11075 | out = hfinfo_char_value_format(hfinfo, buf, value);
11076 |
11077 | label_fill(label_str, 0, hfinfo, out, value_pos);
11078 | }
11079 | }
11080 |
11081 | static void
11082 | fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11083 | {
11084 | const header_field_info *hfinfo = fi->hfinfo;
11085 | uint32_t value;
11086 |
11087 | char buf[NUMBER_LABEL_LENGTH80];
11088 | const char *out;
11089 |
11090 | if (is_signed)
11091 | value = fvalue_get_sinteger(fi->value);
11092 | else
11093 | value = fvalue_get_uinteger(fi->value);
11094 |
11095 | /* Fill in the textual info */
11096 | if (hfinfo->display == BASE_CUSTOM) {
11097 | char tmp[ITEM_LABEL_LENGTH240];
11098 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11099 |
11100 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 11100, "fmtfunc"))));
11101 | fmtfunc(tmp, value);
11102 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
11103 | }
11104 | else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
11105 | /*
11106 | * It makes no sense to have a value-string table for a
11107 | * frame-number field - they're just integers giving
11108 | * the ordinal frame number.
11109 | */
11110 | const char *val_str = hf_try_val_to_str(value, hfinfo);
11111 |
11112 | out = hfinfo_number_vals_format(hfinfo, buf, value);
11113 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11114 | /*
11115 | * Unique values only display value_string string
11116 | * if there is a match. Otherwise it's just a number
11117 | */
11118 | if (val_str) {
11119 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11120 | } else {
11121 | label_fill(label_str, 0, hfinfo, out, value_pos);
11122 | }
11123 | } else {
11124 | if (val_str == NULL((void*)0))
11125 | val_str = "Unknown";
11126 |
11127 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11128 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
11129 | else
11130 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11131 | }
11132 | }
11133 | 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 ))) {
11134 | char tmp[ITEM_LABEL_LENGTH240];
11135 |
11136 | port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11137 | display_to_port_type((field_display_e)hfinfo->display), value);
11138 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
11139 | }
11140 | else {
11141 | out = hfinfo_number_value_format(hfinfo, buf, value);
11142 |
11143 | label_fill(label_str, 0, hfinfo, out, value_pos);
11144 | }
11145 | }
11146 |
11147 | static void
11148 | fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11149 | {
11150 | const header_field_info *hfinfo = fi->hfinfo;
11151 | uint64_t value;
11152 |
11153 | char buf[NUMBER_LABEL_LENGTH80];
11154 | const char *out;
11155 |
11156 | if (is_signed)
11157 | value = fvalue_get_sinteger64(fi->value);
11158 | else
11159 | value = fvalue_get_uinteger64(fi->value);
11160 |
11161 | /* Fill in the textual info */
11162 | if (hfinfo->display == BASE_CUSTOM) {
11163 | char tmp[ITEM_LABEL_LENGTH240];
11164 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11165 |
11166 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 11166, "fmtfunc64" ))));
11167 | fmtfunc64(tmp, value);
11168 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
11169 | }
11170 | else if (hfinfo->strings) {
11171 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
11172 |
11173 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
11174 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11175 | /*
11176 | * Unique values only display value_string string
11177 | * if there is a match. Otherwise it's just a number
11178 | */
11179 | if (val_str) {
11180 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11181 | } else {
11182 | label_fill(label_str, 0, hfinfo, out, value_pos);
11183 | }
11184 | } else {
11185 | if (val_str == NULL((void*)0))
11186 | val_str = "Unknown";
11187 |
11188 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11189 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
11190 | else
11191 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11192 | }
11193 | }
11194 | else {
11195 | out = hfinfo_number_value_format64(hfinfo, buf, value);
11196 |
11197 | label_fill(label_str, 0, hfinfo, out, value_pos);
11198 | }
11199 | }
11200 |
11201 | static size_t
11202 | fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11203 | {
11204 | int display;
11205 | int n;
11206 | double value;
11207 |
11208 | if (label_str_size < 12) {
11209 | /* Not enough room to write an entire floating point value. */
11210 | return 0;
11211 | }
11212 |
11213 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11214 | value = fvalue_get_floating(fi->value);
11215 |
11216 | if (display == BASE_CUSTOM) {
11217 | const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11218 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 11218, "fmtfunc"))));
11219 | fmtfunc(label_str, value);
11220 | return strlen(label_str);
11221 | }
11222 |
11223 | switch (display) {
11224 | case BASE_NONE:
11225 | if (fi->hfinfo->type == FT_FLOAT) {
11226 | n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11227 | } else {
11228 | n = (int)strlen(dtoa_g_fmt(label_str, value));
11229 | }
11230 | break;
11231 | case BASE_DEC:
11232 | n = snprintf(label_str, label_str_size, "%f", value);
11233 | break;
11234 | case BASE_HEX:
11235 | n = snprintf(label_str, label_str_size, "%a", value);
11236 | break;
11237 | case BASE_EXP:
11238 | n = snprintf(label_str, label_str_size, "%e", value);
11239 | break;
11240 | default:
11241 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11241 , __func__, "assertion \"not reached\" failed");
11242 | }
11243 | if (n < 0) {
11244 | return 0; /* error */
11245 | }
11246 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11247 | const char *hf_str_val;
11248 | hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11249 | n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11250 | }
11251 | if (n > label_str_size) {
11252 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11252, __func__, "label length too small"); } } while (0);
11253 | return strlen(label_str);
11254 | }
11255 |
11256 | return n;
11257 | }
11258 |
11259 | void
11260 | fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11261 | {
11262 | char tmp[ITEM_LABEL_LENGTH240];
11263 |
11264 | fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11265 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11266 | }
11267 |
11268 | static size_t
11269 | fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11270 | {
11271 | int display;
11272 | size_t pos = 0;
11273 | double value;
11274 | char* tmp_str;
11275 |
11276 | if (label_str_size < 12) {
11277 | /* Not enough room to write an entire floating point value. */
11278 | return 0;
11279 | }
11280 |
11281 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11282 | tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11283 | pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str, 0);
11284 | wmem_free(NULL((void*)0), tmp_str);
11285 |
11286 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11287 | const char *hf_str_val;
11288 | fvalue_to_double(fi->value, &value);
11289 | hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11290 | pos = label_concat(label_str, pos, (const uint8_t*)hf_str_val)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hf_str_val , 0);
11291 | }
11292 | if ((int)pos > label_str_size) {
11293 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11293, __func__, "label length too small"); } } while (0);
11294 | return strlen(label_str);
11295 | }
11296 |
11297 | return pos;
11298 | }
11299 |
11300 | void
11301 | fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11302 | {
11303 | char tmp[ITEM_LABEL_LENGTH240];
11304 |
11305 | fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11306 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11307 | }
11308 |
11309 | int
11310 | hfinfo_bitshift(const header_field_info *hfinfo)
11311 | {
11312 | return ws_ctz(hfinfo->bitmask);
11313 | }
11314 |
11315 |
11316 | static int
11317 | hfinfo_bitoffset(const header_field_info *hfinfo)
11318 | {
11319 | if (!hfinfo->bitmask) {
11320 | return 0;
11321 | }
11322 |
11323 | /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11324 | * as the first bit */
11325 | return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11326 | }
11327 |
11328 | static int
11329 | hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11330 | {
11331 | if (!hfinfo->bitmask) {
11332 | return 0;
11333 | }
11334 |
11335 | /* ilog2 = first set bit, ctz = last set bit */
11336 | return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11337 | }
11338 |
11339 | static int
11340 | hfinfo_type_bitwidth(enum ftenum type)
11341 | {
11342 | int bitwidth = 0;
11343 |
11344 | switch (type) {
11345 | case FT_CHAR:
11346 | case FT_UINT8:
11347 | case FT_INT8:
11348 | bitwidth = 8;
11349 | break;
11350 | case FT_UINT16:
11351 | case FT_INT16:
11352 | bitwidth = 16;
11353 | break;
11354 | case FT_UINT24:
11355 | case FT_INT24:
11356 | bitwidth = 24;
11357 | break;
11358 | case FT_UINT32:
11359 | case FT_INT32:
11360 | bitwidth = 32;
11361 | break;
11362 | case FT_UINT40:
11363 | case FT_INT40:
11364 | bitwidth = 40;
11365 | break;
11366 | case FT_UINT48:
11367 | case FT_INT48:
11368 | bitwidth = 48;
11369 | break;
11370 | case FT_UINT56:
11371 | case FT_INT56:
11372 | bitwidth = 56;
11373 | break;
11374 | case FT_UINT64:
11375 | case FT_INT64:
11376 | bitwidth = 64;
11377 | break;
11378 | default:
11379 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 11379));
11380 | ;
11381 | }
11382 | return bitwidth;
11383 | }
11384 |
11385 |
11386 | static int
11387 | hfinfo_container_bitwidth(const header_field_info *hfinfo)
11388 | {
11389 | if (!hfinfo->bitmask) {
11390 | return 0;
11391 | }
11392 |
11393 | if (hfinfo->type == FT_BOOLEAN) {
11394 | return hfinfo->display; /* hacky? :) */
11395 | }
11396 |
11397 | return hfinfo_type_bitwidth(hfinfo->type);
11398 | }
11399 |
11400 | static int
11401 | hfinfo_hex_digits(const header_field_info *hfinfo)
11402 | {
11403 | int bitwidth;
11404 |
11405 | /* If we have a bitmask, hfinfo->type is the width of the container, so not
11406 | * appropriate to determine the number of hex digits for the field.
11407 | * So instead, we compute it from the bitmask.
11408 | */
11409 | if (hfinfo->bitmask != 0) {
11410 | bitwidth = hfinfo_mask_bitwidth(hfinfo);
11411 | } else {
11412 | bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11413 | }
11414 |
11415 | /* Divide by 4, rounding up, to get number of hex digits. */
11416 | return (bitwidth + 3) / 4;
11417 | }
11418 |
11419 | const char *
11420 | hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11421 | {
11422 | char *ptr = &buf[6];
11423 | static const char hex_digits[16] =
11424 | { '0', '1', '2', '3', '4', '5', '6', '7',
11425 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11426 |
11427 | *ptr = '\0';
11428 | *(--ptr) = '\'';
11429 | /* Properly format value */
11430 | if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11431 | /*
11432 | * Printable, so just show the character, and, if it needs
11433 | * to be escaped, escape it.
11434 | */
11435 | *(--ptr) = value;
11436 | if (value == '\\' || value == '\'')
11437 | *(--ptr) = '\\';
11438 | } else {
11439 | /*
11440 | * Non-printable; show it as an escape sequence.
11441 | */
11442 | switch (value) {
11443 |
11444 | case '\0':
11445 | /*
11446 | * Show a NUL with only one digit.
11447 | */
11448 | *(--ptr) = '0';
11449 | break;
11450 |
11451 | case '\a':
11452 | case '\b':
11453 | case '\f':
11454 | case '\n':
11455 | case '\r':
11456 | case '\t':
11457 | case '\v':
11458 | *(--ptr) = value - '\a' + 'a';
11459 | break;
11460 |
11461 | default:
11462 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11463 |
11464 | case BASE_OCT:
11465 | *(--ptr) = (value & 0x7) + '0';
11466 | value >>= 3;
11467 | *(--ptr) = (value & 0x7) + '0';
11468 | value >>= 3;
11469 | *(--ptr) = (value & 0x7) + '0';
11470 | break;
11471 |
11472 | case BASE_HEX:
11473 | *(--ptr) = hex_digits[value & 0x0F];
11474 | value >>= 4;
11475 | *(--ptr) = hex_digits[value & 0x0F];
11476 | *(--ptr) = 'x';
11477 | break;
11478 |
11479 | default:
11480 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11481 | }
11482 | }
11483 | *(--ptr) = '\\';
11484 | }
11485 | *(--ptr) = '\'';
11486 | return ptr;
11487 | }
11488 |
11489 | static const char *
11490 | hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11491 | {
11492 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11493 | 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 ));
11494 |
11495 | *ptr = '\0';
11496 | /* Properly format value */
11497 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11498 | case BASE_DEC:
11499 | return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11500 |
11501 | case BASE_DEC_HEX:
11502 | *(--ptr) = ')';
11503 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11504 | *(--ptr) = '(';
11505 | *(--ptr) = ' ';
11506 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11507 | return ptr;
11508 |
11509 | case BASE_OCT:
11510 | return oct_to_str_back(ptr, value);
11511 |
11512 | case BASE_HEX:
11513 | return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11514 |
11515 | case BASE_HEX_DEC:
11516 | *(--ptr) = ')';
11517 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11518 | *(--ptr) = '(';
11519 | *(--ptr) = ' ';
11520 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11521 | return ptr;
11522 |
11523 | case BASE_PT_UDP:
11524 | case BASE_PT_TCP:
11525 | case BASE_PT_DCCP:
11526 | case BASE_PT_SCTP:
11527 | port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11528 | display_to_port_type((field_display_e)display), value);
11529 | return buf;
11530 | case BASE_OUI:
11531 | {
11532 | uint8_t p_oui[3];
11533 | const char *manuf_name;
11534 |
11535 | p_oui[0] = value >> 16 & 0xFF;
11536 | p_oui[1] = value >> 8 & 0xFF;
11537 | p_oui[2] = value & 0xFF;
11538 |
11539 | /* Attempt an OUI lookup. */
11540 | manuf_name = uint_get_manuf_name_if_known(value);
11541 | if (manuf_name == NULL((void*)0)) {
11542 | /* Could not find an OUI. */
11543 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11544 | }
11545 | else {
11546 | /* Found an address string. */
11547 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11548 | }
11549 | return buf;
11550 | }
11551 |
11552 | default:
11553 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11554 | }
11555 | return ptr;
11556 | }
11557 |
11558 | static const char *
11559 | hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11560 | {
11561 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11562 | 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 ));
11563 |
11564 | *ptr = '\0';
11565 | /* Properly format value */
11566 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11567 | case BASE_DEC:
11568 | return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11569 |
11570 | case BASE_DEC_HEX:
11571 | *(--ptr) = ')';
11572 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11573 | *(--ptr) = '(';
11574 | *(--ptr) = ' ';
11575 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11576 | return ptr;
11577 |
11578 | case BASE_OCT:
11579 | return oct64_to_str_back(ptr, value);
11580 |
11581 | case BASE_HEX:
11582 | return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11583 |
11584 | case BASE_HEX_DEC:
11585 | *(--ptr) = ')';
11586 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11587 | *(--ptr) = '(';
11588 | *(--ptr) = ' ';
11589 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11590 | return ptr;
11591 |
11592 | default:
11593 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11594 | }
11595 |
11596 | return ptr;
11597 | }
11598 |
11599 | static const char *
11600 | hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11601 | {
11602 | int display = hfinfo->display;
11603 |
11604 | if (hfinfo->type == FT_FRAMENUM) {
11605 | /*
11606 | * Frame numbers are always displayed in decimal.
11607 | */
11608 | display = BASE_DEC;
11609 | }
11610 |
11611 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11612 | }
11613 |
11614 | static const char *
11615 | hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11616 | {
11617 | int display = hfinfo->display;
11618 |
11619 | if (hfinfo->type == FT_FRAMENUM) {
11620 | /*
11621 | * Frame numbers are always displayed in decimal.
11622 | */
11623 | display = BASE_DEC;
11624 | }
11625 |
11626 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11627 | }
11628 |
11629 | static const char *
11630 | hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11631 | {
11632 | /* Get the underlying BASE_ value */
11633 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11634 |
11635 | return hfinfo_char_value_format_display(display, buf, value);
11636 | }
11637 |
11638 | static const char *
11639 | hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11640 | {
11641 | /* Get the underlying BASE_ value */
11642 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11643 |
11644 | if (hfinfo->type == FT_FRAMENUM) {
11645 | /*
11646 | * Frame numbers are always displayed in decimal.
11647 | */
11648 | display = BASE_DEC;
11649 | }
11650 |
11651 | if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)== BASE_PT_DCCP||(display)==BASE_PT_SCTP))) {
11652 | display = BASE_DEC;
11653 | } else if (display == BASE_OUI) {
11654 | display = BASE_HEX;
11655 | }
11656 |
11657 | switch (display) {
11658 | case BASE_NONE:
11659 | /* case BASE_DEC: */
11660 | case BASE_DEC_HEX:
11661 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11662 | case BASE_CUSTOM:
11663 | display = BASE_DEC;
11664 | break;
11665 |
11666 | /* case BASE_HEX: */
11667 | case BASE_HEX_DEC:
11668 | display = BASE_HEX;
11669 | break;
11670 | }
11671 |
11672 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11673 | }
11674 |
11675 | static const char *
11676 | hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11677 | {
11678 | /* Get the underlying BASE_ value */
11679 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11680 |
11681 | if (hfinfo->type == FT_FRAMENUM) {
11682 | /*
11683 | * Frame numbers are always displayed in decimal.
11684 | */
11685 | display = BASE_DEC;
11686 | }
11687 |
11688 | switch (display) {
11689 | case BASE_NONE:
11690 | /* case BASE_DEC: */
11691 | case BASE_DEC_HEX:
11692 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11693 | case BASE_CUSTOM:
11694 | display = BASE_DEC;
11695 | break;
11696 |
11697 | /* case BASE_HEX: */
11698 | case BASE_HEX_DEC:
11699 | display = BASE_HEX;
11700 | break;
11701 | }
11702 |
11703 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11704 | }
11705 |
11706 | static const char *
11707 | hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11708 | {
11709 | /* Get the underlying BASE_ value */
11710 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11711 |
11712 | return hfinfo_char_value_format_display(display, buf, value);
11713 | }
11714 |
11715 | static const char *
11716 | hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11717 | {
11718 | /* Get the underlying BASE_ value */
11719 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11720 |
11721 | if (display == BASE_NONE)
11722 | return NULL((void*)0);
11723 |
11724 | if (display == BASE_DEC_HEX)
11725 | display = BASE_DEC;
11726 | if (display == BASE_HEX_DEC)
11727 | display = BASE_HEX;
11728 |
11729 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11730 | }
11731 |
11732 | static const char *
11733 | hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11734 | {
11735 | /* Get the underlying BASE_ value */
11736 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11737 |
11738 | if (display == BASE_NONE)
11739 | return NULL((void*)0);
11740 |
11741 | if (display == BASE_DEC_HEX)
11742 | display = BASE_DEC;
11743 | if (display == BASE_HEX_DEC)
11744 | display = BASE_HEX;
11745 |
11746 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11747 | }
11748 |
11749 | const char *
11750 | proto_registrar_get_name(const int n)
11751 | {
11752 | header_field_info *hfinfo;
11753 |
11754 | 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", 11754 , __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", 11754 , "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", 11754, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11755 | return hfinfo->name;
11756 | }
11757 |
11758 | const char *
11759 | proto_registrar_get_abbrev(const int n)
11760 | {
11761 | header_field_info *hfinfo;
11762 |
11763 | 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", 11763 , __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", 11763 , "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", 11763, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11764 | return hfinfo->abbrev;
11765 | }
11766 |
11767 | enum ftenum
11768 | proto_registrar_get_ftype(const int n)
11769 | {
11770 | header_field_info *hfinfo;
11771 |
11772 | 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", 11772 , __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", 11772 , "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", 11772, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11773 | return hfinfo->type;
11774 | }
11775 |
11776 | int
11777 | proto_registrar_get_parent(const int n)
11778 | {
11779 | header_field_info *hfinfo;
11780 |
11781 | 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", 11781 , __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", 11781 , "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", 11781, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11782 | return hfinfo->parent;
11783 | }
11784 |
11785 | bool_Bool
11786 | proto_registrar_is_protocol(const int n)
11787 | {
11788 | header_field_info *hfinfo;
11789 |
11790 | 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", 11790 , __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", 11790 , "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", 11790, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11791 | return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11792 | }
11793 |
11794 | /* Returns length of field in packet (not necessarily the length
11795 | * in our internal representation, as in the case of IPv4).
11796 | * 0 means undeterminable at time of registration
11797 | * -1 means the field is not registered. */
11798 | int
11799 | proto_registrar_get_length(const int n)
11800 | {
11801 | header_field_info *hfinfo;
11802 |
11803 | 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", 11803 , __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", 11803 , "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", 11803, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11804 | return ftype_wire_size(hfinfo->type);
11805 | }
11806 |
11807 | size_t
11808 | proto_registrar_get_count(struct proto_registrar_stats *stats)
11809 | {
11810 | header_field_info *hfinfo;
11811 |
11812 | // Index zero is not used. We have to skip it.
11813 | size_t total_count = gpa_hfinfo.len - 1;
11814 | if (stats == NULL((void*)0)) {
11815 | return total_count;
11816 | }
11817 | for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11818 | if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11819 | stats->deregistered_count++;
11820 | continue; /* This is a deregistered protocol or header field */
11821 | }
11822 |
11823 | PROTO_REGISTRAR_GET_NTH(id, hfinfo)if((id == 0 || (unsigned)id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11823 , __func__, "Unregistered hf! index=%d", id); ((void) ((id > 0 && (unsigned)id < gpa_hfinfo.len) ? (void)0 : ( proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 11823, "id > 0 && (unsigned)id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[id] != (( void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 11823, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[id];;
11824 |
11825 | if (proto_registrar_is_protocol(id))
11826 | stats->protocol_count++;
11827 |
11828 | if (hfinfo->same_name_prev_id != -1)
11829 | stats->same_name_count++;
11830 | }
11831 |
11832 | return total_count;
11833 | }
11834 |
11835 | /* Looks for a protocol or a field in a proto_tree. Returns true if
11836 | * it exists anywhere, or false if it exists nowhere. */
11837 | bool_Bool
11838 | proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11839 | {
11840 | GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11841 |
11842 | if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11843 | return true1;
11844 | }
11845 | else {
11846 | return false0;
11847 | }
11848 | }
11849 |
11850 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11851 | * This only works if the hfindex was "primed" before the dissection
11852 | * took place, as we just pass back the already-created GPtrArray*.
11853 | * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11854 | * handles that. */
11855 | GPtrArray *
11856 | proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11857 | {
11858 | if (!tree)
11859 | return NULL((void*)0);
11860 |
11861 | if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11862 | return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11863 | GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11864 | else
11865 | return NULL((void*)0);
11866 | }
11867 |
11868 | bool_Bool
11869 | proto_tracking_interesting_fields(const proto_tree *tree)
11870 | {
11871 | GHashTable *interesting_hfids;
11872 |
11873 | if (!tree)
11874 | return false0;
11875 |
11876 | interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11877 |
11878 | return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11879 | }
11880 |
11881 | /* Helper struct for proto_find_info() and proto_all_finfos() */
11882 | typedef struct {
11883 | GPtrArray *array;
11884 | int id;
11885 | } ffdata_t;
11886 |
11887 | /* Helper function for proto_find_info() */
11888 | static bool_Bool
11889 | find_finfo(proto_node *node, void * data)
11890 | {
11891 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11892 | if (fi && fi->hfinfo) {
11893 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11894 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11895 | }
11896 | }
11897 |
11898 | /* Don't stop traversing. */
11899 | return false0;
11900 | }
11901 |
11902 | /* Helper function for proto_find_first_info() */
11903 | static bool_Bool
11904 | find_first_finfo(proto_node *node, void *data)
11905 | {
11906 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11907 | if (fi && fi->hfinfo) {
11908 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11909 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11910 |
11911 | /* Stop traversing. */
11912 | return true1;
11913 | }
11914 | }
11915 |
11916 | /* Continue traversing. */
11917 | return false0;
11918 | }
11919 |
11920 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11921 | * This works on any proto_tree, primed or unprimed, but actually searches
11922 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11923 | * The caller does need to free the returned GPtrArray with
11924 | * g_ptr_array_free(<array>, true).
11925 | */
11926 | GPtrArray *
11927 | proto_find_finfo(proto_tree *tree, const int id)
11928 | {
11929 | ffdata_t ffdata;
11930 |
11931 | ffdata.array = g_ptr_array_new();
11932 | ffdata.id = id;
11933 |
11934 | proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11935 |
11936 | return ffdata.array;
11937 | }
11938 |
11939 | /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11940 | * This works on any proto_tree, primed or unprimed, but actually searches
11941 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11942 | * The caller does need to free the returned GPtrArray with
11943 | * g_ptr_array_free(<array>, true).
11944 | */
11945 | GPtrArray *
11946 | proto_find_first_finfo(proto_tree *tree, const int id)
11947 | {
11948 | ffdata_t ffdata;
11949 |
11950 | ffdata.array = g_ptr_array_new();
11951 | ffdata.id = id;
11952 |
11953 | proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11954 |
11955 | return ffdata.array;
11956 | }
11957 |
11958 | /* Helper function for proto_all_finfos() */
11959 | static bool_Bool
11960 | every_finfo(proto_node *node, void * data)
11961 | {
11962 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11963 | if (fi && fi->hfinfo) {
11964 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11965 | }
11966 |
11967 | /* Don't stop traversing. */
11968 | return false0;
11969 | }
11970 |
11971 | /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11972 | * The caller does need to free the returned GPtrArray with
11973 | * g_ptr_array_free(<array>, true).
11974 | */
11975 | GPtrArray *
11976 | proto_all_finfos(proto_tree *tree)
11977 | {
11978 | ffdata_t ffdata;
11979 |
11980 | /* Pre allocate enough space to hold all fields in most cases */
11981 | ffdata.array = g_ptr_array_sized_new(512);
11982 | ffdata.id = 0;
11983 |
11984 | proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11985 |
11986 | return ffdata.array;
11987 | }
11988 |
11989 |
11990 | typedef struct {
11991 | unsigned offset;
11992 | field_info *finfo;
11993 | tvbuff_t *tvb;
11994 | } offset_search_t;
11995 |
11996 | static bool_Bool
11997 | check_for_offset(proto_node *node, void * data)
11998 | {
11999 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
12000 | offset_search_t *offsearch = (offset_search_t *)data;
12001 |
12002 | /* !fi == the top most container node which holds nothing */
12003 | if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
12004 | if (offsearch->offset >= (unsigned) fi->start &&
12005 | offsearch->offset < (unsigned) (fi->start + fi->length)) {
12006 |
12007 | offsearch->finfo = fi;
12008 | return false0; /* keep traversing */
12009 | }
12010 | }
12011 | return false0; /* keep traversing */
12012 | }
12013 |
12014 | /* Search a proto_tree backwards (from leaves to root) looking for the field
12015 | * whose start/length occupies 'offset' */
12016 | /* XXX - I couldn't find an easy way to search backwards, so I search
12017 | * forwards, w/o stopping. Therefore, the last finfo I find will the be
12018 | * the one I want to return to the user. This algorithm is inefficient
12019 | * and could be re-done, but I'd have to handle all the children and
12020 | * siblings of each node myself. When I have more time I'll do that.
12021 | * (yeah right) */
12022 | field_info *
12023 | proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
12024 | {
12025 | offset_search_t offsearch;
12026 |
12027 | offsearch.offset = offset;
12028 | offsearch.finfo = NULL((void*)0);
12029 | offsearch.tvb = tvb;
12030 |
12031 | proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
12032 |
12033 | return offsearch.finfo;
12034 | }
12035 |
12036 | typedef struct {
12037 | unsigned length;
12038 | char *buf;
12039 | } decoded_data_t;
12040 |
12041 | static bool_Bool
12042 | check_for_undecoded(proto_node *node, void * data)
12043 | {
12044 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
12045 | decoded_data_t* decoded = (decoded_data_t*)data;
12046 | unsigned i;
12047 | unsigned byte;
12048 | unsigned bit;
12049 |
12050 | if (fi && fi->hfinfo->type != FT_PROTOCOL) {
12051 | for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
12052 | byte = i / 8;
12053 | bit = i % 8;
12054 | decoded->buf[byte] |= (1 << bit);
12055 | }
12056 | }
12057 |
12058 | return false0;
12059 | }
12060 |
12061 | char*
12062 | proto_find_undecoded_data(proto_tree *tree, unsigned length)
12063 | {
12064 | decoded_data_t decoded;
12065 | decoded.length = length;
12066 | decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
12067 |
12068 | proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
12069 | return decoded.buf;
12070 | }
12071 |
12072 | /* Dumps the protocols in the registration database to stdout. An independent
12073 | * program can take this output and format it into nice tables or HTML or
12074 | * whatever.
12075 | *
12076 | * There is one record per line. The fields are tab-delimited.
12077 | *
12078 | * Field 1 = protocol name
12079 | * Field 2 = protocol short name
12080 | * Field 3 = protocol filter name
12081 | * Field 4 = protocol enabled
12082 | * Field 5 = protocol enabled by default
12083 | * Field 6 = protocol can toggle
12084 | */
12085 | void
12086 | proto_registrar_dump_protocols(void)
12087 | {
12088 | protocol_t *protocol;
12089 | int i;
12090 | void *cookie = NULL((void*)0);
12091 |
12092 |
12093 | i = proto_get_first_protocol(&cookie);
12094 | while (i != -1) {
12095 | protocol = find_protocol_by_id(i);
12096 | printf("%s\t%s\t%s\t%c\t%c\t%c\n",
12097 | protocol->name,
12098 | protocol->short_name,
12099 | protocol->filter_name,
12100 | (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
12101 | (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
12102 | (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
12103 | i = proto_get_next_protocol(&cookie);
12104 | }
12105 | }
12106 |
12107 | /* Dumps the value_strings, extended value string headers, range_strings
12108 | * or true/false strings for fields that have them.
12109 | * There is one record per line. Fields are tab-delimited.
12110 | * There are four types of records: Value String, Extended Value String Header,
12111 | * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
12112 | * the type of record.
12113 | *
12114 | * Note that a record will be generated only if the value_string,... is referenced
12115 | * in a registered hfinfo entry.
12116 | *
12117 | *
12118 | * Value Strings
12119 | * -------------
12120 | * Field 1 = 'V'
12121 | * Field 2 = Field abbreviation to which this value string corresponds
12122 | * Field 3 = Integer value
12123 | * Field 4 = String
12124 | *
12125 | * Extended Value String Headers
12126 | * -----------------------------
12127 | * Field 1 = 'E'
12128 | * Field 2 = Field abbreviation to which this extended value string header corresponds
12129 | * Field 3 = Extended Value String "Name"
12130 | * Field 4 = Number of entries in the associated value_string array
12131 | * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
12132 | *
12133 | * Range Strings
12134 | * -------------
12135 | * Field 1 = 'R'
12136 | * Field 2 = Field abbreviation to which this range string corresponds
12137 | * Field 3 = Integer value: lower bound
12138 | * Field 4 = Integer value: upper bound
12139 | * Field 5 = String
12140 | *
12141 | * True/False Strings
12142 | * ------------------
12143 | * Field 1 = 'T'
12144 | * Field 2 = Field abbreviation to which this true/false string corresponds
12145 | * Field 3 = True String
12146 | * Field 4 = False String
12147 | */
12148 | void
12149 | proto_registrar_dump_values(void)
12150 | {
12151 | header_field_info *hfinfo;
12152 | int i, len, vi;
12153 | const value_string *vals;
12154 | const val64_string *vals64;
12155 | const range_string *range;
12156 | const true_false_string *tfs;
12157 | const unit_name_string *units;
12158 |
12159 | len = gpa_hfinfo.len;
12160 | for (i = 1; i < len ; i++) {
12161 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12162 | continue; /* This is a deregistered protocol or field */
12163 |
12164 | 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", 12164 , __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", 12164 , "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", 12164, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12165 |
12166 | if (hfinfo->id == hf_text_only) {
12167 | continue;
12168 | }
12169 |
12170 | /* ignore protocols */
12171 | if (proto_registrar_is_protocol(i)) {
12172 | continue;
12173 | }
12174 | /* process header fields */
12175 | #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12176 | /*
12177 | * If this field isn't at the head of the list of
12178 | * fields with this name, skip this field - all
12179 | * fields with the same name are really just versions
12180 | * of the same field stored in different bits, and
12181 | * should have the same type/radix/value list, and
12182 | * just differ in their bit masks. (If a field isn't
12183 | * a bitfield, but can be, say, 1 or 2 bytes long,
12184 | * it can just be made FT_UINT16, meaning the
12185 | * *maximum* length is 2 bytes, and be used
12186 | * for all lengths.)
12187 | */
12188 | if (hfinfo->same_name_prev_id != -1)
12189 | continue;
12190 | #endif
12191 | vals = NULL((void*)0);
12192 | vals64 = NULL((void*)0);
12193 | range = NULL((void*)0);
12194 | tfs = NULL((void*)0);
12195 | units = NULL((void*)0);
12196 |
12197 | if (hfinfo->strings != NULL((void*)0)) {
12198 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12199 | (hfinfo->type == FT_CHAR ||
12200 | hfinfo->type == FT_UINT8 ||
12201 | hfinfo->type == FT_UINT16 ||
12202 | hfinfo->type == FT_UINT24 ||
12203 | hfinfo->type == FT_UINT32 ||
12204 | hfinfo->type == FT_UINT40 ||
12205 | hfinfo->type == FT_UINT48 ||
12206 | hfinfo->type == FT_UINT56 ||
12207 | hfinfo->type == FT_UINT64 ||
12208 | hfinfo->type == FT_INT8 ||
12209 | hfinfo->type == FT_INT16 ||
12210 | hfinfo->type == FT_INT24 ||
12211 | hfinfo->type == FT_INT32 ||
12212 | hfinfo->type == FT_INT40 ||
12213 | hfinfo->type == FT_INT48 ||
12214 | hfinfo->type == FT_INT56 ||
12215 | hfinfo->type == FT_INT64 ||
12216 | hfinfo->type == FT_FLOAT ||
12217 | hfinfo->type == FT_DOUBLE)) {
12218 |
12219 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12220 | range = (const range_string *)hfinfo->strings;
12221 | } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12222 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12223 | vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12224 | } else {
12225 | vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12226 | }
12227 | } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12228 | vals64 = (const val64_string *)hfinfo->strings;
12229 | } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12230 | units = (const unit_name_string *)hfinfo->strings;
12231 | } else {
12232 | vals = (const value_string *)hfinfo->strings;
12233 | }
12234 | }
12235 | else if (hfinfo->type == FT_BOOLEAN) {
12236 | tfs = (const struct true_false_string *)hfinfo->strings;
12237 | }
12238 | }
12239 |
12240 | /* Print value strings? */
12241 | if (vals) {
12242 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12243 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12244 | val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12245 | if (!val64_string_ext_validate(vse_p)) {
12246 | ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 12246, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
12247 | continue;
12248 | }
12249 | try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12250 | printf("E\t%s\t%u\t%s\t%s\n",
12251 | hfinfo->abbrev,
12252 | VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12253 | VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12254 | val64_string_ext_match_type_str(vse_p));
12255 | } else {
12256 | value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12257 | if (!value_string_ext_validate(vse_p)) {
12258 | ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 12258, __func__, "Invalid value_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
12259 | continue;
12260 | }
12261 | try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12262 | printf("E\t%s\t%u\t%s\t%s\n",
12263 | hfinfo->abbrev,
12264 | VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12265 | VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12266 | value_string_ext_match_type_str(vse_p));
12267 | }
12268 | }
12269 | vi = 0;
12270 | while (vals[vi].strptr) {
12271 | /* Print in the proper base */
12272 | if (hfinfo->type == FT_CHAR) {
12273 | if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT ) != 0)) {
12274 | printf("V\t%s\t'%c'\t%s\n",
12275 | hfinfo->abbrev,
12276 | vals[vi].value,
12277 | vals[vi].strptr);
12278 | } else {
12279 | if (hfinfo->display == BASE_HEX) {
12280 | printf("V\t%s\t'\\x%02x'\t%s\n",
12281 | hfinfo->abbrev,
12282 | vals[vi].value,
12283 | vals[vi].strptr);
12284 | }
12285 | else {
12286 | printf("V\t%s\t'\\%03o'\t%s\n",
12287 | hfinfo->abbrev,
12288 | vals[vi].value,
12289 | vals[vi].strptr);
12290 | }
12291 | }
12292 | } else {
12293 | if (hfinfo->display == BASE_HEX) {
12294 | printf("V\t%s\t0x%x\t%s\n",
12295 | hfinfo->abbrev,
12296 | vals[vi].value,
12297 | vals[vi].strptr);
12298 | }
12299 | else {
12300 | printf("V\t%s\t%u\t%s\n",
12301 | hfinfo->abbrev,
12302 | vals[vi].value,
12303 | vals[vi].strptr);
12304 | }
12305 | }
12306 | vi++;
12307 | }
12308 | }
12309 | else if (vals64) {
12310 | vi = 0;
12311 | while (vals64[vi].strptr) {
12312 | printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12313 | hfinfo->abbrev,
12314 | vals64[vi].value,
12315 | vals64[vi].strptr);
12316 | vi++;
12317 | }
12318 | }
12319 |
12320 | /* print range strings? */
12321 | else if (range) {
12322 | vi = 0;
12323 | while (range[vi].strptr) {
12324 | /* Print in the proper base */
12325 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12326 | printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12327 | hfinfo->abbrev,
12328 | range[vi].value_min,
12329 | range[vi].value_max,
12330 | range[vi].strptr);
12331 | }
12332 | else {
12333 | printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12334 | hfinfo->abbrev,
12335 | range[vi].value_min,
12336 | range[vi].value_max,
12337 | range[vi].strptr);
12338 | }
12339 | vi++;
12340 | }
12341 | }
12342 |
12343 | /* Print true/false strings? */
12344 | else if (tfs) {
12345 | printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12346 | tfs->true_string, tfs->false_string);
12347 | }
12348 | /* Print unit strings? */
12349 | else if (units) {
12350 | printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12351 | units->singular, units->plural ? units->plural : "(no plural)");
12352 | }
12353 | }
12354 | }
12355 |
12356 | /* Prints the number of registered fields.
12357 | * Useful for determining an appropriate value for
12358 | * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12359 | *
12360 | * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12361 | * the number of fields, true otherwise.
12362 | */
12363 | bool_Bool
12364 | proto_registrar_dump_fieldcount(void)
12365 | {
12366 | struct proto_registrar_stats stats = {0, 0, 0};
12367 | size_t total_count = proto_registrar_get_count(&stats);
12368 |
12369 | printf("There are %zu header fields registered, of which:\n"
12370 | "\t%zu are deregistered\n"
12371 | "\t%zu are protocols\n"
12372 | "\t%zu have the same name as another field\n\n",
12373 | total_count, stats.deregistered_count, stats.protocol_count,
12374 | stats.same_name_count);
12375 |
12376 | printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12377 | (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12378 | "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12379 | "\n");
12380 |
12381 | printf("The header field table consumes %u KiB of memory.\n",
12382 | (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12383 | printf("The fields themselves consume %u KiB of memory.\n",
12384 | (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12385 |
12386 | return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12387 | }
12388 |
12389 | static void
12390 | elastic_add_base_mapping(json_dumper *dumper)
12391 | {
12392 | json_dumper_set_member_name(dumper, "index_patterns");
12393 | json_dumper_begin_array(dumper);
12394 | // The index names from write_json_index() in print.c
12395 | json_dumper_value_string(dumper, "packets-*");
12396 | json_dumper_end_array(dumper);
12397 |
12398 | json_dumper_set_member_name(dumper, "settings");
12399 | json_dumper_begin_object(dumper);
12400 | json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12401 | json_dumper_value_anyf(dumper, "%d", 1000000);
12402 | json_dumper_end_object(dumper);
12403 | }
12404 |
12405 | static char*
12406 | ws_type_to_elastic(unsigned type)
12407 | {
12408 | switch(type) {
12409 | case FT_INT8:
12410 | return "byte";
12411 | case FT_UINT8:
12412 | case FT_INT16:
12413 | return "short";
12414 | case FT_UINT16:
12415 | case FT_INT32:
12416 | case FT_UINT24:
12417 | case FT_INT24:
12418 | return "integer";
12419 | case FT_FRAMENUM:
12420 | case FT_UINT32:
12421 | case FT_UINT40:
12422 | case FT_UINT48:
12423 | case FT_UINT56:
12424 | case FT_INT40:
12425 | case FT_INT48:
12426 | case FT_INT56:
12427 | case FT_INT64:
12428 | return "long";
12429 | case FT_UINT64:
12430 | return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12431 | case FT_FLOAT:
12432 | return "float";
12433 | case FT_DOUBLE:
12434 | case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12435 | return "double";
12436 | case FT_IPv6:
12437 | case FT_IPv4:
12438 | return "ip";
12439 | case FT_ABSOLUTE_TIME:
12440 | return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12441 | case FT_BOOLEAN:
12442 | return "boolean";
12443 | default:
12444 | return NULL((void*)0);
12445 | }
12446 | }
12447 |
12448 | static char*
12449 | dot_to_underscore(char* str)
12450 | {
12451 | unsigned i;
12452 | for (i = 0; i < strlen(str); i++) {
12453 | if (str[i] == '.')
12454 | str[i] = '_';
12455 | }
12456 | return str;
12457 | }
12458 |
12459 | /* Dumps a mapping file for ElasticSearch
12460 | * This is the v1 (legacy) _template API.
12461 | * At some point it may need to be updated with the composable templates
12462 | * introduced in Elasticsearch 7.8 (_index_template)
12463 | */
12464 | void
12465 | proto_registrar_dump_elastic(const char* filter)
12466 | {
12467 | header_field_info *hfinfo;
12468 | header_field_info *parent_hfinfo;
12469 | unsigned i;
12470 | bool_Bool open_object = true1;
12471 | const char* prev_proto = NULL((void*)0);
12472 | char* str;
12473 | char** protos = NULL((void*)0);
12474 | char* proto;
12475 | bool_Bool found;
12476 | unsigned j;
12477 | char* type;
12478 | char* prev_item = NULL((void*)0);
12479 |
12480 | /* We have filtering protocols. Extract them. */
12481 | if (filter) {
12482 | protos = g_strsplit(filter, ",", -1);
12483 | }
12484 |
12485 | /*
12486 | * To help tracking down the json tree, objects have been appended with a comment:
12487 | * n.label -> where n is the indentation level and label the name of the object
12488 | */
12489 |
12490 | json_dumper dumper = {
12491 | .output_file = stdoutstdout,
12492 | .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12493 | };
12494 | json_dumper_begin_object(&dumper); // 1.root
12495 | elastic_add_base_mapping(&dumper);
12496 |
12497 | json_dumper_set_member_name(&dumper, "mappings");
12498 | json_dumper_begin_object(&dumper); // 2.mappings
12499 |
12500 | json_dumper_set_member_name(&dumper, "properties");
12501 | json_dumper_begin_object(&dumper); // 3.properties
12502 | json_dumper_set_member_name(&dumper, "timestamp");
12503 | json_dumper_begin_object(&dumper); // 4.timestamp
12504 | json_dumper_set_member_name(&dumper, "type");
12505 | json_dumper_value_string(&dumper, "date");
12506 | json_dumper_end_object(&dumper); // 4.timestamp
12507 |
12508 | json_dumper_set_member_name(&dumper, "layers");
12509 | json_dumper_begin_object(&dumper); // 4.layers
12510 | json_dumper_set_member_name(&dumper, "properties");
12511 | json_dumper_begin_object(&dumper); // 5.properties
12512 |
12513 | for (i = 1; i < gpa_hfinfo.len; i++) {
12514 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12515 | continue; /* This is a deregistered protocol or header field */
12516 |
12517 | 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", 12517 , __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", 12517 , "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", 12517, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12518 |
12519 | /*
12520 | * Skip the pseudo-field for "proto_tree_add_text()" since
12521 | * we don't want it in the list of filterable protocols.
12522 | */
12523 | if (hfinfo->id == hf_text_only)
12524 | continue;
12525 |
12526 | if (!proto_registrar_is_protocol(i)) {
12527 | 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", 12527 , __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", 12527 , "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", 12527 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12528 |
12529 | /*
12530 | * Skip the field if filter protocols have been set and this one's
12531 | * parent is not listed.
12532 | */
12533 | if (protos) {
12534 | found = false0;
12535 | j = 0;
12536 | proto = protos[0];
12537 | while(proto) {
12538 | if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12539 | found = true1;
12540 | break;
12541 | }
12542 | j++;
12543 | proto = protos[j];
12544 | }
12545 | if (!found)
12546 | continue;
12547 | }
12548 |
12549 | if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12550 | json_dumper_end_object(&dumper); // 7.properties
12551 | json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12552 | open_object = true1;
12553 | }
12554 |
12555 | prev_proto = parent_hfinfo->abbrev;
12556 |
12557 | if (open_object) {
12558 | json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12559 | json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12560 | json_dumper_set_member_name(&dumper, "properties");
12561 | json_dumper_begin_object(&dumper); // 7.properties
12562 | open_object = false0;
12563 | }
12564 | /* Skip the fields that would map into string. This is the default in elasticsearch. */
12565 | type = ws_type_to_elastic(hfinfo->type);
12566 | /* when type is NULL, we have the default mapping: string */
12567 | if (type) {
12568 | str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo-> abbrev);
12569 | dot_to_underscore(str);
12570 | if (g_strcmp0(prev_item, str)) {
12571 | json_dumper_set_member_name(&dumper, str);
12572 | json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12573 | json_dumper_set_member_name(&dumper, "type");
12574 | json_dumper_value_string(&dumper, type);
12575 | json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12576 | }
12577 | g_free(prev_item)(__builtin_object_size ((prev_item), 0) != ((size_t) - 1)) ? g_free_sized (prev_item, __builtin_object_size ((prev_item), 0)) : (g_free ) (prev_item);
12578 | prev_item = str;
12579 | }
12580 | }
12581 | }
12582 | g_free(prev_item)(__builtin_object_size ((prev_item), 0) != ((size_t) - 1)) ? g_free_sized (prev_item, __builtin_object_size ((prev_item), 0)) : (g_free ) (prev_item);
12583 |
12584 | if (prev_proto) {
12585 | json_dumper_end_object(&dumper); // 7.properties
12586 | json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12587 | }
12588 |
12589 | json_dumper_end_object(&dumper); // 5.properties
12590 | json_dumper_end_object(&dumper); // 4.layers
12591 | json_dumper_end_object(&dumper); // 3.properties
12592 | json_dumper_end_object(&dumper); // 2.mappings
12593 | json_dumper_end_object(&dumper); // 1.root
12594 | bool_Bool ret = json_dumper_finish(&dumper);
12595 | DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12595, "ret"))));
12596 |
12597 | g_strfreev(protos);
12598 | }
12599 |
12600 | /* Dumps the contents of the registration database to stdout. An independent
12601 | * program can take this output and format it into nice tables or HTML or
12602 | * whatever.
12603 | *
12604 | * There is one record per line. Each record is either a protocol or a header
12605 | * field, differentiated by the first field. The fields are tab-delimited.
12606 | *
12607 | * Protocols
12608 | * ---------
12609 | * Field 1 = 'P'
12610 | * Field 2 = descriptive protocol name
12611 | * Field 3 = protocol abbreviation
12612 | *
12613 | * Header Fields
12614 | * -------------
12615 | * Field 1 = 'F'
12616 | * Field 2 = descriptive field name
12617 | * Field 3 = field abbreviation
12618 | * Field 4 = type ( textual representation of the ftenum type )
12619 | * Field 5 = parent protocol abbreviation
12620 | * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12621 | * Field 7 = bitmask: format: hex: 0x....
12622 | * Field 8 = blurb describing field
12623 | */
12624 | void
12625 | proto_registrar_dump_fields(void)
12626 | {
12627 | header_field_info *hfinfo, *parent_hfinfo;
12628 | int i, len;
12629 | const char *enum_name;
12630 | const char *base_name;
12631 | const char *blurb;
12632 | char width[5];
12633 |
12634 | len = gpa_hfinfo.len;
12635 | for (i = 1; i < len ; i++) {
12636 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12637 | continue; /* This is a deregistered protocol or header field */
12638 |
12639 | 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", 12639 , __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", 12639 , "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", 12639, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12640 |
12641 | /*
12642 | * Skip the pseudo-field for "proto_tree_add_text()" since
12643 | * we don't want it in the list of filterable fields.
12644 | */
12645 | if (hfinfo->id == hf_text_only)
12646 | continue;
12647 |
12648 | /* format for protocols */
12649 | if (proto_registrar_is_protocol(i)) {
12650 | printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12651 | }
12652 | /* format for header fields */
12653 | else {
12654 | /*
12655 | * If this field isn't at the head of the list of
12656 | * fields with this name, skip this field - all
12657 | * fields with the same name are really just versions
12658 | * of the same field stored in different bits, and
12659 | * should have the same type/radix/value list, and
12660 | * just differ in their bit masks. (If a field isn't
12661 | * a bitfield, but can be, say, 1 or 2 bytes long,
12662 | * it can just be made FT_UINT16, meaning the
12663 | * *maximum* length is 2 bytes, and be used
12664 | * for all lengths.)
12665 | */
12666 | if (hfinfo->same_name_prev_id != -1)
12667 | continue;
12668 |
12669 | 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", 12669 , __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", 12669 , "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", 12669 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12670 |
12671 | enum_name = ftype_name(hfinfo->type);
12672 | base_name = "";
12673 |
12674 | if (hfinfo->type == FT_CHAR ||
12675 | hfinfo->type == FT_UINT8 ||
12676 | hfinfo->type == FT_UINT16 ||
12677 | hfinfo->type == FT_UINT24 ||
12678 | hfinfo->type == FT_UINT32 ||
12679 | hfinfo->type == FT_UINT40 ||
12680 | hfinfo->type == FT_UINT48 ||
12681 | hfinfo->type == FT_UINT56 ||
12682 | hfinfo->type == FT_UINT64 ||
12683 | hfinfo->type == FT_INT8 ||
12684 | hfinfo->type == FT_INT16 ||
12685 | hfinfo->type == FT_INT24 ||
12686 | hfinfo->type == FT_INT32 ||
12687 | hfinfo->type == FT_INT40 ||
12688 | hfinfo->type == FT_INT48 ||
12689 | hfinfo->type == FT_INT56 ||
12690 | hfinfo->type == FT_INT64) {
12691 |
12692 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12693 | case BASE_NONE:
12694 | case BASE_DEC:
12695 | case BASE_HEX:
12696 | case BASE_OCT:
12697 | case BASE_DEC_HEX:
12698 | case BASE_HEX_DEC:
12699 | case BASE_CUSTOM:
12700 | case BASE_PT_UDP:
12701 | case BASE_PT_TCP:
12702 | case BASE_PT_DCCP:
12703 | case BASE_PT_SCTP:
12704 | case BASE_OUI:
12705 | base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12706 | break;
12707 | default:
12708 | base_name = "????";
12709 | break;
12710 | }
12711 | } else if (hfinfo->type == FT_BOOLEAN) {
12712 | /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12713 | snprintf(width, sizeof(width), "%d", hfinfo->display);
12714 | base_name = width;
12715 | }
12716 |
12717 | blurb = hfinfo->blurb;
12718 | if (blurb == NULL((void*)0))
12719 | blurb = "";
12720 | else if (strlen(blurb) == 0)
12721 | blurb = "\"\"";
12722 |
12723 | printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12724 | hfinfo->name, hfinfo->abbrev, enum_name,
12725 | parent_hfinfo->abbrev, base_name,
12726 | hfinfo->bitmask, blurb);
12727 | }
12728 | }
12729 | }
12730 |
12731 | /* Dumps all abbreviated field and protocol completions of the given string to
12732 | * stdout. An independent program may use this for command-line tab completion
12733 | * of fields.
12734 | */
12735 | bool_Bool
12736 | proto_registrar_dump_field_completions(const char *prefix)
12737 | {
12738 | header_field_info *hfinfo;
12739 | int i, len;
12740 | size_t prefix_len;
12741 | bool_Bool matched = false0;
12742 |
12743 | prefix_len = strlen(prefix);
12744 | len = gpa_hfinfo.len;
12745 | for (i = 1; i < len ; i++) {
12746 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12747 | continue; /* This is a deregistered protocol or header field */
12748 |
12749 | 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", 12749 , __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", 12749 , "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", 12749, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12750 |
12751 | /*
12752 | * Skip the pseudo-field for "proto_tree_add_text()" since
12753 | * we don't want it in the list of filterable fields.
12754 | */
12755 | if (hfinfo->id == hf_text_only)
12756 | continue;
12757 |
12758 | /* format for protocols */
12759 | if (proto_registrar_is_protocol(i)) {
12760 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12761 | matched = true1;
12762 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12763 | }
12764 | }
12765 | /* format for header fields */
12766 | else {
12767 | /*
12768 | * If this field isn't at the head of the list of
12769 | * fields with this name, skip this field - all
12770 | * fields with the same name are really just versions
12771 | * of the same field stored in different bits, and
12772 | * should have the same type/radix/value list, and
12773 | * just differ in their bit masks. (If a field isn't
12774 | * a bitfield, but can be, say, 1 or 2 bytes long,
12775 | * it can just be made FT_UINT16, meaning the
12776 | * *maximum* length is 2 bytes, and be used
12777 | * for all lengths.)
12778 | */
12779 | if (hfinfo->same_name_prev_id != -1)
12780 | continue;
12781 |
12782 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12783 | matched = true1;
12784 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12785 | }
12786 | }
12787 | }
12788 | return matched;
12789 | }
12790 |
12791 | /* Dumps field types and descriptive names to stdout. An independent
12792 | * program can take this output and format it into nice tables or HTML or
12793 | * whatever.
12794 | *
12795 | * There is one record per line. The fields are tab-delimited.
12796 | *
12797 | * Field 1 = field type name, e.g. FT_UINT8
12798 | * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12799 | */
12800 | void
12801 | proto_registrar_dump_ftypes(void)
12802 | {
12803 | int fte;
12804 |
12805 | for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12806 | printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12807 | }
12808 | }
12809 |
12810 | /* This function indicates whether it's possible to construct a
12811 | * "match selected" display filter string for the specified field,
12812 | * returns an indication of whether it's possible, and, if it's
12813 | * possible and "filter" is non-null, constructs the filter and
12814 | * sets "*filter" to point to it.
12815 | * You do not need to [g_]free() this string since it will be automatically
12816 | * freed once the next packet is dissected.
12817 | */
12818 | static bool_Bool
12819 | construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12820 | char **filter)
12821 | {
12822 | const header_field_info *hfinfo;
12823 | int start, length, length_remaining;
12824 |
12825 | if (!finfo)
12826 | return false0;
12827 |
12828 | hfinfo = finfo->hfinfo;
12829 | DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12829, "hfinfo"))));
12830 |
12831 | /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12832 | * then "the numeric value ... is not used when preparing
12833 | * filters for the field in question." If it's any other
12834 | * base, we'll generate the filter normally (which will
12835 | * be numeric, even though the human-readable string does
12836 | * work for filtering.)
12837 | *
12838 | * XXX - It might be nice to use fvalue_to_string_repr() in
12839 | * "proto_item_fill_label()" as well, although, there, you'd
12840 | * have to deal with the base *and* with resolved values for
12841 | * addresses.
12842 | *
12843 | * Perhaps in addition to taking the repr type (DISPLAY
12844 | * or DFILTER) and the display (base), fvalue_to_string_repr()
12845 | * should have the the "strings" values in the header_field_info
12846 | * structure for the field as a parameter, so it can have
12847 | * if the field is Boolean or an enumerated integer type,
12848 | * the tables used to generate human-readable values.
12849 | */
12850 | if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12851 | const char *str = NULL((void*)0);
12852 |
12853 | switch (hfinfo->type) {
12854 |
12855 | case FT_INT8:
12856 | case FT_INT16:
12857 | case FT_INT24:
12858 | case FT_INT32:
12859 | str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12860 | break;
12861 |
12862 | case FT_CHAR:
12863 | case FT_UINT8:
12864 | case FT_UINT16:
12865 | case FT_UINT24:
12866 | case FT_UINT32:
12867 | str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12868 | break;
12869 |
12870 | default:
12871 | break;
12872 | }
12873 |
12874 | if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12875 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12876 | return true1;
12877 | }
12878 | }
12879 |
12880 | switch (hfinfo->type) {
12881 |
12882 | case FT_PROTOCOL:
12883 | if (filter != NULL((void*)0))
12884 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12885 | break;
12886 |
12887 | case FT_NONE:
12888 | /*
12889 | * If the length is 0, just match the name of the
12890 | * field.
12891 | *
12892 | * (Also check for negative values, just in case,
12893 | * as we'll cast it to an unsigned value later.)
12894 | */
12895 | length = finfo->length;
12896 | if (length == 0) {
12897 | if (filter != NULL((void*)0))
12898 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12899 | break;
12900 | }
12901 | if (length < 0)
12902 | return false0;
12903 |
12904 | /*
12905 | * This doesn't have a value, so we'd match
12906 | * on the raw bytes at this address.
12907 | *
12908 | * Should we be allowed to access to the raw bytes?
12909 | * If "edt" is NULL, the answer is "no".
12910 | */
12911 | if (edt == NULL((void*)0))
12912 | return false0;
12913 |
12914 | /*
12915 | * Is this field part of the raw frame tvbuff?
12916 | * If not, we can't use "frame[N:M]" to match
12917 | * it.
12918 | *
12919 | * XXX - should this be frame-relative, or
12920 | * protocol-relative?
12921 | *
12922 | * XXX - does this fallback for non-registered
12923 | * fields even make sense?
12924 | */
12925 | if (finfo->ds_tvb != edt->tvb)
12926 | return false0; /* you lose */
12927 |
12928 | /*
12929 | * Don't go past the end of that tvbuff.
12930 | */
12931 | length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12932 | if (length > length_remaining)
12933 | length = length_remaining;
12934 | if (length <= 0)
12935 | return false0;
12936 |
12937 | if (filter != NULL((void*)0)) {
12938 | start = finfo->start;
12939 | char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12940 | *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12941 | wmem_free(NULL((void*)0), str);
12942 | }
12943 | break;
12944 |
12945 | /* By default, use the fvalue's "to_string_repr" method. */
12946 | default:
12947 | if (filter != NULL((void*)0)) {
12948 | char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12949 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12950 | wmem_free(NULL((void*)0), str);
12951 | }
12952 | break;
12953 | }
12954 |
12955 | return true1;
12956 | }
12957 |
12958 | /*
12959 | * Returns true if we can do a "match selected" on the field, false
12960 | * otherwise.
12961 | */
12962 | bool_Bool
12963 | proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12964 | {
12965 | return construct_match_selected_string(finfo, edt, NULL((void*)0));
12966 | }
12967 |
12968 | /* This function attempts to construct a "match selected" display filter
12969 | * string for the specified field; if it can do so, it returns a pointer
12970 | * to the string, otherwise it returns NULL.
12971 | *
12972 | * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12973 | */
12974 | char *
12975 | proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12976 | {
12977 | char *filter = NULL((void*)0);
12978 |
12979 | if (!construct_match_selected_string(finfo, edt, &filter))
12980 | {
12981 | wmem_free(NULL((void*)0), filter);
12982 | return NULL((void*)0);
12983 | }
12984 | return filter;
12985 | }
12986 |
12987 | /* This function is common code for all proto_tree_add_bitmask... functions.
12988 | */
12989 |
12990 | static bool_Bool
12991 | proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
12992 | const unsigned len, const int ett, int * const *fields,
12993 | const int flags, bool_Bool first,
12994 | bool_Bool use_parent_tree,
12995 | proto_tree* tree, uint64_t value)
12996 | {
12997 | uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12998 | uint64_t bitmask = 0;
12999 | uint64_t tmpval;
13000 | header_field_info *hf;
13001 | uint32_t integer32;
13002 | int bit_offset;
13003 | int no_of_bits;
13004 |
13005 | if (!*fields)
13006 | 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" );
13007 |
13008 | if (len > 8)
13009 | REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
13010 | /**
13011 | * packet-frame.c uses len=0 since the value is taken from the packet
13012 | * metadata, not the packet bytes. In that case, assume that all bits
13013 | * in the provided value are valid.
13014 | */
13015 | if (len > 0) {
13016 | available_bits >>= (8 - len)*8;
13017 | }
13018 |
13019 | if (use_parent_tree == false0)
13020 | tree = proto_item_add_subtree(item, ett);
13021 |
13022 | while (*fields) {
13023 | uint64_t present_bits;
13024 | 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", 13024, __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", 13024 , "**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", 13024, "gpa_hfinfo.hfi[**fields] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];;
13025 | 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", 13025 , "hf->bitmask != 0", hf->abbrev))));
13026 |
13027 | bitmask |= hf->bitmask;
13028 |
13029 | /* Skip fields that aren't fully present */
13030 | present_bits = available_bits & hf->bitmask;
13031 | if (present_bits != hf->bitmask) {
13032 | fields++;
13033 | continue;
13034 | }
13035 |
13036 | switch (hf->type) {
13037 | case FT_CHAR:
13038 | case FT_UINT8:
13039 | case FT_UINT16:
13040 | case FT_UINT24:
13041 | case FT_UINT32:
13042 | proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
13043 | break;
13044 |
13045 | case FT_INT8:
13046 | case FT_INT16:
13047 | case FT_INT24:
13048 | case FT_INT32:
13049 | proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
13050 | break;
13051 |
13052 | case FT_UINT40:
13053 | case FT_UINT48:
13054 | case FT_UINT56:
13055 | case FT_UINT64:
13056 | proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
13057 | break;
13058 |
13059 | case FT_INT40:
13060 | case FT_INT48:
13061 | case FT_INT56:
13062 | case FT_INT64:
13063 | proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
13064 | break;
13065 |
13066 | case FT_BOOLEAN:
13067 | proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
13068 | break;
13069 |
13070 | default:
13071 | 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))
13072 | 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))
13073 | 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))
13074 | 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));
13075 | break;
13076 | }
13077 | if (flags & BMT_NO_APPEND0x01) {
13078 | fields++;
13079 | continue;
13080 | }
13081 | tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
13082 |
13083 | /* XXX: README.developer and the comments have always defined
13084 | * BMT_NO_INT as "only boolean flags are added to the title /
13085 | * don't add non-boolean (integral) fields", but the
13086 | * implementation has always added BASE_CUSTOM and fields with
13087 | * value_strings, though not fields with unit_strings.
13088 | * Possibly this is because some dissectors use a FT_UINT8
13089 | * with a value_string for fields that should be a FT_BOOLEAN.
13090 | */
13091 | switch (hf->type) {
13092 | case FT_CHAR:
13093 | if (hf->display == BASE_CUSTOM) {
13094 | char lbl[ITEM_LABEL_LENGTH240];
13095 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13096 |
13097 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13097, "fmtfunc"))));
13098 | fmtfunc(lbl, (uint32_t) tmpval);
13099 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13100 | hf->name, lbl);
13101 | first = false0;
13102 | }
13103 | else if (hf->strings) {
13104 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13105 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13106 | first = false0;
13107 | }
13108 | else if (!(flags & BMT_NO_INT0x02)) {
13109 | char buf[32];
13110 | const char *out;
13111 |
13112 | if (!first) {
13113 | proto_item_append_text(item, ", ");
13114 | }
13115 |
13116 | out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
13117 | proto_item_append_text(item, "%s: %s", hf->name, out);
13118 | first = false0;
13119 | }
13120 |
13121 | break;
13122 |
13123 | case FT_UINT8:
13124 | case FT_UINT16:
13125 | case FT_UINT24:
13126 | case FT_UINT32:
13127 | if (hf->display == BASE_CUSTOM) {
13128 | char lbl[ITEM_LABEL_LENGTH240];
13129 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13130 |
13131 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13131, "fmtfunc"))));
13132 | fmtfunc(lbl, (uint32_t) tmpval);
13133 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13134 | hf->name, lbl);
13135 | first = false0;
13136 | }
13137 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13138 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13139 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13140 | first = false0;
13141 | }
13142 | else if (!(flags & BMT_NO_INT0x02)) {
13143 | char buf[NUMBER_LABEL_LENGTH80];
13144 | const char *out = NULL((void*)0);
13145 |
13146 | if (!first) {
13147 | proto_item_append_text(item, ", ");
13148 | }
13149 |
13150 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13151 | out = hf_try_val_to_str((uint32_t) tmpval, hf);
13152 | }
13153 | if (out == NULL((void*)0)) {
13154 | out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13155 | }
13156 | proto_item_append_text(item, "%s: %s", hf->name, out);
13157 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13158 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13159 | }
13160 | first = false0;
13161 | }
13162 |
13163 | break;
13164 |
13165 | case FT_INT8:
13166 | case FT_INT16:
13167 | case FT_INT24:
13168 | case FT_INT32:
13169 | integer32 = (uint32_t) tmpval;
13170 | if (hf->bitmask) {
13171 | no_of_bits = ws_count_ones(hf->bitmask);
13172 | integer32 = ws_sign_ext32(integer32, no_of_bits);
13173 | }
13174 | if (hf->display == BASE_CUSTOM) {
13175 | char lbl[ITEM_LABEL_LENGTH240];
13176 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13177 |
13178 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13178, "fmtfunc"))));
13179 | fmtfunc(lbl, (int32_t) integer32);
13180 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13181 | hf->name, lbl);
13182 | first = false0;
13183 | }
13184 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13185 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13186 | hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13187 | first = false0;
13188 | }
13189 | else if (!(flags & BMT_NO_INT0x02)) {
13190 | char buf[NUMBER_LABEL_LENGTH80];
13191 | const char *out = NULL((void*)0);
13192 |
13193 | if (!first) {
13194 | proto_item_append_text(item, ", ");
13195 | }
13196 |
13197 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13198 | out = hf_try_val_to_str((int32_t) integer32, hf);
13199 | }
13200 | if (out == NULL((void*)0)) {
13201 | out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13202 | }
13203 | proto_item_append_text(item, "%s: %s", hf->name, out);
13204 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13205 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13206 | }
13207 | first = false0;
13208 | }
13209 |
13210 | break;
13211 |
13212 | case FT_UINT40:
13213 | case FT_UINT48:
13214 | case FT_UINT56:
13215 | case FT_UINT64:
13216 | if (hf->display == BASE_CUSTOM) {
13217 | char lbl[ITEM_LABEL_LENGTH240];
13218 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13219 |
13220 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13220, "fmtfunc"))));
13221 | fmtfunc(lbl, tmpval);
13222 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13223 | hf->name, lbl);
13224 | first = false0;
13225 | }
13226 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13227 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13228 | hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13229 | first = false0;
13230 | }
13231 | else if (!(flags & BMT_NO_INT0x02)) {
13232 | char buf[NUMBER_LABEL_LENGTH80];
13233 | const char *out = NULL((void*)0);
13234 |
13235 | if (!first) {
13236 | proto_item_append_text(item, ", ");
13237 | }
13238 |
13239 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13240 | out = hf_try_val64_to_str(tmpval, hf);
13241 | }
13242 | if (out == NULL((void*)0)) {
13243 | out = hfinfo_number_value_format64(hf, buf, tmpval);
13244 | }
13245 | proto_item_append_text(item, "%s: %s", hf->name, out);
13246 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13247 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13248 | }
13249 | first = false0;
13250 | }
13251 |
13252 | break;
13253 |
13254 | case FT_INT40:
13255 | case FT_INT48:
13256 | case FT_INT56:
13257 | case FT_INT64:
13258 | if (hf->bitmask) {
13259 | no_of_bits = ws_count_ones(hf->bitmask);
13260 | tmpval = ws_sign_ext64(tmpval, no_of_bits);
13261 | }
13262 | if (hf->display == BASE_CUSTOM) {
13263 | char lbl[ITEM_LABEL_LENGTH240];
13264 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13265 |
13266 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13266, "fmtfunc"))));
13267 | fmtfunc(lbl, (int64_t) tmpval);
13268 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13269 | hf->name, lbl);
13270 | first = false0;
13271 | }
13272 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13273 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13274 | hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13275 | first = false0;
13276 | }
13277 | else if (!(flags & BMT_NO_INT0x02)) {
13278 | char buf[NUMBER_LABEL_LENGTH80];
13279 | const char *out = NULL((void*)0);
13280 |
13281 | if (!first) {
13282 | proto_item_append_text(item, ", ");
13283 | }
13284 |
13285 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13286 | out = hf_try_val64_to_str((int64_t) tmpval, hf);
13287 | }
13288 | if (out == NULL((void*)0)) {
13289 | out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13290 | }
13291 | proto_item_append_text(item, "%s: %s", hf->name, out);
13292 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13293 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13294 | }
13295 | first = false0;
13296 | }
13297 |
13298 | break;
13299 |
13300 | case FT_BOOLEAN:
13301 | if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13302 | /* If we have true/false strings, emit full - otherwise messages
13303 | might look weird */
13304 | const struct true_false_string *tfs =
13305 | (const struct true_false_string *)hf->strings;
13306 |
13307 | if (tmpval) {
13308 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13309 | hf->name, tfs->true_string);
13310 | first = false0;
13311 | } else if (!(flags & BMT_NO_FALSE0x04)) {
13312 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13313 | hf->name, tfs->false_string);
13314 | first = false0;
13315 | }
13316 | } else if (hf->bitmask & value) {
13317 | /* If the flag is set, show the name */
13318 | proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13319 | first = false0;
13320 | }
13321 | break;
13322 | default:
13323 | 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))
13324 | 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))
13325 | 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))
13326 | 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));
13327 | break;
13328 | }
13329 |
13330 | fields++;
13331 | }
13332 |
13333 | /* XXX: We don't pass the hfi into this function. Perhaps we should,
13334 | * but then again most dissectors don't set the bitmask field for
13335 | * the higher level bitmask hfi, so calculate the bitmask from the
13336 | * fields present. */
13337 | if (item) {
13338 | bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13339 | no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13340 | FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset))do { if (((item)->finfo)) (((item)->finfo))->flags = (((item)->finfo))->flags | ((((bit_offset) & 63) << 5)); } while(0);
13341 | FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits))do { if (((item)->finfo)) (((item)->finfo))->flags = (((item)->finfo))->flags | ((((no_of_bits) & 63) << 12)); } while(0);
13342 | }
13343 | return first;
13344 | }
13345 |
13346 | /* This function will dissect a sequence of bytes that describe a
13347 | * bitmask and supply the value of that sequence through a pointer.
13348 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13349 | * to be dissected.
13350 | * This field will form an expansion under which the individual fields of the
13351 | * bitmask is dissected and displayed.
13352 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13353 | *
13354 | * fields is an array of pointers to int that lists all the fields of the
13355 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13356 | * or another integer of the same type/size as hf_hdr with a mask specified.
13357 | * This array is terminated by a NULL entry.
13358 | *
13359 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13360 | * FT_integer fields that have a value_string attached will have the
13361 | * matched string displayed on the expansion line.
13362 | */
13363 | proto_item *
13364 | proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13365 | const unsigned offset, const int hf_hdr,
13366 | const int ett, int * const *fields,
13367 | const unsigned encoding, uint64_t *retval)
13368 | {
13369 | 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);
13370 | }
13371 |
13372 | /* This function will dissect a sequence of bytes that describe a
13373 | * bitmask.
13374 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13375 | * to be dissected.
13376 | * This field will form an expansion under which the individual fields of the
13377 | * bitmask is dissected and displayed.
13378 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13379 | *
13380 | * fields is an array of pointers to int that lists all the fields of the
13381 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13382 | * or another integer of the same type/size as hf_hdr with a mask specified.
13383 | * This array is terminated by a NULL entry.
13384 | *
13385 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13386 | * FT_integer fields that have a value_string attached will have the
13387 | * matched string displayed on the expansion line.
13388 | */
13389 | proto_item *
13390 | proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13391 | const unsigned offset, const int hf_hdr,
13392 | const int ett, int * const *fields,
13393 | const unsigned encoding)
13394 | {
13395 | return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13396 | }
13397 |
13398 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13399 | * what data is appended to the header.
13400 | */
13401 | proto_item *
13402 | proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13403 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13404 | uint64_t *retval)
13405 | {
13406 | proto_item *item = NULL((void*)0);
13407 | header_field_info *hf;
13408 | unsigned len;
13409 | uint64_t value;
13410 |
13411 | 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", 13411, __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", 13411 , "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", 13411, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13412 | 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", 13412, (hf)->abbrev)));
13413 | len = ftype_wire_size(hf->type);
13414 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13415 |
13416 | if (parent_tree) {
13417 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13418 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13419 | flags, false0, false0, NULL((void*)0), value);
13420 | }
13421 |
13422 | *retval = value;
13423 | if (hf->bitmask) {
13424 | /* Mask out irrelevant portions */
13425 | *retval &= hf->bitmask;
13426 | /* Shift bits */
13427 | *retval >>= hfinfo_bitshift(hf);
13428 | }
13429 |
13430 | return item;
13431 | }
13432 |
13433 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13434 | * what data is appended to the header.
13435 | */
13436 | proto_item *
13437 | proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13438 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13439 | {
13440 | proto_item *item = NULL((void*)0);
13441 | header_field_info *hf;
13442 | unsigned len;
13443 | uint64_t value;
13444 |
13445 | 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", 13445, __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", 13445 , "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", 13445, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13446 | 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", 13446, (hf)->abbrev)));
13447 |
13448 | if (parent_tree) {
13449 | len = ftype_wire_size(hf->type);
13450 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13451 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13452 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13453 | flags, false0, false0, NULL((void*)0), value);
13454 | }
13455 |
13456 | return item;
13457 | }
13458 |
13459 | /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13460 | can't be retrieved directly from tvb) */
13461 | proto_item *
13462 | proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13463 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13464 | {
13465 | return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13466 | hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13467 | }
13468 |
13469 | /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13470 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13471 | proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13472 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13473 | {
13474 | proto_item *item = NULL((void*)0);
13475 | header_field_info *hf;
13476 | unsigned len;
13477 |
13478 | 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", 13478, __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", 13478 , "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", 13478, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13479 | 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", 13479, (hf)->abbrev)));
13480 | /* the proto_tree_add_uint/_uint64() calls below
13481 | will fail if tvb==NULL and len!=0 */
13482 | len = tvb ? ftype_wire_size(hf->type) : 0;
13483 |
13484 | if (parent_tree) {
13485 | if (len <= 4)
13486 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13487 | else
13488 | item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13489 |
13490 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13491 | flags, false0, false0, NULL((void*)0), value);
13492 | }
13493 |
13494 | return item;
13495 | }
13496 |
13497 | /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13498 | void
13499 | proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13500 | const unsigned len, int * const *fields, const unsigned encoding)
13501 | {
13502 | uint64_t value;
13503 |
13504 | if (tree) {
13505 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13506 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13507 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13508 | }
13509 | }
13510 |
13511 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13512 | proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13513 | const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13514 | {
13515 | uint64_t value;
13516 |
13517 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13518 | if (tree) {
13519 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13520 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13521 | }
13522 | if (retval) {
13523 | *retval = value;
13524 | }
13525 | }
13526 |
13527 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13528 | proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13529 | const unsigned len, int * const *fields, const uint64_t value)
13530 | {
13531 | if (tree) {
13532 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13533 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13534 | }
13535 | }
13536 |
13537 |
13538 | /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13539 | * This is intended to support bitmask fields whose lengths can vary, perhaps
13540 | * as the underlying standard evolves over time.
13541 | * With this API there is the possibility of being called to display more or
13542 | * less data than the dissector was coded to support.
13543 | * In such cases, it is assumed that bitmasks are extended on the MSb end.
13544 | * Thus when presented with "too much" or "too little" data, MSbits will be
13545 | * ignored or MSfields sacrificed.
13546 | *
13547 | * Only fields for which all defined bits are available are displayed.
13548 | */
13549 | proto_item *
13550 | proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13551 | const unsigned offset, const unsigned len, const int hf_hdr,
13552 | const int ett, int * const *fields, struct expert_field* exp,
13553 | const unsigned encoding)
13554 | {
13555 | proto_item *item = NULL((void*)0);
13556 | header_field_info *hf;
13557 | unsigned decodable_len;
13558 | unsigned decodable_offset;
13559 | uint32_t decodable_value;
13560 | uint64_t value;
13561 |
13562 | 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", 13562, __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", 13562 , "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", 13562, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13563 | 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", 13563, (hf)->abbrev)));
13564 |
13565 | decodable_offset = offset;
13566 | decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len ) : ((unsigned) ftype_wire_size(hf->type)));
13567 |
13568 | /* If we are ftype_wire_size-limited,
13569 | * make sure we decode as many LSBs as possible.
13570 | */
13571 | if (encoding == ENC_BIG_ENDIAN0x00000000) {
13572 | decodable_offset += (len - decodable_len);
13573 | }
13574 |
13575 | if (parent_tree) {
13576 | decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13577 | decodable_len, encoding);
13578 |
13579 | /* The root item covers all the bytes even if we can't decode them all */
13580 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13581 | decodable_value);
13582 | }
13583 |
13584 | if (decodable_len < len) {
13585 | /* Dissector likely requires updating for new protocol revision */
13586 | expert_add_info_format(NULL((void*)0), item, exp,
13587 | "Only least-significant %d of %d bytes decoded",
13588 | decodable_len, len);
13589 | }
13590 |
13591 | if (item) {
13592 | value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13593 | proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13594 | ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13595 | }
13596 |
13597 | return item;
13598 | }
13599 |
13600 | /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13601 | proto_item *
13602 | proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13603 | const unsigned offset, const unsigned len,
13604 | const char *name, const char *fallback,
13605 | const int ett, int * const *fields,
13606 | const unsigned encoding, const int flags)
13607 | {
13608 | proto_item *item = NULL((void*)0);
13609 | uint64_t value;
13610 |
13611 | if (parent_tree) {
13612 | item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13613 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13614 | if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13615 | flags, true1, false0, NULL((void*)0), value) && fallback) {
13616 | /* Still at first item - append 'fallback' text if any */
13617 | proto_item_append_text(item, "%s", fallback);
13618 | }
13619 | }
13620 |
13621 | return item;
13622 | }
13623 |
13624 | proto_item *
13625 | proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13626 | const unsigned bit_offset, const int no_of_bits,
13627 | const unsigned encoding)
13628 | {
13629 | header_field_info *hfinfo;
13630 | int octet_length;
13631 | unsigned octet_offset;
13632 |
13633 | 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", 13633, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13633 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13633, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13634 |
13635 | if (no_of_bits < 0) {
13636 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13637 | }
13638 | octet_length = (no_of_bits + 7) >> 3;
13639 | octet_offset = bit_offset >> 3;
13640 | test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13641 |
13642 | /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13643 | * but only after doing a bunch more work (which we can, in the common
13644 | * case, shortcut here).
13645 | */
13646 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13647 | 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", 13647 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13647, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13647, "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", 13647, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
13648 |
13649 | return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13650 | }
13651 |
13652 | /*
13653 | * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13654 | * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13655 | * Offset should be given in bits from the start of the tvb.
13656 | */
13657 |
13658 | static proto_item *
13659 | _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13660 | const unsigned bit_offset, const int no_of_bits,
13661 | uint64_t *return_value, const unsigned encoding)
13662 | {
13663 | unsigned offset;
13664 | unsigned length;
13665 | uint8_t tot_no_bits;
13666 | char *bf_str;
13667 | char lbl_str[ITEM_LABEL_LENGTH240];
13668 | uint64_t value = 0;
13669 | uint8_t *bytes = NULL((void*)0);
13670 | size_t bytes_length = 0;
13671 |
13672 | proto_item *pi;
13673 | header_field_info *hf_field;
13674 |
13675 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13676 | 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", 13676, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13676 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13676, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;;
13677 |
13678 | if (hf_field->bitmask != 0) {
13679 | 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)
13680 | " 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)
13681 | 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);
13682 | }
13683 |
13684 | if (no_of_bits < 0) {
13685 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13686 | } else if (no_of_bits == 0) {
13687 | 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)
13688 | 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);
13689 | }
13690 |
13691 | /* Byte align offset */
13692 | offset = bit_offset>>3;
13693 |
13694 | /*
13695 | * Calculate the number of octets used to hold the bits
13696 | */
13697 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13698 | length = (tot_no_bits + 7) >> 3;
13699 |
13700 | if (no_of_bits < 65) {
13701 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13702 | } else if (hf_field->type != FT_BYTES) {
13703 | REPORT_DISSECTOR_BUG("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 64",proto_report_dissector_bug("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 64" , hf_field->abbrev, no_of_bits)
13704 | hf_field->abbrev, no_of_bits)proto_report_dissector_bug("field %s passed to proto_tree_add_bits_ret_val() has a bit width of %u > 64" , hf_field->abbrev, no_of_bits);
13705 | return NULL((void*)0);
13706 | }
13707 |
13708 | /* Sign extend for signed types */
13709 | switch (hf_field->type) {
13710 | case FT_INT8:
13711 | case FT_INT16:
13712 | case FT_INT24:
13713 | case FT_INT32:
13714 | case FT_INT40:
13715 | case FT_INT48:
13716 | case FT_INT56:
13717 | case FT_INT64:
13718 | value = ws_sign_ext64(value, no_of_bits);
13719 | break;
13720 |
13721 | default:
13722 | break;
13723 | }
13724 |
13725 | if (return_value) {
13726 | *return_value = value;
13727 | }
13728 |
13729 | /* Coast clear. Try and fake it */
13730 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13731 | 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", 13731 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13731, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13731, "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", 13731, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items); ((tree)-> tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items))); } if (!(( (tree)->tree_data)->visible)) { if (proto_item_is_hidden ((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT) && (hf_field->ref_type != HF_REF_TYPE_PRINT) && (hf_field->type != FT_PROTOCOL || ((tree)->tree_data)-> fake_protocols)) { ((void)0); return proto_tree_add_fake_node (tree, hf_field); } } };
13732 |
13733 | bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13734 |
13735 | switch (hf_field->type) {
13736 | case FT_BOOLEAN:
13737 | /* Boolean field */
13738 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13739 | "%s = %s: %s",
13740 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13741 | break;
13742 |
13743 | case FT_CHAR:
13744 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13745 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13746 | break;
13747 |
13748 | case FT_UINT8:
13749 | case FT_UINT16:
13750 | case FT_UINT24:
13751 | case FT_UINT32:
13752 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13753 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13754 | break;
13755 |
13756 | case FT_INT8:
13757 | case FT_INT16:
13758 | case FT_INT24:
13759 | case FT_INT32:
13760 | pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13761 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13762 | break;
13763 |
13764 | case FT_UINT40:
13765 | case FT_UINT48:
13766 | case FT_UINT56:
13767 | case FT_UINT64:
13768 | pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13769 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13770 | break;
13771 |
13772 | case FT_INT40:
13773 | case FT_INT48:
13774 | case FT_INT56:
13775 | case FT_INT64:
13776 | pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13777 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13778 | break;
13779 |
13780 | case FT_BYTES:
13781 | bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13782 | pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13783 | proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13784 | proto_item_set_text(pi, "%s", lbl_str);
13785 | return pi;
13786 |
13787 | /* TODO: should handle FT_UINT_BYTES ? */
13788 |
13789 | default:
13790 | 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))
13791 | 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))
13792 | 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))
13793 | 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));
13794 | return NULL((void*)0);
13795 | }
13796 |
13797 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13798 | return pi;
13799 | }
13800 |
13801 | proto_item *
13802 | proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13803 | const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13804 | uint64_t *return_value)
13805 | {
13806 | proto_item *pi;
13807 | int no_of_bits;
13808 | unsigned octet_offset;
13809 | unsigned mask_initial_bit_offset;
13810 | unsigned mask_greatest_bit_offset;
13811 | unsigned octet_length;
13812 | uint8_t i;
13813 | char bf_str[256];
13814 | char lbl_str[ITEM_LABEL_LENGTH240];
13815 | uint64_t value;
13816 | uint64_t composite_bitmask;
13817 | uint64_t composite_bitmap;
13818 |
13819 | header_field_info *hf_field;
13820 |
13821 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13822 | 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", 13822, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13822 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13822, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;;
13823 |
13824 | if (hf_field->bitmask != 0) {
13825 | 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)
13826 | " 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)
13827 | 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);
13828 | }
13829 |
13830 | mask_initial_bit_offset = bit_offset % 8;
13831 |
13832 | no_of_bits = 0;
13833 | value = 0;
13834 | i = 0;
13835 | mask_greatest_bit_offset = 0;
13836 | composite_bitmask = 0;
13837 | composite_bitmap = 0;
13838 |
13839 | while (crumb_spec[i].crumb_bit_length != 0) {
13840 | uint64_t crumb_mask, crumb_value;
13841 | uint8_t crumb_end_bit_offset;
13842 |
13843 | crumb_value = tvb_get_bits64(tvb,
13844 | bit_offset + crumb_spec[i].crumb_bit_offset,
13845 | crumb_spec[i].crumb_bit_length,
13846 | ENC_BIG_ENDIAN0x00000000);
13847 | value += crumb_value;
13848 | no_of_bits += crumb_spec[i].crumb_bit_length;
13849 | 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", 13849 , "no_of_bits <= 64", "a value larger than 64 bits cannot be represented" ))));
13850 |
13851 | /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13852 | octet containing the initial offset.
13853 | If the mask is beyond 32 bits, then give up on bit map display.
13854 | This could be improved in future, probably showing a table
13855 | of 32 or 64 bits per row */
13856 | if (mask_greatest_bit_offset < 32) {
13857 | crumb_end_bit_offset = mask_initial_bit_offset
13858 | + crumb_spec[i].crumb_bit_offset
13859 | + crumb_spec[i].crumb_bit_length;
13860 | crumb_mask = (UINT64_C(1)1UL << crumb_spec[i].crumb_bit_length) - 1;
13861 |
13862 | if (crumb_end_bit_offset > mask_greatest_bit_offset) {
13863 | mask_greatest_bit_offset = crumb_end_bit_offset;
13864 | }
13865 | /* Currently the bitmap of the crumbs are only shown if
13866 | * smaller than 32 bits. Do not bother calculating the
13867 | * mask if it is larger than that. */
13868 | if (crumb_end_bit_offset <= 32) {
13869 | composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
13870 | composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13871 | }
13872 | }
13873 | /* Shift left for the next segment */
13874 | value <<= crumb_spec[++i].crumb_bit_length;
13875 | }
13876 |
13877 | /* Sign extend for signed types */
13878 | switch (hf_field->type) {
13879 | case FT_INT8:
13880 | case FT_INT16:
13881 | case FT_INT24:
13882 | case FT_INT32:
13883 | case FT_INT40:
13884 | case FT_INT48:
13885 | case FT_INT56:
13886 | case FT_INT64:
13887 | value = ws_sign_ext64(value, no_of_bits);
13888 | break;
13889 | default:
13890 | break;
13891 | }
13892 |
13893 | if (return_value) {
13894 | *return_value = value;
13895 | }
13896 |
13897 | /* Coast clear. Try and fake it */
13898 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13899 | 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", 13899 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13899, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13899, "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", 13899, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items); ((tree)-> tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items))); } if (!(( (tree)->tree_data)->visible)) { if (proto_item_is_hidden ((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT) && (hf_field->ref_type != HF_REF_TYPE_PRINT) && (hf_field->type != FT_PROTOCOL || ((tree)->tree_data)-> fake_protocols)) { ((void)0); return proto_tree_add_fake_node (tree, hf_field); } } };
13900 |
13901 | /* initialise the format string */
13902 | bf_str[0] = '\0';
13903 |
13904 | octet_offset = bit_offset >> 3;
13905 |
13906 | /* Round up mask length to nearest octet */
13907 | octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13908 | mask_greatest_bit_offset = octet_length << 3;
13909 |
13910 | /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13911 | It would be a useful enhancement to eliminate this restriction. */
13912 | if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13913 | other_decode_bitfield_value(bf_str,
13914 | (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13915 | (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13916 | mask_greatest_bit_offset);
13917 | } else {
13918 | /* If the bitmask is too large, try to describe its contents. */
13919 | snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13920 | }
13921 |
13922 | switch (hf_field->type) {
13923 | case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13924 | /* Boolean field */
13925 | return proto_tree_add_boolean_format(tree, hfindex,
13926 | tvb, octet_offset, octet_length, value,
13927 | "%s = %s: %s",
13928 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13929 | break;
13930 |
13931 | case FT_CHAR:
13932 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13933 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13934 | break;
13935 |
13936 | case FT_UINT8:
13937 | case FT_UINT16:
13938 | case FT_UINT24:
13939 | case FT_UINT32:
13940 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13941 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13942 | break;
13943 |
13944 | case FT_INT8:
13945 | case FT_INT16:
13946 | case FT_INT24:
13947 | case FT_INT32:
13948 | pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13949 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13950 | break;
13951 |
13952 | case FT_UINT40:
13953 | case FT_UINT48:
13954 | case FT_UINT56:
13955 | case FT_UINT64:
13956 | pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13957 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13958 | break;
13959 |
13960 | case FT_INT40:
13961 | case FT_INT48:
13962 | case FT_INT56:
13963 | case FT_INT64:
13964 | pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13965 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13966 | break;
13967 |
13968 | default:
13969 | 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))
13970 | 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))
13971 | 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))
13972 | 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));
13973 | return NULL((void*)0);
13974 | }
13975 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13976 | return pi;
13977 | }
13978 |
13979 | void
13980 | proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13981 | const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13982 | {
13983 | header_field_info *hfinfo;
13984 | unsigned start = bit_offset >> 3;
13985 | unsigned length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13986 |
13987 | /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13988 | * so that we can use the tree's memory scope in calculating the string */
13989 | tvb_ensure_bytes_exist(tvb, start, length);
13990 | if (!tree) return;
13991 |
13992 | 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", 13992, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13992 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13992, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13993 | proto_tree_add_text_internal(tree, tvb, start, length,
13994 | "%s crumb %d of %s (decoded above)",
13995 | decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13996 | tvb_get_bits32(tvb,
13997 | bit_offset,
13998 | crumb_spec[crumb_index].crumb_bit_length,
13999 | ENC_BIG_ENDIAN0x00000000),
14000 | ENC_BIG_ENDIAN0x00000000),
14001 | crumb_index,
14002 | hfinfo->name);
14003 | }
14004 |
14005 | proto_item *
14006 | proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14007 | const unsigned bit_offset, const int no_of_bits,
14008 | uint64_t *return_value, const unsigned encoding)
14009 | {
14010 | proto_item *item;
14011 |
14012 | if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
14013 | bit_offset, no_of_bits,
14014 | return_value, encoding))) {
14015 | FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7))do { if (((item)->finfo)) (((item)->finfo))->flags = (((item)->finfo))->flags | ((((bit_offset&0x7) & 63) << 5)); } while(0);
14016 | FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits))do { if (((item)->finfo)) (((item)->finfo))->flags = (((item)->finfo))->flags | ((((no_of_bits) & 63) << 12)); } while(0);
14017 | }
14018 | return item;
14019 | }
14020 |
14021 | static proto_item *
14022 | _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14023 | tvbuff_t *tvb, const unsigned bit_offset,
14024 | const int no_of_bits, void *value_ptr,
14025 | const unsigned encoding, char *value_str)
14026 | {
14027 | unsigned offset;
14028 | unsigned length;
14029 | uint8_t tot_no_bits;
14030 | char *str;
14031 | uint64_t value = 0;
14032 | header_field_info *hf_field;
14033 |
14034 | /* We do not have to return a value, try to fake it as soon as possible */
14035 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14036 | 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", 14036 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14036, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14036, "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", 14036, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items); ((tree)-> tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items))); } if (!(( (tree)->tree_data)->visible)) { if (proto_item_is_hidden ((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT) && (hf_field->ref_type != HF_REF_TYPE_PRINT) && (hf_field->type != FT_PROTOCOL || ((tree)->tree_data)-> fake_protocols)) { ((void)0); return proto_tree_add_fake_node (tree, hf_field); } } };
14037 |
14038 | if (hf_field->bitmask != 0) {
14039 | 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)
14040 | " 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)
14041 | 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);
14042 | }
14043 |
14044 | if (no_of_bits < 0) {
14045 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
14046 | } else if (no_of_bits == 0) {
14047 | 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)
14048 | 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);
14049 | }
14050 |
14051 | /* Byte align offset */
14052 | offset = bit_offset>>3;
14053 |
14054 | /*
14055 | * Calculate the number of octets used to hold the bits
14056 | */
14057 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
14058 | length = tot_no_bits>>3;
14059 | /* If we are using part of the next octet, increase length by 1 */
14060 | if (tot_no_bits & 0x07)
14061 | length++;
14062 |
14063 | if (no_of_bits < 65) {
14064 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
14065 | } else {
14066 | 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)
14067 | 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);
14068 | return NULL((void*)0);
14069 | }
14070 |
14071 | str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
14072 |
14073 | (void) g_strlcat(str, " = ", 256+64);
14074 | (void) g_strlcat(str, hf_field->name, 256+64);
14075 |
14076 | /*
14077 | * This function does not receive an actual value but a dimensionless pointer to that value.
14078 | * For this reason, the type of the header field is examined in order to determine
14079 | * what kind of value we should read from this address.
14080 | * The caller of this function must make sure that for the specific header field type the address of
14081 | * a compatible value is provided.
14082 | */
14083 | switch (hf_field->type) {
14084 | case FT_BOOLEAN:
14085 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14086 | "%s: %s", str, value_str);
14087 | break;
14088 |
14089 | case FT_CHAR:
14090 | case FT_UINT8:
14091 | case FT_UINT16:
14092 | case FT_UINT24:
14093 | case FT_UINT32:
14094 | return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
14095 | "%s: %s", str, value_str);
14096 | break;
14097 |
14098 | case FT_UINT40:
14099 | case FT_UINT48:
14100 | case FT_UINT56:
14101 | case FT_UINT64:
14102 | return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14103 | "%s: %s", str, value_str);
14104 | break;
14105 |
14106 | case FT_INT8:
14107 | case FT_INT16:
14108 | case FT_INT24:
14109 | case FT_INT32:
14110 | return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
14111 | "%s: %s", str, value_str);
14112 | break;
14113 |
14114 | case FT_INT40:
14115 | case FT_INT48:
14116 | case FT_INT56:
14117 | case FT_INT64:
14118 | return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
14119 | "%s: %s", str, value_str);
14120 | break;
14121 |
14122 | case FT_FLOAT:
14123 | return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
14124 | "%s: %s", str, value_str);
14125 | break;
14126 |
14127 | default:
14128 | 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))
14129 | 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))
14130 | 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))
14131 | 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));
14132 | return NULL((void*)0);
14133 | }
14134 | }
14135 |
14136 | static proto_item *
14137 | proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14138 | tvbuff_t *tvb, const unsigned bit_offset,
14139 | const int no_of_bits, void *value_ptr,
14140 | const unsigned encoding, char *value_str)
14141 | {
14142 | proto_item *item;
14143 |
14144 | if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14145 | tvb, bit_offset, no_of_bits,
14146 | value_ptr, encoding, value_str))) {
14147 | FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7))do { if (((item)->finfo)) (((item)->finfo))->flags = (((item)->finfo))->flags | ((((bit_offset&0x7) & 63) << 5)); } while(0);
14148 | FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_SIZE(no_of_bits))do { if (((item)->finfo)) (((item)->finfo))->flags = (((item)->finfo))->flags | ((((no_of_bits) & 63) << 12)); } while(0);
14149 | }
14150 | return item;
14151 | }
14152 |
14153 | #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); \
14154 | va_start(ap, format)__builtin_va_start(ap, format); \
14155 | dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14156 | va_end(ap)__builtin_va_end(ap);
14157 |
14158 | proto_item *
14159 | proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14160 | tvbuff_t *tvb, const unsigned bit_offset,
14161 | const int no_of_bits, uint32_t value,
14162 | const unsigned encoding,
14163 | const char *format, ...)
14164 | {
14165 | va_list ap;
14166 | char *dst;
14167 | header_field_info *hf_field;
14168 |
14169 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14170 |
14171 | 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", 14171 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14171, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14171, "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", 14171, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items); ((tree)-> tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items))); } if (!(( (tree)->tree_data)->visible)) { if (proto_item_is_hidden ((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT) && (hf_field->ref_type != HF_REF_TYPE_PRINT) && (hf_field->type != FT_PROTOCOL || ((tree)->tree_data)-> fake_protocols)) { ((void)0); return proto_tree_add_fake_node (tree, hf_field); } } };
14172 |
14173 | switch (hf_field->type) {
14174 | case FT_UINT8:
14175 | case FT_UINT16:
14176 | case FT_UINT24:
14177 | case FT_UINT32:
14178 | break;
14179 |
14180 | default:
14181 | 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)
14182 | 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);
14183 | return NULL((void*)0);
14184 | }
14185 |
14186 | 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);;
14187 |
14188 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14189 | }
14190 |
14191 | proto_item *
14192 | proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14193 | tvbuff_t *tvb, const unsigned bit_offset,
14194 | const int no_of_bits, uint64_t value,
14195 | const unsigned encoding,
14196 | const char *format, ...)
14197 | {
14198 | va_list ap;
14199 | char *dst;
14200 | header_field_info *hf_field;
14201 |
14202 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14203 |
14204 | 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", 14204 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14204, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14204, "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", 14204, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items); ((tree)-> tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items))); } if (!(( (tree)->tree_data)->visible)) { if (proto_item_is_hidden ((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT) && (hf_field->ref_type != HF_REF_TYPE_PRINT) && (hf_field->type != FT_PROTOCOL || ((tree)->tree_data)-> fake_protocols)) { ((void)0); return proto_tree_add_fake_node (tree, hf_field); } } };
14205 |
14206 | switch (hf_field->type) {
14207 | case FT_UINT40:
14208 | case FT_UINT48:
14209 | case FT_UINT56:
14210 | case FT_UINT64:
14211 | break;
14212 |
14213 | default:
14214 | 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)
14215 | 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);
14216 | return NULL((void*)0);
14217 | }
14218 |
14219 | 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);;
14220 |
14221 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14222 | }
14223 |
14224 | proto_item *
14225 | proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14226 | tvbuff_t *tvb, const unsigned bit_offset,
14227 | const int no_of_bits, float value,
14228 | const unsigned encoding,
14229 | const char *format, ...)
14230 | {
14231 | va_list ap;
14232 | char *dst;
14233 | header_field_info *hf_field;
14234 |
14235 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14236 |
14237 | 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", 14237 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14237, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14237, "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", 14237, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items); ((tree)-> tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items))); } if (!(( (tree)->tree_data)->visible)) { if (proto_item_is_hidden ((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT) && (hf_field->ref_type != HF_REF_TYPE_PRINT) && (hf_field->type != FT_PROTOCOL || ((tree)->tree_data)-> fake_protocols)) { ((void)0); return proto_tree_add_fake_node (tree, hf_field); } } };
14238 |
14239 | 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", 14239, ((hf_field))->abbrev))));
14240 |
14241 | 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);;
14242 |
14243 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14244 | }
14245 |
14246 | proto_item *
14247 | proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14248 | tvbuff_t *tvb, const unsigned bit_offset,
14249 | const int no_of_bits, int32_t value,
14250 | const unsigned encoding,
14251 | const char *format, ...)
14252 | {
14253 | va_list ap;
14254 | char *dst;
14255 | header_field_info *hf_field;
14256 |
14257 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14258 |
14259 | 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", 14259 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14259, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14259, "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", 14259, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items); ((tree)-> tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items))); } if (!(( (tree)->tree_data)->visible)) { if (proto_item_is_hidden ((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT) && (hf_field->ref_type != HF_REF_TYPE_PRINT) && (hf_field->type != FT_PROTOCOL || ((tree)->tree_data)-> fake_protocols)) { ((void)0); return proto_tree_add_fake_node (tree, hf_field); } } };
14260 |
14261 | switch (hf_field->type) {
14262 | case FT_INT8:
14263 | case FT_INT16:
14264 | case FT_INT24:
14265 | case FT_INT32:
14266 | break;
14267 |
14268 | default:
14269 | 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)
14270 | 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);
14271 | return NULL((void*)0);
14272 | }
14273 |
14274 | 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);;
14275 |
14276 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14277 | }
14278 |
14279 | proto_item *
14280 | proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14281 | tvbuff_t *tvb, const unsigned bit_offset,
14282 | const int no_of_bits, int64_t value,
14283 | const unsigned encoding,
14284 | const char *format, ...)
14285 | {
14286 | va_list ap;
14287 | char *dst;
14288 | header_field_info *hf_field;
14289 |
14290 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14291 |
14292 | 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", 14292 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14292, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14292, "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", 14292, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items); ((tree)-> tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items))); } if (!(( (tree)->tree_data)->visible)) { if (proto_item_is_hidden ((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT) && (hf_field->ref_type != HF_REF_TYPE_PRINT) && (hf_field->type != FT_PROTOCOL || ((tree)->tree_data)-> fake_protocols)) { ((void)0); return proto_tree_add_fake_node (tree, hf_field); } } };
14293 |
14294 | switch (hf_field->type) {
14295 | case FT_INT40:
14296 | case FT_INT48:
14297 | case FT_INT56:
14298 | case FT_INT64:
14299 | break;
14300 |
14301 | default:
14302 | 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)
14303 | 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);
14304 | return NULL((void*)0);
14305 | }
14306 |
14307 | 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);;
14308 |
14309 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14310 | }
14311 |
14312 | proto_item *
14313 | proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14314 | tvbuff_t *tvb, const unsigned bit_offset,
14315 | const int no_of_bits, uint64_t value,
14316 | const unsigned encoding,
14317 | const char *format, ...)
14318 | {
14319 | va_list ap;
14320 | char *dst;
14321 | header_field_info *hf_field;
14322 |
14323 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14324 |
14325 | 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", 14325 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14325, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14325, "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", 14325, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items); ((tree)-> tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hf_field->abbrev, prefs.gui_max_tree_items))); } if (!(( (tree)->tree_data)->visible)) { if (proto_item_is_hidden ((tree))) { if ((hf_field->ref_type != HF_REF_TYPE_DIRECT) && (hf_field->ref_type != HF_REF_TYPE_PRINT) && (hf_field->type != FT_PROTOCOL || ((tree)->tree_data)-> fake_protocols)) { ((void)0); return proto_tree_add_fake_node (tree, hf_field); } } };
14326 |
14327 | 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" , 14327, ((hf_field))->abbrev))));
14328 |
14329 | 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);;
14330 |
14331 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14332 | }
14333 |
14334 | proto_item *
14335 | proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14336 | const unsigned bit_offset, const int no_of_chars)
14337 | {
14338 | proto_item *pi;
14339 | header_field_info *hfinfo;
14340 | int byte_length;
14341 | unsigned byte_offset;
14342 | char *string;
14343 |
14344 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14345 |
14346 | 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", 14346 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14346, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14346, "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", 14346, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
14347 |
14348 | 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" , 14348, ((hfinfo))->abbrev))));
14349 |
14350 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14351 | byte_offset = bit_offset >> 3;
14352 |
14353 | string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14354 |
14355 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14356 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14356, "byte_length >= 0" ))));
14357 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14358 |
14359 | return pi;
14360 | }
14361 |
14362 | proto_item *
14363 | proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14364 | const unsigned bit_offset, const int no_of_chars)
14365 | {
14366 | proto_item *pi;
14367 | header_field_info *hfinfo;
14368 | int byte_length;
14369 | unsigned byte_offset;
14370 | char *string;
14371 |
14372 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14373 |
14374 | 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", 14374 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14374, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14374, "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", 14374, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
14375 |
14376 | 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" , 14376, ((hfinfo))->abbrev))));
14377 |
14378 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14379 | byte_offset = bit_offset >> 3;
14380 |
14381 | string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14382 |
14383 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14384 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14384, "byte_length >= 0" ))));
14385 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14386 |
14387 | return pi;
14388 | }
14389 |
14390 | const value_string proto_checksum_vals[] = {
14391 | { PROTO_CHECKSUM_E_BAD, "Bad" },
14392 | { PROTO_CHECKSUM_E_GOOD, "Good" },
14393 | { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14394 | { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14395 | { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14396 |
14397 | { 0, NULL((void*)0) }
14398 | };
14399 |
14400 | #define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14401 |
14402 | proto_item *
14403 | proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14404 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14405 | packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14406 | {
14407 | header_field_info *hfinfo;
14408 | uint32_t checksum;
14409 | uint32_t len;
14410 | proto_item* ti = NULL((void*)0);
14411 | proto_item* ti2;
14412 | bool_Bool incorrect_checksum = true1;
14413 |
14414 | 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", 14414, __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", 14414 , "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", 14414, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14415 |
14416 | switch (hfinfo->type) {
14417 | case FT_UINT8:
14418 | len = 1;
14419 | break;
14420 | case FT_UINT16:
14421 | len = 2;
14422 | break;
14423 | case FT_UINT24:
14424 | len = 3;
14425 | break;
14426 | case FT_UINT32:
14427 | len = 4;
14428 | break;
14429 | default:
14430 | 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)
14431 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32" , hfinfo->abbrev);
14432 | }
14433 |
14434 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14435 | ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14436 | proto_item_set_generated(ti);
14437 | // Backward compatible with use of -1
14438 | if (hf_checksum_status > 0) {
14439 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14440 | proto_item_set_generated(ti2);
14441 | }
14442 | return ti;
14443 | }
14444 |
14445 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14446 | ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14447 | proto_item_set_generated(ti);
14448 | } else {
14449 | ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14450 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14451 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14452 | if (computed_checksum == 0) {
14453 | proto_item_append_text(ti, " [correct]");
14454 | // Backward compatible with use of -1
14455 | if (hf_checksum_status > 0) {
14456 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14457 | proto_item_set_generated(ti2);
14458 | }
14459 | incorrect_checksum = false0;
14460 | } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14461 | computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14462 | /* XXX - This can't distinguish between "shouldbe"
14463 | * 0x0000 and 0xFFFF unless we know whether there
14464 | * were any nonzero bits (other than the checksum).
14465 | * Protocols should not use this path if they might
14466 | * have an all zero packet.
14467 | * Some implementations put the wrong zero; maybe
14468 | * we should have a special expert info for that?
14469 | */
14470 | }
14471 | } else {
14472 | if (checksum == computed_checksum) {
14473 | proto_item_append_text(ti, " [correct]");
14474 | // Backward compatible with use of -1
14475 | if (hf_checksum_status > 0) {
14476 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14477 | proto_item_set_generated(ti2);
14478 | }
14479 | incorrect_checksum = false0;
14480 | }
14481 | }
14482 |
14483 | if (incorrect_checksum) {
14484 | // Backward compatible with use of -1
14485 | if (hf_checksum_status > 0) {
14486 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14487 | proto_item_set_generated(ti2);
14488 | }
14489 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14490 | proto_item_append_text(ti, " [incorrect]");
14491 | if (bad_checksum_expert != NULL((void*)0))
14492 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14493 | } else {
14494 | proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14495 | if (bad_checksum_expert != NULL((void*)0))
14496 | 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);
14497 | }
14498 | }
14499 | } else {
14500 | // Backward compatible with use of -1
14501 | if (hf_checksum_status > 0) {
14502 | proto_item_append_text(ti, " [unverified]");
14503 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14504 | proto_item_set_generated(ti2);
14505 | }
14506 | }
14507 | }
14508 |
14509 | return ti;
14510 | }
14511 |
14512 | proto_item *
14513 | proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14514 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14515 | packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14516 | {
14517 | header_field_info *hfinfo;
14518 | uint8_t *checksum = NULL((void*)0);
14519 | proto_item* ti = NULL((void*)0);
14520 | proto_item* ti2;
14521 | bool_Bool incorrect_checksum = true1;
14522 |
14523 | 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", 14523, __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", 14523 , "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", 14523, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14524 |
14525 | 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", 14525, ((hfinfo))->abbrev))));
14526 |
14527 | /* Make sure a NULL computed_checksum isn't dereferenced.
14528 | * If checksum_len is 0 it probably won't crash, but in the VERIFY
14529 | * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14530 | * cases the behavior is unexpected and still a programmer error;
14531 | * proto_tree_add_bytes retrieves it from the tvb, thus neither
14532 | * _NOT_PRESENT nor _GENERATED is correct.
14533 | */
14534 | DISSECTOR_ASSERT(computed_checksum || ((flags & PROTO_CHECKSUM_COMPUTED_USED) == PROTO_CHECKSUM_NO_FLAGS))((void) ((computed_checksum || ((flags & (0x01|0x02|0x10) ) == 0x00)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 14534, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)" ))));
14535 |
14536 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14537 | ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14538 | proto_item_set_generated(ti);
14539 | // Backward compatible with use of -1
14540 | if (hf_checksum_status > 0) {
14541 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14542 | proto_item_set_generated(ti2);
14543 | }
14544 | return ti;
14545 | }
14546 |
14547 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14548 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14549 | proto_item_set_generated(ti);
14550 | return ti;
14551 | }
14552 |
14553 | checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14554 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14555 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14556 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14557 | bool_Bool non_zero_flag = false0;
14558 | for (size_t index = 0; index < checksum_len; index++) {
14559 | if (computed_checksum[index]) {
14560 | non_zero_flag = true1;
14561 | break;
14562 | }
14563 | }
14564 | if (!non_zero_flag) {
14565 | proto_item_append_text(ti, " [correct]");
14566 | // Backward compatible with use of -1
14567 | if (hf_checksum_status > 0) {
14568 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14569 | proto_item_set_generated(ti2);
14570 | }
14571 | incorrect_checksum = false0;
14572 | }
14573 | } else {
14574 | if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14575 | proto_item_append_text(ti, " [correct]");
14576 | // Backward compatible with use of -1
14577 | if (hf_checksum_status > 0) {
14578 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14579 | proto_item_set_generated(ti2);
14580 | }
14581 | incorrect_checksum = false0;
14582 | }
14583 | }
14584 |
14585 | if (incorrect_checksum) {
14586 | // Backward compatible with use of -1
14587 | if (hf_checksum_status > 0) {
14588 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14589 | proto_item_set_generated(ti2);
14590 | }
14591 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14592 | proto_item_append_text(ti, " [incorrect]");
14593 | if (bad_checksum_expert != NULL((void*)0))
14594 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14595 | } else {
14596 | char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14597 | proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14598 | if (bad_checksum_expert != NULL((void*)0))
14599 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14600 | }
14601 | }
14602 | } else {
14603 | // Backward compatible with use of -1
14604 | if (hf_checksum_status > 0) {
14605 | proto_item_append_text(ti, " [unverified]");
14606 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14607 | proto_item_set_generated(ti2);
14608 | }
14609 | }
14610 |
14611 | return ti;
14612 | }
14613 |
14614 | unsigned char
14615 | proto_check_field_name(const char *field_name)
14616 | {
14617 | return module_check_valid_name(field_name, false0);
14618 | }
14619 |
14620 | unsigned char
14621 | proto_check_field_name_lower(const char *field_name)
14622 | {
14623 | return module_check_valid_name(field_name, true1);
14624 | }
14625 |
14626 | bool_Bool
14627 | tree_expanded(int tree_type)
14628 | {
14629 | if (tree_type <= 0) {
14630 | return false0;
14631 | }
14632 | 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", 14632, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14633 | return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14634 | }
14635 |
14636 | void
14637 | tree_expanded_set(int tree_type, bool_Bool value)
14638 | {
14639 | 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", 14639, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14640 |
14641 | if (value)
14642 | tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14643 | else
14644 | tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14645 | }
14646 |
14647 | /*
14648 | * Editor modelines - https://www.wireshark.org/tools/modelines.html
14649 | *
14650 | * Local variables:
14651 | * c-basic-offset: 8
14652 | * tab-width: 8
14653 | * indent-tabs-mode: t
14654 | * End:
14655 | *
14656 | * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14657 | * :indentSize=8:tabSize=8:noTabs=false:
14658 | */