### Bug Summary

File: | builds/wireshark/wireshark/epan/proto.c
Warning: | line 3405, 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 REX_API=extern -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-08-28-100404-3660-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 gboolean
544 | proto_strcase_equal(const void* name1, const void* name2)
545 | {
546 | const char* s1 = (const char*)name1;
547 | const char* s2 = (const char*)name2;
548 |
549 | return g_ascii_strcasecmp(s1, s2) == 0 ? TRUE(!(0)) : FALSE(0);
550 | }
551 |
552 | static int
553 | proto_compare_name(const void *p1_arg, const void *p2_arg)
554 | {
555 | const protocol_t *p1 = (const protocol_t *)p1_arg;
556 | const protocol_t *p2 = (const protocol_t *)p2_arg;
557 |
558 | return g_ascii_strcasecmp(p1->short_name, p2->short_name);
559 | }
560 |
561 | static GSList *dissector_plugins;
562 |
563 | #ifdef HAVE_PLUGINS1
564 | void
565 | proto_register_plugin(const proto_plugin *plug)
566 | {
567 | dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
568 | }
569 | #else /* HAVE_PLUGINS */
570 | void
571 | proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
572 | {
573 | ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 573, __func__, "proto_register_plugin: built without support for binary plugins" ); } } while (0);
574 | }
575 | #endif /* HAVE_PLUGINS */
576 |
577 | static void
578 | call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
579 | {
580 | proto_plugin *plug = (proto_plugin *)data;
581 |
582 | if (plug->register_protoinfo) {
583 | plug->register_protoinfo();
584 | }
585 | }
586 |
587 | static void
588 | call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
589 | {
590 | proto_plugin *plug = (proto_plugin *)data;
591 |
592 | if (plug->register_handoff) {
593 | plug->register_handoff();
594 | }
595 | }
596 |
597 | void proto_pre_init(void)
598 | {
599 | saved_dir_queue = g_queue_new();
600 |
601 | proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
602 | proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
603 | proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
604 |
605 | proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, proto_strcase_equal);
606 | for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
607 | /* GHashTable has no key destructor so the cast is safe. */
608 | g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
609 | }
610 |
611 | gpa_hfinfo.len = 0;
612 | gpa_hfinfo.allocated_len = 0;
613 | gpa_hfinfo.hfi = NULL((void*)0);
614 | gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
615 | wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
616 | gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
617 | deregistered_fields = g_ptr_array_new();
618 | deregistered_data = g_ptr_array_new();
619 | deregistered_slice = g_ptr_array_new();
620 | }
621 |
622 | /* initialize data structures and register protocols and fields */
623 | void
624 | proto_init(GSList *register_all_plugin_protocols_list,
625 | GSList *register_all_plugin_handoffs_list,
626 | register_entity_func register_func, register_entity_func handoff_func,
627 | register_cb cb,
628 | void *client_data)
629 | {
630 | /* Initialize the ftype subsystem */
631 | ftypes_initialize();
632 |
633 | /* Initialize the address type subsystem */
634 | address_types_initialize();
635 |
636 | /* Register one special-case FT_TEXT_ONLY field for use when
637 | converting wireshark to new-style proto_tree. These fields
638 | are merely strings on the GUI tree; they are not filterable */
639 | hf_text_only = proto_register_field_init(&hfi_text_only, -1);
640 |
641 | /* Register the pseudo-protocols used for exceptions. */
642 | register_show_exception();
643 | register_type_length_mismatch();
644 | register_byte_array_string_decodinws_error();
645 | register_date_time_string_decodinws_error();
646 | register_string_errors();
647 | register_varint_errors();
648 | ftypes_register_pseudofields();
649 | col_register_protocol();
650 |
651 | /* Have each built-in dissector register its protocols, fields,
652 | dissector tables, and dissectors to be called through a
653 | handle, and do whatever one-time initialization it needs to
654 | do. */
655 | if (register_func != NULL((void*)0))
656 | register_func(cb, client_data);
657 |
658 | /* Now call the registration routines for all epan plugins. */
659 | for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
660 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
661 | }
662 |
663 | /* Now call the registration routines for all dissector plugins. */
664 | if (cb)
665 | (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
666 | g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
667 |
668 | /* Now call the "handoff registration" routines of all built-in
669 | dissectors; those routines register the dissector in other
670 | dissectors' handoff tables, and fetch any dissector handles
671 | they need. */
672 | if (handoff_func != NULL((void*)0))
673 | handoff_func(cb, client_data);
674 |
675 | /* Now do the same with epan plugins. */
676 | for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
677 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
678 | }
679 |
680 | /* Now do the same with dissector plugins. */
681 | if (cb)
682 | (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
683 | g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
684 |
685 | /* sort the protocols by protocol name */
686 | protocols = g_list_sort(protocols, proto_compare_name);
687 |
688 | /* sort the dissector handles in dissector tables (for -G reports
689 | * and -d error messages. The GUI sorts the handles itself.) */
690 | packet_all_tables_sort_handles();
691 |
692 | /* We've assigned all the subtree type values; allocate the array
693 | for them, and zero it out. */
694 | 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 )));
695 | }
696 |
697 | static void
698 | proto_cleanup_base(void)
699 | {
700 | protocol_t *protocol;
701 | header_field_info *hfinfo;
702 |
703 | /* Free the abbrev/ID hash table */
704 | if (gpa_name_map) {
705 | // XXX - We don't have a wmem_map_destroy, but
706 | // it does get cleaned up when epan scope is
707 | // destroyed
708 | //g_hash_table_destroy(gpa_name_map);
709 | gpa_name_map = NULL((void*)0);
710 | }
711 | if (gpa_protocol_aliases) {
712 | g_hash_table_destroy(gpa_protocol_aliases);
713 | gpa_protocol_aliases = NULL((void*)0);
714 | }
715 | 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);
716 | last_field_name = NULL((void*)0);
717 |
718 | while (protocols) {
719 | protocol = (protocol_t *)protocols->data;
720 | 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", 720 , __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", 720, "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", 720, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[protocol-> proto_id];;
721 | 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", 721, "protocol->proto_id == hfinfo->id" ))));
722 |
723 | 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);
724 | if (protocol->parent_proto_id != -1) {
725 | // pino protocol
726 | DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 726, "protocol->fields == ((void*)0)" )))); //helpers should not have any registered fields
727 | 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" , 727, "protocol->heur_list == ((void*)0)")))); //helpers should not have a heuristic list
728 | } else {
729 | if (protocol->fields) {
730 | g_ptr_array_free(protocol->fields, true1);
731 | }
732 | g_list_free(protocol->heur_list);
733 | }
734 | protocols = g_list_remove(protocols, protocol);
735 | g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized (protocol, __builtin_object_size ((protocol), 0)) : (g_free) (protocol);
736 | }
737 |
738 | if (proto_names) {
739 | g_hash_table_destroy(proto_names);
740 | proto_names = NULL((void*)0);
741 | }
742 |
743 | if (proto_short_names) {
744 | g_hash_table_destroy(proto_short_names);
745 | proto_short_names = NULL((void*)0);
746 | }
747 |
748 | if (proto_filter_names) {
749 | g_hash_table_destroy(proto_filter_names);
750 | proto_filter_names = NULL((void*)0);
751 | }
752 |
753 | if (proto_reserved_filter_names) {
754 | g_hash_table_destroy(proto_reserved_filter_names);
755 | proto_reserved_filter_names = NULL((void*)0);
756 | }
757 |
758 | if (gpa_hfinfo.allocated_len) {
759 | gpa_hfinfo.len = 0;
760 | gpa_hfinfo.allocated_len = 0;
761 | 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);
762 | gpa_hfinfo.hfi = NULL((void*)0);
763 | }
764 |
765 | if (deregistered_fields) {
766 | g_ptr_array_free(deregistered_fields, true1);
767 | deregistered_fields = NULL((void*)0);
768 | }
769 |
770 | if (deregistered_data) {
771 | g_ptr_array_free(deregistered_data, true1);
772 | deregistered_data = NULL((void*)0);
773 | }
774 |
775 | if (deregistered_slice) {
776 | g_ptr_array_free(deregistered_slice, true1);
777 | deregistered_slice = NULL((void*)0);
778 | }
779 |
780 | 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);
781 | tree_is_expanded = NULL((void*)0);
782 |
783 | if (prefixes)
784 | g_hash_table_destroy(prefixes);
785 |
786 | if (saved_dir_queue != NULL((void*)0)) {
787 | g_queue_clear_full(saved_dir_queue, g_free);
788 | g_queue_free(saved_dir_queue);
789 | saved_dir_queue = NULL((void*)0);
790 | }
791 | }
792 |
793 | void
794 | proto_cleanup(void)
795 | {
796 | proto_free_deregistered_fields();
797 | proto_cleanup_base();
798 |
799 | g_slist_free(dissector_plugins);
800 | dissector_plugins = NULL((void*)0);
801 | }
802 |
803 | static bool_Bool
804 | ws_pushd(const char* dir)
805 | {
806 | //Save the current working directory
807 | const char* save_wd = get_current_working_dir();
808 | if (save_wd != NULL((void*)0))
809 | g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
810 |
811 | //Change to the new one
812 | #ifdef _WIN32
813 | SetCurrentDirectory(utf_8to16(dir));
814 | return true1;
815 | #else
816 | return (chdir(dir) == 0);
817 | #endif
818 | }
819 |
820 | static bool_Bool
821 | ws_popd(void)
822 | {
823 | int ret = 0;
824 | char* saved_wd = g_queue_pop_head(saved_dir_queue);
825 | if (saved_wd == NULL((void*)0))
826 | return false0;
827 |
828 | //Restore the previous one
829 | #ifdef _WIN32
830 | SetCurrentDirectory(utf_8to16(saved_wd));
831 | #else
832 | ret = chdir(saved_wd);
833 | #endif
834 | 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);
835 | return (ret == 0);
836 | }
837 |
838 | void
839 | proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
840 | {
841 | if (ws_pushd(dir))
842 | {
843 | func(param);
844 | ws_popd();
845 | }
846 | }
847 |
848 | static bool_Bool
849 | // NOLINTNEXTLINE(misc-no-recursion)
850 | proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
851 | void *data)
852 | {
853 | proto_node *pnode = tree;
854 | proto_node *child;
855 | proto_node *current;
856 |
857 | if (func(pnode, data))
858 | return true1;
859 |
860 | child = pnode->first_child;
861 | while (child != NULL((void*)0)) {
862 | /*
863 | * The routine we call might modify the child, e.g. by
864 | * freeing it, so we get the child's successor before
865 | * calling that routine.
866 | */
867 | current = child;
868 | child = current->next;
869 | // We recurse here, but we're limited by prefs.gui_max_tree_depth
870 | if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
871 | return true1;
872 | }
873 |
874 | return false0;
875 | }
876 |
877 | void
878 | proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
879 | void *data)
880 | {
881 | proto_node *node = tree;
882 | proto_node *current;
883 |
884 | if (!node)
885 | return;
886 |
887 | node = node->first_child;
888 | while (node != NULL((void*)0)) {
889 | current = node;
890 | node = current->next;
891 | func((proto_tree *)current, data);
892 | }
893 | }
894 |
895 | static void
896 | free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
897 | {
898 | GPtrArray *ptrs = (GPtrArray *)value;
899 | int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
900 | header_field_info *hfinfo;
901 |
902 | 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", 902, __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", 902, "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", 902, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
903 | if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
904 | /* when a field is referenced by a filter this also
905 | affects the refcount for the parent protocol so we need
906 | to adjust the refcount for the parent as well
907 | */
908 | if (hfinfo->parent != -1) {
909 | header_field_info *parent_hfinfo;
910 | 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", 910 , __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", 910, "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", 910, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)" , "Unregistered hf.")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo ->parent];;
911 | parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
912 | }
913 | hfinfo->ref_type = HF_REF_TYPE_NONE;
914 | }
915 |
916 | g_ptr_array_free(ptrs, true1);
917 | }
918 |
919 | static void
920 | proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
921 | {
922 | field_info *finfo = PNODE_FINFO(node)((node)->finfo);
923 |
924 | proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
925 |
926 | if (finfo) {
927 | // The fvalue_t structure was allocated using fvalue_new_pool()
928 | // (see new_field_info()) and will be reclaimed when the pool is
929 | // freed, so we only release the type-specific data it owns here.
930 | fvalue_cleanup(finfo->value);
931 | finfo->value = NULL((void*)0);
932 | }
933 | }
934 |
935 | void
936 | proto_tree_reset(proto_tree *tree)
937 | {
938 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
939 |
940 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
941 |
942 | /* free tree data */
943 | if (tree_data->interesting_hfids) {
944 | /* Free all the GPtrArray's in the interesting_hfids hash. */
945 | g_hash_table_foreach(tree_data->interesting_hfids,
946 | free_GPtrArray_value, NULL((void*)0));
947 |
948 | /* And then remove all values. */
949 | g_hash_table_remove_all(tree_data->interesting_hfids);
950 | }
951 |
952 | /* Reset track of the number of children */
953 | tree_data->count = 0;
954 |
955 | /* Reset our loop checks */
956 | tree_data->idle_count_ds_tvb = NULL((void*)0);
957 | tree_data->max_start = 0;
958 | tree_data->start_idle_count = 0;
959 |
960 | PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void *)0); tree->next = ((void*)0);;
961 | }
962 |
963 | /* frees the resources that the dissection a proto_tree uses */
964 | void
965 | proto_tree_free(proto_tree *tree)
966 | {
967 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
968 |
969 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
970 |
971 | /* free tree data */
972 | if (tree_data->interesting_hfids) {
973 | /* Free all the GPtrArray's in the interesting_hfids hash. */
974 | g_hash_table_foreach(tree_data->interesting_hfids,
975 | free_GPtrArray_value, NULL((void*)0));
976 |
977 | /* And then destroy the hash. */
978 | g_hash_table_destroy(tree_data->interesting_hfids);
979 | }
980 |
981 | 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);
982 |
983 | g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else (void) ((proto_tree*) 0 == (tree)); } while (0);
984 | }
985 |
986 | /* Is the parsing being done for a visible proto_tree or an invisible one?
987 | * By setting this correctly, the proto_tree creation is sped up by not
988 | * having to call vsnprintf and copy strings around.
989 | */
990 | bool_Bool
991 | proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
992 | {
993 | bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
994 |
995 | PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
996 |
997 | return old_visible;
998 | }
999 |
1000 | void
1001 | proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
1002 | {
1003 | if (tree)
1004 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
1005 | }
1006 |
1007 | /* Assume dissector set only its protocol fields.
1008 | This function is called by dissectors and allows the speeding up of filtering
1009 | in wireshark; if this function returns false it is safe to reset tree to NULL
1010 | and thus skip calling most of the expensive proto_tree_add_...()
1011 | functions.
1012 | If the tree is visible we implicitly assume the field is referenced.
1013 | */
1014 | bool_Bool
1015 | proto_field_is_referenced(proto_tree *tree, int proto_id)
1016 | {
1017 | register header_field_info *hfinfo;
1018 |
1019 |
1020 | if (!tree)
1021 | return false0;
1022 |
1023 | if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1024 | return true1;
1025 |
1026 | 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", 1026, __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", 1026, "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", 1026, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
1027 | if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1028 | return true1;
1029 |
1030 | if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1031 | return true1;
1032 |
1033 | return false0;
1034 | }
1035 |
1036 |
1037 | /* Finds a record in the hfinfo array by id. */
1038 | header_field_info *
1039 | proto_registrar_get_nth(unsigned hfindex)
1040 | {
1041 | register header_field_info *hfinfo;
1042 |
1043 | 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", 1043, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1043, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1043, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
1044 | return hfinfo;
1045 | }
1046 |
1047 |
1048 | /* Prefix initialization
1049 | * this allows for a dissector to register a display filter name prefix
1050 | * so that it can delay the initialization of the hf array as long as
1051 | * possible.
1052 | */
1053 |
1054 | /* compute a hash for the part before the dot of a display filter */
1055 | static unsigned
1056 | prefix_hash (const void *key) {
1057 | /* end the string at the dot and compute its hash */
1058 | char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1059 | char* c = copy;
1060 | unsigned tmp;
1061 |
1062 | for (; *c; c++) {
1063 | if (*c == '.') {
1064 | *c = 0;
1065 | break;
1066 | }
1067 | }
1068 |
1069 | tmp = wmem_str_hash(copy);
1070 | g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized (copy, __builtin_object_size ((copy), 0)) : (g_free) (copy);
1071 | return tmp;
1072 | }
1073 |
1074 | /* are both strings equal up to the end or the dot? */
1075 | static gboolean
1076 | prefix_equal (const void *ap, const void *bp) {
1077 | const char* a = (const char *)ap;
1078 | const char* b = (const char *)bp;
1079 |
1080 | do {
1081 | char ac = *a++;
1082 | char bc = *b++;
1083 |
1084 | if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1085 |
1086 | if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1087 | if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1088 |
1089 | if (ac != bc) return FALSE(0);
1090 | } while (1);
1091 |
1092 | return FALSE(0);
1093 | }
1094 |
1095 | /* Register a new prefix for "delayed" initialization of field arrays */
1096 | void
1097 | proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1098 | if (! prefixes ) {
1099 | prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1100 | }
1101 |
1102 | g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1103 | }
1104 |
1105 | /* helper to call all prefix initializers */
1106 | static gboolean
1107 | initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1108 | ((prefix_initializer_t)v)((const char *)k);
1109 | return TRUE(!(0));
1110 | }
1111 |
1112 | /** Initialize every remaining uninitialized prefix. */
1113 | void
1114 | proto_initialize_all_prefixes(void) {
1115 | if (!prefixes) {
1116 | return;
1117 | }
1118 | g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1119 | }
1120 |
1121 | /* Finds a record in the hfinfo array by name.
1122 | * If it fails to find it in the already registered fields,
1123 | * it tries to find and call an initializer in the prefixes
1124 | * table and if so it looks again.
1125 | */
1126 |
1127 | header_field_info *
1128 | proto_registrar_get_byname(const char *field_name)
1129 | {
1130 | header_field_info *hfinfo;
1131 | prefix_initializer_t pi;
1132 |
1133 | if (!field_name)
1134 | return NULL((void*)0);
1135 |
1136 | if (g_strcmp0(field_name, last_field_name) == 0) {
1137 | return last_hfinfo;
1138 | }
1139 |
1140 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1141 |
1142 | if (hfinfo) {
1143 | 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);
1144 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1145 | last_hfinfo = hfinfo;
1146 | return hfinfo;
1147 | }
1148 |
1149 | if (!prefixes)
1150 | return NULL((void*)0);
1151 |
1152 | if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1153 | pi(field_name);
1154 | g_hash_table_remove(prefixes, field_name);
1155 | } else {
1156 | return NULL((void*)0);
1157 | }
1158 |
1159 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1160 |
1161 | if (hfinfo) {
1162 | 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);
1163 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1164 | last_hfinfo = hfinfo;
1165 | }
1166 | return hfinfo;
1167 | }
1168 |
1169 | header_field_info*
1170 | proto_registrar_get_byalias(const char *alias_name)
1171 | {
1172 | if (!alias_name) {
1173 | return NULL((void*)0);
1174 | }
1175 |
1176 | /* Find our aliased protocol. */
1177 | char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1178 | char *dot = strchr(an_copy, '.');
1179 | if (dot) {
1180 | *dot = '\0';
1181 | }
1182 | const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1183 | if (!proto_pfx) {
1184 | 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);
1185 | return NULL((void*)0);
1186 | }
1187 |
1188 | /* Construct our aliased field and look it up. */
1189 | GString *filter_name = g_string_new(proto_pfx);
1190 | if (dot) {
1191 | g_string_append_printf(filter_name, ".%s", dot+1);
1192 | }
1193 | header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1194 | 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);
1195 | 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)))));
1196 |
1197 | return hfinfo;
1198 | }
1199 |
1200 | int
1201 | proto_registrar_get_id_byname(const char *field_name)
1202 | {
1203 | header_field_info *hfinfo;
1204 |
1205 | hfinfo = proto_registrar_get_byname(field_name);
1206 |
1207 | if (!hfinfo)
1208 | return -1;
1209 |
1210 | return hfinfo->id;
1211 | }
1212 |
1213 | static int
1214 | label_strcat_flags(const header_field_info *hfinfo)
1215 | {
1216 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1217 | return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1218 |
1219 | return 0;
1220 | }
1221 |
1222 | static char *
1223 | format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1224 | const uint8_t *bytes, unsigned length, size_t max_str_len)
1225 | {
1226 | char *str = NULL((void*)0);
1227 | const uint8_t *p;
1228 | bool_Bool is_printable;
1229 |
1230 | if (bytes) {
1231 | if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1232 | /*
1233 | * If all bytes are valid and printable UTF-8, show the
1234 | * bytes as a string - in quotes to indicate that it's
1235 | * a string.
1236 | */
1237 | if (isprint_utf8_string((const char*)bytes, length)) {
1238 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1239 | (int)length, bytes);
1240 | return str;
1241 | }
1242 | } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1243 | /*
1244 | * Check whether all bytes are printable.
1245 | */
1246 | is_printable = true1;
1247 | for (p = bytes; p < bytes+length; p++) {
1248 | if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1249 | /* Not printable. */
1250 | is_printable = false0;
1251 | break;
1252 | }
1253 | }
1254 |
1255 | /*
1256 | * If all bytes are printable ASCII, show the bytes
1257 | * as a string - in quotes to indicate that it's
1258 | * a string.
1259 | */
1260 | if (is_printable) {
1261 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1262 | (int)length, bytes);
1263 | return str;
1264 | }
1265 | }
1266 |
1267 | /*
1268 | * Either it's not printable ASCII, or we don't care whether
1269 | * it's printable ASCII; show it as hex bytes.
1270 | */
1271 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1272 | case SEP_DOT:
1273 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1274 | break;
1275 | case SEP_DASH:
1276 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1277 | break;
1278 | case SEP_COLON:
1279 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1280 | break;
1281 | case SEP_SPACE:
1282 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1283 | break;
1284 | case BASE_NONE:
1285 | default:
1286 | if (prefs.display_byte_fields_with_spaces) {
1287 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1288 | } else {
1289 | str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1290 | }
1291 | break;
1292 | }
1293 | }
1294 | else {
1295 | if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1296 | str = wmem_strdup(scope, "<none>");
1297 | } else {
1298 | str = wmem_strdup(scope, "<MISSING>");
1299 | }
1300 | }
1301 | return str;
1302 | }
1303 |
1304 | static char *
1305 | format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1306 | const uint8_t *bytes, unsigned length)
1307 | {
1308 | return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1309 | }
1310 |
1311 | static void
1312 | ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1313 | {
1314 | subtree_lvl *pushed_tree;
1315 |
1316 | 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" , 1316, "ptvc->pushed_tree_max <= 256-8"))));
1317 | ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1318 |
1319 | pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1320 | DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1320, "pushed_tree != ((void*)0)" ))));
1321 | ptvc->pushed_tree = pushed_tree;
1322 | }
1323 |
1324 | static void
1325 | ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1326 | {
1327 | ptvc->pushed_tree = NULL((void*)0);
1328 | ptvc->pushed_tree_max = 0;
1329 | DISSECTOR_ASSERT(ptvc->pushed_tree_index == 0)((void) ((ptvc->pushed_tree_index == 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1329, "ptvc->pushed_tree_index == 0" ))));
1330 | ptvc->pushed_tree_index = 0;
1331 | }
1332 |
1333 | /* Allocates an initializes a ptvcursor_t with 3 variables:
1334 | * proto_tree, tvbuff, and offset. */
1335 | ptvcursor_t *
1336 | ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1337 | {
1338 | ptvcursor_t *ptvc;
1339 |
1340 | ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1341 | ptvc->scope = scope;
1342 | ptvc->tree = tree;
1343 | ptvc->tvb = tvb;
1344 | ptvc->offset = offset;
1345 | ptvc->pushed_tree = NULL((void*)0);
1346 | ptvc->pushed_tree_max = 0;
1347 | ptvc->pushed_tree_index = 0;
1348 | return ptvc;
1349 | }
1350 |
1351 |
1352 | /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1353 | void
1354 | ptvcursor_free(ptvcursor_t *ptvc)
1355 | {
1356 | ptvcursor_free_subtree_levels(ptvc);
1357 | wmem_free(ptvc->scope, ptvc);
1358 | }
1359 |
1360 | /* Returns tvbuff. */
1361 | tvbuff_t *
1362 | ptvcursor_tvbuff(ptvcursor_t *ptvc)
1363 | {
1364 | return ptvc->tvb;
1365 | }
1366 |
1367 | /* Returns current offset. */
1368 | unsigned
1369 | ptvcursor_current_offset(ptvcursor_t *ptvc)
1370 | {
1371 | return ptvc->offset;
1372 | }
1373 |
1374 | proto_tree *
1375 | ptvcursor_tree(ptvcursor_t *ptvc)
1376 | {
1377 | if (!ptvc)
1378 | return NULL((void*)0);
1379 |
1380 | return ptvc->tree;
1381 | }
1382 |
1383 | void
1384 | ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1385 | {
1386 | ptvc->tree = tree;
1387 | }
1388 |
1389 | /* creates a subtree, sets it as the working tree and pushes the old working tree */
1390 | proto_tree *
1391 | ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1392 | {
1393 | subtree_lvl *subtree;
1394 | if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1395 | ptvcursor_new_subtree_levels(ptvc);
1396 |
1397 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1398 | subtree->tree = ptvc->tree;
1399 | subtree->it= NULL((void*)0);
1400 | ptvc->pushed_tree_index++;
1401 | return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1402 | }
1403 |
1404 | /* pops a subtree */
1405 | void
1406 | ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1407 | {
1408 | subtree_lvl *subtree;
1409 |
1410 | if (ptvc->pushed_tree_index <= 0)
1411 | return;
1412 |
1413 | ptvc->pushed_tree_index--;
1414 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1415 | if (subtree->it != NULL((void*)0))
1416 | proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1417 |
1418 | ptvc->tree = subtree->tree;
1419 | }
1420 |
1421 | /* saves the current tvb offset and the item in the current subtree level */
1422 | static void
1423 | ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1424 | {
1425 | subtree_lvl *subtree;
1426 |
1427 | 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", 1427, "ptvc->pushed_tree_index > 0" ))));
1428 |
1429 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1430 | subtree->it = it;
1431 | subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1432 | }
1433 |
1434 | /* Creates a subtree and adds it to the cursor as the working tree but does not
1435 | * save the old working tree */
1436 | proto_tree *
1437 | ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1438 | {
1439 | ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1440 | return ptvc->tree;
1441 | }
1442 |
1443 | static proto_tree *
1444 | ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1445 | {
1446 | ptvcursor_push_subtree(ptvc, it, ett_subtree);
1447 | if (length == SUBTREE_UNDEFINED_LENGTH-1)
1448 | ptvcursor_subtree_set_item(ptvc, it);
1449 | return ptvcursor_tree(ptvc);
1450 | }
1451 |
1452 | /* Add an item to the tree and create a subtree
1453 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1454 | * In this case, when the subtree will be closed, the parent item length will
1455 | * be equal to the advancement of the cursor since the creation of the subtree.
1456 | */
1457 | proto_tree *
1458 | ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1459 | const unsigned encoding, int ett_subtree)
1460 | {
1461 | proto_item *it;
1462 |
1463 | it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1464 | return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1465 | }
1466 |
1467 | static proto_item *
1468 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1469 |
1470 | /* Add a text node to the tree and create a subtree
1471 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1472 | * In this case, when the subtree will be closed, the item length will be equal
1473 | * to the advancement of the cursor since the creation of the subtree.
1474 | */
1475 | proto_tree *
1476 | ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1477 | int ett_subtree, const char *format, ...)
1478 | {
1479 | proto_item *pi;
1480 | va_list ap;
1481 | header_field_info *hfinfo;
1482 | proto_tree *tree;
1483 |
1484 | tree = ptvcursor_tree(ptvc);
1485 |
1486 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1487 |
1488 | 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", 1488 , __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", 1488, "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", 1488, "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", 1488, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1489 |
1490 | pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1491 | ptvcursor_current_offset(ptvc), length);
1492 |
1493 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1493, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1494 |
1495 | va_start(ap, format)__builtin_va_start(ap, format);
1496 | proto_tree_set_representation(pi, format, ap);
1497 | va_end(ap)__builtin_va_end(ap);
1498 |
1499 | return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1500 | }
1501 |
1502 | /* Add a text-only node, leaving it to our caller to fill the text in */
1503 | static proto_item *
1504 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1505 | {
1506 | proto_item *pi;
1507 |
1508 | if (tree == NULL((void*)0))
1509 | return NULL((void*)0);
1510 |
1511 | pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1512 |
1513 | return pi;
1514 | }
1515 |
1516 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1517 | proto_item *
1518 | proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length,
1519 | const char *format, ...)
1520 | {
1521 | proto_item *pi;
1522 | va_list ap;
1523 | header_field_info *hfinfo;
1524 |
1525 | tvb_ensure_bytes_exist(tvb, start, length);
1526 |
1527 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1528 |
1529 | 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", 1529 , __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", 1529, "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", 1529, "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", 1529, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1530 |
1531 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1532 |
1533 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1533, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1534 |
1535 | va_start(ap, format)__builtin_va_start(ap, format);
1536 | proto_tree_set_representation(pi, format, ap);
1537 | va_end(ap)__builtin_va_end(ap);
1538 |
1539 | return pi;
1540 | }
1541 |
1542 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1543 | proto_item *
1544 | proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1545 | unsigned length, const char *format, va_list ap)
1546 | {
1547 | proto_item *pi;
1548 | header_field_info *hfinfo;
1549 |
1550 | /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1551 | * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1552 | * the length to be what's in the tvbuff if length is -1, and the
1553 | * minimum of length and what's in the tvbuff if not.
1554 | */
1555 |
1556 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1557 |
1558 | 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", 1558 , __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", 1558, "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", 1558, "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", 1558, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1559 |
1560 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1561 |
1562 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1562, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1563 |
1564 | proto_tree_set_representation(pi, format, ap);
1565 |
1566 | return pi;
1567 | }
1568 |
1569 | /* Add a text-only node that creates a subtree underneath.
1570 | */
1571 | proto_tree *
1572 | proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1573 | {
1574 | return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1575 | }
1576 |
1577 | /* Add a text-only node that creates a subtree underneath.
1578 | */
1579 | proto_tree *
1580 | proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1581 | {
1582 | proto_tree *pt;
1583 | proto_item *pi;
1584 | va_list ap;
1585 |
1586 | if (length == -1) {
1587 | length = tvb_captured_length_remaining(tvb, start);
1588 | }
1589 |
1590 | va_start(ap, format)__builtin_va_start(ap, format);
1591 | pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1592 | va_end(ap)__builtin_va_end(ap);
1593 |
1594 | if (tree_item != NULL((void*)0))
1595 | *tree_item = pi;
1596 |
1597 | pt = proto_item_add_subtree(pi, idx);
1598 |
1599 | return pt;
1600 | }
1601 |
1602 | /* Add a text-only node for debugging purposes. The caller doesn't need
1603 | * to worry about tvbuff, start, or length. Debug message gets sent to
1604 | * STDOUT, too */
1605 | proto_item *
1606 | proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1607 | {
1608 | proto_item *pi;
1609 | va_list ap;
1610 |
1611 | pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1612 |
1613 | if (pi) {
1614 | va_start(ap, format)__builtin_va_start(ap, format);
1615 | proto_tree_set_representation(pi, format, ap);
1616 | va_end(ap)__builtin_va_end(ap);
1617 | }
1618 | va_start(ap, format)__builtin_va_start(ap, format);
1619 | vprintf(format, ap);
1620 | va_end(ap)__builtin_va_end(ap);
1621 | printf("\n");
1622 |
1623 | return pi;
1624 | }
1625 |
1626 | proto_item *
1627 | proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1628 | {
1629 | proto_item *pi;
1630 | header_field_info *hfinfo;
1631 |
1632 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1633 |
1634 | 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", 1634 , __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", 1634, "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", 1634, "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", 1634, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1635 |
1636 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1637 |
1638 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1638, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1639 |
1640 | proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1641 |
1642 | return pi;
1643 | }
1644 |
1645 | proto_item *
1646 | proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1647 | {
1648 | proto_item *pi;
1649 | header_field_info *hfinfo;
1650 | char *str;
1651 |
1652 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1653 |
1654 | 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", 1654 , __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", 1654, "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", 1654, "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", 1654, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1655 |
1656 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1657 |
1658 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1658, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1659 |
1660 | str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1661 | proto_item_set_text(pi, "%s", str);
1662 | wmem_free(NULL((void*)0), str);
1663 |
1664 | return pi;
1665 | }
1666 |
1667 | void proto_report_dissector_bug(const char *format, ...)
1668 | {
1669 | va_list args;
1670 |
1671 | if (wireshark_abort_on_dissector_bug) {
1672 | /*
1673 | * Try to have the error message show up in the crash
1674 | * information.
1675 | */
1676 | va_start(args, format)__builtin_va_start(args, format);
1677 | ws_vadd_crash_info(format, args);
1678 | va_end(args)__builtin_va_end(args);
1679 |
1680 | /*
1681 | * Print the error message.
1682 | */
1683 | va_start(args, format)__builtin_va_start(args, format);
1684 | vfprintf(stderrstderr, format, args);
1685 | va_end(args)__builtin_va_end(args);
1686 | putc('\n', stderrstderr);
1687 |
1688 | /*
1689 | * And crash.
1690 | */
1691 | abort();
1692 | } else {
1693 | va_start(args, format)__builtin_va_start(args, format);
1694 | VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1695 | va_end(args)__builtin_va_end(args);
1696 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1696 , __func__, "assertion \"not reached\" failed"); /* GCC 12 with ASAN needs this. */
1697 | }
1698 | }
1699 |
1700 | /* We could probably get away with changing is_error to a minimum length value. */
1701 | static void
1702 | report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1703 | {
1704 | if (is_error) {
1705 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1706 | } else {
1707 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1708 | }
1709 |
1710 | if (is_error) {
1711 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1712 | }
1713 | }
1714 |
1715 | static uint32_t
1716 | get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1717 | {
1718 | uint32_t value;
1719 | bool_Bool length_error;
1720 |
1721 | switch (length) {
1722 |
1723 | case 1:
1724 | value = tvb_get_uint8(tvb, offset);
1725 | if (encoding & ENC_ZIGBEE0x40000000) {
1726 | if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1727 | value = 0;
1728 | }
1729 | }
1730 | break;
1731 |
1732 | case 2:
1733 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1734 | : tvb_get_ntohs(tvb, offset);
1735 | if (encoding & ENC_ZIGBEE0x40000000) {
1736 | if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1737 | value = 0;
1738 | }
1739 | }
1740 | break;
1741 |
1742 | case 3:
1743 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1744 | : tvb_get_ntoh24(tvb, offset);
1745 | break;
1746 |
1747 | case 4:
1748 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1749 | : tvb_get_ntohl(tvb, offset);
1750 | break;
1751 |
1752 | default:
1753 | if (length < 1) {
1754 | length_error = true1;
1755 | value = 0;
1756 | } else {
1757 | length_error = false0;
1758 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1759 | : tvb_get_ntohl(tvb, offset);
1760 | }
1761 | report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1762 | break;
1763 | }
1764 | return value;
1765 | }
1766 |
1767 | static inline uint64_t
1768 | get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1769 | {
1770 | uint64_t value;
1771 |
1772 | value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1773 |
1774 | if (length < 1 || length > 8) {
1775 | report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1776 | }
1777 |
1778 | return value;
1779 | }
1780 |
1781 | static int32_t
1782 | get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1783 | {
1784 | int32_t value;
1785 | bool_Bool length_error;
1786 |
1787 | switch (length) {
1788 |
1789 | case 1:
1790 | value = tvb_get_int8(tvb, offset);
1791 | break;
1792 |
1793 | case 2:
1794 | value = encoding ? tvb_get_letohis(tvb, offset)
1795 | : tvb_get_ntohis(tvb, offset);
1796 | break;
1797 |
1798 | case 3:
1799 | value = encoding ? tvb_get_letohi24(tvb, offset)
1800 | : tvb_get_ntohi24(tvb, offset);
1801 | break;
1802 |
1803 | case 4:
1804 | value = encoding ? tvb_get_letohil(tvb, offset)
1805 | : tvb_get_ntohil(tvb, offset);
1806 | break;
1807 |
1808 | default:
1809 | if (length < 1) {
1810 | length_error = true1;
1811 | value = 0;
1812 | } else {
1813 | length_error = false0;
1814 | value = encoding ? tvb_get_letohil(tvb, offset)
1815 | : tvb_get_ntohil(tvb, offset);
1816 | }
1817 | report_type_length_mismatch(tree, "a signed integer", length, length_error);
1818 | break;
1819 | }
1820 | return value;
1821 | }
1822 |
1823 | /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1824 | * be cast-able as a int64_t. This is weird, but what the code has always done.
1825 | */
1826 | static inline uint64_t
1827 | get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1828 | {
1829 | uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1830 |
1831 | switch (length) {
1832 | case 7:
1833 | value = ws_sign_ext64(value, 56);
1834 | break;
1835 | case 6:
1836 | value = ws_sign_ext64(value, 48);
1837 | break;
1838 | case 5:
1839 | value = ws_sign_ext64(value, 40);
1840 | break;
1841 | case 4:
1842 | value = ws_sign_ext64(value, 32);
1843 | break;
1844 | case 3:
1845 | value = ws_sign_ext64(value, 24);
1846 | break;
1847 | case 2:
1848 | value = ws_sign_ext64(value, 16);
1849 | break;
1850 | case 1:
1851 | value = ws_sign_ext64(value, 8);
1852 | break;
1853 | }
1854 |
1855 | return value;
1856 | }
1857 |
1858 | /* For FT_STRING */
1859 | static inline const uint8_t *
1860 | get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1861 | int length, unsigned *ret_length, const unsigned encoding)
1862 | {
1863 | if (length == -1) {
1864 | *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1865 | } else {
1866 | *ret_length = length;
1867 | }
1868 | return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1869 | }
1870 |
1871 | /* For FT_STRINGZ */
1872 | static inline const uint8_t *
1873 | get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1874 | unsigned start, int length, unsigned *ret_length, const unsigned encoding)
1875 | {
1876 | const uint8_t *value;
1877 |
1878 | if (length < -1) {
1879 | report_type_length_mismatch(tree, "a string", length, true1);
1880 | }
1881 |
1882 | /* XXX - Ideally, every "null-terminated string which fits into a
1883 | * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1884 | * as appropriate, not a FT_STRINGZ. If so, then we could always call
1885 | * tvb_get_stringz_enc here. Failing that, we could treat length 0
1886 | * as unknown length as well (since there is a trailing '\0', the real
1887 | * length is never zero), allowing switching to unsigned lengths.
1888 | */
1889 | if (length == -1) {
1890 | /* This can throw an exception */
1891 | value = tvb_get_stringz_enc(scope, tvb, start, ret_length, encoding);
1892 | } else {
1893 | /* In this case, length signifies the length of the string.
1894 | *
1895 | * This could either be a null-padded string, which doesn't
1896 | * necessarily have a '\0' at the end, or a null-terminated
1897 | * string, with a trailing '\0'. (Yes, there are cases
1898 | * where you have a string that's both counted and null-
1899 | * terminated.)
1900 | *
1901 | * In the first case, we must allocate a buffer of length
1902 | * "length+1", to make room for a trailing '\0'.
1903 | *
1904 | * In the second case, we don't assume that there is a
1905 | * trailing '\0' there, as the packet might be malformed.
1906 | * (XXX - should we throw an exception if there's no
1907 | * trailing '\0'?) Therefore, we allocate a buffer of
1908 | * length "length+1", and put in a trailing '\0', just to
1909 | * be safe.
1910 | *
1911 | * (XXX - this would change if we made string values counted
1912 | * rather than null-terminated.)
1913 | */
1914 | *ret_length = length;
1915 | value = tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1916 | }
1917 | return value;
1918 | }
1919 |
1920 | /* For FT_UINT_STRING */
1921 | static inline const uint8_t *
1922 | get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1923 | tvbuff_t *tvb, unsigned start, int length, unsigned *ret_length,
1924 | const unsigned encoding)
1925 | {
1926 | uint32_t n;
1927 | const uint8_t *value;
1928 |
1929 | /* I believe it's ok if this is called with a NULL tree */
1930 | n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1931 | value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1932 | *ret_length = length + n;
1933 | return value;
1934 | }
1935 |
1936 | /* For FT_STRINGZPAD */
1937 | static inline const uint8_t *
1938 | get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1939 | int length, unsigned *ret_length, const unsigned encoding)
1940 | {
1941 | /*
1942 | * XXX - currently, string values are null-
1943 | * terminated, so a "zero-padded" string
1944 | * isn't special. If we represent string
1945 | * values as something that includes a counted
1946 | * array of bytes, we'll need to strip the
1947 | * trailing NULs.
1948 | */
1949 | if (length == -1) {
1950 | *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1951 | } else {
1952 | *ret_length = length;
1953 | }
1954 | return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1955 | }
1956 |
1957 | /* For FT_STRINGZTRUNC */
1958 | static inline const uint8_t *
1959 | get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1960 | int length, unsigned *ret_length, const unsigned encoding)
1961 | {
1962 | /*
1963 | * XXX - currently, string values are null-
1964 | * terminated, so a "zero-truncated" string
1965 | * isn't special. If we represent string
1966 | * values as something that includes a counted
1967 | * array of bytes, we'll need to strip everything
1968 | * starting with the terminating NUL.
1969 | */
1970 | if (length == -1) {
1971 | *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1972 | } else {
1973 | *ret_length = length;
1974 | }
1975 | return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1976 | }
1977 |
1978 | /*
1979 | * Deltas between the epochs for various non-UN*X time stamp formats and
1980 | * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1981 | * stamp format.
1982 | */
1983 |
1984 | /*
1985 | * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1986 | * XXX - if it's OK if this is unsigned, can we just use
1987 | * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1988 | */
1989 | #define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1990 |
1991 | /*
1992 | * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1993 | */
1994 | #define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1995 |
1996 | /* this can be called when there is no tree, so tree may be null */
1997 | static void
1998 | get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1999 | const int length, const unsigned encoding, nstime_t *time_stamp,
2000 | const bool_Bool is_relative)
2001 | {
2002 | uint32_t tmpsecs;
2003 | uint64_t tmp64secs;
2004 | uint64_t todusecs;
2005 |
2006 | switch (encoding) {
2007 |
2008 | case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
2009 | /*
2010 | * If the length is 16, 8-byte seconds, followed
2011 | * by 8-byte fractional time in nanoseconds,
2012 | * both big-endian.
2013 | *
2014 | * If the length is 12, 8-byte seconds, followed
2015 | * by 4-byte fractional time in nanoseconds,
2016 | * both big-endian.
2017 | *
2018 | * If the length is 8, 4-byte seconds, followed
2019 | * by 4-byte fractional time in nanoseconds,
2020 | * both big-endian.
2021 | *
2022 | * For absolute times, the seconds are seconds
2023 | * since the UN*X epoch.
2024 | */
2025 | if (length == 16) {
2026 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2027 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2028 | } else if (length == 12) {
2029 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2030 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2031 | } else if (length == 8) {
2032 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2033 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2034 | } else if (length == 4) {
2035 | /*
2036 | * Backwards compatibility.
2037 | * ENC_TIME_SECS_NSECS is 0; using
2038 | * ENC_BIG_ENDIAN by itself with a 4-byte
2039 | * time-in-seconds value was done in the
2040 | * past.
2041 | */
2042 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2043 | time_stamp->nsecs = 0;
2044 | } else {
2045 | time_stamp->secs = 0;
2046 | time_stamp->nsecs = 0;
2047 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2048 | }
2049 | break;
2050 |
2051 | case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2052 | /*
2053 | * If the length is 16, 8-byte seconds, followed
2054 | * by 8-byte fractional time in nanoseconds,
2055 | * both little-endian.
2056 | *
2057 | * If the length is 12, 8-byte seconds, followed
2058 | * by 4-byte fractional time in nanoseconds,
2059 | * both little-endian.
2060 | *
2061 | * If the length is 8, 4-byte seconds, followed
2062 | * by 4-byte fractional time in nanoseconds,
2063 | * both little-endian.
2064 | *
2065 | * For absolute times, the seconds are seconds
2066 | * since the UN*X epoch.
2067 | */
2068 | if (length == 16) {
2069 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2070 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2071 | } else if (length == 12) {
2072 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2073 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2074 | } else if (length == 8) {
2075 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2076 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2077 | } else if (length == 4) {
2078 | /*
2079 | * Backwards compatibility.
2080 | * ENC_TIME_SECS_NSECS is 0; using
2081 | * ENC_LITTLE_ENDIAN by itself with a 4-byte
2082 | * time-in-seconds value was done in the
2083 | * past.
2084 | */
2085 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2086 | time_stamp->nsecs = 0;
2087 | } else {
2088 | time_stamp->secs = 0;
2089 | time_stamp->nsecs = 0;
2090 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2091 | }
2092 | break;
2093 |
2094 | case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2095 | /*
2096 | * NTP time stamp, big-endian.
2097 | * Only supported for absolute times.
2098 | */
2099 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2099, "!is_relative" ))));
2100 |
2101 | /* We need a temporary variable here so the unsigned math
2102 | * works correctly (for years > 2036 according to RFC 2030
2103 | * chapter 3).
2104 | *
2105 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2106 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2107 | * If bit 0 is not set, the time is in the range 2036-2104 and
2108 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2109 | */
2110 | tmpsecs = tvb_get_ntohl(tvb, start);
2111 | if ((tmpsecs & 0x80000000) != 0)
2112 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2113 | else
2114 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2115 |
2116 | if (length == 8) {
2117 | tmp64secs = tvb_get_ntoh64(tvb, start);
2118 | if (tmp64secs == 0) {
2119 | //This is "NULL" time
2120 | time_stamp->secs = 0;
2121 | time_stamp->nsecs = 0;
2122 | } else {
2123 | /*
2124 | * Convert 1/2^32s of a second to
2125 | * nanoseconds.
2126 | */
2127 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2128 | }
2129 | } else if (length == 4) {
2130 | /*
2131 | * Backwards compatibility.
2132 | */
2133 | if (tmpsecs == 0) {
2134 | //This is "NULL" time
2135 | time_stamp->secs = 0;
2136 | }
2137 | time_stamp->nsecs = 0;
2138 | } else {
2139 | time_stamp->secs = 0;
2140 | time_stamp->nsecs = 0;
2141 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2142 | }
2143 | break;
2144 |
2145 | case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2146 | /*
2147 | * NTP time stamp, little-endian.
2148 | * Only supported for absolute times.
2149 | *
2150 | * NTP doesn't use this, because it's an Internet format
2151 | * and hence big-endian. Any implementation must decide
2152 | * whether the NTP timestamp is a 64-bit unsigned fixed
2153 | * point number (RFC 1305, RFC 4330) or a 64-bit struct
2154 | * with a 32-bit unsigned seconds field followed by a
2155 | * 32-bit fraction field (cf. RFC 5905, which obsoletes
2156 | * the previous two).
2157 | *
2158 | * XXX: We do the latter, but no dissector uses this format.
2159 | * OTOH, ERF timestamps do the former, so perhaps we
2160 | * should switch the interpretation so that packet-erf.c
2161 | * could use this directly? (ENC_TIME_RTPS is this 64-bit
2162 | * struct with two 32-bit fields, but with the UN*X epoch.)
2163 | */
2164 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2164, "!is_relative" ))));
2165 |
2166 | /* We need a temporary variable here so the unsigned math
2167 | * works correctly (for years > 2036 according to RFC 2030
2168 | * chapter 3).
2169 | *
2170 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2171 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2172 | * If bit 0 is not set, the time is in the range 2036-2104 and
2173 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2174 | */
2175 | tmpsecs = tvb_get_letohl(tvb, start);
2176 | if ((tmpsecs & 0x80000000) != 0)
2177 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2178 | else
2179 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2180 |
2181 | if (length == 8) {
2182 | tmp64secs = tvb_get_letoh64(tvb, start);
2183 | if (tmp64secs == 0) {
2184 | //This is "NULL" time
2185 | time_stamp->secs = 0;
2186 | time_stamp->nsecs = 0;
2187 | } else {
2188 | /*
2189 | * Convert 1/2^32s of a second to
2190 | * nanoseconds.
2191 | */
2192 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2193 | }
2194 | } else if (length == 4) {
2195 | /*
2196 | * Backwards compatibility.
2197 | */
2198 | if (tmpsecs == 0) {
2199 | //This is "NULL" time
2200 | time_stamp->secs = 0;
2201 | }
2202 | time_stamp->nsecs = 0;
2203 | } else {
2204 | time_stamp->secs = 0;
2205 | time_stamp->nsecs = 0;
2206 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2207 | }
2208 | break;
2209 |
2210 | case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2211 | /*
2212 | * S/3x0 and z/Architecture TOD clock time stamp,
2213 | * big-endian. The epoch is January 1, 1900,
2214 | * 00:00:00 (proleptic?) UTC.
2215 | *
2216 | * Only supported for absolute times.
2217 | */
2218 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2218, "!is_relative" ))));
2219 | DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2219, "length == 8" ))));
2220 |
2221 | if (length == 8) {
2222 | todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2223 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2224 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2225 | } else {
2226 | time_stamp->secs = 0;
2227 | time_stamp->nsecs = 0;
2228 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2229 | }
2230 | break;
2231 |
2232 | case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2233 | /*
2234 | * S/3x0 and z/Architecture TOD clock time stamp,
2235 | * little-endian. The epoch is January 1, 1900,
2236 | * 00:00:00 (proleptic?) UTC.
2237 | *
2238 | * Only supported for absolute times.
2239 | */
2240 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2240, "!is_relative" ))));
2241 |
2242 | if (length == 8) {
2243 | todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2244 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2245 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2246 | } else {
2247 | time_stamp->secs = 0;
2248 | time_stamp->nsecs = 0;
2249 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2250 | }
2251 | break;
2252 |
2253 | case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2254 | /*
2255 | * Time stamp using the same seconds/fraction format
2256 | * as NTP, but with the origin of the time stamp being
2257 | * the UNIX epoch rather than the NTP epoch; big-
2258 | * endian.
2259 | *
2260 | * Only supported for absolute times.
2261 | */
2262 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2262, "!is_relative" ))));
2263 |
2264 | if (length == 8) {
2265 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2266 | /*
2267 | * Convert 1/2^32s of a second to nanoseconds.
2268 | */
2269 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2270 | } else {
2271 | time_stamp->secs = 0;
2272 | time_stamp->nsecs = 0;
2273 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2274 | }
2275 | break;
2276 |
2277 | case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2278 | /*
2279 | * Time stamp using the same seconds/fraction format
2280 | * as NTP, but with the origin of the time stamp being
2281 | * the UNIX epoch rather than the NTP epoch; little-
2282 | * endian.
2283 | *
2284 | * Only supported for absolute times.
2285 | *
2286 | * The RTPS specification explicitly supports Little
2287 | * Endian encoding. In one place, it states that its
2288 | * Time_t representation "is the one defined by ...
2289 | * RFC 1305", but in another explicitly defines it as
2290 | * a struct consisting of an 32 bit unsigned seconds
2291 | * field and a 32 bit unsigned fraction field, not a 64
2292 | * bit fixed point, so we do that here.
2293 | * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2294 | */
2295 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2295, "!is_relative" ))));
2296 |
2297 | if (length == 8) {
2298 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2299 | /*
2300 | * Convert 1/2^32s of a second to nanoseconds.
2301 | */
2302 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2303 | } else {
2304 | time_stamp->secs = 0;
2305 | time_stamp->nsecs = 0;
2306 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2307 | }
2308 | break;
2309 |
2310 | case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2311 | /*
2312 | * MIP6 time stamp, big-endian.
2313 | * A 64-bit unsigned integer field containing a timestamp. The
2314 | * value indicates the number of seconds since January 1, 1970,
2315 | * 00:00 UTC, by using a fixed point format. In this format, the
2316 | * integer number of seconds is contained in the first 48 bits of
2317 | * the field, and the remaining 16 bits indicate the number of
2318 | * 1/65536 fractions of a second.
2319 |
2320 | * Only supported for absolute times.
2321 | */
2322 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2322, "!is_relative" ))));
2323 |
2324 | if (length == 8) {
2325 | /* We need a temporary variable here so the casting and fractions
2326 | * of a second work correctly.
2327 | */
2328 | tmp64secs = tvb_get_ntoh48(tvb, start);
2329 | tmpsecs = tvb_get_ntohs(tvb, start + 6);
2330 | tmpsecs <<= 16;
2331 |
2332 | if ((tmp64secs == 0) && (tmpsecs == 0)) {
2333 | //This is "NULL" time
2334 | time_stamp->secs = 0;
2335 | time_stamp->nsecs = 0;
2336 | } else {
2337 | time_stamp->secs = (time_t)tmp64secs;
2338 | time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2339 | }
2340 | } else {
2341 | time_stamp->secs = 0;
2342 | time_stamp->nsecs = 0;
2343 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2344 | }
2345 | break;
2346 |
2347 | case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2348 | /*
2349 | * If the length is 16, 8-byte seconds, followed
2350 | * by 8-byte fractional time in microseconds,
2351 | * both big-endian.
2352 | *
2353 | * If the length is 12, 8-byte seconds, followed
2354 | * by 4-byte fractional time in microseconds,
2355 | * both big-endian.
2356 | *
2357 | * If the length is 8, 4-byte seconds, followed
2358 | * by 4-byte fractional time in microseconds,
2359 | * both big-endian.
2360 | *
2361 | * For absolute times, the seconds are seconds
2362 | * since the UN*X epoch.
2363 | */
2364 | if (length == 16) {
2365 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2366 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2367 | } else if (length == 12) {
2368 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2369 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2370 | } else if (length == 8) {
2371 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2372 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2373 | } else {
2374 | time_stamp->secs = 0;
2375 | time_stamp->nsecs = 0;
2376 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2377 | }
2378 | break;
2379 |
2380 | case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2381 | /*
2382 | * If the length is 16, 8-byte seconds, followed
2383 | * by 8-byte fractional time in microseconds,
2384 | * both little-endian.
2385 | *
2386 | * If the length is 12, 8-byte seconds, followed
2387 | * by 4-byte fractional time in microseconds,
2388 | * both little-endian.
2389 | *
2390 | * If the length is 8, 4-byte seconds, followed
2391 | * by 4-byte fractional time in microseconds,
2392 | * both little-endian.
2393 | *
2394 | * For absolute times, the seconds are seconds
2395 | * since the UN*X epoch.
2396 | */
2397 | if (length == 16) {
2398 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2399 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2400 | } else if (length == 12) {
2401 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2402 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2403 | } else if (length == 8) {
2404 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2405 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2406 | } else {
2407 | time_stamp->secs = 0;
2408 | time_stamp->nsecs = 0;
2409 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2410 | }
2411 | break;
2412 |
2413 | case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2414 | case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2415 | /*
2416 | * Seconds, 1 to 8 bytes.
2417 | * For absolute times, it's seconds since the
2418 | * UN*X epoch.
2419 | */
2420 | if (length >= 1 && length <= 8) {
2421 | time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2422 | time_stamp->nsecs = 0;
2423 | } else {
2424 | time_stamp->secs = 0;
2425 | time_stamp->nsecs = 0;
2426 | report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2427 | }
2428 | break;
2429 |
2430 | case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2431 | case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2432 | /*
2433 | * Milliseconds, 1 to 8 bytes.
2434 | * For absolute times, it's milliseconds since the
2435 | * UN*X epoch.
2436 | */
2437 | if (length >= 1 && length <= 8) {
2438 | uint64_t msecs;
2439 |
2440 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2441 | time_stamp->secs = (time_t)(msecs / 1000);
2442 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2443 | } else {
2444 | time_stamp->secs = 0;
2445 | time_stamp->nsecs = 0;
2446 | report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2447 | }
2448 | break;
2449 |
2450 | case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2451 | case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2452 | /*
2453 | * Microseconds, 1 to 8 bytes.
2454 | * For absolute times, it's microseconds since the
2455 | * UN*X epoch.
2456 | */
2457 | if (length >= 1 && length <= 8) {
2458 | uint64_t usecs;
2459 |
2460 | usecs = get_uint64_value(tree, tvb, start, length, encoding);
2461 | time_stamp->secs = (time_t)(usecs / 1000000);
2462 | time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2463 | } else {
2464 | time_stamp->secs = 0;
2465 | time_stamp->nsecs = 0;
2466 | report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2467 | }
2468 | break;
2469 |
2470 | case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2471 | case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2472 | /*
2473 | * nanoseconds, 1 to 8 bytes.
2474 | * For absolute times, it's nanoseconds since the
2475 | * UN*X epoch.
2476 | */
2477 |
2478 | if (length >= 1 && length <= 8) {
2479 | uint64_t nsecs;
2480 |
2481 | nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2482 | time_stamp->secs = (time_t)(nsecs / 1000000000);
2483 | time_stamp->nsecs = (int)(nsecs % 1000000000);
2484 | } else {
2485 | time_stamp->secs = 0;
2486 | time_stamp->nsecs = 0;
2487 | report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2488 | }
2489 | break;
2490 |
2491 | case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2492 | /*
2493 | * 1/64ths of a second since the UN*X epoch,
2494 | * big-endian.
2495 | *
2496 | * Only supported for absolute times.
2497 | */
2498 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2498, "!is_relative" ))));
2499 |
2500 | if (length == 8) {
2501 | /*
2502 | * The upper 48 bits are seconds since the
2503 | * UN*X epoch.
2504 | */
2505 | time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2506 | /*
2507 | * The lower 16 bits are 1/2^16s of a second;
2508 | * convert them to nanoseconds.
2509 | *
2510 | * XXX - this may give the impression of higher
2511 | * precision than you actually get.
2512 | */
2513 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2514 | } else {
2515 | time_stamp->secs = 0;
2516 | time_stamp->nsecs = 0;
2517 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2518 | }
2519 | break;
2520 |
2521 | case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2522 | /*
2523 | * 1/64ths of a second since the UN*X epoch,
2524 | * little-endian.
2525 | *
2526 | * Only supported for absolute times.
2527 | */
2528 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2528, "!is_relative" ))));
2529 |
2530 | if (length == 8) {
2531 | /*
2532 | * XXX - this is assuming that, if anybody
2533 | * were ever to use this format - RFC 3971
2534 | * doesn't, because that's an Internet
2535 | * protocol, and those use network byte
2536 | * order, i.e. big-endian - they'd treat it
2537 | * as a 64-bit count of 1/2^16s of a second,
2538 | * putting the upper 48 bits at the end.
2539 | *
2540 | * The lower 48 bits are seconds since the
2541 | * UN*X epoch.
2542 | */
2543 | time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2544 | /*
2545 | * The upper 16 bits are 1/2^16s of a second;
2546 | * convert them to nanoseconds.
2547 | *
2548 | * XXX - this may give the impression of higher
2549 | * precision than you actually get.
2550 | */
2551 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2552 | } else {
2553 | time_stamp->secs = 0;
2554 | time_stamp->nsecs = 0;
2555 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2556 | }
2557 | break;
2558 |
2559 | case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2560 | /*
2561 | * NTP time stamp, with 1-second resolution (i.e.,
2562 | * seconds since the NTP epoch), big-endian.
2563 | * Only supported for absolute times.
2564 | */
2565 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2565, "!is_relative" ))));
2566 |
2567 | if (length == 4) {
2568 | /*
2569 | * We need a temporary variable here so the unsigned math
2570 | * works correctly (for years > 2036 according to RFC 2030
2571 | * chapter 3).
2572 | *
2573 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2574 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2575 | * If bit 0 is not set, the time is in the range 2036-2104 and
2576 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2577 | */
2578 | tmpsecs = tvb_get_ntohl(tvb, start);
2579 | if ((tmpsecs & 0x80000000) != 0)
2580 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2581 | else
2582 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2583 | time_stamp->nsecs = 0;
2584 | } else {
2585 | time_stamp->secs = 0;
2586 | time_stamp->nsecs = 0;
2587 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2588 | }
2589 | break;
2590 |
2591 | case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2592 | /*
2593 | * NTP time stamp, with 1-second resolution (i.e.,
2594 | * seconds since the NTP epoch), little-endian.
2595 | * Only supported for absolute times.
2596 | */
2597 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2597, "!is_relative" ))));
2598 |
2599 | /*
2600 | * We need a temporary variable here so the unsigned math
2601 | * works correctly (for years > 2036 according to RFC 2030
2602 | * chapter 3).
2603 | *
2604 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2605 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2606 | * If bit 0 is not set, the time is in the range 2036-2104 and
2607 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2608 | */
2609 | if (length == 4) {
2610 | tmpsecs = tvb_get_letohl(tvb, start);
2611 | if ((tmpsecs & 0x80000000) != 0)
2612 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2613 | else
2614 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2615 | time_stamp->nsecs = 0;
2616 | } else {
2617 | time_stamp->secs = 0;
2618 | time_stamp->nsecs = 0;
2619 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2620 | }
2621 | break;
2622 |
2623 | case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2624 | /*
2625 | * Milliseconds, 6 to 8 bytes.
2626 | * For absolute times, it's milliseconds since the
2627 | * NTP epoch.
2628 | *
2629 | * ETSI TS 129.274 8.119 defines this as:
2630 | * "a 48 bit unsigned integer in network order format
2631 | * ...encoded as the number of milliseconds since
2632 | * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2633 | * rounded value of 1000 x the value of the 64-bit
2634 | * timestamp (Seconds + (Fraction / (1<<32))) defined
2635 | * in clause 6 of IETF RFC 5905."
2636 | *
2637 | * Taken literally, the part after "i.e." would
2638 | * mean that the value rolls over before reaching
2639 | * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2640 | * when the 64 bit timestamp rolls over, and we have
2641 | * to pick an NTP Era equivalence class to support
2642 | * (such as 1968-01-20 to 2104-02-06).
2643 | *
2644 | * OTOH, the extra room might be used to store Era
2645 | * information instead, in which case times until
2646 | * 10819-08-03 can be represented with 6 bytes without
2647 | * ambiguity. We handle both implementations, and assume
2648 | * that times before 1968-01-20 are not represented.
2649 | *
2650 | * Only 6 bytes or more makes sense as an absolute
2651 | * time. 5 bytes or fewer could express a span of
2652 | * less than 35 years, either 1900-1934 or 2036-2070.
2653 | */
2654 | if (length >= 6 && length <= 8) {
2655 | uint64_t msecs;
2656 |
2657 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2658 | tmp64secs = (msecs / 1000);
2659 | /*
2660 | * Assume that times in the first half of NTP
2661 | * Era 0 really represent times in the NTP
2662 | * Era 1.
2663 | */
2664 | if (tmp64secs >= 0x80000000)
2665 | time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2666 | else
2667 | time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2668 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2669 | }
2670 | else {
2671 | time_stamp->secs = 0;
2672 | time_stamp->nsecs = 0;
2673 | report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2674 | }
2675 | break;
2676 |
2677 | case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2678 | /*
2679 | * MP4 file time stamps, big-endian.
2680 | * Only supported for absolute times.
2681 | */
2682 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2682, "!is_relative" ))));
2683 |
2684 | if (length == 8) {
2685 | tmp64secs = tvb_get_ntoh64(tvb, start);
2686 | time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2687 | time_stamp->nsecs = 0;
2688 | } else if (length == 4) {
2689 | tmpsecs = tvb_get_ntohl(tvb, start);
2690 | time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2691 | time_stamp->nsecs = 0;
2692 | } else {
2693 | time_stamp->secs = 0;
2694 | time_stamp->nsecs = 0;
2695 | report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2696 | }
2697 | break;
2698 |
2699 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2700 | /*
2701 | * Zigbee ZCL time stamps, big-endian.
2702 | * Only supported for absolute times.
2703 | */
2704 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2704, "!is_relative" ))));
2705 |
2706 | if (length == 8) {
2707 | tmp64secs = tvb_get_ntoh64(tvb, start);
2708 | 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))) {
2709 | /* There are several other possible choices for what to do
2710 | * with overflow; make sure to coordinate with whatever
2711 | * packet-zbee-zcl.h does. */
2712 | 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))))));
2713 | }
2714 | time_stamp->nsecs = 0;
2715 | } else if (length == 4) {
2716 | tmpsecs = tvb_get_ntohl(tvb, start);
2717 | 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))) {
2718 | 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))))));
2719 | }
2720 | time_stamp->nsecs = 0;
2721 | } else {
2722 | time_stamp->secs = 0;
2723 | time_stamp->nsecs = 0;
2724 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2725 | }
2726 | break;
2727 |
2728 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2729 | /*
2730 | * Zigbee ZCL time stamps, little-endian.
2731 | * Only supported for absolute times.
2732 | */
2733 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2733, "!is_relative" ))));
2734 |
2735 | if (length == 8) {
2736 | tmp64secs = tvb_get_letoh64(tvb, start);
2737 | 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))) {
2738 | 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))))));
2739 | }
2740 | time_stamp->nsecs = 0;
2741 | } else if (length == 4) {
2742 | tmpsecs = tvb_get_letohl(tvb, start);
2743 | 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))) {
2744 | 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))))));
2745 | }
2746 | time_stamp->nsecs = 0;
2747 | } else {
2748 | time_stamp->secs = 0;
2749 | time_stamp->nsecs = 0;
2750 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2751 | }
2752 | break;
2753 |
2754 | case ENC_TIME_WINDOWS0x00000034 | ENC_BIG_ENDIAN0x00000000:
2755 | /*
2756 | * WINDOWS FILETIME, big-endian.
2757 | * Only supported for absolute times.
2758 | * A FILETIME is a struct with the low 32-bits followed
2759 | * by the high 32-bits:
2760 | * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2761 | * There exist cases where the value is stored in a
2762 | * 64-bit integer:
2763 | * (See epan/dissectors/pidl/samr/samr.idl "NTTIME_hyper last_password_change;"
2764 | * which is confirmed as "LARGE_INTEGER PasswordLastSet;" in
2765 | * https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/1cd138b9-cc1b-4706-b115-49e53189e32e
2766 | * That doesn't make a difference when retrieving little-endian,
2767 | * because tvb_get_letoh64 handles unaligned accesses and it's
2768 | * otherwise the same. However, for big-endian, it does matter,
2769 | * analogous to the ENC_TIME_NTP little-endian case. We use the
2770 | * struct version, but that means that this MUST NOT be used
2771 | * for dissect_nttime_hyper in packet-windows-common.h, at
2772 | * least
2773 | */
2774 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2774, "!is_relative" ))));
2775 |
2776 | if (length == 8) {
2777 | tmp64secs = tvb_get_ntoh64(tvb, start); // Really 100-ns units
2778 | if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2779 | // With 32-bit time_t, this could overflow in
2780 | // either direction. We should probably add some
2781 | // kind of time overflow expert item to all
2782 | // encodings.
2783 | 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))))));
2784 | time_stamp->nsecs = 0;
2785 | }
2786 | } else {
2787 | time_stamp->secs = 0;
2788 | time_stamp->nsecs = 0;
2789 | report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2790 | }
2791 | break;
2792 |
2793 | case ENC_TIME_WINDOWS0x00000034 | ENC_LITTLE_ENDIAN0x80000000:
2794 | /*
2795 | * WINDOWS FILETIME, big-endian.
2796 | * Only supported for absolute times.
2797 | * https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime
2798 | */
2799 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2799, "!is_relative" ))));
2800 |
2801 | if (length == 8) {
2802 | tmp64secs = tvb_get_letoh64(tvb, start); // Really 100-ns units
2803 | if (!filetime_to_nstime(time_stamp, tmp64secs)) {
2804 | // With 32-bit time_t, this could overflow in
2805 | // either direction. We should probably add some
2806 | // kind of time overflow expert item to all
2807 | // encodings.
2808 | 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))))));
2809 | time_stamp->nsecs = 0;
2810 | }
2811 | } else {
2812 | time_stamp->secs = 0;
2813 | time_stamp->nsecs = 0;
2814 | report_type_length_mismatch(tree, "an NTFS FILETIME time stamp", length, (length < 8));
2815 | }
2816 | break;
2817 | default:
2818 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 2818));
2819 | break;
2820 | }
2821 | }
2822 |
2823 | static void
2824 | tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2825 | {
2826 | const header_field_info *hfinfo = fi->hfinfo;
2827 |
2828 | if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2829 | GPtrArray *ptrs = NULL((void*)0);
2830 |
2831 | if (tree_data->interesting_hfids == NULL((void*)0)) {
2832 | /* Initialize the hash because we now know that it is needed */
2833 | tree_data->interesting_hfids =
2834 | g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2835 | } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2836 | ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2837 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2838 | }
2839 |
2840 | if (!ptrs) {
2841 | /* First element triggers the creation of pointer array */
2842 | ptrs = g_ptr_array_new();
2843 | g_hash_table_insert(tree_data->interesting_hfids,
2844 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2845 | }
2846 |
2847 | g_ptr_array_add(ptrs, fi);
2848 | }
2849 | }
2850 |
2851 |
2852 | /*
2853 | * Validates that field length bytes are available starting from
2854 | * start (pos/neg). Throws an exception if they aren't.
2855 | */
2856 | static void
2857 | test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2858 | unsigned start, int length, const unsigned encoding)
2859 | {
2860 | int size = length;
2861 |
2862 | if (!tvb)
2863 | return;
2864 |
2865 | if ((hfinfo->type == FT_STRINGZ) ||
2866 | ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2867 | (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 ))))) {
2868 | /* If we're fetching until the end of the TVB, only validate
2869 | * that the offset is within range.
2870 | */
2871 | if (length == -1)
2872 | size = 0;
2873 | }
2874 |
2875 | tvb_ensure_bytes_exist(tvb, start, size);
2876 | }
2877 |
2878 | static void
2879 | detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2880 | {
2881 | bool_Bool found_stray_character = false0;
2882 |
2883 | if (!string)
2884 | return;
2885 |
2886 | switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2887 | case ENC_ASCII0x00000000:
2888 | case ENC_UTF_80x00000002:
2889 | for (int i = (int)strlen(string); i < length; i++) {
2890 | if (string[i] != '\0') {
2891 | found_stray_character = true1;
2892 | break;
2893 | }
2894 | }
2895 | break;
2896 |
2897 | default:
2898 | break;
2899 | }
2900 |
2901 | if (found_stray_character) {
2902 | expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2903 | }
2904 | }
2905 |
2906 | /* Add an item to a proto_tree, using the text label registered to that item;
2907 | the item is extracted from the tvbuff handed to it. */
2908 | static proto_item *
2909 | proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2910 | tvbuff_t *tvb, unsigned start, int length,
2911 | unsigned encoding)
2912 | {
2913 | proto_item *pi;
2914 | uint32_t value, n;
2915 | uint64_t value64;
2916 | ws_in4_addr ipv4_value;
2917 | float floatval;
2918 | double doubleval;
2919 | const char *stringval = NULL((void*)0);
2920 | nstime_t time_stamp;
2921 | bool_Bool length_error;
2922 | unsigned item_length;
1 | 'item_length' declared without an initial value | →
2923 |
2924 | // new_fi->value is allocated from the packet-scoped pool (see
2925 | // new_field_info()), so if a tvbuff accessor below throws before the
2926 | // node is added to the tree the fvalue_t structure is still reclaimed
2927 | // when the pool is freed; no explicit cleanup handler is needed. This
2928 | // relies on the invariant that the type-specific data an fvalue owns
2929 | // (byte arrays, string buffers, ...) is only allocated *after* the
2930 | // throwing tvbuff read that produced it succeeds, so nothing that would
2931 | // need fvalue_cleanup() is ever leaked on the exception path.
2932 | switch (new_fi->hfinfo->type) {
2 | ← | Control jumps to 'case FT_NONE:' at line 2933 | →
2933 | case FT_NONE:
2934 | /* no value to set for FT_NONE */
2935 | break;
2936 |
2937 | case FT_PROTOCOL:
2938 | /* Set the protocol_tvb via the start offset, but include
2939 | * rest of the ds_tvb so that if finfo_set_len is called
2940 | * later it can be lengthened as much as possible. */
2941 | 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);
2942 | break;
2943 |
2944 | case FT_BYTES:
2945 | proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2946 | break;
2947 |
2948 | case FT_UINT_BYTES:
2949 | n = get_uint_value(tree, tvb, start, length, encoding);
2950 | proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2951 |
2952 | /* Instead of calling proto_item_set_len(), since we don't yet
2953 | * have a proto_item, we set the field_info's length ourselves. */
2954 | new_fi->length = n + length;
2955 | break;
2956 |
2957 | case FT_BOOLEAN:
2958 | /*
2959 | * Map all non-zero values to little-endian for
2960 | * backwards compatibility.
2961 | */
2962 | if (encoding)
2963 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2964 | proto_tree_set_boolean(new_fi,
2965 | get_uint64_value(tree, tvb, start, length, encoding));
2966 | break;
2967 |
2968 | case FT_CHAR:
2969 | /* XXX - make these just FT_UINT? */
2970 | case FT_UINT8:
2971 | case FT_UINT16:
2972 | case FT_UINT24:
2973 | case FT_UINT32:
2974 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2975 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2976 | value = (uint32_t)value64;
2977 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2978 | new_fi->flags |= FI_VARINT0x00040000;
2979 | }
2980 | }
2981 | else {
2982 | /*
2983 | * Map all non-zero values to little-endian for
2984 | * backwards compatibility.
2985 | */
2986 | if (encoding)
2987 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2988 |
2989 | value = get_uint_value(tree, tvb, start, length, encoding);
2990 | }
2991 | proto_tree_set_uint(new_fi, value);
2992 | break;
2993 |
2994 | case FT_UINT40:
2995 | case FT_UINT48:
2996 | case FT_UINT56:
2997 | case FT_UINT64:
2998 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2999 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
3000 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
3001 | new_fi->flags |= FI_VARINT0x00040000;
3002 | }
3003 | }
3004 | else {
3005 | /*
3006 | * Map all other non-zero values to little-endian for
3007 | * backwards compatibility.
3008 | */
3009 | if (encoding)
3010 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3011 |
3012 | value64 = get_uint64_value(tree, tvb, start, length, encoding);
3013 | }
3014 | proto_tree_set_uint64(new_fi, value64);
3015 | break;
3016 |
3017 | /* XXX - make these just FT_INT? */
3018 | case FT_INT8:
3019 | case FT_INT16:
3020 | case FT_INT24:
3021 | case FT_INT32:
3022 | /*
3023 | * Map all non-zero values to little-endian for
3024 | * backwards compatibility.
3025 | */
3026 | if (encoding)
3027 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3028 | proto_tree_set_int(new_fi,
3029 | get_int_value(tree, tvb, start, length, encoding));
3030 | break;
3031 |
3032 | case FT_INT40:
3033 | case FT_INT48:
3034 | case FT_INT56:
3035 | case FT_INT64:
3036 | /*
3037 | * Map all non-zero values to little-endian for
3038 | * backwards compatibility.
3039 | */
3040 | if (encoding)
3041 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3042 | proto_tree_set_int64(new_fi,
3043 | get_int64_value(tree, tvb, start, length, encoding));
3044 | break;
3045 |
3046 | case FT_IPv4:
3047 | /*
3048 | * Map all non-zero values to little-endian for
3049 | * backwards compatibility.
3050 | */
3051 | if (encoding)
3052 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3053 | if (length != FT_IPv4_LEN4) {
3054 | length_error = length < FT_IPv4_LEN4 ? true1 : false0;
3055 | report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
3056 | }
3057 | ipv4_value = tvb_get_ipv4(tvb, start);
3058 | /*
3059 | * NOTE: to support code written when
3060 | * proto_tree_add_item() took a bool as its
3061 | * last argument, with false meaning "big-endian"
3062 | * and true meaning "little-endian", we treat any
3063 | * non-zero value of "encoding" as meaning
3064 | * "little-endian".
3065 | */
3066 | 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);
3067 | break;
3068 |
3069 | case FT_IPXNET:
3070 | if (length != FT_IPXNET_LEN4) {
3071 | length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
3072 | report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
3073 | }
3074 | proto_tree_set_ipxnet(new_fi,
3075 | get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
3076 | break;
3077 |
3078 | case FT_IPv6:
3079 | if (length != FT_IPv6_LEN16) {
3080 | length_error = length < FT_IPv6_LEN16 ? true1 : false0;
3081 | report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3082 | }
3083 | proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3084 | break;
3085 |
3086 | case FT_FCWWN:
3087 | if (length != FT_FCWWN_LEN8) {
3088 | length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
3089 | report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3090 | }
3091 | proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3092 | break;
3093 |
3094 | case FT_AX25:
3095 | if (length != 7) {
3096 | length_error = length < 7 ? true1 : false0;
3097 | report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3098 | }
3099 | proto_tree_set_ax25_tvb(new_fi, tvb, start);
3100 | break;
3101 |
3102 | case FT_VINES:
3103 | if (length != VINES_ADDR_LEN6) {
3104 | length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3105 | report_type_length_mismatch(tree, "a Vines address", length, length_error);
3106 | }
3107 | proto_tree_set_vines_tvb(new_fi, tvb, start);
3108 | break;
3109 |
3110 | case FT_ETHER:
3111 | if (length != FT_ETHER_LEN6) {
3112 | length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3113 | report_type_length_mismatch(tree, "a MAC address", length, length_error);
3114 | }
3115 | proto_tree_set_ether_tvb(new_fi, tvb, start);
3116 | break;
3117 |
3118 | case FT_EUI64:
3119 | /*
3120 | * Map all non-zero values to little-endian for
3121 | * backwards compatibility.
3122 | */
3123 | if (encoding)
3124 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3125 | if (length != FT_EUI64_LEN8) {
3126 | length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3127 | report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3128 | }
3129 | proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3130 | break;
3131 | case FT_GUID:
3132 | /*
3133 | * Map all non-zero values to little-endian for
3134 | * backwards compatibility.
3135 | */
3136 | if (encoding)
3137 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3138 | if (length != FT_GUID_LEN16) {
3139 | length_error = length < FT_GUID_LEN16 ? true1 : false0;
3140 | report_type_length_mismatch(tree, "a GUID", length, length_error);
3141 | }
3142 | proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3143 | break;
3144 |
3145 | case FT_OID:
3146 | case FT_REL_OID:
3147 | proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3148 | break;
3149 |
3150 | case FT_SYSTEM_ID:
3151 | proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3152 | break;
3153 |
3154 | case FT_FLOAT:
3155 | /*
3156 | * NOTE: to support code written when
3157 | * proto_tree_add_item() took a bool as its
3158 | * last argument, with false meaning "big-endian"
3159 | * and true meaning "little-endian", we treat any
3160 | * non-zero value of "encoding" as meaning
3161 | * "little-endian".
3162 | *
3163 | * At some point in the future, we might
3164 | * support non-IEEE-binary floating-point
3165 | * formats in the encoding as well
3166 | * (IEEE decimal, System/3x0, VAX).
3167 | */
3168 | if (encoding)
3169 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3170 | if (length != 4) {
3171 | length_error = length < 4 ? true1 : false0;
3172 | report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3173 | }
3174 | if (encoding)
3175 | floatval = tvb_get_letohieee_float(tvb, start);
3176 | else
3177 | floatval = tvb_get_ntohieee_float(tvb, start);
3178 | proto_tree_set_float(new_fi, floatval);
3179 | break;
3180 |
3181 | case FT_DOUBLE:
3182 | /*
3183 | * NOTE: to support code written when
3184 | * proto_tree_add_item() took a bool as its
3185 | * last argument, with false meaning "big-endian"
3186 | * and true meaning "little-endian", we treat any
3187 | * non-zero value of "encoding" as meaning
3188 | * "little-endian".
3189 | *
3190 | * At some point in the future, we might
3191 | * support non-IEEE-binary floating-point
3192 | * formats in the encoding as well
3193 | * (IEEE decimal, System/3x0, VAX).
3194 | */
3195 | if (encoding == true1)
3196 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3197 | if (length != 8) {
3198 | length_error = length < 8 ? true1 : false0;
3199 | report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3200 | }
3201 | if (encoding)
3202 | doubleval = tvb_get_letohieee_double(tvb, start);
3203 | else
3204 | doubleval = tvb_get_ntohieee_double(tvb, start);
3205 | proto_tree_set_double(new_fi, doubleval);
3206 | break;
3207 |
3208 | case FT_STRING:
3209 | stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3210 | tvb, start, length, &item_length, encoding);
3211 | proto_tree_set_string(new_fi, stringval);
3212 |
3213 | /* Instead of calling proto_item_set_len(), since we
3214 | * don't yet have a proto_item, we set the
3215 | * field_info's length ourselves.
3216 | *
3217 | * XXX - our caller can't use that length to
3218 | * advance an offset unless they arrange that
3219 | * there always be a protocol tree into which
3220 | * we're putting this item.
3221 | */
3222 | new_fi->length = item_length;
3223 | break;
3224 |
3225 | case FT_STRINGZ:
3226 | stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3227 | tree, tvb, start, length, &item_length, encoding);
3228 | proto_tree_set_string(new_fi, stringval);
3229 |
3230 | /* Instead of calling proto_item_set_len(),
3231 | * since we don't yet have a proto_item, we
3232 | * set the field_info's length ourselves.
3233 | *
3234 | * XXX - our caller can't use that length to
3235 | * advance an offset unless they arrange that
3236 | * there always be a protocol tree into which
3237 | * we're putting this item.
3238 | */
3239 | new_fi->length = item_length;
3240 | break;
3241 |
3242 | case FT_UINT_STRING:
3243 | /*
3244 | * NOTE: to support code written when
3245 | * proto_tree_add_item() took a bool as its
3246 | * last argument, with false meaning "big-endian"
3247 | * and true meaning "little-endian", if the
3248 | * encoding value is true, treat that as
3249 | * ASCII with a little-endian length.
3250 | *
3251 | * This won't work for code that passes
3252 | * arbitrary non-zero values; that code
3253 | * will need to be fixed.
3254 | */
3255 | if (encoding == true1)
3256 | encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3257 | stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3258 | tree, tvb, start, length, &item_length, encoding);
3259 | proto_tree_set_string(new_fi, stringval);
3260 |
3261 | /* Instead of calling proto_item_set_len(), since we
3262 | * don't yet have a proto_item, we set the
3263 | * field_info's length ourselves.
3264 | *
3265 | * XXX - our caller can't use that length to
3266 | * advance an offset unless they arrange that
3267 | * there always be a protocol tree into which
3268 | * we're putting this item.
3269 | */
3270 | new_fi->length = item_length;
3271 | break;
3272 |
3273 | case FT_STRINGZPAD:
3274 | stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3275 | tvb, start, length, &item_length, encoding);
3276 | proto_tree_set_string(new_fi, stringval);
3277 |
3278 | /* Instead of calling proto_item_set_len(), since we
3279 | * don't yet have a proto_item, we set the
3280 | * field_info's length ourselves.
3281 | *
3282 | * XXX - our caller can't use that length to
3283 | * advance an offset unless they arrange that
3284 | * there always be a protocol tree into which
3285 | * we're putting this item.
3286 | */
3287 | new_fi->length = item_length;
3288 | break;
3289 |
3290 | case FT_STRINGZTRUNC:
3291 | stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3292 | tvb, start, length, &item_length, encoding);
3293 | proto_tree_set_string(new_fi, stringval);
3294 |
3295 | /* Instead of calling proto_item_set_len(), since we
3296 | * don't yet have a proto_item, we set the
3297 | * field_info's length ourselves.
3298 | *
3299 | * XXX - our caller can't use that length to
3300 | * advance an offset unless they arrange that
3301 | * there always be a protocol tree into which
3302 | * we're putting this item.
3303 | */
3304 | new_fi->length = item_length;
3305 | break;
3306 |
3307 | case FT_ABSOLUTE_TIME:
3308 | /*
3309 | * Absolute times can be in any of a number of
3310 | * formats, and they can be big-endian or
3311 | * little-endian.
3312 | *
3313 | * Historically FT_TIMEs were only timespecs;
3314 | * the only question was whether they were stored
3315 | * in big- or little-endian format.
3316 | *
3317 | * For backwards compatibility, we interpret an
3318 | * encoding of 1 as meaning "little-endian timespec",
3319 | * so that passing true is interpreted as that.
3320 | */
3321 | if (encoding == true1)
3322 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3323 |
3324 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3325 |
3326 | proto_tree_set_time(new_fi, &time_stamp);
3327 | break;
3328 |
3329 | case FT_RELATIVE_TIME:
3330 | /*
3331 | * Relative times can be in any of a number of
3332 | * formats, and they can be big-endian or
3333 | * little-endian.
3334 | *
3335 | * Historically FT_TIMEs were only timespecs;
3336 | * the only question was whether they were stored
3337 | * in big- or little-endian format.
3338 | *
3339 | * For backwards compatibility, we interpret an
3340 | * encoding of 1 as meaning "little-endian timespec",
3341 | * so that passing true is interpreted as that.
3342 | */
3343 | if (encoding == true1)
3344 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3345 |
3346 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3347 |
3348 | proto_tree_set_time(new_fi, &time_stamp);
3349 | break;
3350 | case FT_IEEE_11073_SFLOAT:
3351 | if (encoding)
3352 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3353 | if (length != 2) {
3354 | length_error = length < 2 ? true1 : false0;
3355 | report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3356 | }
3357 |
3358 | fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3359 |
3360 | break;
3361 | case FT_IEEE_11073_FLOAT:
3362 | if (encoding)
3363 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3364 | if (length != 4) {
3365 | length_error = length < 4 ? true1 : false0;
3366 | report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3367 | }
3368 | fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3369 |
3370 | break;
3371 | default:
3372 | 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))
3373 | 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))
3374 | 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))
3375 | 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));
3376 | break;
3377 | }
3378 | 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 3378 | →
4 | ← | Taking true branch | →
5 | ← | Assuming the condition is false | →
6 | ← | '?' condition is false | →
7 | ← | Loop condition is false. Exiting loop | →
3379 |
3380 | /* Don't add new node to proto_tree until now so that any exceptions
3381 | * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3382 | /* XXX. wouldn't be better to add this item to tree, with some special
3383 | * flag (FI_EXCEPTION?) to know which item caused exception? For
3384 | * strings and bytes, we would have to set new_fi->value to something
3385 | * non-NULL, or otherwise ensure that proto_item_fill_display_label
3386 | * could handle NULL values. */
3387 | pi = proto_tree_add_node(tree, new_fi);
3388 |
3389 | switch (new_fi->hfinfo->type) {
8 | ← | Control jumps to 'case FT_STRING:' at line 3391 | →
3390 |
3391 | case FT_STRING:
3392 | /* XXX: trailing stray character detection should be done
3393 | * _before_ conversion to UTF-8, because conversion can change
3394 | * the length, or else get_string_length should return a value
3395 | * for the "length in bytes of the string after conversion
3396 | * including internal nulls." (Noting that we do, for other
3397 | * reasons, still need the "length in bytes in the field",
3398 | * especially for FT_STRINGZ.)
3399 | *
3400 | * This is true even for ASCII and UTF-8, because
3401 | * substituting REPLACEMENT CHARACTERS for illegal characters
3402 | * can also do so (and for UTF-8 possibly even make the
3403 | * string _shorter_).
3404 | */
3405 | detect_trailing_stray_characters(encoding, stringval, item_length, pi);
9 | ← | 3rd function call argument is an uninitialized value
3406 | break;
3407 |
3408 | default:
3409 | break;
3410 | }
3411 |
3412 | return pi;
3413 | }
3414 |
3415 | proto_item *
3416 | proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3417 | const unsigned start, unsigned length,
3418 | const unsigned encoding, int32_t *retval)
3419 | {
3420 | header_field_info *hfinfo;
3421 | field_info *new_fi;
3422 | int32_t value;
3423 |
3424 | 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", 3424, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3424, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3424, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3425 |
3426 | switch (hfinfo->type) {
3427 | case FT_INT8:
3428 | case FT_INT16:
3429 | case FT_INT24:
3430 | case FT_INT32:
3431 | break;
3432 | case FT_INT64:
3433 | 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)
3434 | hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3435 | default:
3436 | 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)
3437 | hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3438 | }
3439 |
3440 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3441 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3442 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3443 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3444 | *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3445 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3446 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3447 |
3448 | if (encoding & ENC_STRING0x07000000) {
3449 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3450 | }
3451 | /* I believe it's ok if this is called with a NULL tree */
3452 | value = get_int_value(tree, tvb, start, length, encoding);
3453 |
3454 | if (retval) {
3455 | int no_of_bits;
3456 | *retval = value;
3457 | if (hfinfo->bitmask) {
3458 | /* Mask out irrelevant portions */
3459 | *retval &= (uint32_t)(hfinfo->bitmask);
3460 | /* Shift bits */
3461 | *retval >>= hfinfo_bitshift(hfinfo);
3462 | }
3463 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3464 | *retval = ws_sign_ext32(*retval, no_of_bits);
3465 | }
3466 |
3467 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3468 |
3469 | 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", 3469 , __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", 3469, "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", 3469, "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", 3469, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3470 |
3471 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3472 |
3473 | proto_tree_set_int(new_fi, value);
3474 |
3475 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3476 |
3477 | return proto_tree_add_node(tree, new_fi);
3478 | }
3479 |
3480 | proto_item *
3481 | proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3482 | const unsigned start, unsigned length,
3483 | const unsigned encoding, uint32_t *retval)
3484 | {
3485 | header_field_info *hfinfo;
3486 | field_info *new_fi;
3487 | uint32_t value;
3488 |
3489 | 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", 3489, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3489, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3489, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3490 |
3491 | switch (hfinfo->type) {
3492 | case FT_CHAR:
3493 | case FT_UINT8:
3494 | case FT_UINT16:
3495 | case FT_UINT24:
3496 | case FT_UINT32:
3497 | break;
3498 | default:
3499 | 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)
3500 | 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);
3501 | }
3502 |
3503 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3504 | {if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3505 | if (retval) {if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3506 | *retval = 0;if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3507 | }if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3508 | return NULL;if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3509 | }if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3510 | )if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); };
3511 |
3512 | if (encoding & ENC_STRING0x07000000) {
3513 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3514 | }
3515 | /* I believe it's ok if this is called with a NULL tree */
3516 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3517 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3518 | uint64_t temp64;
3519 | tvb_get_varint(tvb, start, length, &temp64, encoding);
3520 | value = (uint32_t)temp64;
3521 | } else {
3522 | value = get_uint_value(tree, tvb, start, length, encoding);
3523 | }
3524 |
3525 | if (retval) {
3526 | *retval = value;
3527 | if (hfinfo->bitmask) {
3528 | /* Mask out irrelevant portions */
3529 | *retval &= (uint32_t)(hfinfo->bitmask);
3530 | /* Shift bits */
3531 | *retval >>= hfinfo_bitshift(hfinfo);
3532 | }
3533 | }
3534 |
3535 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3536 |
3537 | 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", 3537 , __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", 3537, "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", 3537, "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", 3537, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3538 |
3539 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3540 |
3541 | proto_tree_set_uint(new_fi, value);
3542 |
3543 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3544 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3545 | new_fi->flags |= FI_VARINT0x00040000;
3546 | }
3547 | return proto_tree_add_node(tree, new_fi);
3548 | }
3549 |
3550 | proto_item *
3551 | proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3552 | const unsigned start, unsigned length,
3553 | const unsigned encoding, uint32_t *retval)
3554 | {
3555 | return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3556 | }
3557 |
3558 | proto_item *
3559 | proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3560 | const unsigned start, unsigned length,
3561 | const unsigned encoding, uint8_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 = (uint8_t)val32;
3567 | return item;
3568 | }
3569 |
3570 | proto_item *
3571 | proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3572 | const unsigned start, unsigned length,
3573 | const unsigned encoding, uint16_t *retval)
3574 | {
3575 | /* TODO: further restrict by hfinfo->type ? */
3576 | uint32_t val32;
3577 | proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3578 | *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3579 | return item;
3580 | }
3581 |
3582 |
3583 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3584 | * and returns proto_item* and uint value retrieved*/
3585 | proto_item *
3586 | ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3587 | const unsigned encoding, uint32_t *retval)
3588 | {
3589 | field_info *new_fi;
3590 | header_field_info *hfinfo;
3591 | unsigned item_length;
3592 | unsigned offset;
3593 | uint32_t value;
3594 |
3595 | offset = ptvc->offset;
3596 | PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 3596, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3596, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3596, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3597 |
3598 | switch (hfinfo->type) {
3599 | case FT_CHAR:
3600 | case FT_UINT8:
3601 | case FT_UINT16:
3602 | case FT_UINT24:
3603 | case FT_UINT32:
3604 | break;
3605 | default:
3606 | 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)
3607 | 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);
3608 | }
3609 |
3610 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3611 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3612 |
3613 | /* I believe it's ok if this is called with a NULL tree */
3614 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3615 | value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3616 |
3617 | if (retval) {
3618 | *retval = value;
3619 | if (hfinfo->bitmask) {
3620 | /* Mask out irrelevant portions */
3621 | *retval &= (uint32_t)(hfinfo->bitmask);
3622 | /* Shift bits */
3623 | *retval >>= hfinfo_bitshift(hfinfo);
3624 | }
3625 | }
3626 |
3627 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3628 |
3629 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3630 |
3631 | /* Coast clear. Try and fake it */
3632 | 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", 3632 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3632, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3632, "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", 3632, __func__, "Adding %s would put more than %d 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); } } };
3633 |
3634 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3635 |
3636 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3637 | offset, length, encoding);
3638 | }
3639 |
3640 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3641 | * and returns proto_item* and int value retrieved*/
3642 | proto_item *
3643 | ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3644 | const unsigned encoding, int32_t *retval)
3645 | {
3646 | field_info *new_fi;
3647 | header_field_info *hfinfo;
3648 | unsigned item_length;
3649 | unsigned offset;
3650 | uint32_t value;
3651 |
3652 | offset = ptvc->offset;
3653 | 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", 3653, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3653, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3653, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3654 |
3655 | switch (hfinfo->type) {
3656 | case FT_INT8:
3657 | case FT_INT16:
3658 | case FT_INT24:
3659 | case FT_INT32:
3660 | break;
3661 | default:
3662 | 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)
3663 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
3664 | }
3665 |
3666 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3667 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3668 |
3669 | /* I believe it's ok if this is called with a NULL tree */
3670 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3671 | value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3672 |
3673 | if (retval) {
3674 | int no_of_bits;
3675 | *retval = value;
3676 | if (hfinfo->bitmask) {
3677 | /* Mask out irrelevant portions */
3678 | *retval &= (uint32_t)(hfinfo->bitmask);
3679 | /* Shift bits */
3680 | *retval >>= hfinfo_bitshift(hfinfo);
3681 | }
3682 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3683 | *retval = ws_sign_ext32(*retval, no_of_bits);
3684 | }
3685 |
3686 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3687 |
3688 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3689 |
3690 | /* Coast clear. Try and fake it */
3691 | 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", 3691 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3691, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3691, "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", 3691, __func__, "Adding %s would put more than %d 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); } } };
3692 |
3693 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3694 |
3695 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3696 | offset, length, encoding);
3697 | }
3698 |
3699 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3700 | * and returns proto_item* and string value retrieved */
3701 | proto_item*
3702 | ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3703 | {
3704 | header_field_info *hfinfo;
3705 | field_info *new_fi;
3706 | const uint8_t *value;
3707 | unsigned item_length;
3708 | unsigned offset;
3709 |
3710 | offset = ptvc->offset;
3711 |
3712 | 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", 3712 , __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", 3712, "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", 3712, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[hf];;
3713 |
3714 | switch (hfinfo->type) {
3715 | case FT_STRING:
3716 | value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3717 | break;
3718 | case FT_STRINGZ:
3719 | value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3720 | break;
3721 | case FT_UINT_STRING:
3722 | value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3723 | break;
3724 | case FT_STRINGZPAD:
3725 | value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3726 | break;
3727 | case FT_STRINGZTRUNC:
3728 | value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3729 | break;
3730 | default:
3731 | 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)
3732 | 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);
3733 | }
3734 |
3735 | if (retval)
3736 | *retval = value;
3737 |
3738 | ptvcursor_advance(ptvc, item_length);
3739 |
3740 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3741 |
3742 | 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", 3742, __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", 3742, "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", 3742, "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", 3742 , __func__, "Adding %s would put more than %d 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); } } };
3743 |
3744 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3745 |
3746 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3747 | offset, length, encoding);
3748 | }
3749 |
3750 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3751 | * and returns proto_item* and boolean value retrieved */
3752 | proto_item*
3753 | ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3754 | {
3755 | header_field_info *hfinfo;
3756 | field_info *new_fi;
3757 | unsigned item_length;
3758 | unsigned offset;
3759 | uint64_t value, bitval;
3760 |
3761 | offset = ptvc->offset;
3762 | 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", 3762, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3762, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3762, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3763 |
3764 | if (hfinfo->type != FT_BOOLEAN) {
3765 | 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)
3766 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3767 | }
3768 |
3769 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3770 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3771 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3772 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3773 | *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3774 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3775 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3776 |
3777 | if (encoding & ENC_STRING0x07000000) {
3778 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3779 | }
3780 |
3781 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3782 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3783 |
3784 | /* I believe it's ok if this is called with a NULL tree */
3785 | value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3786 |
3787 | if (retval) {
3788 | bitval = value;
3789 | if (hfinfo->bitmask) {
3790 | /* Mask out irrelevant portions */
3791 | bitval &= hfinfo->bitmask;
3792 | }
3793 | *retval = (bitval != 0);
3794 | }
3795 |
3796 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3797 |
3798 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3799 |
3800 | 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", 3800, __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", 3800, "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", 3800, "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", 3800 , __func__, "Adding %s would put more than %d 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); } } };
3801 |
3802 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3803 |
3804 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3805 | offset, length, encoding);
3806 | }
3807 |
3808 | proto_item *
3809 | proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3810 | const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval)
3811 | {
3812 | header_field_info *hfinfo;
3813 | field_info *new_fi;
3814 | uint64_t value;
3815 |
3816 | 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", 3816, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3816, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3816, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3817 |
3818 | switch (hfinfo->type) {
3819 | case FT_UINT40:
3820 | case FT_UINT48:
3821 | case FT_UINT56:
3822 | case FT_UINT64:
3823 | break;
3824 | default:
3825 | 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)
3826 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64" , hfinfo->abbrev);
3827 | }
3828 |
3829 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3830 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3831 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3832 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3833 | *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3834 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3835 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3836 |
3837 | if (encoding & ENC_STRING0x07000000) {
3838 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3839 | }
3840 | /* I believe it's ok if this is called with a NULL tree */
3841 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3842 | tvb_get_varint(tvb, start, length, &value, encoding);
3843 | } else {
3844 | value = get_uint64_value(tree, tvb, start, length, encoding);
3845 | }
3846 |
3847 | if (retval) {
3848 | *retval = value;
3849 | if (hfinfo->bitmask) {
3850 | /* Mask out irrelevant portions */
3851 | *retval &= hfinfo->bitmask;
3852 | /* Shift bits */
3853 | *retval >>= hfinfo_bitshift(hfinfo);
3854 | }
3855 | }
3856 |
3857 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3858 |
3859 | 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", 3859 , __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", 3859, "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", 3859, "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", 3859, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3860 |
3861 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3862 |
3863 | proto_tree_set_uint64(new_fi, value);
3864 |
3865 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3866 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3867 | new_fi->flags |= FI_VARINT0x00040000;
3868 | }
3869 |
3870 | return proto_tree_add_node(tree, new_fi);
3871 | }
3872 |
3873 | proto_item *
3874 | proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3875 | const unsigned start, unsigned length, const unsigned encoding, int64_t *retval)
3876 | {
3877 | header_field_info *hfinfo;
3878 | field_info *new_fi;
3879 | int64_t value;
3880 |
3881 | 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", 3881, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3881, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3881, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3882 |
3883 | switch (hfinfo->type) {
3884 | case FT_INT40:
3885 | case FT_INT48:
3886 | case FT_INT56:
3887 | case FT_INT64:
3888 | break;
3889 | default:
3890 | 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)
3891 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
3892 | }
3893 |
3894 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3895 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3896 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3897 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3898 | *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3899 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3900 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3901 |
3902 | if (encoding & ENC_STRING0x07000000) {
3903 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3904 | }
3905 | /* I believe it's ok if this is called with a NULL tree */
3906 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3907 | tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3908 | }
3909 | else {
3910 | value = get_int64_value(tree, tvb, start, length, encoding);
3911 | }
3912 |
3913 | if (retval) {
3914 | *retval = value;
3915 | }
3916 |
3917 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3918 |
3919 | 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", 3919 , __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", 3919, "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", 3919, "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", 3919, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3920 |
3921 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3922 |
3923 | proto_tree_set_int64(new_fi, value);
3924 |
3925 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3926 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3927 | new_fi->flags |= FI_VARINT0x00040000;
3928 | }
3929 |
3930 | return proto_tree_add_node(tree, new_fi);
3931 | }
3932 |
3933 | proto_item *
3934 | proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3935 | const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval, unsigned *lenretval)
3936 | {
3937 | header_field_info *hfinfo;
3938 | field_info *new_fi;
3939 | uint64_t value;
3940 |
3941 | 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", 3941, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3941, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3941, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3942 |
3943 | 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 )))) {
3944 | 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)
3945 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT" , hfinfo->abbrev);
3946 | }
3947 |
3948 | if (!(encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3949 | REPORT_DISSECTOR_BUG("Encoding must be a VARINT")proto_report_dissector_bug("Encoding must be a VARINT");
3950 | }
3951 |
3952 | if (encoding & ENC_STRING0x07000000) {
3953 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3954 | }
3955 |
3956 | /* tvb_get_varint clamps the max length to FT_VARINT_MAX_LEN (10)
3957 | * It also handles length 0, setting both return values to 0.
3958 | * XXX - Should the max length be affected by the field type and/or
3959 | * encoding, e.g. 5 for FT_[U]INT32?
3960 | * XXX - Should there be separate _varint and _varuint versions to
3961 | * avoid the changing the sign when casting the return value?
3962 | * XXX - Do we even need the length parameter? Every user of this
3963 | * function passes in -1 or FT_VARINT_MAX_LEN. We could have a
3964 | * separate function, but unlike some field types, variable length
3965 | * is the typical case here, not the exception, and the typical
3966 | * case should have the shorter, more convenient function name.
3967 | * Having the length makes the signature more similar to other
3968 | * functions, though. */
3969 | length = tvb_get_varint(tvb, start, length, &value, encoding);
3970 |
3971 | if (length == 0) {
3972 | expert_add_info(NULL((void*)0), tree, &ei_varint_decoding_failed_error);
3973 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
3974 | }
3975 |
3976 | if (retval) {
3977 | *retval = value;
3978 | if (hfinfo->bitmask) {
3979 | /* Mask out irrelevant portions */
3980 | *retval &= hfinfo->bitmask;
3981 | /* Shift bits */
3982 | *retval >>= hfinfo_bitshift(hfinfo);
3983 | }
3984 | }
3985 |
3986 | if (lenretval) {
3987 | *lenretval = length;
3988 | }
3989 |
3990 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3991 |
3992 | 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", 3992 , __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", 3992, "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", 3992, "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", 3992, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3993 |
3994 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3995 |
3996 | proto_tree_set_uint64(new_fi, value);
3997 |
3998 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3999 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
4000 | new_fi->flags |= FI_VARINT0x00040000;
4001 | }
4002 |
4003 | return proto_tree_add_node(tree, new_fi);
4004 |
4005 | }
4006 |
4007 | proto_item *
4008 | proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4009 | const unsigned start, unsigned length,
4010 | const unsigned encoding, bool_Bool *retval)
4011 | {
4012 | header_field_info *hfinfo;
4013 | field_info *new_fi;
4014 | uint64_t value, bitval;
4015 |
4016 | 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", 4016, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4016, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4016, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4017 |
4018 | if (hfinfo->type != FT_BOOLEAN) {
4019 | 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)
4020 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
4021 | }
4022 |
4023 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
4024 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
4025 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
4026 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
4027 | *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
4028 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
4029 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
4030 |
4031 | if (encoding & ENC_STRING0x07000000) {
4032 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4033 | }
4034 | /* I believe it's ok if this is called with a NULL tree */
4035 | value = get_uint64_value(tree, tvb, start, length, encoding);
4036 |
4037 | if (retval) {
4038 | bitval = value;
4039 | if (hfinfo->bitmask) {
4040 | /* Mask out irrelevant portions */
4041 | bitval &= hfinfo->bitmask;
4042 | }
4043 | *retval = (bitval != 0);
4044 | }
4045 |
4046 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4047 |
4048 | 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", 4048 , __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", 4048, "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", 4048, "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", 4048, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4049 |
4050 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4051 |
4052 | proto_tree_set_boolean(new_fi, value);
4053 |
4054 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4055 |
4056 | return proto_tree_add_node(tree, new_fi);
4057 | }
4058 |
4059 | proto_item *
4060 | proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4061 | const unsigned start, unsigned length,
4062 | const unsigned encoding, float *retval)
4063 | {
4064 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4065 | field_info *new_fi;
4066 | float value;
4067 |
4068 | 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", 4068, "hfinfo != ((void*)0)", "Not passed hfi."))));
4069 |
4070 | if (hfinfo->type != FT_FLOAT) {
4071 | 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);
4072 | }
4073 |
4074 | if (length != 4) {
4075 | report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
4076 | }
4077 |
4078 | /* treat any nonzero encoding as little endian for backwards compatibility */
4079 | value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
4080 | if (retval) {
4081 | *retval = value;
4082 | }
4083 |
4084 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4085 |
4086 | 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", 4086 , __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", 4086, "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", 4086, "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", 4086, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4087 |
4088 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4089 | if (encoding) {
4090 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4091 | }
4092 |
4093 | proto_tree_set_float(new_fi, value);
4094 |
4095 | return proto_tree_add_node(tree, new_fi);
4096 | }
4097 |
4098 | proto_item *
4099 | proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4100 | const unsigned start, unsigned length,
4101 | const unsigned encoding, double *retval)
4102 | {
4103 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4104 | field_info *new_fi;
4105 | double value;
4106 |
4107 | 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", 4107, "hfinfo != ((void*)0)", "Not passed hfi."))));
4108 |
4109 | if (hfinfo->type != FT_DOUBLE) {
4110 | 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);
4111 | }
4112 |
4113 | if (length != 8) {
4114 | report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4115 | }
4116 |
4117 | /* treat any nonzero encoding as little endian for backwards compatibility */
4118 | value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4119 | if (retval) {
4120 | *retval = value;
4121 | }
4122 |
4123 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4124 |
4125 | 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", 4125 , __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", 4125, "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", 4125, "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", 4125, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4126 |
4127 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4128 | if (encoding) {
4129 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4130 | }
4131 |
4132 | proto_tree_set_double(new_fi, value);
4133 |
4134 | return proto_tree_add_node(tree, new_fi);
4135 | }
4136 |
4137 | proto_item *
4138 | proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4139 | const unsigned start, unsigned length,
4140 | const unsigned encoding, ws_in4_addr *retval)
4141 | {
4142 | header_field_info *hfinfo;
4143 | field_info *new_fi;
4144 | ws_in4_addr value;
4145 |
4146 | 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", 4146, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4146, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4146, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4147 |
4148 | switch (hfinfo->type) {
4149 | case FT_IPv4:
4150 | break;
4151 | default:
4152 | 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)
4153 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4", hfinfo->abbrev);
4154 | }
4155 |
4156 | if (length != FT_IPv4_LEN4)
4157 | 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)
4158 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4" , length);
4159 |
4160 | if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4161 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4162 | }
4163 |
4164 | /*
4165 | * NOTE: to support code written when proto_tree_add_item() took
4166 | * a bool as its last argument, with false meaning "big-endian"
4167 | * and true meaning "little-endian", we treat any non-zero value
4168 | * of "encoding" as meaning "little-endian".
4169 | */
4170 | value = tvb_get_ipv4(tvb, start);
4171 | if (encoding)
4172 | 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))));
4173 |
4174 | if (retval) {
4175 | *retval = value;
4176 | }
4177 |
4178 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4179 |
4180 | 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", 4180 , __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", 4180, "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", 4180, "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", 4180, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4181 |
4182 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4183 |
4184 | proto_tree_set_ipv4(new_fi, value);
4185 |
4186 | new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4187 | return proto_tree_add_node(tree, new_fi);
4188 | }
4189 |
4190 | proto_item *
4191 | proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4192 | const unsigned start, unsigned length,
4193 | const unsigned encoding, ws_in6_addr *addr)
4194 | {
4195 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4196 | field_info *new_fi;
4197 |
4198 | 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", 4198, "hfinfo != ((void*)0)", "Not passed hfi."))));
4199 |
4200 | switch (hfinfo->type) {
4201 | case FT_IPv6:
4202 | break;
4203 | default:
4204 | 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)
4205 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6", hfinfo->abbrev);
4206 | }
4207 |
4208 | if (length != FT_IPv6_LEN16)
4209 | 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)
4210 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6" , length);
4211 |
4212 | if (encoding) {
4213 | 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" );
4214 | }
4215 |
4216 | tvb_get_ipv6(tvb, start, addr);
4217 |
4218 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4219 |
4220 | 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", 4220 , __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", 4220, "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", 4220, "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", 4220, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4221 |
4222 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4223 |
4224 | proto_tree_set_ipv6(new_fi, addr);
4225 |
4226 | return proto_tree_add_node(tree, new_fi);
4227 | }
4228 |
4229 | proto_item *
4230 | proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4231 | const unsigned start, unsigned length, const unsigned encoding, uint8_t *retval) {
4232 |
4233 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4234 | field_info *new_fi;
4235 |
4236 | 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", 4236, "hfinfo != ((void*)0)", "Not passed hfi."))));
4237 |
4238 | switch (hfinfo->type) {
4239 | case FT_ETHER:
4240 | break;
4241 | default:
4242 | 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)
4243 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER" , hfinfo->abbrev);
4244 | }
4245 |
4246 | if (length != FT_ETHER_LEN6)
4247 | 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)
4248 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether" , length);
4249 |
4250 | if (encoding) {
4251 | 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" );
4252 | }
4253 |
4254 | tvb_memcpy(tvb, retval, start, length);
4255 |
4256 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4257 |
4258 | 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", 4258 , __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", 4258, "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", 4258, "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", 4258, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4259 |
4260 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4261 |
4262 | proto_tree_set_ether(new_fi, retval);
4263 |
4264 | return proto_tree_add_node(tree, new_fi);
4265 | }
4266 |
4267 |
4268 | proto_item *
4269 | proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4270 | tvbuff_t *tvb,
4271 | const unsigned start, int length,
4272 | const unsigned encoding,
4273 | wmem_allocator_t *scope,
4274 | const uint8_t **retval,
4275 | unsigned *lenretval)
4276 | {
4277 | proto_item *pi;
4278 | header_field_info *hfinfo;
4279 | field_info *new_fi;
4280 | const uint8_t *value;
4281 |
4282 | 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", 4282, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4282, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4282, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4283 |
4284 | switch (hfinfo->type) {
4285 | case FT_STRING:
4286 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4287 | break;
4288 | case FT_STRINGZ:
4289 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4290 | break;
4291 | case FT_UINT_STRING:
4292 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4293 | break;
4294 | case FT_STRINGZPAD:
4295 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4296 | break;
4297 | case FT_STRINGZTRUNC:
4298 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4299 | break;
4300 | default:
4301 | 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)
4302 | 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);
4303 | }
4304 |
4305 | if (retval)
4306 | *retval = value;
4307 |
4308 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4309 |
4310 | 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", 4310 , __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", 4310, "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", 4310, "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", 4310, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4311 |
4312 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4313 |
4314 | proto_tree_set_string(new_fi, (const char*)value);
4315 |
4316 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4317 |
4318 | pi = proto_tree_add_node(tree, new_fi);
4319 |
4320 | switch (hfinfo->type) {
4321 |
4322 | case FT_STRINGZ:
4323 | case FT_STRINGZPAD:
4324 | case FT_STRINGZTRUNC:
4325 | case FT_UINT_STRING:
4326 | break;
4327 |
4328 | case FT_STRING:
4329 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4330 | break;
4331 |
4332 | default:
4333 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4333 , __func__, "assertion \"not reached\" failed");
4334 | }
4335 |
4336 | return pi;
4337 | }
4338 |
4339 | proto_item *
4340 | proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4341 | const unsigned start, int length,
4342 | const unsigned encoding, wmem_allocator_t *scope,
4343 | const uint8_t **retval)
4344 | {
4345 | unsigned item_length; // Param cannot be NULL in function below
4346 | return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4347 | tvb, start, length, encoding, scope, retval, &item_length);
4348 | }
4349 |
4350 | proto_item *
4351 | proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4352 | tvbuff_t *tvb,
4353 | const unsigned start, int length,
4354 | const unsigned encoding,
4355 | wmem_allocator_t *scope,
4356 | char **retval,
4357 | unsigned *lenretval)
4358 | {
4359 | proto_item *pi;
4360 | header_field_info *hfinfo;
4361 | field_info *new_fi;
4362 | const uint8_t *value;
4363 | uint32_t n = 0;
4364 |
4365 | 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", 4365, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4365, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4365, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4366 |
4367 | switch (hfinfo->type) {
4368 | case FT_STRING:
4369 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4370 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4371 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4372 | break;
4373 | case FT_STRINGZ:
4374 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4375 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4376 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4377 | break;
4378 | case FT_UINT_STRING:
4379 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4380 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4381 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4382 | break;
4383 | case FT_STRINGZPAD:
4384 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4385 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4386 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4387 | break;
4388 | case FT_STRINGZTRUNC:
4389 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4390 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4391 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4392 | break;
4393 | case FT_BYTES:
4394 | tvb_ensure_bytes_exist(tvb, start, length);
4395 | value = tvb_get_ptr(tvb, start, length);
4396 | *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4397 | *lenretval = length;
4398 | break;
4399 | case FT_UINT_BYTES:
4400 | n = get_uint_value(tree, tvb, start, length, encoding);
4401 | tvb_ensure_bytes_exist(tvb, start + length, n);
4402 | value = tvb_get_ptr(tvb, start + length, n);
4403 | *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4404 | *lenretval = length + n;
4405 | break;
4406 | default:
4407 | 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)
4408 | 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);
4409 | }
4410 |
4411 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4412 |
4413 | 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", 4413 , __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", 4413, "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", 4413, "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", 4413, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4414 |
4415 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4416 |
4417 | switch (hfinfo->type) {
4418 |
4419 | case FT_STRING:
4420 | case FT_STRINGZ:
4421 | case FT_UINT_STRING:
4422 | case FT_STRINGZPAD:
4423 | case FT_STRINGZTRUNC:
4424 | proto_tree_set_string(new_fi, (const char*)value);
4425 | break;
4426 |
4427 | case FT_BYTES:
4428 | proto_tree_set_bytes(new_fi, value, length);
4429 | break;
4430 |
4431 | case FT_UINT_BYTES:
4432 | proto_tree_set_bytes(new_fi, value, n);
4433 | break;
4434 |
4435 | default:
4436 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4436 , __func__, "assertion \"not reached\" failed");
4437 | }
4438 |
4439 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4440 |
4441 | pi = proto_tree_add_node(tree, new_fi);
4442 |
4443 | switch (hfinfo->type) {
4444 |
4445 | case FT_STRINGZ:
4446 | case FT_STRINGZPAD:
4447 | case FT_STRINGZTRUNC:
4448 | case FT_UINT_STRING:
4449 | break;
4450 |
4451 | case FT_STRING:
4452 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4453 | break;
4454 |
4455 | case FT_BYTES:
4456 | case FT_UINT_BYTES:
4457 | break;
4458 |
4459 | default:
4460 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4460 , __func__, "assertion \"not reached\" failed");
4461 | }
4462 |
4463 | return pi;
4464 | }
4465 |
4466 | proto_item *
4467 | proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4468 | tvbuff_t *tvb,
4469 | const unsigned start, int length,
4470 | const unsigned encoding,
4471 | wmem_allocator_t *scope,
4472 | char **retval)
4473 | {
4474 | unsigned item_length; // Param cannot be NULL in function below
4475 | return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4476 | tvb, start, length, encoding, scope, retval, &item_length);
4477 | }
4478 |
4479 | proto_item *
4480 | proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4481 | tvbuff_t *tvb,
4482 | const unsigned start, int length, const unsigned encoding,
4483 | wmem_allocator_t *scope, char **retval)
4484 | {
4485 | header_field_info *hfinfo;
4486 | field_info *new_fi;
4487 | nstime_t time_stamp;
4488 | int flags;
4489 |
4490 | 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", 4490, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4490, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4490, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4491 |
4492 | switch (hfinfo->type) {
4493 | case FT_ABSOLUTE_TIME:
4494 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4495 | flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4496 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4497 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4498 | }
4499 | *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4500 | break;
4501 | case FT_RELATIVE_TIME:
4502 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4503 | *retval = rel_time_to_secs_str(scope, &time_stamp);
4504 | break;
4505 | default:
4506 | 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)
4507 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME" , hfinfo->abbrev);
4508 | }
4509 |
4510 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4511 |
4512 | 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", 4512 , __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", 4512, "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", 4512, "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", 4512, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4513 |
4514 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4515 |
4516 | switch (hfinfo->type) {
4517 |
4518 | case FT_ABSOLUTE_TIME:
4519 | case FT_RELATIVE_TIME:
4520 | proto_tree_set_time(new_fi, &time_stamp);
4521 | break;
4522 | default:
4523 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4523 , __func__, "assertion \"not reached\" failed");
4524 | }
4525 |
4526 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4527 |
4528 | return proto_tree_add_node(tree, new_fi);
4529 | }
4530 |
4531 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
4532 | and returns proto_item* */
4533 | proto_item *
4534 | ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4535 | const unsigned encoding)
4536 | {
4537 | field_info *new_fi;
4538 | header_field_info *hfinfo;
4539 | int item_length;
4540 | unsigned offset;
4541 |
4542 | offset = ptvc->offset;
4543 | 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", 4543, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4543, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4543, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4544 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4545 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4546 |
4547 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4548 |
4549 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4550 |
4551 | /* Coast clear. Try and fake it */
4552 | 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", 4552 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4552, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4552, "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", 4552, __func__, "Adding %s would put more than %d 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); } } };
4553 |
4554 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4555 |
4556 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4557 | offset, length, encoding);
4558 | }
4559 |
4560 | /* Add an item to a proto_tree, using the text label registered to that item;
4561 | the item is extracted from the tvbuff handed to it. */
4562 | proto_item *
4563 | proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4564 | const unsigned start, int length, const unsigned encoding)
4565 | {
4566 | field_info *new_fi;
4567 | int item_length;
4568 |
4569 | 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", 4569, "hfinfo != ((void*)0)", "Not passed hfi."))));
4570 |
4571 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4572 | test_length(hfinfo, tvb, start, item_length, encoding);
4573 |
4574 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4575 |
4576 | 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", 4576 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4576, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4576, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4576, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4577 |
4578 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4579 |
4580 | return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4581 | }
4582 |
4583 | proto_item *
4584 | proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4585 | const unsigned start, int length, const unsigned encoding)
4586 | {
4587 | register header_field_info *hfinfo;
4588 |
4589 | 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", 4589, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4589, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4589, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4590 | return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4591 | }
4592 |
4593 | /* Add an item to a proto_tree, using the text label registered to that item;
4594 | the item is extracted from the tvbuff handed to it.
4595 |
4596 | Return the length of the item through the pointer. */
4597 | proto_item *
4598 | proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4599 | tvbuff_t *tvb, const unsigned start,
4600 | int length, const unsigned encoding,
4601 | unsigned *lenretval)
4602 | {
4603 | field_info *new_fi;
4604 | int item_length;
4605 | proto_item *item;
4606 |
4607 | 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", 4607, "hfinfo != ((void*)0)", "Not passed hfi."))));
4608 |
4609 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4610 | test_length(hfinfo, tvb, start, item_length, encoding);
4611 |
4612 | if (!tree) {
4613 | /*
4614 | * We need to get the correct item length here.
4615 | * That's normally done by proto_tree_new_item(),
4616 | * but we won't be calling it.
4617 | */
4618 | *lenretval = get_full_length(hfinfo, tvb, start, length,
4619 | item_length, encoding);
4620 | return NULL((void*)0);
4621 | }
4622 |
4623 | 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", 4630 , __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", 4630, "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", 4630, "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", 4630 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4624 | /*((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", 4630 , __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", 4630, "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", 4630, "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", 4630 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4625 | * 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", 4630 , __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", 4630, "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", 4630, "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", 4630 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4626 | * 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", 4630 , __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", 4630, "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", 4630, "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", 4630 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4627 | */((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", 4630 , __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", 4630, "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", 4630, "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", 4630 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4628 | *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", 4630 , __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", 4630, "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", 4630, "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", 4630 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4629 | 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", 4630 , __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", 4630, "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", 4630, "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", 4630 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4630 | })((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", 4630 , __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", 4630, "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", 4630, "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", 4630 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } };
4631 |
4632 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4633 |
4634 | item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4635 | *lenretval = new_fi->length;
4636 | return item;
4637 | }
4638 |
4639 | proto_item *
4640 | proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4641 | const unsigned start, int length,
4642 | const unsigned encoding, unsigned *lenretval)
4643 | {
4644 | register header_field_info *hfinfo;
4645 |
4646 | 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", 4646, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4646, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4646, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4647 | return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4648 | }
4649 |
4650 | /* which FT_ types can use proto_tree_add_bytes_item() */
4651 | static inline bool_Bool
4652 | validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4653 | {
4654 | return (type == FT_BYTES ||
4655 | type == FT_UINT_BYTES ||
4656 | type == FT_OID ||
4657 | type == FT_REL_OID ||
4658 | type == FT_SYSTEM_ID );
4659 | }
4660 |
4661 | /* Note: this does no validation that the byte array of an FT_OID or
4662 | FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4663 | so I think it's ok to continue not validating it?
4664 | */
4665 | proto_item *
4666 | proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4667 | const unsigned start, unsigned length,
4668 | const unsigned encoding,
4669 | GByteArray *retval, unsigned *endoff, int *err)
4670 | {
4671 | field_info *new_fi;
4672 | GByteArray *bytes = retval;
4673 | GByteArray *created_bytes = NULL((void*)0);
4674 | bool_Bool failed = false0;
4675 | uint32_t n = 0;
4676 | header_field_info *hfinfo;
4677 | bool_Bool generate = (bytes || tree) ? true1 : false0;
4678 |
4679 | 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", 4679, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4679, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4679, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4680 |
4681 | 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", 4681, "hfinfo != ((void*)0)", "Not passed hfi."))));
4682 |
4683 | 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", 4684, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))))
4684 | "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", 4684, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))));
4685 |
4686 | if (length == 0) {
4687 | return NULL((void*)0);
4688 | }
4689 |
4690 | if (encoding & ENC_STR_NUM0x01000000) {
4691 | 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" );
4692 | }
4693 |
4694 | if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4695 | if (hfinfo->type == FT_UINT_BYTES) {
4696 | /* can't decode FT_UINT_BYTES from strings */
4697 | 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")
4698 | "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");
4699 | }
4700 |
4701 | unsigned hex_encoding = encoding;
4702 | if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4703 | /* If none of the separator values are used,
4704 | * assume no separator (the common case). */
4705 | hex_encoding |= ENC_SEP_NONE0x00010000;
4706 | #if 0
4707 | 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")
4708 | "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");
4709 | #endif
4710 | }
4711 |
4712 | if (!bytes) {
4713 | /* caller doesn't care about return value, but we need it to
4714 | call tvb_get_string_bytes() and set the tree later */
4715 | bytes = created_bytes = g_byte_array_new();
4716 | }
4717 |
4718 | /*
4719 | * bytes might be NULL after this, but can't add expert
4720 | * error until later; if it's NULL, just note that
4721 | * it failed.
4722 | */
4723 | bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4724 | if (bytes == NULL((void*)0))
4725 | failed = true1;
4726 | }
4727 | else if (generate) {
4728 | tvb_ensure_bytes_exist(tvb, start, length);
4729 |
4730 | if (hfinfo->type == FT_UINT_BYTES) {
4731 | n = length; /* n is now the "header" length */
4732 | length = get_uint_value(tree, tvb, start, n, encoding);
4733 | /* length is now the value's length; only store the value in the array */
4734 | tvb_ensure_bytes_exist(tvb, start + n, length);
4735 | if (!bytes) {
4736 | /* caller doesn't care about return value, but
4737 | * we may need it to set the tree later */
4738 | bytes = created_bytes = g_byte_array_new();
4739 | }
4740 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4741 | }
4742 | else if (length > 0) {
4743 | if (!bytes) {
4744 | /* caller doesn't care about return value, but
4745 | * we may need it to set the tree later */
4746 | bytes = created_bytes = g_byte_array_new();
4747 | }
4748 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4749 | }
4750 |
4751 | if (endoff)
4752 | *endoff = start + n + length;
4753 | }
4754 |
4755 | if (err)
4756 | *err = failed ? EINVAL22 : 0;
4757 |
4758 | 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); }
4759 | {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4760 | 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); }
4761 | 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); }
4762 | 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); }
4763 | bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4764 | } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); };
4765 |
4766 | 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", 4772 , __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", 4772, "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", 4772, "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", 4772 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4767 | {((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", 4772 , __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", 4772, "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", 4772, "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", 4772 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4768 | 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", 4772 , __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", 4772, "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", 4772, "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", 4772 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4769 | 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", 4772 , __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", 4772, "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", 4772, "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", 4772 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4770 | 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", 4772 , __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", 4772, "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", 4772, "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", 4772 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4771 | 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", 4772 , __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", 4772, "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", 4772, "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", 4772 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4772 | } )((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", 4772 , __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", 4772, "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", 4772, "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", 4772 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } };
4773 |
4774 | /* n will be zero except when it's a FT_UINT_BYTES */
4775 | new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4776 |
4777 | if (encoding & ENC_STRING0x07000000) {
4778 | if (failed)
4779 | expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4780 |
4781 | if (bytes)
4782 | proto_tree_set_bytes_gbytearray(new_fi, bytes);
4783 | else
4784 | proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4785 |
4786 | if (created_bytes)
4787 | g_byte_array_free(created_bytes, true1);
4788 | }
4789 | else {
4790 | /* n will be zero except when it's a FT_UINT_BYTES */
4791 | proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4792 |
4793 | /* XXX: If we have a non-NULL tree but NULL retval, we don't
4794 | * use the byte array created above in this case.
4795 | */
4796 | if (created_bytes)
4797 | g_byte_array_free(created_bytes, true1);
4798 |
4799 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4800 | (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);
4801 | }
4802 |
4803 | return proto_tree_add_node(tree, new_fi);
4804 | }
4805 |
4806 |
4807 | proto_item *
4808 | proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4809 | const unsigned start, const unsigned length,
4810 | const unsigned encoding,
4811 | nstime_t *retval, unsigned *endoff, int *err)
4812 | {
4813 | field_info *new_fi;
4814 | nstime_t time_stamp;
4815 | int saved_err = 0;
4816 | header_field_info *hfinfo;
4817 |
4818 | 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", 4818, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4818, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4818, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4819 |
4820 | 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", 4820, "hfinfo != ((void*)0)", "Not passed hfi."))));
4821 |
4822 | if (length == 0) {
4823 | if(retval) {
4824 | nstime_set_zero(retval);
4825 | }
4826 | return NULL((void*)0);
4827 | }
4828 |
4829 | nstime_set_zero(&time_stamp);
4830 |
4831 | if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4832 | 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", 4832, ((hfinfo))->abbrev))));
4833 | /* The only string format that could be a relative time is
4834 | * ENC_ISO_8601_TIME, and that is treated as an absolute time
4835 | * relative to "now" currently.
4836 | */
4837 | if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4838 | saved_err = EINVAL22;
4839 | }
4840 | else {
4841 | 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", 4841, ((hfinfo))->abbrev))));
4842 | const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4843 |
4844 | tvb_ensure_bytes_exist(tvb, start, length);
4845 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4846 | if (endoff) *endoff = start + length;
4847 | }
4848 |
4849 | if (err) *err = saved_err;
4850 |
4851 | if (retval) {
4852 | retval->secs = time_stamp.secs;
4853 | retval->nsecs = time_stamp.nsecs;
4854 | }
4855 |
4856 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4857 |
4858 | 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", 4858 , __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", 4858, "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", 4858, "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", 4858, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4859 |
4860 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4861 |
4862 | proto_tree_set_time(new_fi, &time_stamp);
4863 |
4864 | if (encoding & ENC_STRING0x07000000) {
4865 | if (saved_err)
4866 | expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4867 | }
4868 | else {
4869 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4870 | (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);
4871 | }
4872 |
4873 | return proto_tree_add_node(tree, new_fi);
4874 | }
4875 |
4876 | /* Add a FT_NONE to a proto_tree */
4877 | proto_item *
4878 | proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4879 | const unsigned start, int length, const char *format,
4880 | ...)
4881 | {
4882 | proto_item *pi;
4883 | va_list ap;
4884 | header_field_info *hfinfo;
4885 |
4886 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4887 |
4888 | 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", 4888 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4888, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4888, "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", 4888, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4889 |
4890 | 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", 4890 , ((hfinfo))->abbrev))));
4891 |
4892 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4893 |
4894 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4894, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4895 |
4896 | va_start(ap, format)__builtin_va_start(ap, format);
4897 | proto_tree_set_representation(pi, format, ap);
4898 | va_end(ap)__builtin_va_end(ap);
4899 |
4900 | /* no value to set for FT_NONE */
4901 | return pi;
4902 | }
4903 |
4904 | /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4905 | * offset, and returns proto_item* */
4906 | proto_item *
4907 | ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4908 | const unsigned encoding)
4909 | {
4910 | proto_item *item;
4911 |
4912 | item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4913 | length, encoding);
4914 |
4915 | return item;
4916 | }
4917 |
4918 | /* Advance the ptvcursor's offset within its tvbuff without
4919 | * adding anything to the proto_tree. */
4920 | void
4921 | ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4922 | {
4923 | if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc ->offset))) {
4924 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4925 | }
4926 | }
4927 |
4928 |
4929 | static void
4930 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4931 | {
4932 | ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full( "Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4932, __func__, "assertion failed: %s" , "length >= 0"); } while (0);
4933 | fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4934 | }
4935 |
4936 | /* Add a FT_PROTOCOL to a proto_tree */
4937 | proto_item *
4938 | proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4939 | unsigned start, int length, const char *format, ...)
4940 | {
4941 | proto_item *pi;
4942 | field_info *new_fi;
4943 | tvbuff_t *protocol_tvb;
4944 | va_list ap;
4945 | header_field_info *hfinfo;
4946 | char* protocol_rep;
4947 |
4948 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4949 |
4950 | TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4950 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4950, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4950, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4950, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4951 |
4952 | DISSECTOR_ASSERT_FIELD_TYPE(hfinfo, FT_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" , 4952, ((hfinfo))->abbrev))));
4953 |
4954 | /*
4955 | * This can throw an exception when it calls get_hfi_length before
4956 | * it allocates anything, if length is nonzero and start is past
4957 | * the end of the tvb. Afterwards it can't throw an exception,
4958 | * as length is clamped to the captured length remaining.
4959 | */
4960 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4961 | new_fi = PNODE_FINFO(pi)((pi)->finfo);
4962 | /* Start the protocol_tvb at the correct start offset, but allow it
4963 | * to be lengthened later via finfo_set_len. */
4964 | protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4965 |
4966 | va_start(ap, format)__builtin_va_start(ap, format);
4967 | protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4968 | proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4969 | 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);
4970 | va_end(ap)__builtin_va_end(ap);
4971 |
4972 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4972, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4973 |
4974 | va_start(ap, format)__builtin_va_start(ap, format);
4975 | proto_tree_set_representation(pi, format, ap);
4976 | va_end(ap)__builtin_va_end(ap);
4977 |
4978 | return pi;
4979 | }
4980 |
4981 | /* Add a FT_BYTES to a proto_tree */
4982 | proto_item *
4983 | proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4984 | int length, const uint8_t *start_ptr)
4985 | {
4986 | proto_item *pi;
4987 | header_field_info *hfinfo;
4988 | int item_length;
4989 |
4990 | 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", 4990, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4990, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4990, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4991 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4992 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4993 |
4994 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4995 |
4996 | 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", 4996 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4996, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4996, "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", 4996, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4997 |
4998 | 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", 4998, ((hfinfo))->abbrev))));
4999 |
5000 | if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
5001 | start_ptr = tvb_get_ptr(tvb, start, length);
5002 |
5003 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5004 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
5005 |
5006 | return pi;
5007 | }
5008 |
5009 | /* Add a FT_BYTES to a proto_tree */
5010 | proto_item *
5011 | proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5012 | int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
5013 | {
5014 | proto_item *pi;
5015 | header_field_info *hfinfo;
5016 | int item_length;
5017 |
5018 | 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", 5018, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5018, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5018, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
5019 | get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
5020 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5021 |
5022 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5023 |
5024 | 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", 5024 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5024, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5024, "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", 5024, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5025 |
5026 | 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", 5026, ((hfinfo))->abbrev))));
5027 |
5028 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
5029 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
5030 |
5031 | return pi;
5032 | }
5033 |
5034 | proto_item *
5035 | proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5036 | unsigned start, int length,
5037 | const uint8_t *start_ptr,
5038 | const char *format, ...)
5039 | {
5040 | proto_item *pi;
5041 | va_list ap;
5042 |
5043 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5044 |
5045 | 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; };
5046 |
5047 | va_start(ap, format)__builtin_va_start(ap, format);
5048 | proto_tree_set_representation_value(pi, format, ap);
5049 | va_end(ap)__builtin_va_end(ap);
5050 |
5051 | return pi;
5052 | }
5053 |
5054 | proto_item *
5055 | proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5056 | unsigned start, int length, const uint8_t *start_ptr,
5057 | const char *format, ...)
5058 | {
5059 | proto_item *pi;
5060 | va_list ap;
5061 |
5062 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
5063 |
5064 | 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; };
5065 |
5066 | va_start(ap, format)__builtin_va_start(ap, format);
5067 | proto_tree_set_representation(pi, format, ap);
5068 | va_end(ap)__builtin_va_end(ap);
5069 |
5070 | return pi;
5071 | }
5072 |
5073 | static void
5074 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
5075 | {
5076 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5076, "length >= 0" ))));
5077 | 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", 5077, "start_ptr != ((void*)0) || length == 0" ))));
5078 |
5079 | fvalue_set_bytes_data(fi->value, start_ptr, length);
5080 | }
5081 |
5082 |
5083 | static void
5084 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
5085 | {
5086 | tvb_ensure_bytes_exist(tvb, offset, length);
5087 | proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
5088 | }
5089 |
5090 | static void
5091 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
5092 | {
5093 | GByteArray *bytes;
5094 |
5095 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5095, "value != ((void*)0)" ))));
5096 |
5097 | bytes = byte_array_dup(value);
5098 |
5099 | fvalue_set_byte_array(fi->value, bytes);
5100 | }
5101 |
5102 | /* Add a FT_*TIME to a proto_tree */
5103 | proto_item *
5104 | proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5105 | unsigned length, const nstime_t *value_ptr)
5106 | {
5107 | proto_item *pi;
5108 | header_field_info *hfinfo;
5109 |
5110 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5111 |
5112 | 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", 5112 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5112, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5112, "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", 5112, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5113 |
5114 | 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", 5114, ((hfinfo))->abbrev))));
5115 |
5116 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5117 | proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5118 |
5119 | return pi;
5120 | }
5121 |
5122 | proto_item *
5123 | proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5124 | unsigned start, unsigned length, nstime_t *value_ptr,
5125 | const char *format, ...)
5126 | {
5127 | proto_item *pi;
5128 | va_list ap;
5129 |
5130 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5131 | if (pi != tree) {
5132 | va_start(ap, format)__builtin_va_start(ap, format);
5133 | proto_tree_set_representation_value(pi, format, ap);
5134 | va_end(ap)__builtin_va_end(ap);
5135 | }
5136 |
5137 | return pi;
5138 | }
5139 |
5140 | proto_item *
5141 | proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5142 | unsigned start, unsigned length, nstime_t *value_ptr,
5143 | const char *format, ...)
5144 | {
5145 | proto_item *pi;
5146 | va_list ap;
5147 |
5148 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5149 | if (pi != tree) {
5150 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5150, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5151 |
5152 | va_start(ap, format)__builtin_va_start(ap, format);
5153 | proto_tree_set_representation(pi, format, ap);
5154 | va_end(ap)__builtin_va_end(ap);
5155 | }
5156 |
5157 | return pi;
5158 | }
5159 |
5160 | /* Set the FT_*TIME value */
5161 | static void
5162 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5163 | {
5164 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5164, "value_ptr != ((void*)0)" ))));
5165 |
5166 | fvalue_set_time(fi->value, value_ptr);
5167 | }
5168 |
5169 | /* Add a FT_IPXNET to a proto_tree */
5170 | proto_item *
5171 | proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5172 | unsigned length, uint32_t value)
5173 | {
5174 | proto_item *pi;
5175 | header_field_info *hfinfo;
5176 |
5177 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5178 |
5179 | 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", 5179 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5179, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5179, "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", 5179, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5180 |
5181 | 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" , 5181, ((hfinfo))->abbrev))));
5182 |
5183 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5184 | proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5185 |
5186 | return pi;
5187 | }
5188 |
5189 | proto_item *
5190 | proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5191 | unsigned start, unsigned length, uint32_t value,
5192 | const char *format, ...)
5193 | {
5194 | proto_item *pi;
5195 | va_list ap;
5196 |
5197 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5198 | if (pi != tree) {
5199 | va_start(ap, format)__builtin_va_start(ap, format);
5200 | proto_tree_set_representation_value(pi, format, ap);
5201 | va_end(ap)__builtin_va_end(ap);
5202 | }
5203 |
5204 | return pi;
5205 | }
5206 |
5207 | proto_item *
5208 | proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5209 | unsigned start, unsigned length, uint32_t value,
5210 | const char *format, ...)
5211 | {
5212 | proto_item *pi;
5213 | va_list ap;
5214 |
5215 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5216 | if (pi != tree) {
5217 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5217, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5218 |
5219 | va_start(ap, format)__builtin_va_start(ap, format);
5220 | proto_tree_set_representation(pi, format, ap);
5221 | va_end(ap)__builtin_va_end(ap);
5222 | }
5223 |
5224 | return pi;
5225 | }
5226 |
5227 | /* Set the FT_IPXNET value */
5228 | static void
5229 | proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5230 | {
5231 | fvalue_set_uinteger(fi->value, value);
5232 | }
5233 |
5234 | /* Add a FT_IPv4 to a proto_tree */
5235 | proto_item *
5236 | proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5237 | unsigned length, ws_in4_addr value)
5238 | {
5239 | proto_item *pi;
5240 | header_field_info *hfinfo;
5241 |
5242 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5243 |
5244 | 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", 5244 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5244, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5244, "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", 5244, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5245 |
5246 | 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", 5246 , ((hfinfo))->abbrev))));
5247 |
5248 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5249 | proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5250 |
5251 | return pi;
5252 | }
5253 |
5254 | proto_item *
5255 | proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5256 | unsigned start, unsigned length, ws_in4_addr value,
5257 | const char *format, ...)
5258 | {
5259 | proto_item *pi;
5260 | va_list ap;
5261 |
5262 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5263 | if (pi != tree) {
5264 | va_start(ap, format)__builtin_va_start(ap, format);
5265 | proto_tree_set_representation_value(pi, format, ap);
5266 | va_end(ap)__builtin_va_end(ap);
5267 | }
5268 |
5269 | return pi;
5270 | }
5271 |
5272 | proto_item *
5273 | proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5274 | unsigned start, unsigned length, ws_in4_addr value,
5275 | const char *format, ...)
5276 | {
5277 | proto_item *pi;
5278 | va_list ap;
5279 |
5280 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5281 | if (pi != tree) {
5282 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5282, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5283 |
5284 | va_start(ap, format)__builtin_va_start(ap, format);
5285 | proto_tree_set_representation(pi, format, ap);
5286 | va_end(ap)__builtin_va_end(ap);
5287 | }
5288 |
5289 | return pi;
5290 | }
5291 |
5292 | /* Set the FT_IPv4 value */
5293 | static void
5294 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5295 | {
5296 | ipv4_addr_and_mask ipv4;
5297 | ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5298 | fvalue_set_ipv4(fi->value, &ipv4);
5299 | }
5300 |
5301 | /* Add a FT_IPv6 to a proto_tree */
5302 | proto_item *
5303 | proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5304 | unsigned length, const ws_in6_addr *value)
5305 | {
5306 | proto_item *pi;
5307 | header_field_info *hfinfo;
5308 |
5309 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5310 |
5311 | 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", 5311 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5311, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5311, "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", 5311, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5312 |
5313 | 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", 5313 , ((hfinfo))->abbrev))));
5314 |
5315 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5316 | proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5317 |
5318 | return pi;
5319 | }
5320 |
5321 | proto_item *
5322 | proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5323 | unsigned start, unsigned length,
5324 | const ws_in6_addr *value_ptr,
5325 | const char *format, ...)
5326 | {
5327 | proto_item *pi;
5328 | va_list ap;
5329 |
5330 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5331 | if (pi != tree) {
5332 | va_start(ap, format)__builtin_va_start(ap, format);
5333 | proto_tree_set_representation_value(pi, format, ap);
5334 | va_end(ap)__builtin_va_end(ap);
5335 | }
5336 |
5337 | return pi;
5338 | }
5339 |
5340 | proto_item *
5341 | proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5342 | unsigned start, unsigned length,
5343 | const ws_in6_addr *value_ptr,
5344 | const char *format, ...)
5345 | {
5346 | proto_item *pi;
5347 | va_list ap;
5348 |
5349 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5350 | if (pi != tree) {
5351 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5351, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5352 |
5353 | va_start(ap, format)__builtin_va_start(ap, format);
5354 | proto_tree_set_representation(pi, format, ap);
5355 | va_end(ap)__builtin_va_end(ap);
5356 | }
5357 |
5358 | return pi;
5359 | }
5360 |
5361 | /* Set the FT_IPv6 value */
5362 | static void
5363 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5364 | {
5365 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5365, "value != ((void*)0)" ))));
5366 | ipv6_addr_and_prefix ipv6;
5367 | ipv6.addr = *value;
5368 | ipv6.prefix = 128;
5369 | fvalue_set_ipv6(fi->value, &ipv6);
5370 | }
5371 |
5372 | static void
5373 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5374 | {
5375 | proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5376 | }
5377 |
5378 | /* Set the FT_FCWWN value */
5379 | static void
5380 | proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5381 | {
5382 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5382, "value_ptr != ((void*)0)" ))));
5383 | fvalue_set_fcwwn(fi->value, value_ptr);
5384 | }
5385 |
5386 | static void
5387 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5388 | {
5389 | proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5390 | }
5391 |
5392 | /* Add a FT_GUID to a proto_tree */
5393 | proto_item *
5394 | proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5395 | unsigned length, const e_guid_t *value_ptr)
5396 | {
5397 | proto_item *pi;
5398 | header_field_info *hfinfo;
5399 |
5400 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5401 |
5402 | 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", 5402 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5402, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5402, "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", 5402, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5403 |
5404 | 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", 5404 , ((hfinfo))->abbrev))));
5405 |
5406 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5407 | proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5408 |
5409 | return pi;
5410 | }
5411 |
5412 | proto_item *
5413 | proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5414 | unsigned start, unsigned length,
5415 | const e_guid_t *value_ptr,
5416 | const char *format, ...)
5417 | {
5418 | proto_item *pi;
5419 | va_list ap;
5420 |
5421 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5422 | if (pi != tree) {
5423 | va_start(ap, format)__builtin_va_start(ap, format);
5424 | proto_tree_set_representation_value(pi, format, ap);
5425 | va_end(ap)__builtin_va_end(ap);
5426 | }
5427 |
5428 | return pi;
5429 | }
5430 |
5431 | proto_item *
5432 | proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5433 | unsigned start, unsigned length, const e_guid_t *value_ptr,
5434 | const char *format, ...)
5435 | {
5436 | proto_item *pi;
5437 | va_list ap;
5438 |
5439 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5440 | if (pi != tree) {
5441 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5441, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5442 |
5443 | va_start(ap, format)__builtin_va_start(ap, format);
5444 | proto_tree_set_representation(pi, format, ap);
5445 | va_end(ap)__builtin_va_end(ap);
5446 | }
5447 |
5448 | return pi;
5449 | }
5450 |
5451 | /* Set the FT_GUID value */
5452 | static void
5453 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5454 | {
5455 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5455, "value_ptr != ((void*)0)" ))));
5456 | fvalue_set_guid(fi->value, value_ptr);
5457 | }
5458 |
5459 | static void
5460 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5461 | const unsigned encoding)
5462 | {
5463 | e_guid_t guid;
5464 |
5465 | tvb_get_guid(tvb, start, &guid, encoding);
5466 | proto_tree_set_guid(fi, &guid);
5467 | }
5468 |
5469 | /* Add a FT_OID to a proto_tree */
5470 | proto_item *
5471 | proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5472 | unsigned length, const uint8_t* value_ptr)
5473 | {
5474 | proto_item *pi;
5475 | header_field_info *hfinfo;
5476 |
5477 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5478 |
5479 | 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", 5479 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5479, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5479, "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", 5479, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5480 |
5481 | 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", 5481 , ((hfinfo))->abbrev))));
5482 |
5483 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5484 | proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5485 |
5486 | return pi;
5487 | }
5488 |
5489 | proto_item *
5490 | proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5491 | unsigned start, unsigned length,
5492 | const uint8_t* value_ptr,
5493 | const char *format, ...)
5494 | {
5495 | proto_item *pi;
5496 | va_list ap;
5497 |
5498 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5499 | if (pi != tree) {
5500 | va_start(ap, format)__builtin_va_start(ap, format);
5501 | proto_tree_set_representation_value(pi, format, ap);
5502 | va_end(ap)__builtin_va_end(ap);
5503 | }
5504 |
5505 | return pi;
5506 | }
5507 |
5508 | proto_item *
5509 | proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5510 | unsigned start, unsigned length, const uint8_t* value_ptr,
5511 | const char *format, ...)
5512 | {
5513 | proto_item *pi;
5514 | va_list ap;
5515 |
5516 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5517 | if (pi != tree) {
5518 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5518, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5519 |
5520 | va_start(ap, format)__builtin_va_start(ap, format);
5521 | proto_tree_set_representation(pi, format, ap);
5522 | va_end(ap)__builtin_va_end(ap);
5523 | }
5524 |
5525 | return pi;
5526 | }
5527 |
5528 | /* Set the FT_OID value */
5529 | static void
5530 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5531 | {
5532 | GByteArray *bytes;
5533 |
5534 | 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", 5534, "value_ptr != ((void*)0) || length == 0" ))));
5535 |
5536 | bytes = g_byte_array_new();
5537 | if (length > 0) {
5538 | g_byte_array_append(bytes, value_ptr, length);
5539 | }
5540 | fvalue_set_byte_array(fi->value, bytes);
5541 | }
5542 |
5543 | static void
5544 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5545 | {
5546 | proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5547 | }
5548 |
5549 | /* Set the FT_SYSTEM_ID value */
5550 | static void
5551 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5552 | {
5553 | GByteArray *bytes;
5554 |
5555 | 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", 5555, "value_ptr != ((void*)0) || length == 0" ))));
5556 |
5557 | bytes = g_byte_array_new();
5558 | if (length > 0) {
5559 | g_byte_array_append(bytes, value_ptr, length);
5560 | }
5561 | fvalue_set_byte_array(fi->value, bytes);
5562 | }
5563 |
5564 | static void
5565 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5566 | {
5567 | proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5568 | }
5569 |
5570 | /* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5571 | * proto_tree. Creates own copy of string, and frees it when the proto_tree
5572 | * is destroyed. */
5573 | proto_item *
5574 | proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5575 | int length, const char* value)
5576 | {
5577 | proto_item *pi;
5578 | header_field_info *hfinfo;
5579 | int item_length;
5580 |
5581 | 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", 5581, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5581, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5581, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
5582 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5583 | /*
5584 | * Special case - if the length is 0, skip the test, so that
5585 | * we can have an empty string right after the end of the
5586 | * packet. (This handles URL-encoded forms where the last field
5587 | * has no value so the form ends right after the =.)
5588 | *
5589 | * XXX - length zero makes sense for FT_STRING, and more or less
5590 | * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5591 | * for FT_STRINGZ (except that a number of fields that should be
5592 | * one of the others are actually registered as FT_STRINGZ.)
5593 | */
5594 | if (item_length != 0)
5595 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5596 |
5597 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5598 |
5599 | 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", 5599 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5599, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5599, "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", 5599, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5600 |
5601 | 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", 5601, ((hfinfo))->abbrev))));
5602 |
5603 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5604 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5604, "length >= 0" ))));
5605 |
5606 | 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", 5606, __func__, value, -1, __uni_endptr); } } while (0); } } while (0);
5607 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5608 |
5609 | return pi;
5610 | }
5611 |
5612 | proto_item *
5613 | proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5614 | unsigned start, int length, const char* value,
5615 | const char *format,
5616 | ...)
5617 | {
5618 | proto_item *pi;
5619 | va_list ap;
5620 |
5621 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5622 | if (pi != tree) {
5623 | va_start(ap, format)__builtin_va_start(ap, format);
5624 | proto_tree_set_representation_value(pi, format, ap);
5625 | va_end(ap)__builtin_va_end(ap);
5626 | }
5627 |
5628 | return pi;
5629 | }
5630 |
5631 | proto_item *
5632 | proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5633 | unsigned start, int length, const char* value,
5634 | const char *format, ...)
5635 | {
5636 | proto_item *pi;
5637 | va_list ap;
5638 |
5639 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5640 | if (pi != tree) {
5641 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5641, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5642 |
5643 | va_start(ap, format)__builtin_va_start(ap, format);
5644 | proto_tree_set_representation(pi, format, ap);
5645 | va_end(ap)__builtin_va_end(ap);
5646 | }
5647 |
5648 | return pi;
5649 | }
5650 |
5651 | /* Set the FT_STRING value */
5652 | static void
5653 | proto_tree_set_string(field_info *fi, const char* value)
5654 | {
5655 | if (value) {
5656 | fvalue_set_string(fi->value, value);
5657 | } else {
5658 | /*
5659 | * XXX - why is a null value for a string field
5660 | * considered valid?
5661 | */
5662 | fvalue_set_string(fi->value, "[ Null ]");
5663 | }
5664 | }
5665 |
5666 | /* Set the FT_AX25 value */
5667 | static void
5668 | proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5669 | {
5670 | fvalue_set_ax25(fi->value, value);
5671 | }
5672 |
5673 | static void
5674 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5675 | {
5676 | proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5677 | }
5678 |
5679 | /* Set the FT_VINES value */
5680 | static void
5681 | proto_tree_set_vines(field_info *fi, const uint8_t* value)
5682 | {
5683 | fvalue_set_vines(fi->value, value);
5684 | }
5685 |
5686 | static void
5687 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5688 | {
5689 | proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5690 | }
5691 |
5692 | /* Add a FT_ETHER to a proto_tree */
5693 | proto_item *
5694 | proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5695 | unsigned length, const uint8_t* value)
5696 | {
5697 | proto_item *pi;
5698 | header_field_info *hfinfo;
5699 |
5700 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5701 |
5702 | 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", 5702 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5702, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5702, "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", 5702, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5703 |
5704 | 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", 5704, ((hfinfo))->abbrev))));
5705 |
5706 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5707 | proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5708 |
5709 | return pi;
5710 | }
5711 |
5712 | proto_item *
5713 | proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5714 | unsigned start, unsigned length, const uint8_t* value,
5715 | const char *format, ...)
5716 | {
5717 | proto_item *pi;
5718 | va_list ap;
5719 |
5720 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5721 | if (pi != tree) {
5722 | va_start(ap, format)__builtin_va_start(ap, format);
5723 | proto_tree_set_representation_value(pi, format, ap);
5724 | va_end(ap)__builtin_va_end(ap);
5725 | }
5726 |
5727 | return pi;
5728 | }
5729 |
5730 | proto_item *
5731 | proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5732 | unsigned start, unsigned length, const uint8_t* value,
5733 | const char *format, ...)
5734 | {
5735 | proto_item *pi;
5736 | va_list ap;
5737 |
5738 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5739 | if (pi != tree) {
5740 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5740, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5741 |
5742 | va_start(ap, format)__builtin_va_start(ap, format);
5743 | proto_tree_set_representation(pi, format, ap);
5744 | va_end(ap)__builtin_va_end(ap);
5745 | }
5746 |
5747 | return pi;
5748 | }
5749 |
5750 | /* Set the FT_ETHER value */
5751 | static void
5752 | proto_tree_set_ether(field_info *fi, const uint8_t* value)
5753 | {
5754 | fvalue_set_ether(fi->value, value);
5755 | }
5756 |
5757 | static void
5758 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5759 | {
5760 | proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5761 | }
5762 |
5763 | /* Add a FT_BOOLEAN to a proto_tree */
5764 | proto_item *
5765 | proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5766 | unsigned length, uint64_t value)
5767 | {
5768 | proto_item *pi;
5769 | header_field_info *hfinfo;
5770 |
5771 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5772 |
5773 | 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", 5773 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5773, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5773, "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", 5773, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5774 |
5775 | 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" , 5775, ((hfinfo))->abbrev))));
5776 |
5777 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5778 | proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5779 |
5780 | return pi;
5781 | }
5782 |
5783 | proto_item *
5784 | proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5785 | tvbuff_t *tvb, unsigned start, unsigned length,
5786 | uint64_t value, const char *format, ...)
5787 | {
5788 | proto_item *pi;
5789 | va_list ap;
5790 |
5791 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5792 | if (pi != tree) {
5793 | va_start(ap, format)__builtin_va_start(ap, format);
5794 | proto_tree_set_representation_value(pi, format, ap);
5795 | va_end(ap)__builtin_va_end(ap);
5796 | }
5797 |
5798 | return pi;
5799 | }
5800 |
5801 | proto_item *
5802 | proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5803 | unsigned start, unsigned length, uint64_t value,
5804 | const char *format, ...)
5805 | {
5806 | proto_item *pi;
5807 | va_list ap;
5808 |
5809 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5810 | if (pi != tree) {
5811 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5811, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5812 |
5813 | va_start(ap, format)__builtin_va_start(ap, format);
5814 | proto_tree_set_representation(pi, format, ap);
5815 | va_end(ap)__builtin_va_end(ap);
5816 | }
5817 |
5818 | return pi;
5819 | }
5820 |
5821 | /* Set the FT_BOOLEAN value */
5822 | static void
5823 | proto_tree_set_boolean(field_info *fi, uint64_t value)
5824 | {
5825 | proto_tree_set_uint64(fi, value);
5826 | }
5827 |
5828 | /* Generate, into "buf", a string showing the bits of a bitfield.
5829 | Return a pointer to the character after that string. */
5830 | static char *
5831 | other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5832 | {
5833 | int i = 0;
5834 | uint64_t bit;
5835 | char *p;
5836 |
5837 | p = buf;
5838 |
5839 | /* This is a devel error. It is safer to stop here. */
5840 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5840, "width >= 1" ))));
5841 |
5842 | bit = UINT64_C(1)1UL << (width - 1);
5843 | for (;;) {
5844 | if (mask & bit) {
5845 | /* This bit is part of the field. Show its value. */
5846 | if (val & bit)
5847 | *p++ = '1';
5848 | else
5849 | *p++ = '0';
5850 | } else {
5851 | /* This bit is not part of the field. */
5852 | *p++ = '.';
5853 | }
5854 | bit >>= 1;
5855 | i++;
5856 | if (i >= width)
5857 | break;
5858 | if (i % 4 == 0)
5859 | *p++ = ' ';
5860 | }
5861 | *p = '\0';
5862 | return p;
5863 | }
5864 |
5865 | static char *
5866 | decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5867 | {
5868 | char *p;
5869 |
5870 | p = other_decode_bitfield_value(buf, val, mask, width);
5871 | p = g_stpcpy(p, " = ");
5872 |
5873 | return p;
5874 | }
5875 |
5876 | static char *
5877 | other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5878 | {
5879 | int i = 0;
5880 | uint64_t bit;
5881 | char *p;
5882 |
5883 | p = buf;
5884 |
5885 | /* This is a devel error. It is safer to stop here. */
5886 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5886, "width >= 1" ))));
5887 |
5888 | bit = UINT64_C(1)1UL << (width - 1);
5889 | for (;;) {
5890 | if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5891 | (mask & bit)) {
5892 | /* This bit is part of the field. Show its value. */
5893 | if (val & bit)
5894 | *p++ = '1';
5895 | else
5896 | *p++ = '0';
5897 | } else {
5898 | /* This bit is not part of the field. */
5899 | *p++ = '.';
5900 | }
5901 | bit >>= 1;
5902 | i++;
5903 | if (i >= width)
5904 | break;
5905 | if (i % 4 == 0)
5906 | *p++ = ' ';
5907 | }
5908 |
5909 | *p = '\0';
5910 | return p;
5911 | }
5912 |
5913 | static char *
5914 | decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5915 | {
5916 | char *p;
5917 |
5918 | p = other_decode_bitfield_varint_value(buf, val, mask, width);
5919 | p = g_stpcpy(p, " = ");
5920 |
5921 | return p;
5922 | }
5923 |
5924 | /* Add a FT_FLOAT to a proto_tree */
5925 | proto_item *
5926 | proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5927 | unsigned length, float value)
5928 | {
5929 | proto_item *pi;
5930 | header_field_info *hfinfo;
5931 |
5932 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5933 |
5934 | 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", 5934 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5934, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5934, "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", 5934, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5935 |
5936 | 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", 5936, ((hfinfo))->abbrev))));
5937 |
5938 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5939 | proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5940 |
5941 | return pi;
5942 | }
5943 |
5944 | proto_item *
5945 | proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5946 | unsigned start, unsigned length, float value,
5947 | const char *format, ...)
5948 | {
5949 | proto_item *pi;
5950 | va_list ap;
5951 |
5952 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5953 | if (pi != tree) {
5954 | va_start(ap, format)__builtin_va_start(ap, format);
5955 | proto_tree_set_representation_value(pi, format, ap);
5956 | va_end(ap)__builtin_va_end(ap);
5957 | }
5958 |
5959 | return pi;
5960 | }
5961 |
5962 | proto_item *
5963 | proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5964 | unsigned start, unsigned length, float value,
5965 | const char *format, ...)
5966 | {
5967 | proto_item *pi;
5968 | va_list ap;
5969 |
5970 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5971 | if (pi != tree) {
5972 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5972, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5973 |
5974 | va_start(ap, format)__builtin_va_start(ap, format);
5975 | proto_tree_set_representation(pi, format, ap);
5976 | va_end(ap)__builtin_va_end(ap);
5977 | }
5978 |
5979 | return pi;
5980 | }
5981 |
5982 | /* Set the FT_FLOAT value */
5983 | static void
5984 | proto_tree_set_float(field_info *fi, float value)
5985 | {
5986 | fvalue_set_floating(fi->value, value);
5987 | }
5988 |
5989 | /* Add a FT_DOUBLE to a proto_tree */
5990 | proto_item *
5991 | proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5992 | unsigned length, double value)
5993 | {
5994 | proto_item *pi;
5995 | header_field_info *hfinfo;
5996 |
5997 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5998 |
5999 | 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", 5999 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5999, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5999, "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", 5999, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6000 |
6001 | 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" , 6001, ((hfinfo))->abbrev))));
6002 |
6003 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6004 | proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
6005 |
6006 | return pi;
6007 | }
6008 |
6009 | proto_item *
6010 | proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6011 | unsigned start, unsigned length, double value,
6012 | const char *format, ...)
6013 | {
6014 | proto_item *pi;
6015 | va_list ap;
6016 |
6017 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6018 | if (pi != tree) {
6019 | va_start(ap, format)__builtin_va_start(ap, format);
6020 | proto_tree_set_representation_value(pi, format, ap);
6021 | va_end(ap)__builtin_va_end(ap);
6022 | }
6023 |
6024 | return pi;
6025 | }
6026 |
6027 | proto_item *
6028 | proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6029 | unsigned start, unsigned length, double value,
6030 | const char *format, ...)
6031 | {
6032 | proto_item *pi;
6033 | va_list ap;
6034 |
6035 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
6036 | if (pi != tree) {
6037 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6037, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6038 |
6039 | va_start(ap, format)__builtin_va_start(ap, format);
6040 | proto_tree_set_representation(pi, format, ap);
6041 | va_end(ap)__builtin_va_end(ap);
6042 | }
6043 |
6044 | return pi;
6045 | }
6046 |
6047 | /* Set the FT_DOUBLE value */
6048 | static void
6049 | proto_tree_set_double(field_info *fi, double value)
6050 | {
6051 | fvalue_set_floating(fi->value, value);
6052 | }
6053 |
6054 | /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
6055 | proto_item *
6056 | proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6057 | unsigned length, uint32_t value)
6058 | {
6059 | proto_item *pi = NULL((void*)0);
6060 | header_field_info *hfinfo;
6061 |
6062 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6063 |
6064 | 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", 6064 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6064, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6064, "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", 6064, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6065 |
6066 | switch (hfinfo->type) {
6067 | case FT_CHAR:
6068 | case FT_UINT8:
6069 | case FT_UINT16:
6070 | case FT_UINT24:
6071 | case FT_UINT32:
6072 | case FT_FRAMENUM:
6073 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6074 | proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
6075 | break;
6076 |
6077 | default:
6078 | 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)
6079 | 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);
6080 | }
6081 |
6082 | return pi;
6083 | }
6084 |
6085 | proto_item *
6086 | proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6087 | unsigned start, unsigned length, uint32_t value,
6088 | const char *format, ...)
6089 | {
6090 | proto_item *pi;
6091 | va_list ap;
6092 |
6093 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6094 | if (pi != tree) {
6095 | va_start(ap, format)__builtin_va_start(ap, format);
6096 | proto_tree_set_representation_value(pi, format, ap);
6097 | va_end(ap)__builtin_va_end(ap);
6098 | }
6099 |
6100 | return pi;
6101 | }
6102 |
6103 | proto_item *
6104 | proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6105 | unsigned start, unsigned length, uint32_t value,
6106 | const char *format, ...)
6107 | {
6108 | proto_item *pi;
6109 | va_list ap;
6110 |
6111 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6112 | if (pi != tree) {
6113 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6113, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6114 |
6115 | va_start(ap, format)__builtin_va_start(ap, format);
6116 | proto_tree_set_representation(pi, format, ap);
6117 | va_end(ap)__builtin_va_end(ap);
6118 | }
6119 |
6120 | return pi;
6121 | }
6122 |
6123 | /* Set the FT_UINT{8,16,24,32} value */
6124 | static void
6125 | proto_tree_set_uint(field_info *fi, uint32_t value)
6126 | {
6127 | const header_field_info *hfinfo;
6128 | uint32_t integer;
6129 |
6130 | hfinfo = fi->hfinfo;
6131 | integer = value;
6132 |
6133 | if (hfinfo->bitmask) {
6134 | /* Mask out irrelevant portions */
6135 | integer &= (uint32_t)(hfinfo->bitmask);
6136 |
6137 | /* Shift bits */
6138 | integer >>= hfinfo_bitshift(hfinfo);
6139 |
6140 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6141 | 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);
6142 | }
6143 |
6144 | fvalue_set_uinteger(fi->value, integer);
6145 | }
6146 |
6147 | /* Add FT_UINT{40,48,56,64} to a proto_tree */
6148 | proto_item *
6149 | proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6150 | unsigned length, uint64_t value)
6151 | {
6152 | proto_item *pi = NULL((void*)0);
6153 | header_field_info *hfinfo;
6154 |
6155 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6156 |
6157 | 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", 6157 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6157, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6157, "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", 6157, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6158 |
6159 | switch (hfinfo->type) {
6160 | case FT_UINT40:
6161 | case FT_UINT48:
6162 | case FT_UINT56:
6163 | case FT_UINT64:
6164 | case FT_FRAMENUM:
6165 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6166 | proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6167 | break;
6168 |
6169 | default:
6170 | 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)
6171 | 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);
6172 | }
6173 |
6174 | return pi;
6175 | }
6176 |
6177 | proto_item *
6178 | proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6179 | unsigned start, unsigned length, uint64_t value,
6180 | const char *format, ...)
6181 | {
6182 | proto_item *pi;
6183 | va_list ap;
6184 |
6185 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6186 | if (pi != tree) {
6187 | va_start(ap, format)__builtin_va_start(ap, format);
6188 | proto_tree_set_representation_value(pi, format, ap);
6189 | va_end(ap)__builtin_va_end(ap);
6190 | }
6191 |
6192 | return pi;
6193 | }
6194 |
6195 | proto_item *
6196 | proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6197 | unsigned start, unsigned length, uint64_t value,
6198 | const char *format, ...)
6199 | {
6200 | proto_item *pi;
6201 | va_list ap;
6202 |
6203 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6204 | if (pi != tree) {
6205 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6205, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6206 |
6207 | va_start(ap, format)__builtin_va_start(ap, format);
6208 | proto_tree_set_representation(pi, format, ap);
6209 | va_end(ap)__builtin_va_end(ap);
6210 | }
6211 |
6212 | return pi;
6213 | }
6214 |
6215 | /* Set the FT_UINT{40,48,56,64} value */
6216 | static void
6217 | proto_tree_set_uint64(field_info *fi, uint64_t value)
6218 | {
6219 | const header_field_info *hfinfo;
6220 | uint64_t integer;
6221 |
6222 | hfinfo = fi->hfinfo;
6223 | integer = value;
6224 |
6225 | if (hfinfo->bitmask) {
6226 | /* Mask out irrelevant portions */
6227 | integer &= hfinfo->bitmask;
6228 |
6229 | /* Shift bits */
6230 | integer >>= hfinfo_bitshift(hfinfo);
6231 |
6232 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6233 | 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);
6234 | }
6235 |
6236 | fvalue_set_uinteger64(fi->value, integer);
6237 | }
6238 |
6239 | /* Add FT_INT{8,16,24,32} to a proto_tree */
6240 | proto_item *
6241 | proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6242 | unsigned length, int32_t value)
6243 | {
6244 | proto_item *pi = NULL((void*)0);
6245 | header_field_info *hfinfo;
6246 |
6247 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6248 |
6249 | 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", 6249 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6249, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6249, "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", 6249, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6250 |
6251 | switch (hfinfo->type) {
6252 | case FT_INT8:
6253 | case FT_INT16:
6254 | case FT_INT24:
6255 | case FT_INT32:
6256 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6257 | proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6258 | break;
6259 |
6260 | default:
6261 | 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)
6262 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
6263 | }
6264 |
6265 | return pi;
6266 | }
6267 |
6268 | proto_item *
6269 | proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6270 | unsigned start, unsigned length, int32_t value,
6271 | const char *format, ...)
6272 | {
6273 | proto_item *pi;
6274 | va_list ap;
6275 |
6276 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6277 | if (pi != tree) {
6278 | va_start(ap, format)__builtin_va_start(ap, format);
6279 | proto_tree_set_representation_value(pi, format, ap);
6280 | va_end(ap)__builtin_va_end(ap);
6281 | }
6282 |
6283 | return pi;
6284 | }
6285 |
6286 | proto_item *
6287 | proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6288 | unsigned start, unsigned length, int32_t value,
6289 | const char *format, ...)
6290 | {
6291 | proto_item *pi;
6292 | va_list ap;
6293 |
6294 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6295 | if (pi != tree) {
6296 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6296, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6297 |
6298 | va_start(ap, format)__builtin_va_start(ap, format);
6299 | proto_tree_set_representation(pi, format, ap);
6300 | va_end(ap)__builtin_va_end(ap);
6301 | }
6302 |
6303 | return pi;
6304 | }
6305 |
6306 | /* Set the FT_INT{8,16,24,32} value */
6307 | static void
6308 | proto_tree_set_int(field_info *fi, int32_t value)
6309 | {
6310 | const header_field_info *hfinfo;
6311 | uint32_t integer;
6312 | int no_of_bits;
6313 |
6314 | hfinfo = fi->hfinfo;
6315 | integer = (uint32_t) value;
6316 |
6317 | if (hfinfo->bitmask) {
6318 | /* Mask out irrelevant portions */
6319 | integer &= (uint32_t)(hfinfo->bitmask);
6320 |
6321 | /* Shift bits */
6322 | integer >>= hfinfo_bitshift(hfinfo);
6323 |
6324 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6325 | integer = ws_sign_ext32(integer, no_of_bits);
6326 |
6327 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6328 | 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);
6329 | }
6330 |
6331 | fvalue_set_sinteger(fi->value, integer);
6332 | }
6333 |
6334 | /* Add FT_INT{40,48,56,64} to a proto_tree */
6335 | proto_item *
6336 | proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6337 | unsigned length, int64_t value)
6338 | {
6339 | proto_item *pi = NULL((void*)0);
6340 | header_field_info *hfinfo;
6341 |
6342 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6343 |
6344 | 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", 6344 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6344, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6344, "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", 6344, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6345 |
6346 | switch (hfinfo->type) {
6347 | case FT_INT40:
6348 | case FT_INT48:
6349 | case FT_INT56:
6350 | case FT_INT64:
6351 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6352 | proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6353 | break;
6354 |
6355 | default:
6356 | 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)
6357 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
6358 | }
6359 |
6360 | return pi;
6361 | }
6362 |
6363 | proto_item *
6364 | proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6365 | unsigned start, unsigned length, int64_t value,
6366 | const char *format, ...)
6367 | {
6368 | proto_item *pi;
6369 | va_list ap;
6370 |
6371 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6372 | if (pi != tree) {
6373 | va_start(ap, format)__builtin_va_start(ap, format);
6374 | proto_tree_set_representation_value(pi, format, ap);
6375 | va_end(ap)__builtin_va_end(ap);
6376 | }
6377 |
6378 | return pi;
6379 | }
6380 |
6381 | /* Set the FT_INT{40,48,56,64} value */
6382 | static void
6383 | proto_tree_set_int64(field_info *fi, int64_t value)
6384 | {
6385 | const header_field_info *hfinfo;
6386 | uint64_t integer;
6387 | int no_of_bits;
6388 |
6389 | hfinfo = fi->hfinfo;
6390 | integer = value;
6391 |
6392 | if (hfinfo->bitmask) {
6393 | /* Mask out irrelevant portions */
6394 | integer &= hfinfo->bitmask;
6395 |
6396 | /* Shift bits */
6397 | integer >>= hfinfo_bitshift(hfinfo);
6398 |
6399 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6400 | integer = ws_sign_ext64(integer, no_of_bits);
6401 |
6402 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6403 | 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);
6404 | }
6405 |
6406 | fvalue_set_sinteger64(fi->value, integer);
6407 | }
6408 |
6409 | proto_item *
6410 | proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6411 | unsigned start, unsigned length, int64_t value,
6412 | const char *format, ...)
6413 | {
6414 | proto_item *pi;
6415 | va_list ap;
6416 |
6417 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6418 | if (pi != tree) {
6419 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6419, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6420 |
6421 | va_start(ap, format)__builtin_va_start(ap, format);
6422 | proto_tree_set_representation(pi, format, ap);
6423 | va_end(ap)__builtin_va_end(ap);
6424 | }
6425 |
6426 | return pi;
6427 | }
6428 |
6429 | /* Add a FT_EUI64 to a proto_tree */
6430 | proto_item *
6431 | proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6432 | unsigned length, const uint64_t value)
6433 | {
6434 | proto_item *pi;
6435 | header_field_info *hfinfo;
6436 |
6437 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6438 |
6439 | 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", 6439 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6439, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6439, "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", 6439, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6440 |
6441 | 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", 6441, ((hfinfo))->abbrev))));
6442 |
6443 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6444 | proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6445 |
6446 | return pi;
6447 | }
6448 |
6449 | proto_item *
6450 | proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6451 | unsigned start, unsigned length, const uint64_t value,
6452 | const char *format, ...)
6453 | {
6454 | proto_item *pi;
6455 | va_list ap;
6456 |
6457 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6458 | if (pi != tree) {
6459 | va_start(ap, format)__builtin_va_start(ap, format);
6460 | proto_tree_set_representation_value(pi, format, ap);
6461 | va_end(ap)__builtin_va_end(ap);
6462 | }
6463 |
6464 | return pi;
6465 | }
6466 |
6467 | proto_item *
6468 | proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6469 | unsigned start, unsigned length, const uint64_t value,
6470 | const char *format, ...)
6471 | {
6472 | proto_item *pi;
6473 | va_list ap;
6474 |
6475 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6476 | if (pi != tree) {
6477 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6477, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6478 |
6479 | va_start(ap, format)__builtin_va_start(ap, format);
6480 | proto_tree_set_representation(pi, format, ap);
6481 | va_end(ap)__builtin_va_end(ap);
6482 | }
6483 |
6484 | return pi;
6485 | }
6486 |
6487 | /* Set the FT_EUI64 value */
6488 | static void
6489 | proto_tree_set_eui64(field_info *fi, const uint64_t value)
6490 | {
6491 | uint8_t v[FT_EUI64_LEN8];
6492 | phtonu64(v, value);
6493 | fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6494 | }
6495 |
6496 | static void
6497 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6498 | {
6499 | if (encoding)
6500 | {
6501 | proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6502 | } else {
6503 | proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6504 | }
6505 | }
6506 |
6507 | proto_item *
6508 | proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6509 | const mac_hf_list_t *list_generic,
6510 | int idx, tvbuff_t *tvb,
6511 | proto_tree *tree, unsigned offset)
6512 | {
6513 | uint8_t addr[6];
6514 | const char *addr_name = NULL((void*)0);
6515 | const char *oui_name = NULL((void*)0);
6516 | proto_item *addr_item = NULL((void*)0);
6517 | proto_tree *addr_tree = NULL((void*)0);
6518 | proto_item *ret_val = NULL((void*)0);
6519 |
6520 | if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6521 | return NULL((void*)0);
6522 | }
6523 |
6524 | /* Resolve what we can of the address */
6525 | tvb_memcpy(tvb, addr, offset, sizeof addr);
6526 | if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6527 | addr_name = get_ether_name(addr);
6528 | }
6529 | if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6530 | oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6531 | }
6532 |
6533 | /* Add the item for the specific address type */
6534 | ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6535 | if (idx >= 0) {
6536 | addr_tree = proto_item_add_subtree(ret_val, idx);
6537 | }
6538 | else {
6539 | addr_tree = tree;
6540 | }
6541 |
6542 | if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6543 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6544 | tvb, offset, 6, addr_name);
6545 | proto_item_set_generated(addr_item);
6546 | proto_item_set_hidden(addr_item);
6547 | }
6548 |
6549 | if (list_specific->hf_oui != NULL((void*)0)) {
6550 | addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6551 | proto_item_set_generated(addr_item);
6552 | proto_item_set_hidden(addr_item);
6553 |
6554 | if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6555 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6556 | proto_item_set_generated(addr_item);
6557 | proto_item_set_hidden(addr_item);
6558 | }
6559 | }
6560 |
6561 | if (list_specific->hf_lg != NULL((void*)0)) {
6562 | proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6563 | }
6564 | if (list_specific->hf_ig != NULL((void*)0)) {
6565 | proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6566 | }
6567 |
6568 | /* Were we given a list for generic address fields? If not, stop here */
6569 | if (list_generic == NULL((void*)0)) {
6570 | return ret_val;
6571 | }
6572 |
6573 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6574 | proto_item_set_hidden(addr_item);
6575 |
6576 | if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6577 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6578 | tvb, offset, 6, addr_name);
6579 | proto_item_set_generated(addr_item);
6580 | proto_item_set_hidden(addr_item);
6581 | }
6582 |
6583 | if (list_generic->hf_oui != NULL((void*)0)) {
6584 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6585 | proto_item_set_generated(addr_item);
6586 | proto_item_set_hidden(addr_item);
6587 |
6588 | if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6589 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6590 | proto_item_set_generated(addr_item);
6591 | proto_item_set_hidden(addr_item);
6592 | }
6593 | }
6594 |
6595 | if (list_generic->hf_lg != NULL((void*)0)) {
6596 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6597 | proto_item_set_hidden(addr_item);
6598 | }
6599 | if (list_generic->hf_ig != NULL((void*)0)) {
6600 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6601 | proto_item_set_hidden(addr_item);
6602 | }
6603 | return ret_val;
6604 | }
6605 |
6606 | static proto_item *
6607 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6608 | {
6609 | proto_node *pnode, *tnode, *sibling;
6610 | field_info *tfi;
6611 | unsigned depth = 1;
6612 |
6613 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6613, __func__, "assertion failed: %s", "tree" ); } while (0);
6614 |
6615 | /*
6616 | * Restrict our depth. proto_tree_traverse_pre_order and
6617 | * proto_tree_traverse_post_order (and possibly others) are recursive
6618 | * so we need to be mindful of our stack size.
6619 | */
6620 | if (tree->first_child == NULL((void*)0)) {
6621 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6622 | depth++;
6623 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6624 | 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__)), 6627)))
6625 | "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__)), 6627)))
6626 | 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__)), 6627)))
6627 | 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__)), 6627)));
6628 | }
6629 | }
6630 | }
6631 |
6632 | /*
6633 | * Make sure "tree" is ready to have subtrees under it, by
6634 | * checking whether it's been given an ett_ value.
6635 | *
6636 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6637 | * node of the protocol tree. That node is not displayed,
6638 | * so it doesn't need an ett_ value to remember whether it
6639 | * was expanded.
6640 | */
6641 | tnode = tree;
6642 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6643 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6644 | 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" , 6645)
6645 | 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" , 6645);
6646 | /* XXX - is it safe to continue here? */
6647 | }
6648 |
6649 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6650 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6651 | pnode->parent = tnode;
6652 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6653 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6654 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6655 |
6656 | if (tnode->last_child != NULL((void*)0)) {
6657 | sibling = tnode->last_child;
6658 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6658, "sibling->next == ((void*)0)" ))));
6659 | sibling->next = pnode;
6660 | } else
6661 | tnode->first_child = pnode;
6662 | tnode->last_child = pnode;
6663 |
6664 | /* We should not be adding a fake node for an interesting field */
6665 | 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", 6665, __func__, "assertion failed: %s" , "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT" ); } while (0);
6666 |
6667 | /* XXX - Should the proto_item have a header_field_info member, at least
6668 | * for faked items, to know what hfi was faked? (Some dissectors look at
6669 | * the tree items directly.)
6670 | */
6671 | return (proto_item *)pnode;
6672 | }
6673 |
6674 | /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6675 | static proto_item *
6676 | proto_tree_add_node(proto_tree *tree, field_info *fi)
6677 | {
6678 | proto_node *pnode, *tnode, *sibling;
6679 | field_info *tfi;
6680 | unsigned depth = 1;
6681 |
6682 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6682, __func__, "assertion failed: %s", "tree" ); } while (0);
6683 |
6684 | /*
6685 | * Restrict our depth. proto_tree_traverse_pre_order and
6686 | * proto_tree_traverse_post_order (and possibly others) are recursive
6687 | * so we need to be mindful of our stack size.
6688 | */
6689 | if (tree->first_child == NULL((void*)0)) {
6690 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6691 | depth++;
6692 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6693 | /* The fvalue_t is pool-allocated; just release the
6694 | * type-specific data it owns (see new_field_info()). */
6695 | fvalue_cleanup(fi->value);
6696 | fi->value = NULL((void*)0);
6697 | 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__)), 6700)))
6698 | "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__)), 6700)))
6699 | 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__)), 6700)))
6700 | 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__)), 6700)));
6701 | }
6702 | }
6703 | }
6704 |
6705 | /*
6706 | * Make sure "tree" is ready to have subtrees under it, by
6707 | * checking whether it's been given an ett_ value.
6708 | *
6709 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6710 | * node of the protocol tree. That node is not displayed,
6711 | * so it doesn't need an ett_ value to remember whether it
6712 | * was expanded.
6713 | */
6714 | tnode = tree;
6715 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6716 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6717 | /* Since we are not adding fi to a node, its fvalue won't get
6718 | * cleaned up by proto_tree_free_node(), so release the
6719 | * type-specific data it owns now. The fvalue_t structure itself
6720 | * is pool-allocated (see new_field_info()).
6721 | */
6722 | fvalue_cleanup(fi->value);
6723 | fi->value = NULL((void*)0);
6724 | 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", 6725)
6725 | 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", 6725);
6726 | /* XXX - is it safe to continue here? */
6727 | }
6728 |
6729 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6730 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6731 | pnode->parent = tnode;
6732 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6733 | PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6734 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6735 |
6736 | if (tnode->last_child != NULL((void*)0)) {
6737 | sibling = tnode->last_child;
6738 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6738, "sibling->next == ((void*)0)" ))));
6739 | sibling->next = pnode;
6740 | } else
6741 | tnode->first_child = pnode;
6742 | tnode->last_child = pnode;
6743 |
6744 | tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6745 |
6746 | return (proto_item *)pnode;
6747 | }
6748 |
6749 |
6750 | /* Generic way to allocate field_info and add to proto_tree.
6751 | * Sets *pfi to address of newly-allocated field_info struct */
6752 | static proto_item *
6753 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6754 | int *length)
6755 | {
6756 | proto_item *pi;
6757 | field_info *fi;
6758 | int item_length;
6759 |
6760 | get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6761 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6762 | pi = proto_tree_add_node(tree, fi);
6763 |
6764 | return pi;
6765 | }
6766 |
6767 | /* Generic way to allocate field_info and add to proto_tree with unsigned length.
6768 | * Eventually this should replace the other function.
6769 | * Sets *pfi to address of newly-allocated field_info struct */
6770 | static proto_item *
6771 | proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6772 | unsigned *length)
6773 | {
6774 | proto_item *pi;
6775 | field_info *fi;
6776 | unsigned item_length;
6777 |
6778 | get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6779 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6780 | pi = proto_tree_add_node(tree, fi);
6781 |
6782 | return pi;
6783 | }
6784 |
6785 | static void
6786 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6787 | int *item_length, const unsigned encoding)
6788 | {
6789 | int length_remaining;
6790 |
6791 | /*
6792 | * We only allow a null tvbuff if the item has a zero length,
6793 | * i.e. if there's no data backing it.
6794 | */
6795 | 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", 6795, "tvb != ((void*)0) || *length == 0" ))));
6796 |
6797 | /*
6798 | * XXX - in some protocols, there are 32-bit unsigned length
6799 | * fields, so lengths in protocol tree and tvbuff routines
6800 | * should really be unsigned. We should have, for those
6801 | * field types for which "to the end of the tvbuff" makes sense,
6802 | * additional routines that take no length argument and
6803 | * add fields that run to the end of the tvbuff.
6804 | */
6805 | if (*length == -1) {
6806 | /*
6807 | * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6808 | * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6809 | * of -1 means "set the length to what remains in the
6810 | * tvbuff".
6811 | *
6812 | * The assumption is either that
6813 | *
6814 | * 1) the length of the item can only be determined
6815 | * by dissection (typically true of items with
6816 | * subitems, which are probably FT_NONE or
6817 | * FT_PROTOCOL)
6818 | *
6819 | * or
6820 | *
6821 | * 2) if the tvbuff is "short" (either due to a short
6822 | * snapshot length or due to lack of reassembly of
6823 | * fragments/segments/whatever), we want to display
6824 | * what's available in the field (probably FT_BYTES
6825 | * or FT_STRING) and then throw an exception later
6826 | *
6827 | * or
6828 | *
6829 | * 3) the field is defined to be "what's left in the
6830 | * packet"
6831 | *
6832 | * so we set the length to what remains in the tvbuff so
6833 | * that, if we throw an exception while dissecting, it
6834 | * has what is probably the right value.
6835 | *
6836 | * For FT_STRINGZ, it means "the string is null-terminated,
6837 | * not null-padded; set the length to the actual length
6838 | * of the string", and if the tvbuff if short, we just
6839 | * throw an exception.
6840 | *
6841 | * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6842 | * it means "find the end of the string",
6843 | * and if the tvbuff if short, we just throw an exception.
6844 | *
6845 | * It's not valid for any other type of field. For those
6846 | * fields, we treat -1 the same way we treat other
6847 | * negative values - we assume the length is a Really
6848 | * Big Positive Number, and throw a ReportedBoundsError
6849 | * exception, under the assumption that the Really Big
6850 | * Length would run past the end of the packet.
6851 | */
6852 | 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 )))) {
6853 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6854 | /*
6855 | * Leave the length as -1, so our caller knows
6856 | * it was -1.
6857 | */
6858 | *item_length = *length;
6859 | return;
6860 | } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6861 | switch (tvb_get_uint8(tvb, start) >> 6)
6862 | {
6863 | case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6864 | *item_length = 1;
6865 | break;
6866 | case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6867 | *item_length = 2;
6868 | break;
6869 | case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6870 | *item_length = 4;
6871 | break;
6872 | case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6873 | *item_length = 8;
6874 | break;
6875 | }
6876 | }
6877 | }
6878 |
6879 | switch (hfinfo->type) {
6880 |
6881 | case FT_PROTOCOL:
6882 | case FT_NONE:
6883 | case FT_BYTES:
6884 | case FT_STRING:
6885 | case FT_STRINGZPAD:
6886 | case FT_STRINGZTRUNC:
6887 | /*
6888 | * We allow FT_PROTOCOLs to be zero-length -
6889 | * for example, an ONC RPC NULL procedure has
6890 | * neither arguments nor reply, so the
6891 | * payload for that protocol is empty.
6892 | *
6893 | * We also allow the others to be zero-length -
6894 | * because that's the way the code has been for a
6895 | * long, long time.
6896 | *
6897 | * However, we want to ensure that the start
6898 | * offset is not *past* the byte past the end
6899 | * of the tvbuff: we throw an exception in that
6900 | * case.
6901 | */
6902 | *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6903 | DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6903, "*length >= 0" ))));
6904 | break;
6905 |
6906 | case FT_STRINGZ:
6907 | /*
6908 | * Leave the length as -1, so our caller knows
6909 | * it was -1.
6910 | */
6911 | break;
6912 |
6913 | default:
6914 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6915 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 6915));
6916 | }
6917 | *item_length = *length;
6918 | } else {
6919 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6920 | /*
6921 | * These types are for interior nodes of the
6922 | * tree, and don't have data associated with
6923 | * them; if the length is negative (XXX - see
6924 | * above) or goes past the end of the tvbuff,
6925 | * cut it short at the end of the tvbuff.
6926 | * That way, if this field is selected in
6927 | * Wireshark, we don't highlight stuff past
6928 | * the end of the data.
6929 | *
6930 | * If we don't have a tvb, then length must be zero,
6931 | * per the DISSECTOR_ASSERT() above.
6932 | *
6933 | * If we do have a tvb, and the length requested is
6934 | * nonzero, we want to ensure that the start offset
6935 | * is not *past* the byte past the end of the tvbuff
6936 | * data: we throw an exception in that case as above.
6937 | */
6938 | if (tvb && *length) {
6939 | length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6940 | if (*length < 0 ||
6941 | (*length > 0 &&
6942 | (length_remaining < *length)))
6943 | *length = length_remaining;
6944 | }
6945 | }
6946 | *item_length = *length;
6947 | if (*item_length < 0) {
6948 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6949 | }
6950 | }
6951 | }
6952 |
6953 | static void
6954 | get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6955 | unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6956 | {
6957 | unsigned length_remaining;
6958 |
6959 | /*
6960 | * We only allow a null tvbuff if the item has a zero length,
6961 | * i.e. if there's no data backing it.
6962 | */
6963 | 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", 6963, "tvb != ((void*)0) || *length == 0" ))));
6964 |
6965 |
6966 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6967 | /*
6968 | * These types are for interior nodes of the
6969 | * tree, and don't have data associated with
6970 | * them; if the length is negative (XXX - see
6971 | * above) or goes past the end of the tvbuff,
6972 | * cut it short at the end of the tvbuff.
6973 | * That way, if this field is selected in
6974 | * Wireshark, we don't highlight stuff past
6975 | * the end of the data.
6976 | *
6977 | * If we don't have a tvb, then length must be zero,
6978 | * per the DISSECTOR_ASSERT() above.
6979 | *
6980 | * If we do have a tvb, and the length requested is
6981 | * nonzero, we want to ensure that the start offset
6982 | * is not *past* the byte past the end of the tvbuff
6983 | * data: we throw an exception in that case as above.
6984 | * (If the length requested is zero, then it's quite
6985 | * likely that the start offset is the byte past the
6986 | * end, but that's ok.)
6987 | */
6988 | if (tvb && *length) {
6989 | length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6990 | if (length_remaining < *length) {
6991 | *length = length_remaining;
6992 | }
6993 | }
6994 | }
6995 | *item_length = *length;
6996 | }
6997 |
6998 | static int
6999 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
7000 | int length, unsigned item_length, const int encoding)
7001 | {
7002 | uint32_t n;
7003 |
7004 | /*
7005 | * We need to get the correct item length here.
7006 | * That's normally done by proto_tree_new_item(),
7007 | * but we won't be calling it.
7008 | */
7009 | switch (hfinfo->type) {
7010 |
7011 | case FT_NONE:
7012 | case FT_PROTOCOL:
7013 | case FT_BYTES:
7014 | /*
7015 | * The length is the specified length.
7016 | */
7017 | break;
7018 |
7019 | case FT_UINT_BYTES:
7020 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
7021 | item_length += n;
7022 | if ((int)item_length < length) {
7023 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7024 | }
7025 | break;
7026 |
7027 | /* XXX - make these just FT_UINT? */
7028 | case FT_UINT8:
7029 | case FT_UINT16:
7030 | case FT_UINT24:
7031 | case FT_UINT32:
7032 | case FT_UINT40:
7033 | case FT_UINT48:
7034 | case FT_UINT56:
7035 | case FT_UINT64:
7036 | /* XXX - make these just FT_INT? */
7037 | case FT_INT8:
7038 | case FT_INT16:
7039 | case FT_INT24:
7040 | case FT_INT32:
7041 | case FT_INT40:
7042 | case FT_INT48:
7043 | case FT_INT56:
7044 | case FT_INT64:
7045 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
7046 | if (length < -1) {
7047 | report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
7048 | }
7049 | if (length == -1) {
7050 | uint64_t dummy;
7051 | /* This can throw an exception */
7052 | /* XXX - do this without fetching the varint? */
7053 | length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
7054 | if (length == 0) {
7055 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7056 | }
7057 | }
7058 | item_length = length;
7059 | break;
7060 | }
7061 |
7062 | /*
7063 | * The length is the specified length.
7064 | */
7065 | break;
7066 |
7067 | case FT_BOOLEAN:
7068 | case FT_CHAR:
7069 | case FT_IPv4:
7070 | case FT_IPXNET:
7071 | case FT_IPv6:
7072 | case FT_FCWWN:
7073 | case FT_AX25:
7074 | case FT_VINES:
7075 | case FT_ETHER:
7076 | case FT_EUI64:
7077 | case FT_GUID:
7078 | case FT_OID:
7079 | case FT_REL_OID:
7080 | case FT_SYSTEM_ID:
7081 | case FT_FLOAT:
7082 | case FT_DOUBLE:
7083 | case FT_STRING:
7084 | /*
7085 | * The length is the specified length.
7086 | */
7087 | break;
7088 |
7089 | case FT_STRINGZ:
7090 | if (length < -1) {
7091 | report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
7092 | }
7093 | if (length == -1) {
7094 | /* This can throw an exception */
7095 | item_length = tvb_strsize_enc(tvb, start, encoding);
7096 | }
7097 | break;
7098 |
7099 | case FT_UINT_STRING:
7100 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
7101 | item_length += n;
7102 | if ((int)item_length < length) {
7103 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7104 | }
7105 | break;
7106 |
7107 | case FT_STRINGZPAD:
7108 | case FT_STRINGZTRUNC:
7109 | case FT_ABSOLUTE_TIME:
7110 | case FT_RELATIVE_TIME:
7111 | case FT_IEEE_11073_SFLOAT:
7112 | case FT_IEEE_11073_FLOAT:
7113 | /*
7114 | * The length is the specified length.
7115 | */
7116 | break;
7117 |
7118 | default:
7119 | 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 ))
7120 | 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 ))
7121 | 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 ))
7122 | 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 ));
7123 | break;
7124 | }
7125 | return item_length;
7126 | }
7127 |
7128 | // This was arbitrarily chosen, but if you're adding 50K items to the tree
7129 | // without advancing the offset you should probably take a long, hard look
7130 | // at what you're doing.
7131 | // We *could* make this a configurable option, but I (Gerald) would like to
7132 | // avoid adding yet another nerd knob.
7133 | # define PROTO_TREE_MAX_IDLE50000 50000
7134 | static field_info *
7135 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7136 | const unsigned start, const int item_length)
7137 | {
7138 | field_info *fi;
7139 |
7140 | FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo ->pool)), sizeof(field_info)));
7141 |
7142 | fi->hfinfo = hfinfo;
7143 | fi->start = start;
7144 | fi->start += (tvb)?tvb_raw_offset(tvb):0;
7145 | /* add the data source tvbuff */
7146 | fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7147 |
7148 | // If our start offset hasn't advanced after adding many items it probably
7149 | // means we're in a large or infinite loop.
7150 | if (fi->start > 0) {
7151 | if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7152 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7153 | if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7154 | if (wireshark_abort_on_too_many_items) {
7155 | 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", 7156 , __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)
7156 | hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7156 , __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000);
7157 | }
7158 | /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7159 | * but if not, we should hit the max item error earlier,
7160 | * so we shouldn't need to reset the tree count to
7161 | * ensure that the exception handler can add the item. */
7162 | 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)))
7163 | 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)))
7164 | "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)))
7165 | 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)));
7166 | }
7167 | } else {
7168 | PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7169 | PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7170 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7171 | }
7172 | }
7173 | fi->length = item_length;
7174 | fi->tree_type = -1;
7175 | fi->flags = 0;
7176 | if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7177 | /* If the tree is not visible, set the item hidden, unless we
7178 | * need the representation or length and can't fake them.
7179 | */
7180 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7181 | FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); } while(0);
7182 | }
7183 | }
7184 | fi->value = fvalue_new_pool(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), fi->hfinfo->type);
7185 | fi->rep = NULL((void*)0);
7186 |
7187 | fi->appendix_start = 0;
7188 | fi->appendix_length = 0;
7189 |
7190 | fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7191 | fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7192 |
7193 | return fi;
7194 | }
7195 |
7196 | static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7197 | {
7198 | if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7199 | return 0;
7200 | }
7201 |
7202 | /* Search for field name */
7203 | char *ptr = strstr(representation, hfinfo->name);
7204 | if (!ptr) {
7205 | return 0;
7206 | }
7207 |
7208 | /* Check if field name ends with the ": " delimiter */
7209 | ptr += strlen(hfinfo->name);
7210 | if (strncmp(ptr, ": ", 2) == 0) {
7211 | ptr += 2;
7212 | }
7213 |
7214 | /* Return offset to after field name */
7215 | return ptr - representation;
7216 | }
7217 |
7218 | static size_t label_find_name_pos(const item_label_t *rep)
7219 | {
7220 | size_t name_pos = 0;
7221 |
7222 | /* If the value_pos is too small or too large, we can't find the expected format */
7223 | if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7224 | return 0;
7225 | }
7226 |
7227 | /* Check if the format looks like "label: value", then set name_pos before ':'. */
7228 | if (rep->representation[rep->value_pos-2] == ':') {
7229 | name_pos = rep->value_pos - 2;
7230 | }
7231 |
7232 | return name_pos;
7233 | }
7234 |
7235 | /* If the protocol tree is to be visible, set the representation of a
7236 | proto_tree entry with the name of the field for the item and with
7237 | the value formatted with the supplied printf-style format and
7238 | argument list. */
7239 | static void
7240 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7241 | {
7242 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 7242, __func__, "assertion failed: %s", "pi" ); } while (0);
7243 |
7244 | /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7245 | * items string representation */
7246 | if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7247 | size_t name_pos, ret = 0;
7248 | char *str;
7249 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7250 | const header_field_info *hf;
7251 |
7252 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7252, "fi"))));
7253 |
7254 | hf = fi->hfinfo;
7255 |
7256 | 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;;
7257 | 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)))) {
7258 | uint64_t val;
7259 | char *p;
7260 |
7261 | 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))
7262 | val = fvalue_get_uinteger(fi->value);
7263 | else
7264 | val = fvalue_get_uinteger64(fi->value);
7265 |
7266 | val <<= hfinfo_bitshift(hf);
7267 |
7268 | p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7269 | ret = (p - fi->rep->representation);
7270 | }
7271 |
7272 | /* put in the hf name */
7273 | 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);
7274 |
7275 | ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const uint8_t*)": ", 0);
7276 | /* If possible, Put in the value of the string */
7277 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7278 | 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" , 7278, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7279 | fi->rep->value_pos = ret;
7280 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7281 | if (ret >= ITEM_LABEL_LENGTH240) {
7282 | /* Uh oh, we don't have enough room. Tell the user
7283 | * that the field is truncated.
7284 | */
7285 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7286 | }
7287 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7288 | }
7289 | }
7290 |
7291 | /* If the protocol tree is to be visible, set the representation of a
7292 | proto_tree entry with the representation formatted with the supplied
7293 | printf-style format and argument list. */
7294 | static void
7295 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7296 | {
7297 | size_t ret; /*tmp return value */
7298 | char *str;
7299 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7300 |
7301 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7301, "fi"))));
7302 |
7303 | if (!proto_item_is_hidden(pi)) {
7304 | 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;;
7305 |
7306 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7307 | 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" , 7307, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7308 | fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7309 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7310 | if (ret >= ITEM_LABEL_LENGTH240) {
7311 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7312 | size_t name_pos = label_find_name_pos(fi->rep);
7313 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7314 | }
7315 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7316 | }
7317 | }
7318 |
7319 | static int
7320 | proto_strlcpy(char *dest, const char *src, size_t dest_size)
7321 | {
7322 | if (dest_size == 0) return 0;
7323 |
7324 | size_t res = g_strlcpy(dest, src, dest_size);
7325 |
7326 | /* At most dest_size - 1 characters will be copied
7327 | * (unless dest_size is 0). */
7328 | if (res >= dest_size)
7329 | res = dest_size - 1;
7330 | return (int) res;
7331 | }
7332 |
7333 | static header_field_info *
7334 | hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7335 | {
7336 | header_field_info *dup_hfinfo;
7337 |
7338 | if (hfinfo->same_name_prev_id == -1)
7339 | return NULL((void*)0);
7340 | 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", 7340 , __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", 7340, "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", 7340, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf.")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo ->same_name_prev_id];;
7341 | return dup_hfinfo;
7342 | }
7343 |
7344 | static void
7345 | hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7346 | {
7347 | 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);
7348 | last_field_name = NULL((void*)0);
7349 |
7350 | if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7351 | /* No hfinfo with the same name */
7352 | wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7353 | return;
7354 | }
7355 |
7356 | if (hfinfo->same_name_next) {
7357 | hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7358 | }
7359 |
7360 | if (hfinfo->same_name_prev_id != -1) {
7361 | header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7362 | same_name_prev->same_name_next = hfinfo->same_name_next;
7363 | if (!hfinfo->same_name_next) {
7364 | /* It's always the latest added hfinfo which is stored in gpa_name_map */
7365 | wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7366 | }
7367 | }
7368 | }
7369 |
7370 | int
7371 | proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7372 | {
7373 | const header_field_info *hfinfo = finfo->hfinfo;
7374 | int label_len = 0;
7375 | char *tmp_str;
7376 | const char *str;
7377 | const uint8_t *bytes;
7378 | uint32_t number;
7379 | uint64_t number64;
7380 | const char *hf_str_val;
7381 | char number_buf[NUMBER_LABEL_LENGTH80];
7382 | const char *number_out;
7383 | address addr;
7384 | const ipv4_addr_and_mask *ipv4;
7385 | const ipv6_addr_and_prefix *ipv6;
7386 |
7387 | switch (hfinfo->type) {
7388 |
7389 | case FT_NONE:
7390 | case FT_PROTOCOL:
7391 | return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7392 |
7393 | case FT_UINT_BYTES:
7394 | case FT_BYTES:
7395 | tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7396 | hfinfo,
7397 | fvalue_get_bytes_data(finfo->value),
7398 | (unsigned)fvalue_length2(finfo->value),
7399 | label_str_size);
7400 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7401 | wmem_free(NULL((void*)0), tmp_str);
7402 | break;
7403 |
7404 | case FT_ABSOLUTE_TIME:
7405 | {
7406 | const nstime_t *value = fvalue_get_time(finfo->value);
7407 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7408 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7409 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7410 | }
7411 | if (hfinfo->strings) {
7412 | const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7413 | if (time_string != NULL((void*)0)) {
7414 | label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7415 | break;
7416 | }
7417 | }
7418 | tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7419 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7420 | wmem_free(NULL((void*)0), tmp_str);
7421 | break;
7422 | }
7423 |
7424 | case FT_RELATIVE_TIME:
7425 | tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7426 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7427 | wmem_free(NULL((void*)0), tmp_str);
7428 | break;
7429 |
7430 | case FT_BOOLEAN:
7431 | number64 = fvalue_get_uinteger64(finfo->value);
7432 | label_len = proto_strlcpy(display_label_str,
7433 | tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7434 | break;
7435 |
7436 | case FT_CHAR:
7437 | number = fvalue_get_uinteger(finfo->value);
7438 |
7439 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7440 | char tmp[ITEM_LABEL_LENGTH240];
7441 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7442 |
7443 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7443, "fmtfunc"))));
7444 | fmtfunc(tmp, number);
7445 |
7446 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7447 |
7448 | } else if (hfinfo->strings) {
7449 | number_out = hf_try_val_to_str(number, hfinfo);
7450 |
7451 | if (!number_out) {
7452 | number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7453 | }
7454 |
7455 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7456 |
7457 | } else {
7458 | number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7459 |
7460 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7461 | }
7462 |
7463 | break;
7464 |
7465 | /* XXX - make these just FT_NUMBER? */
7466 | case FT_INT8:
7467 | case FT_INT16:
7468 | case FT_INT24:
7469 | case FT_INT32:
7470 | case FT_UINT8:
7471 | case FT_UINT16:
7472 | case FT_UINT24:
7473 | case FT_UINT32:
7474 | case FT_FRAMENUM:
7475 | hf_str_val = NULL((void*)0);
7476 | 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 )) ?
7477 | (uint32_t) fvalue_get_sinteger(finfo->value) :
7478 | fvalue_get_uinteger(finfo->value);
7479 |
7480 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7481 | char tmp[ITEM_LABEL_LENGTH240];
7482 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7483 |
7484 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7484, "fmtfunc"))));
7485 | fmtfunc(tmp, number);
7486 |
7487 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7488 |
7489 | } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7490 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7491 | number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7492 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7493 | hf_str_val = hf_try_val_to_str(number, hfinfo);
7494 | if (hf_str_val)
7495 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7496 | } else {
7497 | number_out = hf_try_val_to_str(number, hfinfo);
7498 |
7499 | if (!number_out) {
7500 | number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7501 | }
7502 |
7503 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7504 | }
7505 | } else {
7506 | number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7507 |
7508 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7509 | }
7510 |
7511 | break;
7512 |
7513 | case FT_INT40:
7514 | case FT_INT48:
7515 | case FT_INT56:
7516 | case FT_INT64:
7517 | case FT_UINT40:
7518 | case FT_UINT48:
7519 | case FT_UINT56:
7520 | case FT_UINT64:
7521 | hf_str_val = NULL((void*)0);
7522 | 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 )) ?
7523 | (uint64_t) fvalue_get_sinteger64(finfo->value) :
7524 | fvalue_get_uinteger64(finfo->value);
7525 |
7526 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7527 | char tmp[ITEM_LABEL_LENGTH240];
7528 | custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7529 |
7530 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 7530, "fmtfunc64" ))));
7531 | fmtfunc64(tmp, number64);
7532 |
7533 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7534 | } else if (hfinfo->strings) {
7535 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7536 | number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7537 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7538 | hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7539 | if (hf_str_val)
7540 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7541 | } else {
7542 | number_out = hf_try_val64_to_str(number64, hfinfo);
7543 |
7544 | if (!number_out)
7545 | number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7546 |
7547 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7548 | }
7549 | } else {
7550 | number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7551 |
7552 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7553 | }
7554 |
7555 | break;
7556 |
7557 | case FT_EUI64:
7558 | set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7559 | tmp_str = address_to_display(NULL((void*)0), &addr);
7560 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7561 | wmem_free(NULL((void*)0), tmp_str);
7562 | break;
7563 |
7564 | case FT_IPv4:
7565 | ipv4 = fvalue_get_ipv4(finfo->value);
7566 | //XXX: Should we ignore the mask?
7567 | set_address_ipv4(&addr, ipv4);
7568 | tmp_str = address_to_display(NULL((void*)0), &addr);
7569 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7570 | wmem_free(NULL((void*)0), tmp_str);
7571 | free_address(&addr);
7572 | break;
7573 |
7574 | case FT_IPv6:
7575 | ipv6 = fvalue_get_ipv6(finfo->value);
7576 | set_address_ipv6(&addr, ipv6);
7577 | tmp_str = address_to_display(NULL((void*)0), &addr);
7578 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7579 | wmem_free(NULL((void*)0), tmp_str);
7580 | free_address(&addr);
7581 | break;
7582 |
7583 | case FT_FCWWN:
7584 | set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7585 | tmp_str = address_to_display(NULL((void*)0), &addr);
7586 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7587 | wmem_free(NULL((void*)0), tmp_str);
7588 | break;
7589 |
7590 | case FT_ETHER:
7591 | set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7592 | tmp_str = address_to_display(NULL((void*)0), &addr);
7593 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7594 | wmem_free(NULL((void*)0), tmp_str);
7595 | break;
7596 |
7597 | case FT_GUID:
7598 | tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7599 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7600 | wmem_free(NULL((void*)0), tmp_str);
7601 | break;
7602 |
7603 | case FT_REL_OID:
7604 | bytes = fvalue_get_bytes_data(finfo->value);
7605 | tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7606 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7607 | wmem_free(NULL((void*)0), tmp_str);
7608 | break;
7609 |
7610 | case FT_OID:
7611 | bytes = fvalue_get_bytes_data(finfo->value);
7612 | tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7613 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7614 | wmem_free(NULL((void*)0), tmp_str);
7615 | break;
7616 |
7617 | case FT_SYSTEM_ID:
7618 | bytes = fvalue_get_bytes_data(finfo->value);
7619 | tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7620 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7621 | wmem_free(NULL((void*)0), tmp_str);
7622 | break;
7623 |
7624 | case FT_FLOAT:
7625 | case FT_DOUBLE:
7626 | label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7627 | break;
7628 |
7629 | case FT_IEEE_11073_SFLOAT:
7630 | case FT_IEEE_11073_FLOAT:
7631 | label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7632 | break;
7633 |
7634 | case FT_STRING:
7635 | case FT_STRINGZ:
7636 | case FT_UINT_STRING:
7637 | case FT_STRINGZPAD:
7638 | case FT_STRINGZTRUNC:
7639 | str = fvalue_get_string(finfo->value);
7640 | label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7641 | if (label_len >= label_str_size) {
7642 | /* Truncation occurred. Get the real length
7643 | * copied (not including '\0') */
7644 | label_len = label_str_size ? label_str_size - 1 : 0;
7645 | }
7646 | break;
7647 |
7648 | default:
7649 | /* First try ftype string representation */
7650 | tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7651 | if (!tmp_str) {
7652 | /* Default to show as bytes */
7653 | bytes = fvalue_get_bytes_data(finfo->value);
7654 | tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo-> value), 36);
7655 | }
7656 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7657 | wmem_free(NULL((void*)0), tmp_str);
7658 | break;
7659 | }
7660 | return label_len;
7661 | }
7662 |
7663 | const char *
7664 | proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7665 | char *result, char *expr, const int size)
7666 | {
7667 | int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7668 | GPtrArray *finfos;
7669 | field_info *finfo = NULL((void*)0);
7670 | header_field_info* hfinfo;
7671 | const char *abbrev = NULL((void*)0);
7672 |
7673 | char *str;
7674 | col_custom_t *field_idx;
7675 | int field_id;
7676 | int ii = 0;
7677 |
7678 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7678, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7679 | while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7680 | field_id = field_idx->field_id;
7681 | if (field_id == 0) {
7682 | GPtrArray *fvals = NULL((void*)0);
7683 | bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7684 | if (fvals != NULL((void*)0)) {
7685 |
7686 | // XXX - Handling occurrences is unusual when more
7687 | // than one field is involved, e.g. there's four
7688 | // results for tcp.port + tcp.port. We may really
7689 | // want to apply it to the operands, not the output.
7690 | // Note that occurrences are not quite the same as
7691 | // the layer operator (should the grammar support
7692 | // both?)
7693 | /* Calculate single index or set outer boundaries */
7694 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7695 | if (occurrence < 0) {
7696 | i = occurrence + len;
7697 | last = i;
7698 | } else if (occurrence > 0) {
7699 | i = occurrence - 1;
7700 | last = i;
7701 | } else {
7702 | i = 0;
7703 | last = len - 1;
7704 | }
7705 | if (i < 0 || i >= len) {
7706 | g_ptr_array_unref(fvals);
7707 | continue;
7708 | }
7709 | for (; i <= last; i++) {
7710 | /* XXX - We could have a "resolved" result
7711 | * for types where the value depends only
7712 | * on the type, e.g. FT_IPv4, and not on
7713 | * hfinfo->strings. Supporting the latter
7714 | * requires knowing which hfinfo matched
7715 | * if there are multiple with the same
7716 | * abbreviation. In any case, we need to
7717 | * know the expected return type of the
7718 | * field expression.
7719 | */
7720 | str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7721 | if (offset_r && (offset_r < (size - 1)))
7722 | result[offset_r++] = ',';
7723 | if (offset_e && (offset_e < (size - 1)))
7724 | expr[offset_e++] = ',';
7725 | offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7726 | // col_{add,append,set}_* calls ws_label_strcpy
7727 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7728 |
7729 | g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized (str, __builtin_object_size ((str), 0)) : (g_free) (str);
7730 | }
7731 | g_ptr_array_unref(fvals);
7732 | } else if (passed) {
7733 | // XXX - Occurrence doesn't make sense for a test
7734 | // output, it should be applied to the operands.
7735 | if (offset_r && (offset_r < (size - 1)))
7736 | result[offset_r++] = ',';
7737 | if (offset_e && (offset_e < (size - 1)))
7738 | expr[offset_e++] = ',';
7739 | /* Prevent multiple check marks */
7740 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7741 | offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7742 | } else {
7743 | result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7744 | }
7745 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7746 | offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7747 | } else {
7748 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7749 | }
7750 | }
7751 | continue;
7752 | }
7753 | 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", 7753 , __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", 7753, "(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", 7753, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7754 |
7755 | /* do we need to rewind ? */
7756 | if (!hfinfo)
7757 | return "";
7758 |
7759 | if (occurrence < 0) {
7760 | /* Search other direction */
7761 | while (hfinfo->same_name_prev_id != -1) {
7762 | 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", 7762 , __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", 7762, "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", 7762, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7763 | }
7764 | }
7765 |
7766 | prev_len = 0; /* Reset handled occurrences */
7767 |
7768 | while (hfinfo) {
7769 | finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7770 |
7771 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7772 | if (occurrence < 0) {
7773 | hfinfo = hfinfo->same_name_next;
7774 | } else {
7775 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7776 | }
7777 | continue;
7778 | }
7779 |
7780 | /* Are there enough occurrences of the field? */
7781 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7782 | if (occurrence < 0) {
7783 | hfinfo = hfinfo->same_name_next;
7784 | } else {
7785 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7786 | }
7787 | prev_len += len;
7788 | continue;
7789 | }
7790 |
7791 | /* Calculate single index or set outer boundaries */
7792 | if (occurrence < 0) {
7793 | i = occurrence + len + prev_len;
7794 | last = i;
7795 | } else if (occurrence > 0) {
7796 | i = occurrence - 1 - prev_len;
7797 | last = i;
7798 | } else {
7799 | i = 0;
7800 | last = len - 1;
7801 | }
7802 |
7803 | prev_len += len; /* Count handled occurrences */
7804 |
7805 | while (i <= last) {
7806 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7807 |
7808 | if (offset_r && (offset_r < (size - 1)))
7809 | result[offset_r++] = ',';
7810 |
7811 | if (display_details) {
7812 | char representation[ITEM_LABEL_LENGTH240];
7813 | size_t offset = 0;
7814 |
7815 | if (finfo->rep && finfo->rep->value_len) {
7816 | (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7817 | MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo-> rep->value_len + 1) : (240)));
7818 | } else {
7819 | proto_item_fill_label(finfo, representation, &offset);
7820 | }
7821 | offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7822 | } else {
7823 | switch (hfinfo->type) {
7824 |
7825 | case FT_NONE:
7826 | case FT_PROTOCOL:
7827 | /* Prevent multiple check marks */
7828 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7829 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7830 | } else {
7831 | result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7832 | }
7833 | break;
7834 |
7835 | default:
7836 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7837 | break;
7838 | }
7839 | }
7840 |
7841 | if (offset_e && (offset_e < (size - 1)))
7842 | expr[offset_e++] = ',';
7843 |
7844 | 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 )))) {
7845 | const char *hf_str_val;
7846 | /* Integer types with BASE_NONE never get the numeric value. */
7847 | if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16 || (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32 )) {
7848 | hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7849 | } 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 )) {
7850 | hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7851 | } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48 || (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64 )) {
7852 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7853 | } else { // if (FT_IS_UINT64(hfinfo->type)) {
7854 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7855 | }
7856 | snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7857 | offset_e = (int)strlen(expr);
7858 | } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7859 | /* Prevent multiple check marks */
7860 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7861 | offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7862 | } else {
7863 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7864 | }
7865 | } else {
7866 | str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7867 | // col_{add,append,set}_* calls ws_label_strcpy
7868 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7869 | wmem_free(NULL((void*)0), str);
7870 | }
7871 | i++;
7872 | }
7873 |
7874 | /* XXX: Why is only the first abbreviation returned for a multifield
7875 | * custom column? */
7876 | if (!abbrev) {
7877 | /* Store abbrev for return value */
7878 | abbrev = hfinfo->abbrev;
7879 | }
7880 |
7881 | if (occurrence == 0) {
7882 | /* Fetch next hfinfo with same name (abbrev) */
7883 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7884 | } else {
7885 | hfinfo = NULL((void*)0);
7886 | }
7887 | }
7888 | }
7889 |
7890 | if (offset_r >= (size - 1)) {
7891 | mark_truncated(result, 0, size, NULL((void*)0));
7892 | }
7893 | if (offset_e >= (size - 1)) {
7894 | mark_truncated(expr, 0, size, NULL((void*)0));
7895 | }
7896 | return abbrev ? abbrev : "";
7897 | }
7898 |
7899 | char *
7900 | proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7901 | {
7902 | int len, prev_len, last, i;
7903 | GPtrArray *finfos;
7904 | field_info *finfo = NULL((void*)0);
7905 | header_field_info* hfinfo;
7906 |
7907 | char *filter = NULL((void*)0);
7908 | GPtrArray *filter_array;
7909 |
7910 | col_custom_t *col_custom;
7911 | int field_id;
7912 |
7913 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7913, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7914 | filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7915 | for (GSList *iter = field_ids; iter; iter = iter->next) {
7916 | col_custom = (col_custom_t*)iter->data;
7917 | field_id = col_custom->field_id;
7918 | if (field_id == 0) {
7919 | GPtrArray *fvals = NULL((void*)0);
7920 | bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7921 | if (fvals != NULL((void*)0)) {
7922 | // XXX - Handling occurrences is unusual when more
7923 | // than one field is involved, e.g. there's four
7924 | // results for tcp.port + tcp.port. We really
7925 | // want to apply it to the operands, not the output.
7926 | /* Calculate single index or set outer boundaries */
7927 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7928 | if (occurrence < 0) {
7929 | i = occurrence + len;
7930 | last = i;
7931 | } else if (occurrence > 0) {
7932 | i = occurrence - 1;
7933 | last = i;
7934 | } else {
7935 | i = 0;
7936 | last = len - 1;
7937 | }
7938 | if (i < 0 || i >= len) {
7939 | g_ptr_array_unref(fvals);
7940 | continue;
7941 | }
7942 | for (; i <= last; i++) {
7943 | /* XXX - Should multiple values for one
7944 | * field use set membership to reduce
7945 | * verbosity, here and below? */
7946 | char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7947 | filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7948 | wmem_free(NULL((void*)0), str);
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 | g_ptr_array_unref(fvals);
7954 | } else if (passed) {
7955 | filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7956 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7957 | g_ptr_array_add(filter_array, filter);
7958 | }
7959 | } else {
7960 | filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7961 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7962 | g_ptr_array_add(filter_array, filter);
7963 | }
7964 | }
7965 | continue;
7966 | }
7967 |
7968 | 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", 7968 , __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", 7968, "(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", 7968, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7969 |
7970 | /* do we need to rewind ? */
7971 | if (!hfinfo)
7972 | return NULL((void*)0);
7973 |
7974 | if (occurrence < 0) {
7975 | /* Search other direction */
7976 | while (hfinfo->same_name_prev_id != -1) {
7977 | 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", 7977 , __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", 7977, "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", 7977, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7978 | }
7979 | }
7980 |
7981 | prev_len = 0; /* Reset handled occurrences */
7982 |
7983 | while (hfinfo) {
7984 | finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7985 |
7986 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7987 | if (occurrence < 0) {
7988 | hfinfo = hfinfo->same_name_next;
7989 | } else {
7990 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7991 | }
7992 | continue;
7993 | }
7994 |
7995 | /* Are there enough occurrences of the field? */
7996 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7997 | if (occurrence < 0) {
7998 | hfinfo = hfinfo->same_name_next;
7999 | } else {
8000 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
8001 | }
8002 | prev_len += len;
8003 | continue;
8004 | }
8005 |
8006 | /* Calculate single index or set outer boundaries */
8007 | if (occurrence < 0) {
8008 | i = occurrence + len + prev_len;
8009 | last = i;
8010 | } else if (occurrence > 0) {
8011 | i = occurrence - 1 - prev_len;
8012 | last = i;
8013 | } else {
8014 | i = 0;
8015 | last = len - 1;
8016 | }
8017 |
8018 | prev_len += len; /* Count handled occurrences */
8019 |
8020 | while (i <= last) {
8021 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
8022 |
8023 | filter = proto_construct_match_selected_string(finfo, edt);
8024 | if (filter) {
8025 | /* Only add the same expression once (especially for FT_PROTOCOL).
8026 | * The ptr array doesn't have NULL entries so g_str_equal is fine.
8027 | */
8028 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
8029 | g_ptr_array_add(filter_array, filter);
8030 | }
8031 | }
8032 | i++;
8033 | }
8034 |
8035 | if (occurrence == 0) {
8036 | /* Fetch next hfinfo with same name (abbrev) */
8037 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
8038 | } else {
8039 | hfinfo = NULL((void*)0);
8040 | }
8041 | }
8042 | }
8043 |
8044 | g_ptr_array_add(filter_array, NULL((void*)0));
8045 |
8046 | /* XXX: Should this be || or && ? */
8047 | char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
8048 |
8049 | g_ptr_array_free(filter_array, true1);
8050 |
8051 | return output;
8052 | }
8053 |
8054 | /* Set text of proto_item after having already been created. */
8055 | void
8056 | proto_item_set_text(proto_item *pi, const char *format, ...)
8057 | {
8058 | field_info *fi = NULL((void*)0);
8059 | va_list ap;
8060 |
8061 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
8062 |
8063 | fi = PITEM_FINFO(pi)((pi)->finfo);
8064 | if (fi == NULL((void*)0))
8065 | return;
8066 |
8067 | if (fi->rep) {
8068 | ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep );;
8069 | fi->rep = NULL((void*)0);
8070 | }
8071 |
8072 | va_start(ap, format)__builtin_va_start(ap, format);
8073 | proto_tree_set_representation(pi, format, ap);
8074 | va_end(ap)__builtin_va_end(ap);
8075 | }
8076 |
8077 | /* Append to text of proto_item after having already been created. */
8078 | void
8079 | proto_item_append_text(proto_item *pi, const char *format, ...)
8080 | {
8081 | field_info *fi = NULL((void*)0);
8082 | size_t curlen;
8083 | char *str;
8084 | va_list ap;
8085 |
8086 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
8087 |
8088 | fi = PITEM_FINFO(pi)((pi)->finfo);
8089 | if (fi == NULL((void*)0)) {
8090 | return;
8091 | }
8092 |
8093 | if (!proto_item_is_hidden(pi)) {
8094 | /*
8095 | * If we don't already have a representation,
8096 | * generate the default representation.
8097 | */
8098 | if (fi->rep == NULL((void*)0)) {
8099 | 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;;
8100 | proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
8101 | /* Check for special case append value to FT_NONE or FT_PROTOCOL */
8102 | if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
8103 | (strncmp(format, ": ", 2) == 0)) {
8104 | fi->rep->value_pos += 2;
8105 | }
8106 | }
8107 | if (fi->rep) {
8108 | curlen = strlen(fi->rep->representation);
8109 | /* curlen doesn't include the \0 byte.
8110 | * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8111 | * the representation has already been truncated (of an up
8112 | * to 4 byte UTF-8 character) or is just at the maximum length
8113 | * unless we search for " [truncated]" (which may not be
8114 | * at the start.)
8115 | * It's safer to do nothing.
8116 | */
8117 | if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8118 | va_start(ap, format)__builtin_va_start(ap, format);
8119 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8120 | va_end(ap)__builtin_va_end(ap);
8121 | 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" , 8121, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
8122 | /* Keep fi->rep->value_pos */
8123 | curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8124 | if (curlen >= ITEM_LABEL_LENGTH240) {
8125 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8126 | size_t name_pos = label_find_name_pos(fi->rep);
8127 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8128 | }
8129 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8130 | }
8131 | }
8132 | }
8133 | }
8134 |
8135 | /* Prepend to text of proto_item after having already been created. */
8136 | void
8137 | proto_item_prepend_text(proto_item *pi, const char *format, ...)
8138 | {
8139 | field_info *fi = NULL((void*)0);
8140 | size_t pos;
8141 | char representation[ITEM_LABEL_LENGTH240];
8142 | char *str;
8143 | va_list ap;
8144 |
8145 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
8146 |
8147 | fi = PITEM_FINFO(pi)((pi)->finfo);
8148 | if (fi == NULL((void*)0)) {
8149 | return;
8150 | }
8151 |
8152 | if (!proto_item_is_hidden(pi)) {
8153 | /*
8154 | * If we don't already have a representation,
8155 | * generate the default representation.
8156 | */
8157 | if (fi->rep == NULL((void*)0)) {
8158 | 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;;
8159 | proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8160 | } else
8161 | (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8162 |
8163 | va_start(ap, format)__builtin_va_start(ap, format);
8164 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8165 | va_end(ap)__builtin_va_end(ap);
8166 | 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" , 8166, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
8167 | fi->rep->value_pos += strlen(str);
8168 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8169 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8170 | /* XXX: As above, if the old representation is close to the label
8171 | * length, it might already be marked as truncated. */
8172 | if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8173 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8174 | size_t name_pos = label_find_name_pos(fi->rep);
8175 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8176 | }
8177 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8178 | }
8179 | }
8180 |
8181 | static void
8182 | finfo_set_len(field_info *fi, const unsigned length)
8183 | {
8184 | unsigned length_remaining;
8185 |
8186 | length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8187 | if (length > length_remaining)
8188 | fi->length = length_remaining;
8189 | else
8190 | fi->length = length;
8191 |
8192 | /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8193 | if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8194 | fvalue_set_protocol_length(fi->value, fi->length);
8195 | }
8196 |
8197 | /*
8198 | * You cannot just make the "len" field of a GByteArray
8199 | * larger, if there's no data to back that length;
8200 | * you can only make it smaller.
8201 | */
8202 | if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8203 | GBytes *bytes = fvalue_get_bytes(fi->value);
8204 | size_t size;
8205 | const void *data = g_bytes_get_data(bytes, &size);
8206 | if ((size_t)fi->length <= size) {
8207 | fvalue_set_bytes_data(fi->value, data, fi->length);
8208 | }
8209 | g_bytes_unref(bytes);
8210 | }
8211 | }
8212 |
8213 | void
8214 | proto_item_set_len(proto_item *pi, const unsigned length)
8215 | {
8216 | field_info *fi;
8217 |
8218 | if (pi == NULL((void*)0))
8219 | return;
8220 |
8221 | fi = PITEM_FINFO(pi)((pi)->finfo);
8222 | if (fi == NULL((void*)0))
8223 | return;
8224 |
8225 | finfo_set_len(fi, length);
8226 | }
8227 |
8228 | /*
8229 | * Sets the length of the item based on its start and on the specified
8230 | * offset, which is the offset past the end of the item; as the start
8231 | * in the item is relative to the beginning of the data source tvbuff,
8232 | * we need to pass in a tvbuff - the end offset is relative to the beginning
8233 | * of that tvbuff.
8234 | */
8235 | void
8236 | proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8237 | {
8238 | field_info *fi;
8239 | unsigned length;
8240 |
8241 | if (pi == NULL((void*)0))
8242 | return;
8243 |
8244 | fi = PITEM_FINFO(pi)((pi)->finfo);
8245 | if (fi == NULL((void*)0))
8246 | return;
8247 |
8248 | if (G_LIKELY(tvb)(tvb)) {
8249 | 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" , 8249, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))));
8250 | end += tvb_raw_offset(tvb);
8251 | } else {
8252 | 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", 8252, "((void*)0) == fi->ds_tvb" ))));
8253 | }
8254 | DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8254, "end >= fi->start" ))));
8255 | length = end - fi->start;
8256 |
8257 | finfo_set_len(fi, length);
8258 | }
8259 |
8260 | unsigned
8261 | proto_item_get_len(const proto_item *pi)
8262 | {
8263 | /* XXX - The only use case where this is really guaranteed to work is
8264 | * increasing the length of an item (which has no effect if the item
8265 | * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8266 | *
8267 | * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8268 | *
8269 | * Should there be a macro or function to do that, and possibly this
8270 | * be deprecated? As a bonus, we could handle overflow.
8271 | */
8272 | field_info *fi;
8273 |
8274 | if (!pi)
8275 | return 0;
8276 | fi = PITEM_FINFO(pi)((pi)->finfo);
8277 | if (fi) {
8278 | return fi->length;
8279 | }
8280 | return 0;
8281 | }
8282 |
8283 | void
8284 | proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8285 | if (!ti) {
8286 | return;
8287 | }
8288 | 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);
8289 | 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);
8290 | }
8291 |
8292 | char *
8293 | proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8294 | {
8295 | field_info *fi;
8296 |
8297 | if (!pi)
8298 | return wmem_strdup(scope, "");
8299 | fi = PITEM_FINFO(pi)((pi)->finfo);
8300 | if (!fi)
8301 | return wmem_strdup(scope, "");
8302 | DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8302, "fi->hfinfo != ((void*)0)" ))));
8303 | return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8304 | }
8305 |
8306 | proto_tree *
8307 | proto_tree_create_root(packet_info *pinfo)
8308 | {
8309 | proto_node *pnode;
8310 |
8311 | /* Initialize the proto_node */
8312 | pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof (proto_tree) : 1)));
8313 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
8314 | pnode->parent = NULL((void*)0);
8315 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8316 | 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)));
8317 |
8318 | /* Make sure we can access pinfo everywhere */
8319 | pnode->tree_data->pinfo = pinfo;
8320 |
8321 | /* Don't initialize the tree_data_t. Wait until we know we need it */
8322 | pnode->tree_data->interesting_hfids = NULL((void*)0);
8323 |
8324 | /* Set the default to false so it's easier to
8325 | * find errors; if we expect to see the protocol tree
8326 | * but for some reason the default 'visible' is not
8327 | * changed, then we'll find out very quickly. */
8328 | pnode->tree_data->visible = false0;
8329 |
8330 | /* Make sure that we fake protocols (if possible) */
8331 | pnode->tree_data->fake_protocols = true1;
8332 |
8333 | /* Keep track of the number of children */
8334 | pnode->tree_data->count = 0;
8335 |
8336 | /* Initialize our loop checks */
8337 | pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8338 | pnode->tree_data->max_start = 0;
8339 | pnode->tree_data->start_idle_count = 0;
8340 |
8341 | return (proto_tree *)pnode;
8342 | }
8343 |
8344 |
8345 | /* "prime" a proto_tree with a single hfid that a dfilter
8346 | * is interested in. */
8347 | void
8348 | proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8349 | {
8350 | header_field_info *hfinfo;
8351 |
8352 | 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", 8352, __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", 8352, "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", 8352, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8353 | /* this field is referenced by a filter so increase the refcount.
8354 | also increase the refcount for the parent, i.e the protocol.
8355 | Don't increase the refcount if we're already printing the
8356 | type, as that is a superset of direct reference.
8357 | */
8358 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8359 | hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8360 | }
8361 | /* only increase the refcount if there is a parent.
8362 | if this is a protocol and not a field then parent will be -1
8363 | and there is no parent to add any refcounting for.
8364 | */
8365 | if (hfinfo->parent != -1) {
8366 | header_field_info *parent_hfinfo;
8367 | 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", 8367 , __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", 8367, "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", 8367, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf." )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8368 |
8369 | /* Mark parent as indirectly referenced unless it is already directly
8370 | * referenced, i.e. the user has specified the parent in a filter.
8371 | */
8372 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8373 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8374 | }
8375 | }
8376 |
8377 | /* "prime" a proto_tree with a single hfid that a dfilter
8378 | * is interested in. */
8379 | void
8380 | proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8381 | {
8382 | header_field_info *hfinfo;
8383 |
8384 | 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", 8384, __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", 8384, "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", 8384, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8385 | /* this field is referenced by an (output) filter so increase the refcount.
8386 | also increase the refcount for the parent, i.e the protocol.
8387 | */
8388 | hfinfo->ref_type = HF_REF_TYPE_PRINT;
8389 | /* only increase the refcount if there is a parent.
8390 | if this is a protocol and not a field then parent will be -1
8391 | and there is no parent to add any refcounting for.
8392 | */
8393 | if (hfinfo->parent != -1) {
8394 | header_field_info *parent_hfinfo;
8395 | 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", 8395 , __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", 8395, "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", 8395, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf." )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8396 |
8397 | /* Mark parent as indirectly referenced unless it is already directly
8398 | * referenced, i.e. the user has specified the parent in a filter.
8399 | */
8400 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8401 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8402 | }
8403 | }
8404 |
8405 | proto_tree *
8406 | proto_item_add_subtree(proto_item *pi, const int idx) {
8407 | field_info *fi;
8408 |
8409 | if (!pi)
8410 | return NULL((void*)0);
8411 |
8412 | 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", 8412, "idx >= 0 && idx < num_tree_types" ))));
8413 |
8414 | fi = PITEM_FINFO(pi)((pi)->finfo);
8415 | if (!fi)
8416 | return (proto_tree *)pi;
8417 |
8418 | fi->tree_type = idx;
8419 |
8420 | return (proto_tree *)pi;
8421 | }
8422 |
8423 | proto_tree *
8424 | proto_item_get_subtree(proto_item *pi) {
8425 | field_info *fi;
8426 |
8427 | if (!pi)
8428 | return NULL((void*)0);
8429 | fi = PITEM_FINFO(pi)((pi)->finfo);
8430 | if ( (fi) && (fi->tree_type == -1) )
8431 | return NULL((void*)0);
8432 | return (proto_tree *)pi;
8433 | }
8434 |
8435 | proto_item *
8436 | proto_item_get_parent(const proto_item *ti) {
8437 | if (!ti)
8438 | return NULL((void*)0);
8439 | return ti->parent;
8440 | }
8441 |
8442 | proto_item *
8443 | proto_item_get_parent_nth(proto_item *ti, int gen) {
8444 | if (!ti)
8445 | return NULL((void*)0);
8446 | while (gen--) {
8447 | ti = ti->parent;
8448 | if (!ti)
8449 | return NULL((void*)0);
8450 | }
8451 | return ti;
8452 | }
8453 |
8454 |
8455 | proto_item *
8456 | proto_tree_get_parent(proto_tree *tree) {
8457 | if (!tree)
8458 | return NULL((void*)0);
8459 | return (proto_item *)tree;
8460 | }
8461 |
8462 | proto_tree *
8463 | proto_tree_get_parent_tree(proto_tree *tree) {
8464 | if (!tree)
8465 | return NULL((void*)0);
8466 |
8467 | /* we're the root tree, there's no parent
8468 | return ourselves so the caller has at least a tree to attach to */
8469 | if (!tree->parent)
8470 | return tree;
8471 |
8472 | return (proto_tree *)tree->parent;
8473 | }
8474 |
8475 | proto_tree *
8476 | proto_tree_get_root(proto_tree *tree) {
8477 | if (!tree)
8478 | return NULL((void*)0);
8479 | while (tree->parent) {
8480 | tree = tree->parent;
8481 | }
8482 | return tree;
8483 | }
8484 |
8485 | void
8486 | proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8487 | proto_item *item_to_move)
8488 | {
8489 | /* This function doesn't generate any values. It only reorganizes the protocol tree
8490 | * so we can bail out immediately if it isn't visible. */
8491 | if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8492 | return;
8493 |
8494 | 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", 8494, "item_to_move->parent == tree" ))));
8495 | 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", 8495, "fixed_item->parent == tree" ))));
8496 |
8497 | /*** cut item_to_move out ***/
8498 |
8499 | /* is item_to_move the first? */
8500 | if (tree->first_child == item_to_move) {
8501 | /* simply change first child to next */
8502 | tree->first_child = item_to_move->next;
8503 |
8504 | 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", 8504, "tree->last_child != item_to_move" ))));
8505 | } else {
8506 | proto_item *curr_item;
8507 | /* find previous and change it's next */
8508 | for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8509 | if (curr_item->next == item_to_move) {
8510 | break;
8511 | }
8512 | }
8513 |
8514 | DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 8514, "curr_item" ))));
8515 |
8516 | curr_item->next = item_to_move->next;
8517 |
8518 | /* fix last_child if required */
8519 | if (tree->last_child == item_to_move) {
8520 | tree->last_child = curr_item;
8521 | }
8522 | }
8523 |
8524 | /*** insert to_move after fixed ***/
8525 | item_to_move->next = fixed_item->next;
8526 | fixed_item->next = item_to_move;
8527 | if (tree->last_child == fixed_item) {
8528 | tree->last_child = item_to_move;
8529 | }
8530 | }
8531 |
8532 | void
8533 | proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8534 | const unsigned length)
8535 | {
8536 | field_info *fi;
8537 |
8538 | if (tree == NULL((void*)0))
8539 | return;
8540 |
8541 | fi = PTREE_FINFO(tree)((tree)->finfo);
8542 | if (fi == NULL((void*)0))
8543 | return;
8544 |
8545 | /* We don't store a separate data source tvb for the appendix, so
8546 | * it must be from the same data source. (XXX - Are there any
8547 | * situations where it makes sense to have an appendix from a
8548 | * different data source?) */
8549 | if (G_LIKELY(tvb)(tvb)) {
8550 | 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" , 8550, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))));
8551 | start += tvb_raw_offset(tvb);
8552 | } else {
8553 | 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", 8553, "((void*)0) == fi->ds_tvb" ))));
8554 | }
8555 |
8556 | /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8557 | * main body? */
8558 |
8559 | fi->appendix_start = start;
8560 | fi->appendix_length = length;
8561 | }
8562 |
8563 | static void
8564 | check_protocol_filter_name_or_fail(const char *filter_name)
8565 | {
8566 | /* Require at least two characters. */
8567 | if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8568 | 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);
8569 | }
8570 |
8571 | if (proto_check_field_name(filter_name) != '\0') {
8572 | 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)
8573 | " 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)
8574 | " 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);
8575 | }
8576 |
8577 | /* Check that it doesn't match some very common numeric forms. */
8578 | if (filter_name[0] == '0' &&
8579 | (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8580 | filter_name[1] == 'b' || filter_name[1] == 'B')) {
8581 | 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])
8582 | 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]);
8583 | }
8584 |
8585 | /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8586 |
8587 | /* Check that it contains at least one letter. */
8588 | bool_Bool have_letter = false0;
8589 | for (const char *s = filter_name; *s != '\0'; s++) {
8590 | if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8591 | have_letter = true1;
8592 | break;
8593 | }
8594 | }
8595 | if (!have_letter) {
8596 | 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)
8597 | filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z." , filter_name);
8598 | }
8599 |
8600 | /* Check for reserved keywords. */
8601 | if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8602 | 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)
8603 | " 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);
8604 | }
8605 | }
8606 |
8607 | int
8608 | proto_register_protocol(const char *name, const char *short_name,
8609 | const char *filter_name)
8610 | {
8611 | protocol_t *protocol;
8612 | header_field_info *hfinfo;
8613 |
8614 | check_protocol_filter_name_or_fail(filter_name);
8615 |
8616 | /*
8617 | * Add this protocol to the list of known protocols;
8618 | * the list is sorted by protocol short name.
8619 | */
8620 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8621 | protocol->name = name;
8622 | protocol->short_name = short_name;
8623 | protocol->filter_name = filter_name;
8624 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8625 | protocol->is_enabled = true1; /* protocol is enabled by default */
8626 | protocol->enabled_by_default = true1; /* see previous comment */
8627 | protocol->can_toggle = true1;
8628 | protocol->parent_proto_id = -1;
8629 | protocol->heur_list = NULL((void*)0);
8630 |
8631 | /* List will be sorted later by name, when all protocols completed registering */
8632 | protocols = g_list_prepend(protocols, protocol);
8633 | /*
8634 | * Make sure there's not already a protocol with any of those
8635 | * names. Crash if there is, as that's an error in the code
8636 | * or an inappropriate plugin.
8637 | * This situation has to be fixed to not register more than one
8638 | * protocol with the same name.
8639 | */
8640 | if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8641 | /* ws_error will terminate the program */
8642 | 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)
8643 | " 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);
8644 | }
8645 | if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8646 | 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)
8647 | " 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);
8648 | }
8649 | if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8650 | 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)
8651 | " 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);
8652 | }
8653 |
8654 | /* Here we allocate a new header_field_info struct */
8655 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info ) > 0 ? sizeof (header_field_info) : 1)));
8656 | hfinfo->name = name;
8657 | hfinfo->abbrev = filter_name;
8658 | hfinfo->type = FT_PROTOCOL;
8659 | hfinfo->display = BASE_NONE;
8660 | hfinfo->strings = protocol;
8661 | hfinfo->bitmask = 0;
8662 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8663 | hfinfo->blurb = NULL((void*)0);
8664 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8665 |
8666 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8667 | return protocol->proto_id;
8668 | }
8669 |
8670 | int
8671 | proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8672 | {
8673 | protocol_t *protocol;
8674 | header_field_info *hfinfo;
8675 |
8676 | /*
8677 | * Helper protocols don't need the strict rules as a "regular" protocol
8678 | * Just register it in a list and make a hf_ field from it
8679 | */
8680 | if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8681 | 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);
8682 | }
8683 |
8684 | if (parent_proto <= 0) {
8685 | 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)
8686 | " 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);
8687 | }
8688 |
8689 | check_protocol_filter_name_or_fail(filter_name);
8690 |
8691 | /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8692 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8693 | protocol->name = name;
8694 | protocol->short_name = short_name;
8695 | protocol->filter_name = filter_name;
8696 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8697 |
8698 | /* Enabling and toggling is really determined by parent protocol,
8699 | but provide default values here */
8700 | protocol->is_enabled = true1;
8701 | protocol->enabled_by_default = true1;
8702 | protocol->can_toggle = true1;
8703 |
8704 | protocol->parent_proto_id = parent_proto;
8705 | protocol->heur_list = NULL((void*)0);
8706 |
8707 | /* List will be sorted later by name, when all protocols completed registering */
8708 | protocols = g_list_prepend(protocols, protocol);
8709 |
8710 | /* Here we allocate a new header_field_info struct */
8711 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info ) > 0 ? sizeof (header_field_info) : 1)));
8712 | hfinfo->name = name;
8713 | hfinfo->abbrev = filter_name;
8714 | hfinfo->type = field_type;
8715 | hfinfo->display = BASE_NONE;
8716 | if (field_type == FT_BYTES) {
8717 | hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8718 | }
8719 | hfinfo->strings = protocol;
8720 | hfinfo->bitmask = 0;
8721 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8722 | hfinfo->blurb = NULL((void*)0);
8723 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8724 |
8725 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8726 | return protocol->proto_id;
8727 | }
8728 |
8729 | bool_Bool
8730 | proto_deregister_protocol(const char *short_name)
8731 | {
8732 | protocol_t *protocol;
8733 | header_field_info *hfinfo;
8734 | int proto_id;
8735 | unsigned i;
8736 |
8737 | proto_id = proto_get_id_by_short_name(short_name);
8738 | protocol = find_protocol_by_id(proto_id);
8739 | if (protocol == NULL((void*)0))
8740 | return false0;
8741 |
8742 | g_hash_table_remove(proto_names, protocol->name);
8743 | g_hash_table_remove(proto_short_names, (void *)short_name);
8744 | g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8745 |
8746 | if (protocol->fields) {
8747 | for (i = 0; i < protocol->fields->len; i++) {
8748 | hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8749 | hfinfo_remove_from_gpa_name_map(hfinfo);
8750 | expert_deregister_expertinfo(hfinfo->abbrev);
8751 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8752 | }
8753 | g_ptr_array_free(protocol->fields, true1);
8754 | protocol->fields = NULL((void*)0);
8755 | }
8756 |
8757 | g_list_free(protocol->heur_list);
8758 |
8759 | /* Remove this protocol from the list of known protocols */
8760 | protocols = g_list_remove(protocols, protocol);
8761 |
8762 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8763 | wmem_map_remove(gpa_name_map, protocol->filter_name);
8764 |
8765 | 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);
8766 | last_field_name = NULL((void*)0);
8767 |
8768 | return true1;
8769 | }
8770 |
8771 | void
8772 | proto_register_alias(const int proto_id, const char *alias_name)
8773 | {
8774 | protocol_t *protocol;
8775 |
8776 | protocol = find_protocol_by_id(proto_id);
8777 | if (alias_name && protocol) {
8778 | g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8779 | }
8780 | }
8781 |
8782 | /*
8783 | * Routines to use to iterate over the protocols.
8784 | * The argument passed to the iterator routines is an opaque cookie to
8785 | * their callers; it's the GList pointer for the current element in
8786 | * the list.
8787 | * The ID of the protocol is returned, or -1 if there is no protocol.
8788 | */
8789 | int
8790 | proto_get_first_protocol(void **cookie)
8791 | {
8792 | protocol_t *protocol;
8793 |
8794 | if (protocols == NULL((void*)0))
8795 | return -1;
8796 | *cookie = protocols;
8797 | protocol = (protocol_t *)protocols->data;
8798 | return protocol->proto_id;
8799 | }
8800 |
8801 | int
8802 | proto_get_data_protocol(void *cookie)
8803 | {
8804 | GList *list_item = (GList *)cookie;
8805 |
8806 | protocol_t *protocol = (protocol_t *)list_item->data;
8807 | return protocol->proto_id;
8808 | }
8809 |
8810 | int
8811 | proto_get_next_protocol(void **cookie)
8812 | {
8813 | GList *list_item = (GList *)*cookie;
8814 | protocol_t *protocol;
8815 |
8816 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8817 | if (list_item == NULL((void*)0))
8818 | return -1;
8819 | *cookie = list_item;
8820 | protocol = (protocol_t *)list_item->data;
8821 | return protocol->proto_id;
8822 | }
8823 |
8824 | header_field_info *
8825 | proto_get_first_protocol_field(const int proto_id, void **cookie)
8826 | {
8827 | protocol_t *protocol = find_protocol_by_id(proto_id);
8828 |
8829 | if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8830 | return NULL((void*)0);
8831 |
8832 | *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8833 | return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8834 | }
8835 |
8836 | header_field_info *
8837 | proto_get_next_protocol_field(const int proto_id, void **cookie)
8838 | {
8839 | protocol_t *protocol = find_protocol_by_id(proto_id);
8840 | unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8841 |
8842 | i++;
8843 |
8844 | if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8845 | return NULL((void*)0);
8846 |
8847 | *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8848 | return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8849 | }
8850 |
8851 | protocol_t *
8852 | find_protocol_by_id(const int proto_id)
8853 | {
8854 | header_field_info *hfinfo;
8855 |
8856 | if (proto_id <= 0)
8857 | return NULL((void*)0);
8858 |
8859 | 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", 8859, __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", 8859, "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", 8859, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
8860 | if (hfinfo->type != FT_PROTOCOL) {
8861 | 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", 8861, "hfinfo->display & 0x00004000" ))));
8862 | }
8863 | return (protocol_t *)hfinfo->strings;
8864 | }
8865 |
8866 | int
8867 | proto_get_id(const protocol_t *protocol)
8868 | {
8869 | return protocol->proto_id;
8870 | }
8871 |
8872 | bool_Bool
8873 | proto_name_already_registered(const char *name)
8874 | {
8875 | DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 8875, "name", "No name present"))));
8876 |
8877 | if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8878 | return true1;
8879 | return false0;
8880 | }
8881 |
8882 | int
8883 | proto_get_id_by_filter_name(const char *filter_name)
8884 | {
8885 | const protocol_t *protocol = NULL((void*)0);
8886 |
8887 | 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", 8887, "filter_name", "No filter name present"))));
8888 |
8889 | protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8890 |
8891 | if (protocol == NULL((void*)0))
8892 | return -1;
8893 | return protocol->proto_id;
8894 | }
8895 |
8896 | int
8897 | proto_get_id_by_short_name(const char *short_name)
8898 | {
8899 | const protocol_t *protocol = NULL((void*)0);
8900 |
8901 | 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", 8901, "short_name", "No short name present"))));
8902 |
8903 | protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8904 |
8905 | if (protocol == NULL((void*)0))
8906 | return -1;
8907 | return protocol->proto_id;
8908 | }
8909 |
8910 | const char *
8911 | proto_get_protocol_name(const int proto_id)
8912 | {
8913 | protocol_t *protocol;
8914 |
8915 | protocol = find_protocol_by_id(proto_id);
8916 |
8917 | if (protocol == NULL((void*)0))
8918 | return NULL((void*)0);
8919 | return protocol->name;
8920 | }
8921 |
8922 | const char *
8923 | proto_get_protocol_short_name(const protocol_t *protocol)
8924 | {
8925 | if (protocol == NULL((void*)0))
8926 | return "(none)";
8927 | return protocol->short_name;
8928 | }
8929 |
8930 | const char *
8931 | proto_get_protocol_long_name(const protocol_t *protocol)
8932 | {
8933 | if (protocol == NULL((void*)0))
8934 | return "(none)";
8935 | return protocol->name;
8936 | }
8937 |
8938 | const char *
8939 | proto_get_protocol_filter_name(const int proto_id)
8940 | {
8941 | protocol_t *protocol;
8942 |
8943 | protocol = find_protocol_by_id(proto_id);
8944 | if (protocol == NULL((void*)0))
8945 | return "(none)";
8946 | return protocol->filter_name;
8947 | }
8948 |
8949 | void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8950 | {
8951 | heur_dtbl_entry_t* heuristic_dissector;
8952 |
8953 | if (protocol == NULL((void*)0))
8954 | return;
8955 |
8956 | heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8957 | if (heuristic_dissector != NULL((void*)0))
8958 | {
8959 | protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8960 | }
8961 | }
8962 |
8963 | void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8964 | {
8965 | if (protocol == NULL((void*)0))
8966 | return;
8967 |
8968 | g_list_foreach(protocol->heur_list, func, user_data);
8969 | }
8970 |
8971 | void
8972 | proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8973 | bool_Bool *is_tcp, bool_Bool *is_udp,
8974 | bool_Bool *is_sctp, bool_Bool *is_tls,
8975 | bool_Bool *is_rtp,
8976 | bool_Bool *is_lte_rlc)
8977 | {
8978 | wmem_list_frame_t *protos = wmem_list_head(layers);
8979 | int proto_id;
8980 | const char *proto_name;
8981 |
8982 | /* Walk the list of a available protocols in the packet and
8983 | attempt to find "major" ones. */
8984 | /* It might make more sense to assemble and return a bitfield. */
8985 | while (protos != NULL((void*)0))
8986 | {
8987 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8988 | proto_name = proto_get_protocol_filter_name(proto_id);
8989 |
8990 | if (is_ip && ((!strcmp(proto_name, "ip")) ||
8991 | (!strcmp(proto_name, "ipv6")))) {
8992 | *is_ip = true1;
8993 | } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8994 | *is_tcp = true1;
8995 | } else if (is_udp && !strcmp(proto_name, "udp")) {
8996 | *is_udp = true1;
8997 | } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8998 | *is_sctp = true1;
8999 | } else if (is_tls && !strcmp(proto_name, "tls")) {
9000 | *is_tls = true1;
9001 | } else if (is_rtp && !strcmp(proto_name, "rtp")) {
9002 | *is_rtp = true1;
9003 | } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
9004 | *is_lte_rlc = true1;
9005 | }
9006 |
9007 | protos = wmem_list_frame_next(protos);
9008 | }
9009 | }
9010 |
9011 | bool_Bool
9012 | proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
9013 | {
9014 | wmem_list_frame_t *protos = wmem_list_head(layers);
9015 | int proto_id;
9016 | const char *name;
9017 |
9018 | /* Walk the list of a available protocols in the packet and
9019 | attempt to find the specified protocol. */
9020 | while (protos != NULL((void*)0))
9021 | {
9022 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
9023 | name = proto_get_protocol_filter_name(proto_id);
9024 |
9025 | if (!strcmp(name, proto_name))
9026 | {
9027 | return true1;
9028 | }
9029 |
9030 | protos = wmem_list_frame_next(protos);
9031 | }
9032 |
9033 | return false0;
9034 | }
9035 |
9036 | char *
9037 | proto_list_layers(const packet_info *pinfo)
9038 | {
9039 | wmem_strbuf_t *buf;
9040 | wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
9041 |
9042 | buf = wmem_strbuf_new_sized(pinfo->pool, 128);
9043 |
9044 | /* Walk the list of layers in the packet and
9045 | return a string of all entries. */
9046 | while (layers != NULL((void*)0))
9047 | {
9048 | wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
9049 |
9050 | layers = wmem_list_frame_next(layers);
9051 | if (layers != NULL((void*)0)) {
9052 | wmem_strbuf_append_c(buf, ':');
9053 | }
9054 | }
9055 |
9056 | return wmem_strbuf_finalize(buf);
9057 | }
9058 |
9059 | uint8_t
9060 | proto_get_layer_num(const packet_info *pinfo, const int proto_id)
9061 | {
9062 | int *proto_layer_num_ptr;
9063 |
9064 | proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
9065 | if (proto_layer_num_ptr == NULL((void*)0)) {
9066 | return 0;
9067 | }
9068 |
9069 | return (uint8_t)*proto_layer_num_ptr;
9070 | }
9071 |
9072 | bool_Bool
9073 | proto_is_pino(const protocol_t *protocol)
9074 | {
9075 | return (protocol->parent_proto_id != -1);
9076 | }
9077 |
9078 | bool_Bool
9079 | proto_is_bytes_pino(const protocol_t *protocol)
9080 | {
9081 | header_field_info *hfinfo;
9082 |
9083 | if (!proto_is_pino(protocol))
9084 | return false0;
9085 |
9086 | 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", 9086 , __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", 9086, "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", 9086, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[protocol->proto_id];;
9087 | return hfinfo->type != FT_PROTOCOL;
9088 | }
9089 |
9090 | bool_Bool
9091 | // NOLINTNEXTLINE(misc-no-recursion)
9092 | proto_is_protocol_enabled(const protocol_t *protocol)
9093 | {
9094 | if (protocol == NULL((void*)0))
9095 | return false0;
9096 |
9097 | //parent protocol determines enable/disable for helper dissectors
9098 | if (proto_is_pino(protocol))
9099 | return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
9100 |
9101 | return protocol->is_enabled;
9102 | }
9103 |
9104 | bool_Bool
9105 | // NOLINTNEXTLINE(misc-no-recursion)
9106 | proto_is_protocol_enabled_by_default(const protocol_t *protocol)
9107 | {
9108 | //parent protocol determines enable/disable for helper dissectors
9109 | if (proto_is_pino(protocol))
9110 | return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
9111 |
9112 | return protocol->enabled_by_default;
9113 | }
9114 |
9115 | bool_Bool
9116 | // NOLINTNEXTLINE(misc-no-recursion)
9117 | proto_can_toggle_protocol(const int proto_id)
9118 | {
9119 | protocol_t *protocol;
9120 |
9121 | protocol = find_protocol_by_id(proto_id);
9122 | //parent protocol determines toggling for helper dissectors
9123 | if (proto_is_pino(protocol))
9124 | return proto_can_toggle_protocol(protocol->parent_proto_id);
9125 |
9126 | return protocol->can_toggle;
9127 | }
9128 |
9129 | void
9130 | proto_disable_by_default(const int proto_id)
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 = false0;
9138 | protocol->enabled_by_default = false0;
9139 | }
9140 |
9141 | void
9142 | proto_set_decoding(const int proto_id, const bool_Bool enabled)
9143 | {
9144 | protocol_t *protocol;
9145 |
9146 | protocol = find_protocol_by_id(proto_id);
9147 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9147, "protocol->can_toggle" ))));
9148 | 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", 9148, "proto_is_pino(protocol) == 0" ))));
9149 | protocol->is_enabled = enabled;
9150 | }
9151 |
9152 | void
9153 | proto_disable_all(void)
9154 | {
9155 | /* This doesn't explicitly disable heuristic protocols,
9156 | * but the heuristic doesn't get called if the parent
9157 | * protocol isn't enabled.
9158 | */
9159 | protocol_t *protocol;
9160 | GList *list_item = protocols;
9161 |
9162 | if (protocols == NULL((void*)0))
9163 | return;
9164 |
9165 | while (list_item) {
9166 | protocol = (protocol_t *)list_item->data;
9167 | if (protocol->can_toggle) {
9168 | protocol->is_enabled = false0;
9169 | }
9170 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
9171 | }
9172 | }
9173 |
9174 | static void
9175 | heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9176 | {
9177 | heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9178 |
9179 | heur->enabled = heur->enabled_by_default;
9180 | }
9181 |
9182 | void
9183 | proto_reenable_all(void)
9184 | {
9185 | protocol_t *protocol;
9186 | GList *list_item = protocols;
9187 |
9188 | if (protocols == NULL((void*)0))
9189 | return;
9190 |
9191 | while (list_item) {
9192 | protocol = (protocol_t *)list_item->data;
9193 | if (protocol->can_toggle)
9194 | protocol->is_enabled = protocol->enabled_by_default;
9195 | proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9196 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
9197 | }
9198 | }
9199 |
9200 | void
9201 | proto_set_cant_toggle(const int proto_id)
9202 | {
9203 | protocol_t *protocol;
9204 |
9205 | protocol = find_protocol_by_id(proto_id);
9206 | protocol->can_toggle = false0;
9207 | }
9208 |
9209 | static int
9210 | proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9211 | {
9212 | g_ptr_array_add(proto->fields, hfi);
9213 |
9214 | return proto_register_field_init(hfi, parent);
9215 | }
9216 |
9217 | /* for use with static arrays only, since we don't allocate our own copies
9218 | of the header_field_info struct contained within the hf_register_info struct */
9219 | void
9220 | proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9221 | {
9222 | hf_register_info *ptr = hf;
9223 | protocol_t *proto;
9224 | int i;
9225 |
9226 | proto = find_protocol_by_id(parent);
9227 |
9228 | /* if (proto == NULL) - error or return? */
9229 |
9230 | if (proto->fields == NULL((void*)0)) {
9231 | /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9232 | * GLib introduced g_ptr_array_new_from_array, which might have
9233 | * given a reason to actually use it. (#17774)
9234 | */
9235 | proto->fields = g_ptr_array_sized_new(num_records);
9236 | }
9237 |
9238 | for (i = 0; i < num_records; i++, ptr++) {
9239 | /*
9240 | * Make sure we haven't registered this yet.
9241 | * Most fields have variables associated with them that
9242 | * are initialized to 0; some are initialized to -1 (which
9243 | * was the standard before 4.4).
9244 | *
9245 | * XXX - Since this is called almost 300000 times at startup,
9246 | * it might be nice to compare to only 0 and require
9247 | * dissectors to pass in zero for unregistered fields.
9248 | */
9249 | if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9250 | REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev)
9251 | "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)
9252 | ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev);
9253 | return;
9254 | }
9255 |
9256 | *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9257 | }
9258 | }
9259 |
9260 | /* deregister already registered fields */
9261 | void
9262 | proto_deregister_field (const int parent, int hf_id)
9263 | {
9264 | header_field_info *hfi;
9265 | protocol_t *proto;
9266 | unsigned i;
9267 |
9268 | 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);
9269 | last_field_name = NULL((void*)0);
9270 |
9271 | if (hf_id == -1 || hf_id == 0)
9272 | return;
9273 |
9274 | proto = find_protocol_by_id (parent);
9275 | if (!proto || proto->fields == NULL((void*)0)) {
9276 | return;
9277 | }
9278 |
9279 | for (i = 0; i < proto->fields->len; i++) {
9280 | hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9281 | if (hfi->id == hf_id) {
9282 | /* Found the hf_id in this protocol */
9283 | wmem_map_remove(gpa_name_map, hfi->abbrev);
9284 | g_ptr_array_remove_index_fast(proto->fields, i);
9285 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9286 | return;
9287 | }
9288 | }
9289 | }
9290 |
9291 | /* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9292 | void
9293 | proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9294 | {
9295 | header_field_info *hfinfo;
9296 | protocol_t *proto;
9297 |
9298 | 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);
9299 | last_field_name = NULL((void*)0);
9300 |
9301 | proto = find_protocol_by_id(parent);
9302 | if (proto && proto->fields && proto->fields->len > 0) {
9303 | unsigned i = proto->fields->len;
9304 | do {
9305 | i--;
9306 |
9307 | hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9308 | 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) )) {
9309 | hfinfo_remove_from_gpa_name_map(hfinfo);
9310 | expert_deregister_expertinfo(hfinfo->abbrev);
9311 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9312 | g_ptr_array_remove_index_fast(proto->fields, i);
9313 | }
9314 | } while (i > 0);
9315 | }
9316 | }
9317 |
9318 | void
9319 | proto_add_deregistered_data (void *data)
9320 | {
9321 | g_ptr_array_add(deregistered_data, data);
9322 | }
9323 |
9324 | void
9325 | proto_add_deregistered_slice (size_t block_size, void *mem_block)
9326 | {
9327 | 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)));
9328 |
9329 | slice_data->block_size = block_size;
9330 | slice_data->mem_block = mem_block;
9331 |
9332 | g_ptr_array_add(deregistered_slice, slice_data);
9333 | }
9334 |
9335 | void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9336 | {
9337 | if (field_strings == NULL((void*)0)) {
9338 | return;
9339 | }
9340 |
9341 | switch (field_type) {
9342 | case FT_FRAMENUM:
9343 | /* This is just an integer represented as a pointer */
9344 | break;
9345 | case FT_PROTOCOL: {
9346 | protocol_t *protocol = (protocol_t *)field_strings;
9347 | 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);
9348 | break;
9349 | }
9350 | case FT_BOOLEAN: {
9351 | true_false_string *tf = (true_false_string *)field_strings;
9352 | 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);
9353 | 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);
9354 | break;
9355 | }
9356 | case FT_UINT40:
9357 | case FT_INT40:
9358 | case FT_UINT48:
9359 | case FT_INT48:
9360 | case FT_UINT56:
9361 | case FT_INT56:
9362 | case FT_UINT64:
9363 | case FT_INT64: {
9364 | if (field_display & BASE_UNIT_STRING0x00001000) {
9365 | unit_name_string *unit = (unit_name_string *)field_strings;
9366 | 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);
9367 | 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);
9368 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9369 | range_string *rs = (range_string *)field_strings;
9370 | while (rs->strptr) {
9371 | 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 );
9372 | rs++;
9373 | }
9374 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9375 | val64_string_ext *vse = (val64_string_ext *)field_strings;
9376 | val64_string *vs = (val64_string *)vse->_vs_p;
9377 | while (vs->strptr) {
9378 | 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 );
9379 | vs++;
9380 | }
9381 | val64_string_ext_free(vse);
9382 | field_strings = NULL((void*)0);
9383 | } else if (field_display == BASE_CUSTOM) {
9384 | /* this will be a pointer to a function, don't free that */
9385 | field_strings = NULL((void*)0);
9386 | } else {
9387 | val64_string *vs64 = (val64_string *)field_strings;
9388 | while (vs64->strptr) {
9389 | 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);
9390 | vs64++;
9391 | }
9392 | }
9393 | break;
9394 | }
9395 | case FT_CHAR:
9396 | case FT_UINT8:
9397 | case FT_INT8:
9398 | case FT_UINT16:
9399 | case FT_INT16:
9400 | case FT_UINT24:
9401 | case FT_INT24:
9402 | case FT_UINT32:
9403 | case FT_INT32:
9404 | case FT_FLOAT:
9405 | case FT_DOUBLE: {
9406 | if (field_display & BASE_UNIT_STRING0x00001000) {
9407 | unit_name_string *unit = (unit_name_string *)field_strings;
9408 | 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);
9409 | 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);
9410 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9411 | range_string *rs = (range_string *)field_strings;
9412 | while (rs->strptr) {
9413 | 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 );
9414 | rs++;
9415 | }
9416 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9417 | value_string_ext *vse = (value_string_ext *)field_strings;
9418 | value_string *vs = (value_string *)vse->_vs_p;
9419 | while (vs->strptr) {
9420 | 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 );
9421 | vs++;
9422 | }
9423 | value_string_ext_free(vse);
9424 | field_strings = NULL((void*)0);
9425 | } else if (field_display == BASE_CUSTOM) {
9426 | /* this will be a pointer to a function, don't free that */
9427 | field_strings = NULL((void*)0);
9428 | } else {
9429 | value_string *vs = (value_string *)field_strings;
9430 | while (vs->strptr) {
9431 | 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 );
9432 | vs++;
9433 | }
9434 | }
9435 | break;
9436 | default:
9437 | break;
9438 | }
9439 | }
9440 |
9441 | if (field_type != FT_FRAMENUM) {
9442 | 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 );
9443 | }
9444 | }
9445 |
9446 | static void
9447 | free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9448 | {
9449 | header_field_info *hfi = (header_field_info *) data;
9450 | int hf_id = hfi->id;
9451 |
9452 | 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 );
9453 | 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 );
9454 | 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 );
9455 |
9456 | proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9457 |
9458 | if (hfi->parent == -1)
9459 | 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);
9460 |
9461 | gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9462 | }
9463 |
9464 | static void
9465 | free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9466 | {
9467 | g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized (data, __builtin_object_size ((data), 0)) : (g_free) (data);
9468 | }
9469 |
9470 | static void
9471 | free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9472 | {
9473 | struct g_slice_data *slice_data = (struct g_slice_data *)data;
9474 |
9475 | g_slice_free1(slice_data->block_size, slice_data->mem_block);
9476 | 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);
9477 | }
9478 |
9479 | /* free deregistered fields and data */
9480 | void
9481 | proto_free_deregistered_fields (void)
9482 | {
9483 | expert_free_deregistered_expertinfos();
9484 |
9485 | g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9486 | g_ptr_array_free(deregistered_fields, true1);
9487 | deregistered_fields = g_ptr_array_new();
9488 |
9489 | g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9490 | g_ptr_array_free(deregistered_data, true1);
9491 | deregistered_data = g_ptr_array_new();
9492 |
9493 | g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9494 | g_ptr_array_free(deregistered_slice, true1);
9495 | deregistered_slice = g_ptr_array_new();
9496 | }
9497 |
9498 | static const value_string hf_display[] = {
9499 | { BASE_NONE, "BASE_NONE" },
9500 | { BASE_DEC, "BASE_DEC" },
9501 | { BASE_HEX, "BASE_HEX" },
9502 | { BASE_OCT, "BASE_OCT" },
9503 | { BASE_DEC_HEX, "BASE_DEC_HEX" },
9504 | { BASE_HEX_DEC, "BASE_HEX_DEC" },
9505 | { BASE_CUSTOM, "BASE_CUSTOM" },
9506 | { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9507 | { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9508 | { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9509 | { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9510 | { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9511 | { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9512 | { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9513 | { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9514 | { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9515 | { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9516 | { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9517 | { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9518 | { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9519 | { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9520 | { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9521 | { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9522 | { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9523 | { BASE_PT_UDP, "BASE_PT_UDP" },
9524 | { BASE_PT_TCP, "BASE_PT_TCP" },
9525 | { BASE_PT_DCCP, "BASE_PT_DCCP" },
9526 | { BASE_PT_SCTP, "BASE_PT_SCTP" },
9527 | { BASE_OUI, "BASE_OUI" },
9528 | { 0, NULL((void*)0) } };
9529 |
9530 | const char* proto_field_display_to_string(int field_display)
9531 | {
9532 | return val_to_str_const(field_display, hf_display, "Unknown");
9533 | }
9534 |
9535 | static inline port_type
9536 | display_to_port_type(field_display_e e)
9537 | {
9538 | switch (e) {
9539 | case BASE_PT_UDP:
9540 | return PT_UDP;
9541 | case BASE_PT_TCP:
9542 | return PT_TCP;
9543 | case BASE_PT_DCCP:
9544 | return PT_DCCP;
9545 | case BASE_PT_SCTP:
9546 | return PT_SCTP;
9547 | default:
9548 | break;
9549 | }
9550 | return PT_NONE;
9551 | }
9552 |
9553 | /* temporary function containing assert part for easier profiling */
9554 | static void
9555 | tmp_fld_check_assert(header_field_info *hfinfo)
9556 | {
9557 | char* tmp_str;
9558 |
9559 | /* The field must have a name (with length > 0) */
9560 | if (!hfinfo->name || !hfinfo->name[0]) {
9561 | if (hfinfo->abbrev)
9562 | /* Try to identify the field */
9563 | 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)
9564 | hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name" , hfinfo->abbrev);
9565 | else
9566 | /* Hum, no luck */
9567 | 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)" );
9568 | }
9569 |
9570 | /* fields with an empty string for an abbreviation aren't filterable */
9571 | if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9572 | 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);
9573 |
9574 | /* TODO: This check is a significant percentage of startup time (~10%),
9575 | although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9576 | It might be nice to have a way to disable this check when, e.g.,
9577 | running TShark many times with the same configuration. */
9578 | /* Check that the filter name (abbreviation) is legal;
9579 | * it must contain only alphanumerics, '-', "_", and ".". */
9580 | unsigned char c;
9581 | c = module_check_valid_name(hfinfo->abbrev, false0);
9582 | if (c) {
9583 | if (c == '.') {
9584 | 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);
9585 | } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9586 | 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);
9587 | } else {
9588 | 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);
9589 | }
9590 | }
9591 |
9592 | /* These types of fields are allowed to have value_strings,
9593 | * true_false_strings or a protocol_t struct
9594 | */
9595 | if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9596 | switch (hfinfo->type) {
9597 |
9598 | /*
9599 | * These types are allowed to support display value_strings,
9600 | * value64_strings, the extended versions of the previous
9601 | * two, range strings, or unit strings.
9602 | */
9603 | case FT_CHAR:
9604 | case FT_UINT8:
9605 | case FT_UINT16:
9606 | case FT_UINT24:
9607 | case FT_UINT32:
9608 | case FT_UINT40:
9609 | case FT_UINT48:
9610 | case FT_UINT56:
9611 | case FT_UINT64:
9612 | case FT_INT8:
9613 | case FT_INT16:
9614 | case FT_INT24:
9615 | case FT_INT32:
9616 | case FT_INT40:
9617 | case FT_INT48:
9618 | case FT_INT56:
9619 | case FT_INT64:
9620 | case FT_BOOLEAN:
9621 | case FT_PROTOCOL:
9622 | break;
9623 |
9624 | /*
9625 | * This is allowed to have a value of type
9626 | * enum ft_framenum_type to indicate what relationship
9627 | * the frame in question has to the frame in which
9628 | * the field is put.
9629 | */
9630 | case FT_FRAMENUM:
9631 | break;
9632 |
9633 | /*
9634 | * These types are allowed to support only unit strings.
9635 | */
9636 | case FT_FLOAT:
9637 | case FT_DOUBLE:
9638 | case FT_IEEE_11073_SFLOAT:
9639 | case FT_IEEE_11073_FLOAT:
9640 | if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9641 | 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))
9642 | " (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))
9643 | 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));
9644 | }
9645 | break;
9646 |
9647 | /*
9648 | * These types are allowed to support display
9649 | * time_value_strings.
9650 | */
9651 | case FT_ABSOLUTE_TIME:
9652 | if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9653 | hfinfo->display & BASE_EXT_STRING0x00000200 ||
9654 | hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9655 | hfinfo->display & BASE_UNIT_STRING0x00001000) {
9656 | 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))
9657 | " (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))
9658 | 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));
9659 | }
9660 | break;
9661 |
9662 | /*
9663 | * This type is only allowed to support a string if it's
9664 | * a protocol (for pinos).
9665 | */
9666 | case FT_BYTES:
9667 | if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9668 | 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))
9669 | " (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))
9670 | 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));
9671 | }
9672 | break;
9673 |
9674 | default:
9675 | 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))
9676 | " (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))
9677 | 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));
9678 | }
9679 | }
9680 |
9681 | /* TODO: This check may slow down startup, and output quite a few warnings.
9682 | It would be good to be able to enable this (and possibly other checks?)
9683 | in non-release builds. */
9684 | #ifdef ENABLE_CHECK_FILTER
9685 | /* Check for duplicate value_string values.
9686 | There are lots that have the same value *and* string, so for now only
9687 | report those that have same value but different string. */
9688 | if ((hfinfo->strings != NULL((void*)0)) &&
9689 | !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9690 | !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9691 | !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9692 | (
9693 | (hfinfo->type == FT_CHAR) ||
9694 | (hfinfo->type == FT_UINT8) ||
9695 | (hfinfo->type == FT_UINT16) ||
9696 | (hfinfo->type == FT_UINT24) ||
9697 | (hfinfo->type == FT_UINT32) ||
9698 | (hfinfo->type == FT_INT8) ||
9699 | (hfinfo->type == FT_INT16) ||
9700 | (hfinfo->type == FT_INT24) ||
9701 | (hfinfo->type == FT_INT32) )) {
9702 |
9703 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9704 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9705 | const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9706 | CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9707 | } else {
9708 | const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9709 | CHECK_HF_VALUE(value_string, "u", start_values);
9710 | }
9711 | } else {
9712 | const value_string *start_values = (const value_string*)hfinfo->strings;
9713 | CHECK_HF_VALUE(value_string, "u", start_values);
9714 | }
9715 | }
9716 |
9717 | if (hfinfo->type == FT_BOOLEAN) {
9718 | const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9719 | if (tfs) {
9720 | if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9721 | ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9723 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string)
9722 | hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9723 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string)
9723 | tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9723 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string);
9724 | }
9725 | }
9726 | }
9727 |
9728 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9729 | const range_string *rs = (const range_string*)(hfinfo->strings);
9730 | if (rs) {
9731 | const range_string *this_it = rs;
9732 |
9733 | do {
9734 | if (this_it->value_max < this_it->value_min) {
9735 | 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" , 9739, __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)
9736 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9739, __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)
9737 | this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9739, __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)
9738 | this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9739, __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)
9739 | this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9739, __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);
9740 | ++this_it;
9741 | continue;
9742 | }
9743 |
9744 | for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9745 | /* Not OK if this one is completely hidden by an earlier one! */
9746 | if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9747 | 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" , 9753, __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)
9748 | "(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" , 9753, __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)
9749 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9753, __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)
9750 | prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9753, __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)
9751 | prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9753, __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)
9752 | this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9753, __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)
9753 | this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9753, __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);
9754 | }
9755 | }
9756 | ++this_it;
9757 | } while (this_it->strptr);
9758 | }
9759 | }
9760 | #endif
9761 |
9762 | switch (hfinfo->type) {
9763 |
9764 | case FT_CHAR:
9765 | /* Require the char type to have BASE_HEX, BASE_OCT,
9766 | * BASE_CUSTOM, or BASE_NONE as its base.
9767 | *
9768 | * If the display value is BASE_NONE and there is a
9769 | * strings conversion then the dissector writer is
9770 | * telling us that the field's numerical value is
9771 | * meaningless; we'll avoid showing the value to the
9772 | * user.
9773 | */
9774 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9775 | case BASE_HEX:
9776 | case BASE_OCT:
9777 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9778 | break;
9779 | case BASE_NONE:
9780 | if (hfinfo->strings == NULL((void*)0))
9781 | 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 ))
9782 | " 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 ))
9783 | " 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 ))
9784 | 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 ))
9785 | 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 ));
9786 | break;
9787 | default:
9788 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9789 | 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)
9790 | " 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)
9791 | 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)
9792 | 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);
9793 | //wmem_free(NULL, tmp_str);
9794 | }
9795 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9796 | 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 ))
9797 | 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 ))
9798 | 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 ));
9799 | }
9800 | break;
9801 | case FT_INT8:
9802 | case FT_INT16:
9803 | case FT_INT24:
9804 | case FT_INT32:
9805 | case FT_INT40:
9806 | case FT_INT48:
9807 | case FT_INT56:
9808 | case FT_INT64:
9809 | /* Hexadecimal and octal are, in printf() and everywhere
9810 | * else, unsigned so don't allow dissectors to register a
9811 | * signed field to be displayed unsigned. (Else how would
9812 | * we display negative values?)
9813 | */
9814 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9815 | case BASE_HEX:
9816 | case BASE_OCT:
9817 | case BASE_DEC_HEX:
9818 | case BASE_HEX_DEC:
9819 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9820 | 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)
9821 | 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)
9822 | 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);
9823 | //wmem_free(NULL, tmp_str);
9824 | }
9825 | /* FALL THROUGH */
9826 | case FT_UINT8:
9827 | case FT_UINT16:
9828 | case FT_UINT24:
9829 | case FT_UINT32:
9830 | case FT_UINT40:
9831 | case FT_UINT48:
9832 | case FT_UINT56:
9833 | case FT_UINT64:
9834 | 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 ))) {
9835 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9836 | if (hfinfo->type != FT_UINT16) {
9837 | 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))
9838 | 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))
9839 | 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));
9840 | }
9841 | if (hfinfo->strings != NULL((void*)0)) {
9842 | 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)
9843 | 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)
9844 | 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);
9845 | }
9846 | if (hfinfo->bitmask != 0) {
9847 | 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)
9848 | 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)
9849 | 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);
9850 | }
9851 | wmem_free(NULL((void*)0), tmp_str);
9852 | break;
9853 | }
9854 |
9855 | if (hfinfo->display == BASE_OUI) {
9856 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9857 | 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) {
9858 | 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))
9859 | 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))
9860 | 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));
9861 | }
9862 | if (hfinfo->strings != NULL((void*)0)) {
9863 | 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)
9864 | 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)
9865 | 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);
9866 | }
9867 | /* It can be a FT_UINT24 with a 0 bitmask, or
9868 | * larger with a bitmask with 24 bits set. */
9869 | if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9870 | 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)
9871 | 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)
9872 | 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);
9873 | }
9874 | wmem_free(NULL((void*)0), tmp_str);
9875 | break;
9876 | }
9877 |
9878 | /* Require integral types (other than frame number,
9879 | * which is always displayed in decimal) to have a
9880 | * number base.
9881 | *
9882 | * If the display value is BASE_NONE and there is a
9883 | * strings conversion then the dissector writer is
9884 | * telling us that the field's numerical value is
9885 | * meaningless; we'll avoid showing the value to the
9886 | * user.
9887 | */
9888 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9889 | case BASE_DEC:
9890 | case BASE_HEX:
9891 | case BASE_OCT:
9892 | case BASE_DEC_HEX:
9893 | case BASE_HEX_DEC:
9894 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9895 | break;
9896 | case BASE_NONE:
9897 | if (hfinfo->strings == NULL((void*)0)) {
9898 | 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 ))
9899 | " 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 ))
9900 | " 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 ))
9901 | 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 ))
9902 | 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 ));
9903 | }
9904 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9905 | 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 ))
9906 | " 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 ))
9907 | " 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 ))
9908 | 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 ))
9909 | 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 ));
9910 | }
9911 | break;
9912 |
9913 | default:
9914 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9915 | 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)
9916 | " 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)
9917 | 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)
9918 | 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);
9919 | //wmem_free(NULL, tmp_str);
9920 | }
9921 | break;
9922 | case FT_BYTES:
9923 | case FT_UINT_BYTES:
9924 | /* Require bytes to have a "display type" that could
9925 | * add a character between displayed bytes.
9926 | */
9927 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9928 | case BASE_NONE:
9929 | case SEP_DOT:
9930 | case SEP_DASH:
9931 | case SEP_COLON:
9932 | case SEP_SPACE:
9933 | break;
9934 | default:
9935 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9936 | 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)
9937 | 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);
9938 | //wmem_free(NULL, tmp_str);
9939 | }
9940 | if (hfinfo->bitmask != 0)
9941 | 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 ))
9942 | 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 ))
9943 | 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 ));
9944 | //allowed to support string if its a protocol (for pinos)
9945 | if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9946 | 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 ))
9947 | 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 ))
9948 | 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 ));
9949 | break;
9950 |
9951 | case FT_PROTOCOL:
9952 | case FT_FRAMENUM:
9953 | if (hfinfo->display != BASE_NONE) {
9954 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9955 | 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)
9956 | 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)
9957 | 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);
9958 | //wmem_free(NULL, tmp_str);
9959 | }
9960 | if (hfinfo->bitmask != 0)
9961 | 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 ))
9962 | 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 ))
9963 | 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 ));
9964 | break;
9965 |
9966 | case FT_BOOLEAN:
9967 | break;
9968 |
9969 | case FT_ABSOLUTE_TIME:
9970 | if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL && ((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)) {
9971 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9972 | 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)
9973 | 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);
9974 | //wmem_free(NULL, tmp_str);
9975 | }
9976 | if (hfinfo->bitmask != 0)
9977 | 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 ))
9978 | 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 ))
9979 | 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 ));
9980 | break;
9981 |
9982 | case FT_STRING:
9983 | case FT_STRINGZ:
9984 | case FT_UINT_STRING:
9985 | case FT_STRINGZPAD:
9986 | case FT_STRINGZTRUNC:
9987 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9988 | case BASE_NONE:
9989 | case BASE_STR_WSP:
9990 | break;
9991 |
9992 | default:
9993 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9994 | 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)
9995 | " 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)
9996 | 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)
9997 | 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);
9998 | //wmem_free(NULL, tmp_str);
9999 | }
10000 |
10001 | if (hfinfo->bitmask != 0)
10002 | 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 ))
10003 | 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 ))
10004 | 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 ));
10005 | if (hfinfo->strings != NULL((void*)0))
10006 | 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 ))
10007 | 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 ))
10008 | 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 ));
10009 | break;
10010 |
10011 | case FT_IPv4:
10012 | switch (hfinfo->display) {
10013 | case BASE_NONE:
10014 | case BASE_NETMASK:
10015 | break;
10016 |
10017 | default:
10018 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10019 | 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)
10020 | " 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)
10021 | 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)
10022 | 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);
10023 | //wmem_free(NULL, tmp_str);
10024 | break;
10025 | }
10026 | break;
10027 | case FT_FLOAT:
10028 | case FT_DOUBLE:
10029 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
10030 | case BASE_NONE:
10031 | case BASE_DEC:
10032 | case BASE_HEX:
10033 | case BASE_EXP:
10034 | case BASE_CUSTOM:
10035 | break;
10036 | default:
10037 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
10038 | 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)
10039 | " 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)
10040 | 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)
10041 | 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);
10042 | //wmem_free(NULL, tmp_str);
10043 | }
10044 | if (hfinfo->bitmask != 0)
10045 | 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 ))
10046 | 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 ))
10047 | 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 ));
10048 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
10049 | 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 ))
10050 | 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 ))
10051 | 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 ));
10052 | break;
10053 | case FT_IEEE_11073_SFLOAT:
10054 | case FT_IEEE_11073_FLOAT:
10055 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
10056 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10057 | 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)
10058 | 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)
10059 | 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)
10060 | 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);
10061 | //wmem_free(NULL, tmp_str);
10062 | }
10063 | if (hfinfo->bitmask != 0)
10064 | 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 ))
10065 | 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 ))
10066 | 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 ));
10067 | if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
10068 | 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 ))
10069 | 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 ))
10070 | 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 ));
10071 | break;
10072 | default:
10073 | if (hfinfo->display != BASE_NONE) {
10074 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
10075 | 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)
10076 | 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)
10077 | 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)
10078 | 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);
10079 | //wmem_free(NULL, tmp_str);
10080 | }
10081 | if (hfinfo->bitmask != 0)
10082 | 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 ))
10083 | 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 ))
10084 | 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 ));
10085 | if (hfinfo->strings != NULL((void*)0))
10086 | 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 ))
10087 | 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 ))
10088 | 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 ));
10089 | break;
10090 | }
10091 | }
10092 |
10093 | static void
10094 | register_type_length_mismatch(void)
10095 | {
10096 | static ei_register_info ei[] = {
10097 | { &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)}} }},
10098 | { &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)}} }},
10099 | };
10100 |
10101 | expert_module_t* expert_type_length_mismatch;
10102 |
10103 | proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
10104 |
10105 | expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
10106 | expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10107 |
10108 | /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
10109 | disabling them makes no sense. */
10110 | proto_set_cant_toggle(proto_type_length_mismatch);
10111 | }
10112 |
10113 | static void
10114 | register_byte_array_string_decodinws_error(void)
10115 | {
10116 | static ei_register_info ei[] = {
10117 | { &ei_byte_array_string_decoding_failed_error,
10118 | { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10119 | "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)}}
10120 | }
10121 | },
10122 | };
10123 |
10124 | expert_module_t* expert_byte_array_string_decoding_error;
10125 |
10126 | proto_byte_array_string_decoding_error =
10127 | proto_register_protocol("Byte Array-String Decoding Error",
10128 | "Byte Array-string decoding error",
10129 | "_ws.byte_array_string.decoding_error");
10130 |
10131 | expert_byte_array_string_decoding_error =
10132 | expert_register_protocol(proto_byte_array_string_decoding_error);
10133 | expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10134 |
10135 | /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10136 | disabling them makes no sense. */
10137 | proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10138 | }
10139 |
10140 | static void
10141 | register_date_time_string_decodinws_error(void)
10142 | {
10143 | static ei_register_info ei[] = {
10144 | { &ei_date_time_string_decoding_failed_error,
10145 | { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10146 | "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)}}
10147 | }
10148 | },
10149 | };
10150 |
10151 | expert_module_t* expert_date_time_string_decoding_error;
10152 |
10153 | proto_date_time_string_decoding_error =
10154 | proto_register_protocol("Date and Time-String Decoding Error",
10155 | "Date and Time-string decoding error",
10156 | "_ws.date_time_string.decoding_error");
10157 |
10158 | expert_date_time_string_decoding_error =
10159 | expert_register_protocol(proto_date_time_string_decoding_error);
10160 | expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10161 |
10162 | /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10163 | disabling them makes no sense. */
10164 | proto_set_cant_toggle(proto_date_time_string_decoding_error);
10165 | }
10166 |
10167 | static void
10168 | register_string_errors(void)
10169 | {
10170 | static ei_register_info ei[] = {
10171 | { &ei_string_trailing_characters,
10172 | { "_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)}} }
10173 | },
10174 | };
10175 |
10176 | expert_module_t* expert_string_errors;
10177 |
10178 | proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10179 |
10180 | expert_string_errors = expert_register_protocol(proto_string_errors);
10181 | expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10182 |
10183 | /* "String Errors" isn't really a protocol, it's an error indication;
10184 | disabling them makes no sense. */
10185 | proto_set_cant_toggle(proto_string_errors);
10186 | }
10187 |
10188 | static void
10189 | register_varint_errors(void)
10190 | {
10191 | static ei_register_info ei[] = {
10192 | { &ei_varint_decoding_failed_error,
10193 | { "_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)}} }
10194 | },
10195 | };
10196 |
10197 | expert_module_t* expert_varint_errors;
10198 |
10199 | proto_varint_errors = proto_register_protocol("Varint Errors", "Varint errors", "_ws.varint");
10200 |
10201 | expert_varint_errors = expert_register_protocol(proto_varint_errors);
10202 | expert_register_field_array(expert_varint_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10203 |
10204 | /* "Varint Errors" isn't really a protocol, it's an error indication;
10205 | disabling them makes no sense. */
10206 | proto_set_cant_toggle(proto_varint_errors);
10207 | }
10208 |
10209 | static int
10210 | proto_register_field_init(header_field_info *hfinfo, const int parent)
10211 | {
10212 |
10213 | tmp_fld_check_assert(hfinfo);
10214 |
10215 | hfinfo->parent = parent;
10216 | hfinfo->same_name_next = NULL((void*)0);
10217 | hfinfo->same_name_prev_id = -1;
10218 |
10219 | /* if we always add and never delete, then id == len - 1 is correct */
10220 | if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10221 | if (!gpa_hfinfo.hfi) {
10222 | gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10223 | gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10224 | /* The entry with index 0 is not used. */
10225 | gpa_hfinfo.hfi[0] = NULL((void*)0);
10226 | gpa_hfinfo.len = 1;
10227 | } else {
10228 | gpa_hfinfo.allocated_len += 1000;
10229 | gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10230 | sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10231 | /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10232 | }
10233 | }
10234 | gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10235 | gpa_hfinfo.len++;
10236 | hfinfo->id = gpa_hfinfo.len - 1;
10237 |
10238 | /* if we have real names, enter this field in the name tree */
10239 | /* Already checked in tmp_fld_check_assert */
10240 | /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10241 | {
10242 |
10243 | header_field_info *same_name_next_hfinfo;
10244 |
10245 | /* We allow multiple hfinfo's to be registered under the same
10246 | * abbreviation. This was done for X.25, as, depending
10247 | * on whether it's modulo-8 or modulo-128 operation,
10248 | * some bitfield fields may be in different bits of
10249 | * a byte, and we want to be able to refer to that field
10250 | * with one name regardless of whether the packets
10251 | * are modulo-8 or modulo-128 packets. */
10252 |
10253 | /* wmem_map_insert - if key is already present the previous
10254 | * hfinfo with the same key/name is returned, otherwise NULL */
10255 | same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10256 | if (same_name_hfinfo) {
10257 | /* There's already a field with this name.
10258 | * Put the current field *before* that field
10259 | * in the list of fields with this name, Thus,
10260 | * we end up with an effectively
10261 | * doubly-linked-list of same-named hfinfo's,
10262 | * with the head of the list (stored in the
10263 | * hash) being the last seen hfinfo.
10264 | */
10265 | same_name_next_hfinfo =
10266 | same_name_hfinfo->same_name_next;
10267 |
10268 | hfinfo->same_name_next = same_name_next_hfinfo;
10269 | if (same_name_next_hfinfo)
10270 | same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10271 |
10272 | same_name_hfinfo->same_name_next = hfinfo;
10273 | hfinfo->same_name_prev_id = same_name_hfinfo->id;
10274 | #ifdef ENABLE_CHECK_FILTER
10275 | while (same_name_hfinfo) {
10276 | if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10277 | 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", 10277 , __func__, "'%s' exists multiple times with incompatible types: %s and %s" , hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name( same_name_hfinfo->type));
10278 | same_name_hfinfo = same_name_hfinfo->same_name_next;
10279 | }
10280 | #endif
10281 | }
10282 | }
10283 |
10284 | return hfinfo->id;
10285 | }
10286 |
10287 | void
10288 | proto_register_subtree_array(int * const *indices, const int num_indices)
10289 | {
10290 | int i;
10291 | int *const *ptr = indices;
10292 |
10293 | /*
10294 | * If we've already allocated the array of tree types, expand
10295 | * it; this lets plugins such as mate add tree types after
10296 | * the initial startup. (If we haven't already allocated it,
10297 | * we don't allocate it; on the first pass, we just assign
10298 | * ett values and keep track of how many we've assigned, and
10299 | * when we're finished registering all dissectors we allocate
10300 | * the array, so that we do only one allocation rather than
10301 | * wasting CPU time and memory by growing the array for each
10302 | * dissector that registers ett values.)
10303 | */
10304 | if (tree_is_expanded != NULL((void*)0)) {
10305 | tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10306 |
10307 | /* set new items to 0 */
10308 | /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10309 | for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10310 | tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10311 | }
10312 |
10313 | /*
10314 | * Assign "num_indices" subtree numbers starting at "num_tree_types",
10315 | * returning the indices through the pointers in the array whose
10316 | * first element is pointed to by "indices", and update
10317 | * "num_tree_types" appropriately.
10318 | */
10319 | for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10320 | if (**ptr != -1 && **ptr != 0) {
10321 | 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.")
10322 | " 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.")
10323 | " 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.")
10324 | " 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.");
10325 | }
10326 | **ptr = num_tree_types;
10327 | }
10328 | }
10329 |
10330 | static void
10331 | mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10332 | {
10333 | static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10334 | const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10335 | char *last_char;
10336 |
10337 | /* ..... field_name: dataaaaaaaaaaaaa
10338 | * |
10339 | * ^^^^^ name_pos
10340 | *
10341 | * ..... field_name […]: dataaaaaaaaaaaaa
10342 | *
10343 | * name_pos==0 means that we have only data or only a field_name
10344 | */
10345 |
10346 | ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10346, __func__, "assertion failed: %s" , "size > trunc_len"); } while (0);
10347 |
10348 | if (name_pos >= size - trunc_len) {
10349 | /* No room for trunc_str after the field_name, put it first. */
10350 | name_pos = 0;
10351 | }
10352 |
10353 | memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10354 | if (name_pos == 0) {
10355 | /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10356 | memcpy(label_str, trunc_str + 1, trunc_len);
10357 | } else {
10358 | memcpy(label_str + name_pos, trunc_str, trunc_len);
10359 | }
10360 | /* in general, label_str is UTF-8
10361 | we can truncate it only at the beginning of a new character
10362 | we go backwards from the byte right after our buffer and
10363 | find the next starting byte of a UTF-8 character, this is
10364 | where we cut
10365 | there's no need to use g_utf8_find_prev_char(), the search
10366 | will always succeed since we copied trunc_str into the
10367 | buffer */
10368 | /* g_utf8_prev_char does not deference the memory address
10369 | * passed in (until after decrementing it, so it is perfectly
10370 | * legal to pass in a pointer one past the last element.
10371 | */
10372 | last_char = g_utf8_prev_char(label_str + size);
10373 | *last_char = '\0';
10374 | /* This is unnecessary (above always terminates), but try to
10375 | * convince Coverity to avoid dozens of false positives. */
10376 | label_str[size - 1] = '\0';
10377 |
10378 | if (value_pos && *value_pos > 0) {
10379 | if (name_pos == 0) {
10380 | *value_pos += trunc_len;
10381 | } else {
10382 | /* Move one back to include trunc_str in the value. */
10383 | *value_pos -= 1;
10384 | }
10385 | }
10386 |
10387 | /* Check if value_pos is past label_str. */
10388 | if (value_pos && *value_pos >= size) {
10389 | *value_pos = size - 1;
10390 | }
10391 | }
10392 |
10393 | static void
10394 | label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10395 | {
10396 | mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10397 | }
10398 |
10399 | static size_t
10400 | label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10401 | {
10402 | size_t name_pos;
10403 |
10404 | /* "%s: %s", hfinfo->name, text */
10405 | 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);
10406 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10407 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10408 | if (value_pos) {
10409 | *value_pos = pos;
10410 | }
10411 | pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10412 | }
10413 |
10414 | if (pos >= ITEM_LABEL_LENGTH240) {
10415 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10416 | label_mark_truncated(label_str, name_pos, value_pos);
10417 | }
10418 |
10419 | return pos;
10420 | }
10421 |
10422 | static size_t
10423 | label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10424 | {
10425 | size_t name_pos;
10426 |
10427 | /* "%s: %s (%s)", hfinfo->name, text, descr */
10428 | 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);
10429 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10430 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10431 | if (value_pos) {
10432 | *value_pos = pos;
10433 | }
10434 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10435 | 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);
10436 | 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);
10437 | } else {
10438 | 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);
10439 | pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10440 | 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);
10441 | pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10442 | }
10443 | }
10444 |
10445 | if (pos >= ITEM_LABEL_LENGTH240) {
10446 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10447 | label_mark_truncated(label_str, name_pos, value_pos);
10448 | }
10449 |
10450 | return pos;
10451 | }
10452 |
10453 | void
10454 | proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10455 | {
10456 | const header_field_info *hfinfo;
10457 | const char *str;
10458 | const uint8_t *bytes;
10459 | uint32_t integer;
10460 | const ipv4_addr_and_mask *ipv4;
10461 | const ipv6_addr_and_prefix *ipv6;
10462 | const e_guid_t *guid;
10463 | char *name;
10464 | address addr;
10465 | char *addr_str;
10466 | char *tmp;
10467 |
10468 | if (!label_str) {
10469 | ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10469, __func__, "NULL label_str passed to proto_item_fill_label." ); } } while (0);
10470 | return;
10471 | }
10472 |
10473 | label_str[0]= '\0';
10474 |
10475 | if (!fi) {
10476 | return;
10477 | }
10478 |
10479 | hfinfo = fi->hfinfo;
10480 |
10481 | switch (hfinfo->type) {
10482 | case FT_NONE:
10483 | case FT_PROTOCOL:
10484 | (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10485 | if (value_pos) {
10486 | *value_pos = strlen(hfinfo->name);
10487 | }
10488 | break;
10489 |
10490 | case FT_BOOLEAN:
10491 | fill_label_boolean(fi, label_str, value_pos);
10492 | break;
10493 |
10494 | case FT_BYTES:
10495 | case FT_UINT_BYTES:
10496 | tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10497 | fvalue_get_bytes_data(fi->value),
10498 | (unsigned)fvalue_length2(fi->value));
10499 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10500 | wmem_free(NULL((void*)0), tmp);
10501 | break;
10502 |
10503 | case FT_CHAR:
10504 | if (hfinfo->bitmask) {
10505 | fill_label_bitfield_char(fi, label_str, value_pos);
10506 | } else {
10507 | fill_label_char(fi, label_str, value_pos);
10508 | }
10509 | break;
10510 |
10511 | /* Four types of integers to take care of:
10512 | * Bitfield, with val_string
10513 | * Bitfield, w/o val_string
10514 | * Non-bitfield, with val_string
10515 | * Non-bitfield, w/o val_string
10516 | */
10517 | case FT_UINT8:
10518 | case FT_UINT16:
10519 | case FT_UINT24:
10520 | case FT_UINT32:
10521 | if (hfinfo->bitmask) {
10522 | fill_label_bitfield(fi, label_str, value_pos, false0);
10523 | } else {
10524 | fill_label_number(fi, label_str, value_pos, false0);
10525 | }
10526 | break;
10527 |
10528 | case FT_FRAMENUM:
10529 | fill_label_number(fi, label_str, value_pos, false0);
10530 | break;
10531 |
10532 | case FT_UINT40:
10533 | case FT_UINT48:
10534 | case FT_UINT56:
10535 | case FT_UINT64:
10536 | if (hfinfo->bitmask) {
10537 | fill_label_bitfield64(fi, label_str, value_pos, false0);
10538 | } else {
10539 | fill_label_number64(fi, label_str, value_pos, false0);
10540 | }
10541 | break;
10542 |
10543 | case FT_INT8:
10544 | case FT_INT16:
10545 | case FT_INT24:
10546 | case FT_INT32:
10547 | if (hfinfo->bitmask) {
10548 | fill_label_bitfield(fi, label_str, value_pos, true1);
10549 | } else {
10550 | fill_label_number(fi, label_str, value_pos, true1);
10551 | }
10552 | break;
10553 |
10554 | case FT_INT40:
10555 | case FT_INT48:
10556 | case FT_INT56:
10557 | case FT_INT64:
10558 | if (hfinfo->bitmask) {
10559 | fill_label_bitfield64(fi, label_str, value_pos, true1);
10560 | } else {
10561 | fill_label_number64(fi, label_str, value_pos, true1);
10562 | }
10563 | break;
10564 |
10565 | case FT_FLOAT:
10566 | case FT_DOUBLE:
10567 | fill_label_float(fi, label_str, value_pos);
10568 | break;
10569 |
10570 | case FT_ABSOLUTE_TIME:
10571 | {
10572 | const nstime_t *value = fvalue_get_time(fi->value);
10573 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10574 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10575 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10576 | }
10577 | if (hfinfo->strings) {
10578 | /*
10579 | * Table of time values to be displayed
10580 | * specially.
10581 | *
10582 | * XXX - Initializing these time_value_strings can be a pain
10583 | * because the special times usually have special values in
10584 | * the original encoding, not when converted to a nstime_t
10585 | * relative to the UN*X epoch.
10586 | */
10587 | const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10588 | if (time_string != NULL((void*)0)) {
10589 | label_fill(label_str, 0, hfinfo, time_string, value_pos);
10590 | break;
10591 | }
10592 | }
10593 | tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10594 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10595 | wmem_free(NULL((void*)0), tmp);
10596 | break;
10597 | }
10598 | case FT_RELATIVE_TIME:
10599 | tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10600 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10601 | wmem_free(NULL((void*)0), tmp);
10602 | break;
10603 |
10604 | case FT_IPXNET:
10605 | integer = fvalue_get_uinteger(fi->value);
10606 | tmp = get_ipxnet_name(NULL((void*)0), integer);
10607 | addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10608 | label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10609 | wmem_free(NULL((void*)0), tmp);
10610 | wmem_free(NULL((void*)0), addr_str);
10611 | break;
10612 |
10613 | case FT_VINES:
10614 | addr.type = AT_VINES;
10615 | addr.len = VINES_ADDR_LEN6;
10616 | addr.data = fvalue_get_bytes_data(fi->value);
10617 |
10618 | addr_str = (char*)address_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_ETHER:
10624 | bytes = fvalue_get_bytes_data(fi->value);
10625 |
10626 | addr.type = AT_ETHER;
10627 | addr.len = 6;
10628 | addr.data = bytes;
10629 |
10630 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10631 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10632 | wmem_free(NULL((void*)0), addr_str);
10633 | break;
10634 |
10635 | case FT_IPv4:
10636 | ipv4 = fvalue_get_ipv4(fi->value);
10637 | set_address_ipv4(&addr, ipv4);
10638 |
10639 | if (hfinfo->display == BASE_NETMASK) {
10640 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10641 | } else {
10642 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10643 | }
10644 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10645 | wmem_free(NULL((void*)0), addr_str);
10646 | free_address(&addr);
10647 | break;
10648 |
10649 | case FT_IPv6:
10650 | ipv6 = fvalue_get_ipv6(fi->value);
10651 | set_address_ipv6(&addr, ipv6);
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 | free_address(&addr);
10657 | break;
10658 |
10659 | case FT_FCWWN:
10660 | bytes = fvalue_get_bytes_data(fi->value);
10661 | addr.type = AT_FCWWN;
10662 | addr.len = FCWWN_ADDR_LEN8;
10663 | addr.data = bytes;
10664 |
10665 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10666 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10667 | wmem_free(NULL((void*)0), addr_str);
10668 | break;
10669 |
10670 | case FT_GUID:
10671 | guid = fvalue_get_guid(fi->value);
10672 | tmp = guid_to_str(NULL((void*)0), guid);
10673 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10674 | wmem_free(NULL((void*)0), tmp);
10675 | break;
10676 |
10677 | case FT_OID:
10678 | bytes = fvalue_get_bytes_data(fi->value);
10679 | name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10680 | tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10681 | if (name) {
10682 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10683 | wmem_free(NULL((void*)0), name);
10684 | } else {
10685 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10686 | }
10687 | wmem_free(NULL((void*)0), tmp);
10688 | break;
10689 |
10690 | case FT_REL_OID:
10691 | bytes = fvalue_get_bytes_data(fi->value);
10692 | name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10693 | tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10694 | if (name) {
10695 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10696 | wmem_free(NULL((void*)0), name);
10697 | } else {
10698 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10699 | }
10700 | wmem_free(NULL((void*)0), tmp);
10701 | break;
10702 |
10703 | case FT_SYSTEM_ID:
10704 | bytes = fvalue_get_bytes_data(fi->value);
10705 | tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10706 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10707 | wmem_free(NULL((void*)0), tmp);
10708 | break;
10709 |
10710 | case FT_EUI64:
10711 | bytes = fvalue_get_bytes_data(fi->value);
10712 | addr.type = AT_EUI64;
10713 | addr.len = EUI64_ADDR_LEN8;
10714 | addr.data = bytes;
10715 |
10716 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10717 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10718 | wmem_free(NULL((void*)0), addr_str);
10719 | break;
10720 | case FT_STRING:
10721 | case FT_STRINGZ:
10722 | case FT_UINT_STRING:
10723 | case FT_STRINGZPAD:
10724 | case FT_STRINGZTRUNC:
10725 | case FT_AX25:
10726 | str = fvalue_get_string(fi->value);
10727 | label_fill(label_str, 0, hfinfo, str, value_pos);
10728 | break;
10729 |
10730 | case FT_IEEE_11073_SFLOAT:
10731 | case FT_IEEE_11073_FLOAT:
10732 | fill_label_ieee_11073_float(fi, label_str, value_pos);
10733 | break;
10734 |
10735 | default:
10736 | 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 ))
10737 | 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 ))
10738 | 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 ))
10739 | 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 ));
10740 | break;
10741 | }
10742 | }
10743 |
10744 | static void
10745 | fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10746 | {
10747 | char *p;
10748 | unsigned bitfield_byte_length = 0;
10749 | int bitwidth;
10750 | uint64_t unshifted_value;
10751 | uint64_t value;
10752 |
10753 | const header_field_info *hfinfo = fi->hfinfo;
10754 |
10755 | value = fvalue_get_uinteger64(fi->value);
10756 | if (hfinfo->bitmask) {
10757 | /* Figure out the bit width */
10758 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10759 |
10760 | /* Un-shift bits */
10761 | unshifted_value = value;
10762 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10763 |
10764 | /* Create the bitfield first */
10765 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10766 | bitfield_byte_length = (unsigned) (p - label_str);
10767 | }
10768 |
10769 | /* Fill in the textual info */
10770 | label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10771 | }
10772 |
10773 | static const char *
10774 | hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10775 | {
10776 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10777 | return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10778 |
10779 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10780 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10781 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10782 | else
10783 | return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10784 | }
10785 |
10786 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10787 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10788 |
10789 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10790 | return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10791 |
10792 | return try_val_to_str(value, (const value_string *) hfinfo->strings);
10793 | }
10794 |
10795 | static const char *
10796 | hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10797 | {
10798 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10799 | if (hfinfo->display & BASE_EXT_STRING0x00000200)
10800 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10801 | else
10802 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10803 | }
10804 |
10805 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10806 | return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10807 |
10808 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10809 | return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10810 |
10811 | /* If this is reached somebody registered a 64-bit field with a 32-bit
10812 | * value-string, which isn't right. */
10813 | 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)
10814 | hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string" , hfinfo->abbrev);
10815 |
10816 | /* This is necessary to squelch MSVC errors; is there
10817 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10818 | never returns? */
10819 | return NULL((void*)0);
10820 | }
10821 |
10822 | static const char *
10823 | hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10824 | {
10825 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10826 | return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10827 |
10828 | 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);
10829 |
10830 | /* This is necessary to squelch MSVC errors; is there
10831 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10832 | never returns? */
10833 | return NULL((void*)0);
10834 | }
10835 |
10836 | static const char *
10837 | hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10838 | {
10839 | const char *str = hf_try_val_to_str(value, hfinfo);
10840 |
10841 | return (str) ? str : unknown_str;
10842 | }
10843 |
10844 | static const char *
10845 | hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10846 | {
10847 | const char *str = hf_try_val64_to_str(value, hfinfo);
10848 |
10849 | return (str) ? str : unknown_str;
10850 | }
10851 |
10852 | /* Fills data for bitfield chars with val_strings */
10853 | static void
10854 | fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10855 | {
10856 | char *p;
10857 | unsigned bitfield_byte_length;
10858 | int bitwidth;
10859 | uint32_t unshifted_value;
10860 | uint32_t value;
10861 |
10862 | char buf[32];
10863 | const char *out;
10864 |
10865 | const header_field_info *hfinfo = fi->hfinfo;
10866 |
10867 | /* Figure out the bit width */
10868 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10869 |
10870 | /* Un-shift bits */
10871 | value = fvalue_get_uinteger(fi->value);
10872 |
10873 | unshifted_value = value;
10874 | if (hfinfo->bitmask) {
10875 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10876 | }
10877 |
10878 | /* Create the bitfield first */
10879 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10880 | bitfield_byte_length = (unsigned) (p - label_str);
10881 |
10882 | /* Fill in the textual info using stored (shifted) value */
10883 | if (hfinfo->display == BASE_CUSTOM) {
10884 | char tmp[ITEM_LABEL_LENGTH240];
10885 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10886 |
10887 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10887, "fmtfunc"))));
10888 | fmtfunc(tmp, value);
10889 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10890 | }
10891 | else if (hfinfo->strings) {
10892 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10893 |
10894 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10895 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10896 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10897 | else
10898 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10899 | }
10900 | else {
10901 | out = hfinfo_char_value_format(hfinfo, buf, value);
10902 |
10903 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10904 | }
10905 | }
10906 |
10907 | /* Fills data for bitfield ints with val_strings */
10908 | static void
10909 | fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10910 | {
10911 | char *p;
10912 | unsigned bitfield_byte_length;
10913 | int bitwidth;
10914 | uint32_t value, unshifted_value;
10915 | char buf[NUMBER_LABEL_LENGTH80];
10916 | const char *out;
10917 |
10918 | const header_field_info *hfinfo = fi->hfinfo;
10919 |
10920 | /* Figure out the bit width */
10921 | if (fi->flags & FI_VARINT0x00040000)
10922 | bitwidth = fi->length*8;
10923 | else
10924 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10925 |
10926 | /* Un-shift bits */
10927 | if (is_signed)
10928 | value = fvalue_get_sinteger(fi->value);
10929 | else
10930 | value = fvalue_get_uinteger(fi->value);
10931 |
10932 | unshifted_value = value;
10933 | if (hfinfo->bitmask) {
10934 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10935 | }
10936 |
10937 | /* Create the bitfield first */
10938 | if (fi->flags & FI_VARINT0x00040000)
10939 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10940 | else
10941 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10942 | bitfield_byte_length = (unsigned) (p - label_str);
10943 |
10944 | /* Fill in the textual info using stored (shifted) value */
10945 | if (hfinfo->display == BASE_CUSTOM) {
10946 | char tmp[ITEM_LABEL_LENGTH240];
10947 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10948 |
10949 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10949, "fmtfunc"))));
10950 | fmtfunc(tmp, value);
10951 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10952 | }
10953 | else if (hfinfo->strings) {
10954 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10955 |
10956 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10957 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10958 | /*
10959 | * Unique values only display value_string string
10960 | * if there is a match. Otherwise it's just a number
10961 | */
10962 | if (val_str) {
10963 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10964 | } else {
10965 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10966 | }
10967 | } else {
10968 | if (val_str == NULL((void*)0))
10969 | val_str = "Unknown";
10970 |
10971 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10972 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10973 | else
10974 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10975 | }
10976 | }
10977 | else {
10978 | out = hfinfo_number_value_format(hfinfo, buf, value);
10979 |
10980 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10981 | }
10982 | }
10983 |
10984 | static void
10985 | fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10986 | {
10987 | char *p;
10988 | unsigned bitfield_byte_length;
10989 | int bitwidth;
10990 | uint64_t value, unshifted_value;
10991 | char buf[NUMBER_LABEL_LENGTH80];
10992 | const char *out;
10993 |
10994 | const header_field_info *hfinfo = fi->hfinfo;
10995 |
10996 | /* Figure out the bit width */
10997 | if (fi->flags & FI_VARINT0x00040000)
10998 | bitwidth = fi->length*8;
10999 | else
11000 | bitwidth = hfinfo_container_bitwidth(hfinfo);
11001 |
11002 | /* Un-shift bits */
11003 | if (is_signed)
11004 | value = fvalue_get_sinteger64(fi->value);
11005 | else
11006 | value = fvalue_get_uinteger64(fi->value);
11007 |
11008 | unshifted_value = value;
11009 | if (hfinfo->bitmask) {
11010 | unshifted_value <<= hfinfo_bitshift(hfinfo);
11011 | }
11012 |
11013 | /* Create the bitfield first */
11014 | if (fi->flags & FI_VARINT0x00040000)
11015 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11016 | else
11017 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
11018 | bitfield_byte_length = (unsigned) (p - label_str);
11019 |
11020 | /* Fill in the textual info using stored (shifted) value */
11021 | if (hfinfo->display == BASE_CUSTOM) {
11022 | char tmp[ITEM_LABEL_LENGTH240];
11023 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11024 |
11025 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 11025, "fmtfunc64" ))));
11026 | fmtfunc64(tmp, value);
11027 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
11028 | }
11029 | else if (hfinfo->strings) {
11030 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
11031 |
11032 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
11033 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11034 | /*
11035 | * Unique values only display value_string string
11036 | * if there is a match. Otherwise it's just a number
11037 | */
11038 | if (val_str) {
11039 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11040 | } else {
11041 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11042 | }
11043 | } else {
11044 | if (val_str == NULL((void*)0))
11045 | val_str = "Unknown";
11046 |
11047 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11048 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
11049 | else
11050 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
11051 | }
11052 | }
11053 | else {
11054 | out = hfinfo_number_value_format64(hfinfo, buf, value);
11055 |
11056 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
11057 | }
11058 | }
11059 |
11060 | static void
11061 | fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
11062 | {
11063 | const header_field_info *hfinfo = fi->hfinfo;
11064 | uint32_t value;
11065 |
11066 | char buf[32];
11067 | const char *out;
11068 |
11069 | value = fvalue_get_uinteger(fi->value);
11070 |
11071 | /* Fill in the textual info */
11072 | if (hfinfo->display == BASE_CUSTOM) {
11073 | char tmp[ITEM_LABEL_LENGTH240];
11074 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11075 |
11076 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 11076, "fmtfunc"))));
11077 | fmtfunc(tmp, value);
11078 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
11079 | }
11080 | else if (hfinfo->strings) {
11081 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
11082 |
11083 | out = hfinfo_char_vals_format(hfinfo, buf, value);
11084 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11085 | }
11086 | else {
11087 | out = hfinfo_char_value_format(hfinfo, buf, value);
11088 |
11089 | label_fill(label_str, 0, hfinfo, out, value_pos);
11090 | }
11091 | }
11092 |
11093 | static void
11094 | fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11095 | {
11096 | const header_field_info *hfinfo = fi->hfinfo;
11097 | uint32_t value;
11098 |
11099 | char buf[NUMBER_LABEL_LENGTH80];
11100 | const char *out;
11101 |
11102 | if (is_signed)
11103 | value = fvalue_get_sinteger(fi->value);
11104 | else
11105 | value = fvalue_get_uinteger(fi->value);
11106 |
11107 | /* Fill in the textual info */
11108 | if (hfinfo->display == BASE_CUSTOM) {
11109 | char tmp[ITEM_LABEL_LENGTH240];
11110 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
11111 |
11112 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 11112, "fmtfunc"))));
11113 | fmtfunc(tmp, value);
11114 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
11115 | }
11116 | else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
11117 | /*
11118 | * It makes no sense to have a value-string table for a
11119 | * frame-number field - they're just integers giving
11120 | * the ordinal frame number.
11121 | */
11122 | const char *val_str = hf_try_val_to_str(value, hfinfo);
11123 |
11124 | out = hfinfo_number_vals_format(hfinfo, buf, value);
11125 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11126 | /*
11127 | * Unique values only display value_string string
11128 | * if there is a match. Otherwise it's just a number
11129 | */
11130 | if (val_str) {
11131 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11132 | } else {
11133 | label_fill(label_str, 0, hfinfo, out, value_pos);
11134 | }
11135 | } else {
11136 | if (val_str == NULL((void*)0))
11137 | val_str = "Unknown";
11138 |
11139 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11140 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
11141 | else
11142 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11143 | }
11144 | }
11145 | 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 ))) {
11146 | char tmp[ITEM_LABEL_LENGTH240];
11147 |
11148 | port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11149 | display_to_port_type((field_display_e)hfinfo->display), value);
11150 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
11151 | }
11152 | else {
11153 | out = hfinfo_number_value_format(hfinfo, buf, value);
11154 |
11155 | label_fill(label_str, 0, hfinfo, out, value_pos);
11156 | }
11157 | }
11158 |
11159 | static void
11160 | fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11161 | {
11162 | const header_field_info *hfinfo = fi->hfinfo;
11163 | uint64_t value;
11164 |
11165 | char buf[NUMBER_LABEL_LENGTH80];
11166 | const char *out;
11167 |
11168 | if (is_signed)
11169 | value = fvalue_get_sinteger64(fi->value);
11170 | else
11171 | value = fvalue_get_uinteger64(fi->value);
11172 |
11173 | /* Fill in the textual info */
11174 | if (hfinfo->display == BASE_CUSTOM) {
11175 | char tmp[ITEM_LABEL_LENGTH240];
11176 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11177 |
11178 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 11178, "fmtfunc64" ))));
11179 | fmtfunc64(tmp, value);
11180 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
11181 | }
11182 | else if (hfinfo->strings) {
11183 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
11184 |
11185 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
11186 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11187 | /*
11188 | * Unique values only display value_string string
11189 | * if there is a match. Otherwise it's just a number
11190 | */
11191 | if (val_str) {
11192 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11193 | } else {
11194 | label_fill(label_str, 0, hfinfo, out, value_pos);
11195 | }
11196 | } else {
11197 | if (val_str == NULL((void*)0))
11198 | val_str = "Unknown";
11199 |
11200 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11201 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
11202 | else
11203 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11204 | }
11205 | }
11206 | else {
11207 | out = hfinfo_number_value_format64(hfinfo, buf, value);
11208 |
11209 | label_fill(label_str, 0, hfinfo, out, value_pos);
11210 | }
11211 | }
11212 |
11213 | static size_t
11214 | fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11215 | {
11216 | int display;
11217 | int n;
11218 | double value;
11219 |
11220 | if (label_str_size < 12) {
11221 | /* Not enough room to write an entire floating point value. */
11222 | return 0;
11223 | }
11224 |
11225 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11226 | value = fvalue_get_floating(fi->value);
11227 |
11228 | if (display == BASE_CUSTOM) {
11229 | const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11230 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 11230, "fmtfunc"))));
11231 | fmtfunc(label_str, value);
11232 | return strlen(label_str);
11233 | }
11234 |
11235 | switch (display) {
11236 | case BASE_NONE:
11237 | if (fi->hfinfo->type == FT_FLOAT) {
11238 | n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11239 | } else {
11240 | n = (int)strlen(dtoa_g_fmt(label_str, value));
11241 | }
11242 | break;
11243 | case BASE_DEC:
11244 | n = snprintf(label_str, label_str_size, "%f", value);
11245 | break;
11246 | case BASE_HEX:
11247 | n = snprintf(label_str, label_str_size, "%a", value);
11248 | break;
11249 | case BASE_EXP:
11250 | n = snprintf(label_str, label_str_size, "%e", value);
11251 | break;
11252 | default:
11253 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11253 , __func__, "assertion \"not reached\" failed");
11254 | }
11255 | if (n < 0) {
11256 | return 0; /* error */
11257 | }
11258 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11259 | const char *hf_str_val;
11260 | hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11261 | n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11262 | }
11263 | if (n > label_str_size) {
11264 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11264, __func__, "label length too small"); } } while (0);
11265 | return strlen(label_str);
11266 | }
11267 |
11268 | return n;
11269 | }
11270 |
11271 | void
11272 | fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11273 | {
11274 | char tmp[ITEM_LABEL_LENGTH240];
11275 |
11276 | fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11277 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11278 | }
11279 |
11280 | static size_t
11281 | fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11282 | {
11283 | int display;
11284 | size_t pos = 0;
11285 | double value;
11286 | char* tmp_str;
11287 |
11288 | if (label_str_size < 12) {
11289 | /* Not enough room to write an entire floating point value. */
11290 | return 0;
11291 | }
11292 |
11293 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11294 | tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11295 | pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str, 0);
11296 | wmem_free(NULL((void*)0), tmp_str);
11297 |
11298 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11299 | const char *hf_str_val;
11300 | fvalue_to_double(fi->value, &value);
11301 | hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11302 | 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);
11303 | }
11304 | if ((int)pos > label_str_size) {
11305 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11305, __func__, "label length too small"); } } while (0);
11306 | return strlen(label_str);
11307 | }
11308 |
11309 | return pos;
11310 | }
11311 |
11312 | void
11313 | fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11314 | {
11315 | char tmp[ITEM_LABEL_LENGTH240];
11316 |
11317 | fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11318 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11319 | }
11320 |
11321 | int
11322 | hfinfo_bitshift(const header_field_info *hfinfo)
11323 | {
11324 | return ws_ctz(hfinfo->bitmask);
11325 | }
11326 |
11327 |
11328 | static int
11329 | hfinfo_bitoffset(const header_field_info *hfinfo)
11330 | {
11331 | if (!hfinfo->bitmask) {
11332 | return 0;
11333 | }
11334 |
11335 | /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11336 | * as the first bit */
11337 | return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11338 | }
11339 |
11340 | static int
11341 | hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11342 | {
11343 | if (!hfinfo->bitmask) {
11344 | return 0;
11345 | }
11346 |
11347 | /* ilog2 = first set bit, ctz = last set bit */
11348 | return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11349 | }
11350 |
11351 | static int
11352 | hfinfo_type_bitwidth(enum ftenum type)
11353 | {
11354 | int bitwidth = 0;
11355 |
11356 | switch (type) {
11357 | case FT_CHAR:
11358 | case FT_UINT8:
11359 | case FT_INT8:
11360 | bitwidth = 8;
11361 | break;
11362 | case FT_UINT16:
11363 | case FT_INT16:
11364 | bitwidth = 16;
11365 | break;
11366 | case FT_UINT24:
11367 | case FT_INT24:
11368 | bitwidth = 24;
11369 | break;
11370 | case FT_UINT32:
11371 | case FT_INT32:
11372 | bitwidth = 32;
11373 | break;
11374 | case FT_UINT40:
11375 | case FT_INT40:
11376 | bitwidth = 40;
11377 | break;
11378 | case FT_UINT48:
11379 | case FT_INT48:
11380 | bitwidth = 48;
11381 | break;
11382 | case FT_UINT56:
11383 | case FT_INT56:
11384 | bitwidth = 56;
11385 | break;
11386 | case FT_UINT64:
11387 | case FT_INT64:
11388 | bitwidth = 64;
11389 | break;
11390 | default:
11391 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 11391));
11392 | ;
11393 | }
11394 | return bitwidth;
11395 | }
11396 |
11397 |
11398 | static int
11399 | hfinfo_container_bitwidth(const header_field_info *hfinfo)
11400 | {
11401 | if (!hfinfo->bitmask) {
11402 | return 0;
11403 | }
11404 |
11405 | if (hfinfo->type == FT_BOOLEAN) {
11406 | return hfinfo->display; /* hacky? :) */
11407 | }
11408 |
11409 | return hfinfo_type_bitwidth(hfinfo->type);
11410 | }
11411 |
11412 | static int
11413 | hfinfo_hex_digits(const header_field_info *hfinfo)
11414 | {
11415 | int bitwidth;
11416 |
11417 | /* If we have a bitmask, hfinfo->type is the width of the container, so not
11418 | * appropriate to determine the number of hex digits for the field.
11419 | * So instead, we compute it from the bitmask.
11420 | */
11421 | if (hfinfo->bitmask != 0) {
11422 | bitwidth = hfinfo_mask_bitwidth(hfinfo);
11423 | } else {
11424 | bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11425 | }
11426 |
11427 | /* Divide by 4, rounding up, to get number of hex digits. */
11428 | return (bitwidth + 3) / 4;
11429 | }
11430 |
11431 | const char *
11432 | hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11433 | {
11434 | char *ptr = &buf[6];
11435 | static const char hex_digits[16] =
11436 | { '0', '1', '2', '3', '4', '5', '6', '7',
11437 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11438 |
11439 | *ptr = '\0';
11440 | *(--ptr) = '\'';
11441 | /* Properly format value */
11442 | if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11443 | /*
11444 | * Printable, so just show the character, and, if it needs
11445 | * to be escaped, escape it.
11446 | */
11447 | *(--ptr) = value;
11448 | if (value == '\\' || value == '\'')
11449 | *(--ptr) = '\\';
11450 | } else {
11451 | /*
11452 | * Non-printable; show it as an escape sequence.
11453 | */
11454 | switch (value) {
11455 |
11456 | case '\0':
11457 | /*
11458 | * Show a NUL with only one digit.
11459 | */
11460 | *(--ptr) = '0';
11461 | break;
11462 |
11463 | case '\a':
11464 | case '\b':
11465 | case '\f':
11466 | case '\n':
11467 | case '\r':
11468 | case '\t':
11469 | case '\v':
11470 | *(--ptr) = value - '\a' + 'a';
11471 | break;
11472 |
11473 | default:
11474 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11475 |
11476 | case BASE_OCT:
11477 | *(--ptr) = (value & 0x7) + '0';
11478 | value >>= 3;
11479 | *(--ptr) = (value & 0x7) + '0';
11480 | value >>= 3;
11481 | *(--ptr) = (value & 0x7) + '0';
11482 | break;
11483 |
11484 | case BASE_HEX:
11485 | *(--ptr) = hex_digits[value & 0x0F];
11486 | value >>= 4;
11487 | *(--ptr) = hex_digits[value & 0x0F];
11488 | *(--ptr) = 'x';
11489 | break;
11490 |
11491 | default:
11492 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11493 | }
11494 | }
11495 | *(--ptr) = '\\';
11496 | }
11497 | *(--ptr) = '\'';
11498 | return ptr;
11499 | }
11500 |
11501 | static const char *
11502 | hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11503 | {
11504 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11505 | 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 ));
11506 |
11507 | *ptr = '\0';
11508 | /* Properly format value */
11509 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11510 | case BASE_DEC:
11511 | return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11512 |
11513 | case BASE_DEC_HEX:
11514 | *(--ptr) = ')';
11515 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11516 | *(--ptr) = '(';
11517 | *(--ptr) = ' ';
11518 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11519 | return ptr;
11520 |
11521 | case BASE_OCT:
11522 | return oct_to_str_back(ptr, value);
11523 |
11524 | case BASE_HEX:
11525 | return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11526 |
11527 | case BASE_HEX_DEC:
11528 | *(--ptr) = ')';
11529 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11530 | *(--ptr) = '(';
11531 | *(--ptr) = ' ';
11532 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11533 | return ptr;
11534 |
11535 | case BASE_PT_UDP:
11536 | case BASE_PT_TCP:
11537 | case BASE_PT_DCCP:
11538 | case BASE_PT_SCTP:
11539 | port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11540 | display_to_port_type((field_display_e)display), value);
11541 | return buf;
11542 | case BASE_OUI:
11543 | {
11544 | uint8_t p_oui[3];
11545 | const char *manuf_name;
11546 |
11547 | p_oui[0] = value >> 16 & 0xFF;
11548 | p_oui[1] = value >> 8 & 0xFF;
11549 | p_oui[2] = value & 0xFF;
11550 |
11551 | /* Attempt an OUI lookup. */
11552 | manuf_name = uint_get_manuf_name_if_known(value);
11553 | if (manuf_name == NULL((void*)0)) {
11554 | /* Could not find an OUI. */
11555 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11556 | }
11557 | else {
11558 | /* Found an address string. */
11559 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11560 | }
11561 | return buf;
11562 | }
11563 |
11564 | default:
11565 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11566 | }
11567 | return ptr;
11568 | }
11569 |
11570 | static const char *
11571 | hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11572 | {
11573 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11574 | 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 ));
11575 |
11576 | *ptr = '\0';
11577 | /* Properly format value */
11578 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11579 | case BASE_DEC:
11580 | return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11581 |
11582 | case BASE_DEC_HEX:
11583 | *(--ptr) = ')';
11584 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11585 | *(--ptr) = '(';
11586 | *(--ptr) = ' ';
11587 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11588 | return ptr;
11589 |
11590 | case BASE_OCT:
11591 | return oct64_to_str_back(ptr, value);
11592 |
11593 | case BASE_HEX:
11594 | return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11595 |
11596 | case BASE_HEX_DEC:
11597 | *(--ptr) = ')';
11598 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11599 | *(--ptr) = '(';
11600 | *(--ptr) = ' ';
11601 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11602 | return ptr;
11603 |
11604 | default:
11605 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11606 | }
11607 |
11608 | return ptr;
11609 | }
11610 |
11611 | static const char *
11612 | hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11613 | {
11614 | int display = hfinfo->display;
11615 |
11616 | if (hfinfo->type == FT_FRAMENUM) {
11617 | /*
11618 | * Frame numbers are always displayed in decimal.
11619 | */
11620 | display = BASE_DEC;
11621 | }
11622 |
11623 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11624 | }
11625 |
11626 | static const char *
11627 | hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11628 | {
11629 | int display = hfinfo->display;
11630 |
11631 | if (hfinfo->type == FT_FRAMENUM) {
11632 | /*
11633 | * Frame numbers are always displayed in decimal.
11634 | */
11635 | display = BASE_DEC;
11636 | }
11637 |
11638 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11639 | }
11640 |
11641 | static const char *
11642 | hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11643 | {
11644 | /* Get the underlying BASE_ value */
11645 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11646 |
11647 | return hfinfo_char_value_format_display(display, buf, value);
11648 | }
11649 |
11650 | static const char *
11651 | hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11652 | {
11653 | /* Get the underlying BASE_ value */
11654 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11655 |
11656 | if (hfinfo->type == FT_FRAMENUM) {
11657 | /*
11658 | * Frame numbers are always displayed in decimal.
11659 | */
11660 | display = BASE_DEC;
11661 | }
11662 |
11663 | if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)== BASE_PT_DCCP||(display)==BASE_PT_SCTP))) {
11664 | display = BASE_DEC;
11665 | } else if (display == BASE_OUI) {
11666 | display = BASE_HEX;
11667 | }
11668 |
11669 | switch (display) {
11670 | case BASE_NONE:
11671 | /* case BASE_DEC: */
11672 | case BASE_DEC_HEX:
11673 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11674 | case BASE_CUSTOM:
11675 | display = BASE_DEC;
11676 | break;
11677 |
11678 | /* case BASE_HEX: */
11679 | case BASE_HEX_DEC:
11680 | display = BASE_HEX;
11681 | break;
11682 | }
11683 |
11684 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11685 | }
11686 |
11687 | static const char *
11688 | hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11689 | {
11690 | /* Get the underlying BASE_ value */
11691 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11692 |
11693 | if (hfinfo->type == FT_FRAMENUM) {
11694 | /*
11695 | * Frame numbers are always displayed in decimal.
11696 | */
11697 | display = BASE_DEC;
11698 | }
11699 |
11700 | switch (display) {
11701 | case BASE_NONE:
11702 | /* case BASE_DEC: */
11703 | case BASE_DEC_HEX:
11704 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11705 | case BASE_CUSTOM:
11706 | display = BASE_DEC;
11707 | break;
11708 |
11709 | /* case BASE_HEX: */
11710 | case BASE_HEX_DEC:
11711 | display = BASE_HEX;
11712 | break;
11713 | }
11714 |
11715 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11716 | }
11717 |
11718 | static const char *
11719 | hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11720 | {
11721 | /* Get the underlying BASE_ value */
11722 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11723 |
11724 | return hfinfo_char_value_format_display(display, buf, value);
11725 | }
11726 |
11727 | static const char *
11728 | hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11729 | {
11730 | /* Get the underlying BASE_ value */
11731 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11732 |
11733 | if (display == BASE_NONE)
11734 | return NULL((void*)0);
11735 |
11736 | if (display == BASE_DEC_HEX)
11737 | display = BASE_DEC;
11738 | if (display == BASE_HEX_DEC)
11739 | display = BASE_HEX;
11740 |
11741 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11742 | }
11743 |
11744 | static const char *
11745 | hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11746 | {
11747 | /* Get the underlying BASE_ value */
11748 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11749 |
11750 | if (display == BASE_NONE)
11751 | return NULL((void*)0);
11752 |
11753 | if (display == BASE_DEC_HEX)
11754 | display = BASE_DEC;
11755 | if (display == BASE_HEX_DEC)
11756 | display = BASE_HEX;
11757 |
11758 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11759 | }
11760 |
11761 | const char *
11762 | proto_registrar_get_name(const int n)
11763 | {
11764 | header_field_info *hfinfo;
11765 |
11766 | 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", 11766 , __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", 11766 , "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", 11766, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11767 | return hfinfo->name;
11768 | }
11769 |
11770 | const char *
11771 | proto_registrar_get_abbrev(const int n)
11772 | {
11773 | header_field_info *hfinfo;
11774 |
11775 | 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", 11775 , __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", 11775 , "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", 11775, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11776 | return hfinfo->abbrev;
11777 | }
11778 |
11779 | enum ftenum
11780 | proto_registrar_get_ftype(const int n)
11781 | {
11782 | header_field_info *hfinfo;
11783 |
11784 | 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", 11784 , __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", 11784 , "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", 11784, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11785 | return hfinfo->type;
11786 | }
11787 |
11788 | int
11789 | proto_registrar_get_parent(const int n)
11790 | {
11791 | header_field_info *hfinfo;
11792 |
11793 | 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", 11793 , __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", 11793 , "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", 11793, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11794 | return hfinfo->parent;
11795 | }
11796 |
11797 | bool_Bool
11798 | proto_registrar_is_protocol(const int n)
11799 | {
11800 | header_field_info *hfinfo;
11801 |
11802 | 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", 11802 , __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", 11802 , "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", 11802, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11803 | return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11804 | }
11805 |
11806 | /* Returns length of field in packet (not necessarily the length
11807 | * in our internal representation, as in the case of IPv4).
11808 | * 0 means undeterminable at time of registration
11809 | * -1 means the field is not registered. */
11810 | int
11811 | proto_registrar_get_length(const int n)
11812 | {
11813 | header_field_info *hfinfo;
11814 |
11815 | 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", 11815 , __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", 11815 , "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", 11815, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11816 | return ftype_wire_size(hfinfo->type);
11817 | }
11818 |
11819 | size_t
11820 | proto_registrar_get_count(struct proto_registrar_stats *stats)
11821 | {
11822 | header_field_info *hfinfo;
11823 |
11824 | // Index zero is not used. We have to skip it.
11825 | size_t total_count = gpa_hfinfo.len - 1;
11826 | if (stats == NULL((void*)0)) {
11827 | return total_count;
11828 | }
11829 | for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11830 | if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11831 | stats->deregistered_count++;
11832 | continue; /* This is a deregistered protocol or header field */
11833 | }
11834 |
11835 | 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", 11835 , __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", 11835, "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", 11835, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[id];;
11836 |
11837 | if (proto_registrar_is_protocol(id))
11838 | stats->protocol_count++;
11839 |
11840 | if (hfinfo->same_name_prev_id != -1)
11841 | stats->same_name_count++;
11842 | }
11843 |
11844 | return total_count;
11845 | }
11846 |
11847 | /* Looks for a protocol or a field in a proto_tree. Returns true if
11848 | * it exists anywhere, or false if it exists nowhere. */
11849 | bool_Bool
11850 | proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11851 | {
11852 | GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11853 |
11854 | if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11855 | return true1;
11856 | }
11857 | else {
11858 | return false0;
11859 | }
11860 | }
11861 |
11862 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11863 | * This only works if the hfindex was "primed" before the dissection
11864 | * took place, as we just pass back the already-created GPtrArray*.
11865 | * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11866 | * handles that. */
11867 | GPtrArray *
11868 | proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11869 | {
11870 | if (!tree)
11871 | return NULL((void*)0);
11872 |
11873 | if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11874 | return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11875 | GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11876 | else
11877 | return NULL((void*)0);
11878 | }
11879 |
11880 | bool_Bool
11881 | proto_tracking_interesting_fields(const proto_tree *tree)
11882 | {
11883 | GHashTable *interesting_hfids;
11884 |
11885 | if (!tree)
11886 | return false0;
11887 |
11888 | interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11889 |
11890 | return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11891 | }
11892 |
11893 | /* Helper struct for proto_find_info() and proto_all_finfos() */
11894 | typedef struct {
11895 | GPtrArray *array;
11896 | int id;
11897 | } ffdata_t;
11898 |
11899 | /* Helper function for proto_find_info() */
11900 | static bool_Bool
11901 | find_finfo(proto_node *node, void * data)
11902 | {
11903 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11904 | if (fi && fi->hfinfo) {
11905 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11906 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11907 | }
11908 | }
11909 |
11910 | /* Don't stop traversing. */
11911 | return false0;
11912 | }
11913 |
11914 | /* Helper function for proto_find_first_info() */
11915 | static bool_Bool
11916 | find_first_finfo(proto_node *node, void *data)
11917 | {
11918 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11919 | if (fi && fi->hfinfo) {
11920 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11921 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11922 |
11923 | /* Stop traversing. */
11924 | return true1;
11925 | }
11926 | }
11927 |
11928 | /* Continue traversing. */
11929 | return false0;
11930 | }
11931 |
11932 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11933 | * This works on any proto_tree, primed or unprimed, but actually searches
11934 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11935 | * The caller does need to free the returned GPtrArray with
11936 | * g_ptr_array_free(<array>, true).
11937 | */
11938 | GPtrArray *
11939 | proto_find_finfo(proto_tree *tree, const int id)
11940 | {
11941 | ffdata_t ffdata;
11942 |
11943 | ffdata.array = g_ptr_array_new();
11944 | ffdata.id = id;
11945 |
11946 | proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11947 |
11948 | return ffdata.array;
11949 | }
11950 |
11951 | /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11952 | * This works on any proto_tree, primed or unprimed, but actually searches
11953 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11954 | * The caller does need to free the returned GPtrArray with
11955 | * g_ptr_array_free(<array>, true).
11956 | */
11957 | GPtrArray *
11958 | proto_find_first_finfo(proto_tree *tree, const int id)
11959 | {
11960 | ffdata_t ffdata;
11961 |
11962 | ffdata.array = g_ptr_array_new();
11963 | ffdata.id = id;
11964 |
11965 | proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11966 |
11967 | return ffdata.array;
11968 | }
11969 |
11970 | /* Helper function for proto_all_finfos() */
11971 | static bool_Bool
11972 | every_finfo(proto_node *node, void * data)
11973 | {
11974 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11975 | if (fi && fi->hfinfo) {
11976 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11977 | }
11978 |
11979 | /* Don't stop traversing. */
11980 | return false0;
11981 | }
11982 |
11983 | /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11984 | * The caller does need to free the returned GPtrArray with
11985 | * g_ptr_array_free(<array>, true).
11986 | */
11987 | GPtrArray *
11988 | proto_all_finfos(proto_tree *tree)
11989 | {
11990 | ffdata_t ffdata;
11991 |
11992 | /* Pre allocate enough space to hold all fields in most cases */
11993 | ffdata.array = g_ptr_array_sized_new(512);
11994 | ffdata.id = 0;
11995 |
11996 | proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11997 |
11998 | return ffdata.array;
11999 | }
12000 |
12001 |
12002 | typedef struct {
12003 | unsigned offset;
12004 | field_info *finfo;
12005 | tvbuff_t *tvb;
12006 | } offset_search_t;
12007 |
12008 | static bool_Bool
12009 | check_for_offset(proto_node *node, void * data)
12010 | {
12011 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
12012 | offset_search_t *offsearch = (offset_search_t *)data;
12013 |
12014 | /* !fi == the top most container node which holds nothing */
12015 | if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
12016 | if (offsearch->offset >= (unsigned) fi->start &&
12017 | offsearch->offset < (unsigned) (fi->start + fi->length)) {
12018 |
12019 | offsearch->finfo = fi;
12020 | return false0; /* keep traversing */
12021 | }
12022 | }
12023 | return false0; /* keep traversing */
12024 | }
12025 |
12026 | /* Search a proto_tree backwards (from leaves to root) looking for the field
12027 | * whose start/length occupies 'offset' */
12028 | /* XXX - I couldn't find an easy way to search backwards, so I search
12029 | * forwards, w/o stopping. Therefore, the last finfo I find will the be
12030 | * the one I want to return to the user. This algorithm is inefficient
12031 | * and could be re-done, but I'd have to handle all the children and
12032 | * siblings of each node myself. When I have more time I'll do that.
12033 | * (yeah right) */
12034 | field_info *
12035 | proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
12036 | {
12037 | offset_search_t offsearch;
12038 |
12039 | offsearch.offset = offset;
12040 | offsearch.finfo = NULL((void*)0);
12041 | offsearch.tvb = tvb;
12042 |
12043 | proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
12044 |
12045 | return offsearch.finfo;
12046 | }
12047 |
12048 | typedef struct {
12049 | unsigned length;
12050 | char *buf;
12051 | } decoded_data_t;
12052 |
12053 | static bool_Bool
12054 | check_for_undecoded(proto_node *node, void * data)
12055 | {
12056 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
12057 | decoded_data_t* decoded = (decoded_data_t*)data;
12058 | unsigned i;
12059 | unsigned byte;
12060 | unsigned bit;
12061 |
12062 | if (fi && fi->hfinfo->type != FT_PROTOCOL) {
12063 | for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
12064 | byte = i / 8;
12065 | bit = i % 8;
12066 | decoded->buf[byte] |= (1 << bit);
12067 | }
12068 | }
12069 |
12070 | return false0;
12071 | }
12072 |
12073 | char*
12074 | proto_find_undecoded_data(proto_tree *tree, unsigned length)
12075 | {
12076 | decoded_data_t decoded;
12077 | decoded.length = length;
12078 | decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
12079 |
12080 | proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
12081 | return decoded.buf;
12082 | }
12083 |
12084 | /* Dumps the protocols in the registration database to stdout. An independent
12085 | * program can take this output and format it into nice tables or HTML or
12086 | * whatever.
12087 | *
12088 | * There is one record per line. The fields are tab-delimited.
12089 | *
12090 | * Field 1 = protocol name
12091 | * Field 2 = protocol short name
12092 | * Field 3 = protocol filter name
12093 | * Field 4 = protocol enabled
12094 | * Field 5 = protocol enabled by default
12095 | * Field 6 = protocol can toggle
12096 | */
12097 | void
12098 | proto_registrar_dump_protocols(void)
12099 | {
12100 | protocol_t *protocol;
12101 | int i;
12102 | void *cookie = NULL((void*)0);
12103 |
12104 |
12105 | i = proto_get_first_protocol(&cookie);
12106 | while (i != -1) {
12107 | protocol = find_protocol_by_id(i);
12108 | printf("%s\t%s\t%s\t%c\t%c\t%c\n",
12109 | protocol->name,
12110 | protocol->short_name,
12111 | protocol->filter_name,
12112 | (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
12113 | (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
12114 | (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
12115 | i = proto_get_next_protocol(&cookie);
12116 | }
12117 | }
12118 |
12119 | /* Dumps the value_strings, extended value string headers, range_strings
12120 | * or true/false strings for fields that have them.
12121 | * There is one record per line. Fields are tab-delimited.
12122 | * There are four types of records: Value String, Extended Value String Header,
12123 | * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
12124 | * the type of record.
12125 | *
12126 | * Note that a record will be generated only if the value_string,... is referenced
12127 | * in a registered hfinfo entry.
12128 | *
12129 | *
12130 | * Value Strings
12131 | * -------------
12132 | * Field 1 = 'V'
12133 | * Field 2 = Field abbreviation to which this value string corresponds
12134 | * Field 3 = Integer value
12135 | * Field 4 = String
12136 | *
12137 | * Extended Value String Headers
12138 | * -----------------------------
12139 | * Field 1 = 'E'
12140 | * Field 2 = Field abbreviation to which this extended value string header corresponds
12141 | * Field 3 = Extended Value String "Name"
12142 | * Field 4 = Number of entries in the associated value_string array
12143 | * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
12144 | *
12145 | * Range Strings
12146 | * -------------
12147 | * Field 1 = 'R'
12148 | * Field 2 = Field abbreviation to which this range string corresponds
12149 | * Field 3 = Integer value: lower bound
12150 | * Field 4 = Integer value: upper bound
12151 | * Field 5 = String
12152 | *
12153 | * True/False Strings
12154 | * ------------------
12155 | * Field 1 = 'T'
12156 | * Field 2 = Field abbreviation to which this true/false string corresponds
12157 | * Field 3 = True String
12158 | * Field 4 = False String
12159 | */
12160 | void
12161 | proto_registrar_dump_values(void)
12162 | {
12163 | header_field_info *hfinfo;
12164 | int i, len, vi;
12165 | const value_string *vals;
12166 | const val64_string *vals64;
12167 | const range_string *range;
12168 | const true_false_string *tfs;
12169 | const unit_name_string *units;
12170 |
12171 | len = gpa_hfinfo.len;
12172 | for (i = 1; i < len ; i++) {
12173 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12174 | continue; /* This is a deregistered protocol or field */
12175 |
12176 | 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", 12176 , __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", 12176 , "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", 12176, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12177 |
12178 | if (hfinfo->id == hf_text_only) {
12179 | continue;
12180 | }
12181 |
12182 | /* ignore protocols */
12183 | if (proto_registrar_is_protocol(i)) {
12184 | continue;
12185 | }
12186 | /* process header fields */
12187 | #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12188 | /*
12189 | * If this field isn't at the head of the list of
12190 | * fields with this name, skip this field - all
12191 | * fields with the same name are really just versions
12192 | * of the same field stored in different bits, and
12193 | * should have the same type/radix/value list, and
12194 | * just differ in their bit masks. (If a field isn't
12195 | * a bitfield, but can be, say, 1 or 2 bytes long,
12196 | * it can just be made FT_UINT16, meaning the
12197 | * *maximum* length is 2 bytes, and be used
12198 | * for all lengths.)
12199 | */
12200 | if (hfinfo->same_name_prev_id != -1)
12201 | continue;
12202 | #endif
12203 | vals = NULL((void*)0);
12204 | vals64 = NULL((void*)0);
12205 | range = NULL((void*)0);
12206 | tfs = NULL((void*)0);
12207 | units = NULL((void*)0);
12208 |
12209 | if (hfinfo->strings != NULL((void*)0)) {
12210 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12211 | (hfinfo->type == FT_CHAR ||
12212 | hfinfo->type == FT_UINT8 ||
12213 | hfinfo->type == FT_UINT16 ||
12214 | hfinfo->type == FT_UINT24 ||
12215 | hfinfo->type == FT_UINT32 ||
12216 | hfinfo->type == FT_UINT40 ||
12217 | hfinfo->type == FT_UINT48 ||
12218 | hfinfo->type == FT_UINT56 ||
12219 | hfinfo->type == FT_UINT64 ||
12220 | hfinfo->type == FT_INT8 ||
12221 | hfinfo->type == FT_INT16 ||
12222 | hfinfo->type == FT_INT24 ||
12223 | hfinfo->type == FT_INT32 ||
12224 | hfinfo->type == FT_INT40 ||
12225 | hfinfo->type == FT_INT48 ||
12226 | hfinfo->type == FT_INT56 ||
12227 | hfinfo->type == FT_INT64 ||
12228 | hfinfo->type == FT_FLOAT ||
12229 | hfinfo->type == FT_DOUBLE)) {
12230 |
12231 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12232 | range = (const range_string *)hfinfo->strings;
12233 | } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12234 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12235 | vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12236 | } else {
12237 | vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12238 | }
12239 | } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12240 | vals64 = (const val64_string *)hfinfo->strings;
12241 | } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12242 | units = (const unit_name_string *)hfinfo->strings;
12243 | } else {
12244 | vals = (const value_string *)hfinfo->strings;
12245 | }
12246 | }
12247 | else if (hfinfo->type == FT_BOOLEAN) {
12248 | tfs = (const struct true_false_string *)hfinfo->strings;
12249 | }
12250 | }
12251 |
12252 | /* Print value strings? */
12253 | if (vals) {
12254 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12255 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12256 | val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12257 | if (!val64_string_ext_validate(vse_p)) {
12258 | ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 12258, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
12259 | continue;
12260 | }
12261 | try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12262 | printf("E\t%s\t%u\t%s\t%s\n",
12263 | hfinfo->abbrev,
12264 | VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12265 | VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12266 | val64_string_ext_match_type_str(vse_p));
12267 | } else {
12268 | value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12269 | if (!value_string_ext_validate(vse_p)) {
12270 | ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 12270, __func__, "Invalid value_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
12271 | continue;
12272 | }
12273 | try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12274 | printf("E\t%s\t%u\t%s\t%s\n",
12275 | hfinfo->abbrev,
12276 | VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12277 | VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12278 | value_string_ext_match_type_str(vse_p));
12279 | }
12280 | }
12281 | vi = 0;
12282 | while (vals[vi].strptr) {
12283 | /* Print in the proper base */
12284 | if (hfinfo->type == FT_CHAR) {
12285 | if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT ) != 0)) {
12286 | printf("V\t%s\t'%c'\t%s\n",
12287 | hfinfo->abbrev,
12288 | vals[vi].value,
12289 | vals[vi].strptr);
12290 | } else {
12291 | if (hfinfo->display == BASE_HEX) {
12292 | printf("V\t%s\t'\\x%02x'\t%s\n",
12293 | hfinfo->abbrev,
12294 | vals[vi].value,
12295 | vals[vi].strptr);
12296 | }
12297 | else {
12298 | printf("V\t%s\t'\\%03o'\t%s\n",
12299 | hfinfo->abbrev,
12300 | vals[vi].value,
12301 | vals[vi].strptr);
12302 | }
12303 | }
12304 | } else {
12305 | if (hfinfo->display == BASE_HEX) {
12306 | printf("V\t%s\t0x%x\t%s\n",
12307 | hfinfo->abbrev,
12308 | vals[vi].value,
12309 | vals[vi].strptr);
12310 | }
12311 | else {
12312 | printf("V\t%s\t%u\t%s\n",
12313 | hfinfo->abbrev,
12314 | vals[vi].value,
12315 | vals[vi].strptr);
12316 | }
12317 | }
12318 | vi++;
12319 | }
12320 | }
12321 | else if (vals64) {
12322 | vi = 0;
12323 | while (vals64[vi].strptr) {
12324 | printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12325 | hfinfo->abbrev,
12326 | vals64[vi].value,
12327 | vals64[vi].strptr);
12328 | vi++;
12329 | }
12330 | }
12331 |
12332 | /* print range strings? */
12333 | else if (range) {
12334 | vi = 0;
12335 | while (range[vi].strptr) {
12336 | /* Print in the proper base */
12337 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12338 | printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12339 | hfinfo->abbrev,
12340 | range[vi].value_min,
12341 | range[vi].value_max,
12342 | range[vi].strptr);
12343 | }
12344 | else {
12345 | printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12346 | hfinfo->abbrev,
12347 | range[vi].value_min,
12348 | range[vi].value_max,
12349 | range[vi].strptr);
12350 | }
12351 | vi++;
12352 | }
12353 | }
12354 |
12355 | /* Print true/false strings? */
12356 | else if (tfs) {
12357 | printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12358 | tfs->true_string, tfs->false_string);
12359 | }
12360 | /* Print unit strings? */
12361 | else if (units) {
12362 | printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12363 | units->singular, units->plural ? units->plural : "(no plural)");
12364 | }
12365 | }
12366 | }
12367 |
12368 | /* Prints the number of registered fields.
12369 | * Useful for determining an appropriate value for
12370 | * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12371 | *
12372 | * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12373 | * the number of fields, true otherwise.
12374 | */
12375 | bool_Bool
12376 | proto_registrar_dump_fieldcount(void)
12377 | {
12378 | struct proto_registrar_stats stats = {0, 0, 0};
12379 | size_t total_count = proto_registrar_get_count(&stats);
12380 |
12381 | printf("There are %zu header fields registered, of which:\n"
12382 | "\t%zu are deregistered\n"
12383 | "\t%zu are protocols\n"
12384 | "\t%zu have the same name as another field\n\n",
12385 | total_count, stats.deregistered_count, stats.protocol_count,
12386 | stats.same_name_count);
12387 |
12388 | printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12389 | (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12390 | "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12391 | "\n");
12392 |
12393 | printf("The header field table consumes %u KiB of memory.\n",
12394 | (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12395 | printf("The fields themselves consume %u KiB of memory.\n",
12396 | (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12397 |
12398 | return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12399 | }
12400 |
12401 | static void
12402 | elastic_add_base_mapping(json_dumper *dumper)
12403 | {
12404 | json_dumper_set_member_name(dumper, "index_patterns");
12405 | json_dumper_begin_array(dumper);
12406 | // The index names from write_json_index() in print.c
12407 | json_dumper_value_string(dumper, "packets-*");
12408 | json_dumper_end_array(dumper);
12409 |
12410 | json_dumper_set_member_name(dumper, "settings");
12411 | json_dumper_begin_object(dumper);
12412 | json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12413 | json_dumper_value_anyf(dumper, "%d", 1000000);
12414 | json_dumper_end_object(dumper);
12415 | }
12416 |
12417 | static char*
12418 | ws_type_to_elastic(unsigned type)
12419 | {
12420 | switch(type) {
12421 | case FT_INT8:
12422 | return "byte";
12423 | case FT_UINT8:
12424 | case FT_INT16:
12425 | return "short";
12426 | case FT_UINT16:
12427 | case FT_INT32:
12428 | case FT_UINT24:
12429 | case FT_INT24:
12430 | return "integer";
12431 | case FT_FRAMENUM:
12432 | case FT_UINT32:
12433 | case FT_UINT40:
12434 | case FT_UINT48:
12435 | case FT_UINT56:
12436 | case FT_INT40:
12437 | case FT_INT48:
12438 | case FT_INT56:
12439 | case FT_INT64:
12440 | return "long";
12441 | case FT_UINT64:
12442 | return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12443 | case FT_FLOAT:
12444 | return "float";
12445 | case FT_DOUBLE:
12446 | case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12447 | return "double";
12448 | case FT_IPv6:
12449 | case FT_IPv4:
12450 | return "ip";
12451 | case FT_ABSOLUTE_TIME:
12452 | return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12453 | case FT_BOOLEAN:
12454 | return "boolean";
12455 | default:
12456 | return NULL((void*)0);
12457 | }
12458 | }
12459 |
12460 | static char*
12461 | dot_to_underscore(char* str)
12462 | {
12463 | unsigned i;
12464 | for (i = 0; i < strlen(str); i++) {
12465 | if (str[i] == '.')
12466 | str[i] = '_';
12467 | }
12468 | return str;
12469 | }
12470 |
12471 | /* Dumps a mapping file for ElasticSearch
12472 | * This is the v1 (legacy) _template API.
12473 | * At some point it may need to be updated with the composable templates
12474 | * introduced in Elasticsearch 7.8 (_index_template)
12475 | */
12476 | void
12477 | proto_registrar_dump_elastic(const char* filter)
12478 | {
12479 | header_field_info *hfinfo;
12480 | header_field_info *parent_hfinfo;
12481 | unsigned i;
12482 | bool_Bool open_object = true1;
12483 | const char* prev_proto = NULL((void*)0);
12484 | char* str;
12485 | char** protos = NULL((void*)0);
12486 | char* proto;
12487 | bool_Bool found;
12488 | unsigned j;
12489 | char* type;
12490 | char* prev_item = NULL((void*)0);
12491 |
12492 | /* We have filtering protocols. Extract them. */
12493 | if (filter) {
12494 | protos = g_strsplit(filter, ",", -1);
12495 | }
12496 |
12497 | /*
12498 | * To help tracking down the json tree, objects have been appended with a comment:
12499 | * n.label -> where n is the indentation level and label the name of the object
12500 | */
12501 |
12502 | json_dumper dumper = {
12503 | .output_file = stdoutstdout,
12504 | .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12505 | };
12506 | json_dumper_begin_object(&dumper); // 1.root
12507 | elastic_add_base_mapping(&dumper);
12508 |
12509 | json_dumper_set_member_name(&dumper, "mappings");
12510 | json_dumper_begin_object(&dumper); // 2.mappings
12511 |
12512 | json_dumper_set_member_name(&dumper, "properties");
12513 | json_dumper_begin_object(&dumper); // 3.properties
12514 | json_dumper_set_member_name(&dumper, "timestamp");
12515 | json_dumper_begin_object(&dumper); // 4.timestamp
12516 | json_dumper_set_member_name(&dumper, "type");
12517 | json_dumper_value_string(&dumper, "date");
12518 | json_dumper_end_object(&dumper); // 4.timestamp
12519 |
12520 | json_dumper_set_member_name(&dumper, "layers");
12521 | json_dumper_begin_object(&dumper); // 4.layers
12522 | json_dumper_set_member_name(&dumper, "properties");
12523 | json_dumper_begin_object(&dumper); // 5.properties
12524 |
12525 | for (i = 1; i < gpa_hfinfo.len; i++) {
12526 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12527 | continue; /* This is a deregistered protocol or header field */
12528 |
12529 | 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", 12529 , __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", 12529 , "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", 12529, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12530 |
12531 | /*
12532 | * Skip the pseudo-field for "proto_tree_add_text()" since
12533 | * we don't want it in the list of filterable protocols.
12534 | */
12535 | if (hfinfo->id == hf_text_only)
12536 | continue;
12537 |
12538 | if (!proto_registrar_is_protocol(i)) {
12539 | 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", 12539 , __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", 12539 , "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", 12539 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf." )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12540 |
12541 | /*
12542 | * Skip the field if filter protocols have been set and this one's
12543 | * parent is not listed.
12544 | */
12545 | if (protos) {
12546 | found = false0;
12547 | j = 0;
12548 | proto = protos[0];
12549 | while(proto) {
12550 | if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12551 | found = true1;
12552 | break;
12553 | }
12554 | j++;
12555 | proto = protos[j];
12556 | }
12557 | if (!found)
12558 | continue;
12559 | }
12560 |
12561 | if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12562 | json_dumper_end_object(&dumper); // 7.properties
12563 | json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12564 | open_object = true1;
12565 | }
12566 |
12567 | prev_proto = parent_hfinfo->abbrev;
12568 |
12569 | if (open_object) {
12570 | json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12571 | json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12572 | json_dumper_set_member_name(&dumper, "properties");
12573 | json_dumper_begin_object(&dumper); // 7.properties
12574 | open_object = false0;
12575 | }
12576 | /* Skip the fields that would map into string. This is the default in elasticsearch. */
12577 | type = ws_type_to_elastic(hfinfo->type);
12578 | /* when type is NULL, we have the default mapping: string */
12579 | if (type) {
12580 | str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo-> abbrev);
12581 | dot_to_underscore(str);
12582 | if (g_strcmp0(prev_item, str)) {
12583 | json_dumper_set_member_name(&dumper, str);
12584 | json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12585 | json_dumper_set_member_name(&dumper, "type");
12586 | json_dumper_value_string(&dumper, type);
12587 | json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12588 | }
12589 | 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);
12590 | prev_item = str;
12591 | }
12592 | }
12593 | }
12594 | 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);
12595 |
12596 | if (prev_proto) {
12597 | json_dumper_end_object(&dumper); // 7.properties
12598 | json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12599 | }
12600 |
12601 | json_dumper_end_object(&dumper); // 5.properties
12602 | json_dumper_end_object(&dumper); // 4.layers
12603 | json_dumper_end_object(&dumper); // 3.properties
12604 | json_dumper_end_object(&dumper); // 2.mappings
12605 | json_dumper_end_object(&dumper); // 1.root
12606 | bool_Bool ret = json_dumper_finish(&dumper);
12607 | DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12607, "ret"))));
12608 |
12609 | g_strfreev(protos);
12610 | }
12611 |
12612 | /* Dumps the contents of the registration database to stdout. An independent
12613 | * program can take this output and format it into nice tables or HTML or
12614 | * whatever.
12615 | *
12616 | * There is one record per line. Each record is either a protocol or a header
12617 | * field, differentiated by the first field. The fields are tab-delimited.
12618 | *
12619 | * Protocols
12620 | * ---------
12621 | * Field 1 = 'P'
12622 | * Field 2 = descriptive protocol name
12623 | * Field 3 = protocol abbreviation
12624 | *
12625 | * Header Fields
12626 | * -------------
12627 | * Field 1 = 'F'
12628 | * Field 2 = descriptive field name
12629 | * Field 3 = field abbreviation
12630 | * Field 4 = type ( textual representation of the ftenum type )
12631 | * Field 5 = parent protocol abbreviation
12632 | * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12633 | * Field 7 = bitmask: format: hex: 0x....
12634 | * Field 8 = blurb describing field
12635 | */
12636 | void
12637 | proto_registrar_dump_fields(void)
12638 | {
12639 | header_field_info *hfinfo, *parent_hfinfo;
12640 | int i, len;
12641 | const char *enum_name;
12642 | const char *base_name;
12643 | const char *blurb;
12644 | char width[5];
12645 |
12646 | len = gpa_hfinfo.len;
12647 | for (i = 1; i < len ; i++) {
12648 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12649 | continue; /* This is a deregistered protocol or header field */
12650 |
12651 | 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", 12651 , __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", 12651 , "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", 12651, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12652 |
12653 | /*
12654 | * Skip the pseudo-field for "proto_tree_add_text()" since
12655 | * we don't want it in the list of filterable fields.
12656 | */
12657 | if (hfinfo->id == hf_text_only)
12658 | continue;
12659 |
12660 | /* format for protocols */
12661 | if (proto_registrar_is_protocol(i)) {
12662 | printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12663 | }
12664 | /* format for header fields */
12665 | else {
12666 | /*
12667 | * If this field isn't at the head of the list of
12668 | * fields with this name, skip this field - all
12669 | * fields with the same name are really just versions
12670 | * of the same field stored in different bits, and
12671 | * should have the same type/radix/value list, and
12672 | * just differ in their bit masks. (If a field isn't
12673 | * a bitfield, but can be, say, 1 or 2 bytes long,
12674 | * it can just be made FT_UINT16, meaning the
12675 | * *maximum* length is 2 bytes, and be used
12676 | * for all lengths.)
12677 | */
12678 | if (hfinfo->same_name_prev_id != -1)
12679 | continue;
12680 |
12681 | 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", 12681 , __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", 12681 , "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", 12681 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf." )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12682 |
12683 | enum_name = ftype_name(hfinfo->type);
12684 | base_name = "";
12685 |
12686 | if (hfinfo->type == FT_CHAR ||
12687 | hfinfo->type == FT_UINT8 ||
12688 | hfinfo->type == FT_UINT16 ||
12689 | hfinfo->type == FT_UINT24 ||
12690 | hfinfo->type == FT_UINT32 ||
12691 | hfinfo->type == FT_UINT40 ||
12692 | hfinfo->type == FT_UINT48 ||
12693 | hfinfo->type == FT_UINT56 ||
12694 | hfinfo->type == FT_UINT64 ||
12695 | hfinfo->type == FT_INT8 ||
12696 | hfinfo->type == FT_INT16 ||
12697 | hfinfo->type == FT_INT24 ||
12698 | hfinfo->type == FT_INT32 ||
12699 | hfinfo->type == FT_INT40 ||
12700 | hfinfo->type == FT_INT48 ||
12701 | hfinfo->type == FT_INT56 ||
12702 | hfinfo->type == FT_INT64) {
12703 |
12704 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12705 | case BASE_NONE:
12706 | case BASE_DEC:
12707 | case BASE_HEX:
12708 | case BASE_OCT:
12709 | case BASE_DEC_HEX:
12710 | case BASE_HEX_DEC:
12711 | case BASE_CUSTOM:
12712 | case BASE_PT_UDP:
12713 | case BASE_PT_TCP:
12714 | case BASE_PT_DCCP:
12715 | case BASE_PT_SCTP:
12716 | case BASE_OUI:
12717 | base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12718 | break;
12719 | default:
12720 | base_name = "????";
12721 | break;
12722 | }
12723 | } else if (hfinfo->type == FT_BOOLEAN) {
12724 | /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12725 | snprintf(width, sizeof(width), "%d", hfinfo->display);
12726 | base_name = width;
12727 | }
12728 |
12729 | blurb = hfinfo->blurb;
12730 | if (blurb == NULL((void*)0))
12731 | blurb = "";
12732 | else if (strlen(blurb) == 0)
12733 | blurb = "\"\"";
12734 |
12735 | printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12736 | hfinfo->name, hfinfo->abbrev, enum_name,
12737 | parent_hfinfo->abbrev, base_name,
12738 | hfinfo->bitmask, blurb);
12739 | }
12740 | }
12741 | }
12742 |
12743 | /* Dumps all abbreviated field and protocol completions of the given string to
12744 | * stdout. An independent program may use this for command-line tab completion
12745 | * of fields.
12746 | */
12747 | bool_Bool
12748 | proto_registrar_dump_field_completions(const char *prefix)
12749 | {
12750 | header_field_info *hfinfo;
12751 | int i, len;
12752 | size_t prefix_len;
12753 | bool_Bool matched = false0;
12754 |
12755 | prefix_len = strlen(prefix);
12756 | len = gpa_hfinfo.len;
12757 | for (i = 1; i < len ; i++) {
12758 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12759 | continue; /* This is a deregistered protocol or header field */
12760 |
12761 | 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", 12761 , __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", 12761 , "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", 12761, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf." )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12762 |
12763 | /*
12764 | * Skip the pseudo-field for "proto_tree_add_text()" since
12765 | * we don't want it in the list of filterable fields.
12766 | */
12767 | if (hfinfo->id == hf_text_only)
12768 | continue;
12769 |
12770 | /* format for protocols */
12771 | if (proto_registrar_is_protocol(i)) {
12772 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12773 | matched = true1;
12774 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12775 | }
12776 | }
12777 | /* format for header fields */
12778 | else {
12779 | /*
12780 | * If this field isn't at the head of the list of
12781 | * fields with this name, skip this field - all
12782 | * fields with the same name are really just versions
12783 | * of the same field stored in different bits, and
12784 | * should have the same type/radix/value list, and
12785 | * just differ in their bit masks. (If a field isn't
12786 | * a bitfield, but can be, say, 1 or 2 bytes long,
12787 | * it can just be made FT_UINT16, meaning the
12788 | * *maximum* length is 2 bytes, and be used
12789 | * for all lengths.)
12790 | */
12791 | if (hfinfo->same_name_prev_id != -1)
12792 | continue;
12793 |
12794 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12795 | matched = true1;
12796 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12797 | }
12798 | }
12799 | }
12800 | return matched;
12801 | }
12802 |
12803 | /* Dumps field types and descriptive names to stdout. An independent
12804 | * program can take this output and format it into nice tables or HTML or
12805 | * whatever.
12806 | *
12807 | * There is one record per line. The fields are tab-delimited.
12808 | *
12809 | * Field 1 = field type name, e.g. FT_UINT8
12810 | * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12811 | */
12812 | void
12813 | proto_registrar_dump_ftypes(void)
12814 | {
12815 | int fte;
12816 |
12817 | for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12818 | printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12819 | }
12820 | }
12821 |
12822 | /* This function indicates whether it's possible to construct a
12823 | * "match selected" display filter string for the specified field,
12824 | * returns an indication of whether it's possible, and, if it's
12825 | * possible and "filter" is non-null, constructs the filter and
12826 | * sets "*filter" to point to it.
12827 | * You do not need to [g_]free() this string since it will be automatically
12828 | * freed once the next packet is dissected.
12829 | */
12830 | static bool_Bool
12831 | construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12832 | char **filter)
12833 | {
12834 | const header_field_info *hfinfo;
12835 | int start, length, length_remaining;
12836 |
12837 | if (!finfo)
12838 | return false0;
12839 |
12840 | hfinfo = finfo->hfinfo;
12841 | DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12841, "hfinfo"))));
12842 |
12843 | /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12844 | * then "the numeric value ... is not used when preparing
12845 | * filters for the field in question." If it's any other
12846 | * base, we'll generate the filter normally (which will
12847 | * be numeric, even though the human-readable string does
12848 | * work for filtering.)
12849 | *
12850 | * XXX - It might be nice to use fvalue_to_string_repr() in
12851 | * "proto_item_fill_label()" as well, although, there, you'd
12852 | * have to deal with the base *and* with resolved values for
12853 | * addresses.
12854 | *
12855 | * Perhaps in addition to taking the repr type (DISPLAY
12856 | * or DFILTER) and the display (base), fvalue_to_string_repr()
12857 | * should have the the "strings" values in the header_field_info
12858 | * structure for the field as a parameter, so it can have
12859 | * if the field is Boolean or an enumerated integer type,
12860 | * the tables used to generate human-readable values.
12861 | */
12862 | if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12863 | const char *str = NULL((void*)0);
12864 |
12865 | switch (hfinfo->type) {
12866 |
12867 | case FT_INT8:
12868 | case FT_INT16:
12869 | case FT_INT24:
12870 | case FT_INT32:
12871 | str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12872 | break;
12873 |
12874 | case FT_CHAR:
12875 | case FT_UINT8:
12876 | case FT_UINT16:
12877 | case FT_UINT24:
12878 | case FT_UINT32:
12879 | str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12880 | break;
12881 |
12882 | default:
12883 | break;
12884 | }
12885 |
12886 | if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12887 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12888 | return true1;
12889 | }
12890 | }
12891 |
12892 | switch (hfinfo->type) {
12893 |
12894 | case FT_PROTOCOL:
12895 | if (filter != NULL((void*)0))
12896 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12897 | break;
12898 |
12899 | case FT_NONE:
12900 | /*
12901 | * If the length is 0, just match the name of the
12902 | * field.
12903 | *
12904 | * (Also check for negative values, just in case,
12905 | * as we'll cast it to an unsigned value later.)
12906 | */
12907 | length = finfo->length;
12908 | if (length == 0) {
12909 | if (filter != NULL((void*)0))
12910 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12911 | break;
12912 | }
12913 | if (length < 0)
12914 | return false0;
12915 |
12916 | /*
12917 | * This doesn't have a value, so we'd match
12918 | * on the raw bytes at this address.
12919 | *
12920 | * Should we be allowed to access to the raw bytes?
12921 | * If "edt" is NULL, the answer is "no".
12922 | */
12923 | if (edt == NULL((void*)0))
12924 | return false0;
12925 |
12926 | /*
12927 | * Is this field part of the raw frame tvbuff?
12928 | * If not, we can't use "frame[N:M]" to match
12929 | * it.
12930 | *
12931 | * XXX - should this be frame-relative, or
12932 | * protocol-relative?
12933 | *
12934 | * XXX - does this fallback for non-registered
12935 | * fields even make sense?
12936 | */
12937 | if (finfo->ds_tvb != edt->tvb)
12938 | return false0; /* you lose */
12939 |
12940 | /*
12941 | * Don't go past the end of that tvbuff.
12942 | */
12943 | length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12944 | if (length > length_remaining)
12945 | length = length_remaining;
12946 | if (length <= 0)
12947 | return false0;
12948 |
12949 | if (filter != NULL((void*)0)) {
12950 | start = finfo->start;
12951 | char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12952 | *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12953 | wmem_free(NULL((void*)0), str);
12954 | }
12955 | break;
12956 |
12957 | /* By default, use the fvalue's "to_string_repr" method. */
12958 | default:
12959 | if (filter != NULL((void*)0)) {
12960 | char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12961 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12962 | wmem_free(NULL((void*)0), str);
12963 | }
12964 | break;
12965 | }
12966 |
12967 | return true1;
12968 | }
12969 |
12970 | /*
12971 | * Returns true if we can do a "match selected" on the field, false
12972 | * otherwise.
12973 | */
12974 | bool_Bool
12975 | proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12976 | {
12977 | return construct_match_selected_string(finfo, edt, NULL((void*)0));
12978 | }
12979 |
12980 | /* This function attempts to construct a "match selected" display filter
12981 | * string for the specified field; if it can do so, it returns a pointer
12982 | * to the string, otherwise it returns NULL.
12983 | *
12984 | * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12985 | */
12986 | char *
12987 | proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12988 | {
12989 | char *filter = NULL((void*)0);
12990 |
12991 | if (!construct_match_selected_string(finfo, edt, &filter))
12992 | {
12993 | wmem_free(NULL((void*)0), filter);
12994 | return NULL((void*)0);
12995 | }
12996 | return filter;
12997 | }
12998 |
12999 | /* This function is common code for all proto_tree_add_bitmask... functions.
13000 | */
13001 |
13002 | static bool_Bool
13003 | proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
13004 | const unsigned len, const int ett, int * const *fields,
13005 | const int flags, bool_Bool first,
13006 | bool_Bool use_parent_tree,
13007 | proto_tree* tree, uint64_t value)
13008 | {
13009 | uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
13010 | uint64_t bitmask = 0;
13011 | uint64_t tmpval;
13012 | header_field_info *hf;
13013 | uint32_t integer32;
13014 | int bit_offset;
13015 | int no_of_bits;
13016 |
13017 | if (!*fields)
13018 | 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" );
13019 |
13020 | if (len > 8)
13021 | REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
13022 | /**
13023 | * packet-frame.c uses len=0 since the value is taken from the packet
13024 | * metadata, not the packet bytes. In that case, assume that all bits
13025 | * in the provided value are valid.
13026 | */
13027 | if (len > 0) {
13028 | available_bits >>= (8 - len)*8;
13029 | }
13030 |
13031 | if (use_parent_tree == false0)
13032 | tree = proto_item_add_subtree(item, ett);
13033 |
13034 | while (*fields) {
13035 | uint64_t present_bits;
13036 | 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", 13036, __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", 13036 , "**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", 13036, "gpa_hfinfo.hfi[**fields] != ((void*)0)" , "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[**fields];;
13037 | 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", 13037 , "hf->bitmask != 0", hf->abbrev))));
13038 |
13039 | bitmask |= hf->bitmask;
13040 |
13041 | /* Skip fields that aren't fully present */
13042 | present_bits = available_bits & hf->bitmask;
13043 | if (present_bits != hf->bitmask) {
13044 | fields++;
13045 | continue;
13046 | }
13047 |
13048 | switch (hf->type) {
13049 | case FT_CHAR:
13050 | case FT_UINT8:
13051 | case FT_UINT16:
13052 | case FT_UINT24:
13053 | case FT_UINT32:
13054 | proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
13055 | break;
13056 |
13057 | case FT_INT8:
13058 | case FT_INT16:
13059 | case FT_INT24:
13060 | case FT_INT32:
13061 | proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
13062 | break;
13063 |
13064 | case FT_UINT40:
13065 | case FT_UINT48:
13066 | case FT_UINT56:
13067 | case FT_UINT64:
13068 | proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
13069 | break;
13070 |
13071 | case FT_INT40:
13072 | case FT_INT48:
13073 | case FT_INT56:
13074 | case FT_INT64:
13075 | proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
13076 | break;
13077 |
13078 | case FT_BOOLEAN:
13079 | proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
13080 | break;
13081 |
13082 | default:
13083 | 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))
13084 | 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))
13085 | 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))
13086 | 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));
13087 | break;
13088 | }
13089 | if (flags & BMT_NO_APPEND0x01) {
13090 | fields++;
13091 | continue;
13092 | }
13093 | tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
13094 |
13095 | /* XXX: README.developer and the comments have always defined
13096 | * BMT_NO_INT as "only boolean flags are added to the title /
13097 | * don't add non-boolean (integral) fields", but the
13098 | * implementation has always added BASE_CUSTOM and fields with
13099 | * value_strings, though not fields with unit_strings.
13100 | * Possibly this is because some dissectors use a FT_UINT8
13101 | * with a value_string for fields that should be a FT_BOOLEAN.
13102 | */
13103 | switch (hf->type) {
13104 | case FT_CHAR:
13105 | if (hf->display == BASE_CUSTOM) {
13106 | char lbl[ITEM_LABEL_LENGTH240];
13107 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13108 |
13109 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13109, "fmtfunc"))));
13110 | fmtfunc(lbl, (uint32_t) tmpval);
13111 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13112 | hf->name, lbl);
13113 | first = false0;
13114 | }
13115 | else if (hf->strings) {
13116 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13117 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13118 | first = false0;
13119 | }
13120 | else if (!(flags & BMT_NO_INT0x02)) {
13121 | char buf[32];
13122 | const char *out;
13123 |
13124 | if (!first) {
13125 | proto_item_append_text(item, ", ");
13126 | }
13127 |
13128 | out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
13129 | proto_item_append_text(item, "%s: %s", hf->name, out);
13130 | first = false0;
13131 | }
13132 |
13133 | break;
13134 |
13135 | case FT_UINT8:
13136 | case FT_UINT16:
13137 | case FT_UINT24:
13138 | case FT_UINT32:
13139 | if (hf->display == BASE_CUSTOM) {
13140 | char lbl[ITEM_LABEL_LENGTH240];
13141 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13142 |
13143 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13143, "fmtfunc"))));
13144 | fmtfunc(lbl, (uint32_t) tmpval);
13145 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13146 | hf->name, lbl);
13147 | first = false0;
13148 | }
13149 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13150 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13151 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13152 | first = false0;
13153 | }
13154 | else if (!(flags & BMT_NO_INT0x02)) {
13155 | char buf[NUMBER_LABEL_LENGTH80];
13156 | const char *out = NULL((void*)0);
13157 |
13158 | if (!first) {
13159 | proto_item_append_text(item, ", ");
13160 | }
13161 |
13162 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13163 | out = hf_try_val_to_str((uint32_t) tmpval, hf);
13164 | }
13165 | if (out == NULL((void*)0)) {
13166 | out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13167 | }
13168 | proto_item_append_text(item, "%s: %s", hf->name, out);
13169 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13170 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13171 | }
13172 | first = false0;
13173 | }
13174 |
13175 | break;
13176 |
13177 | case FT_INT8:
13178 | case FT_INT16:
13179 | case FT_INT24:
13180 | case FT_INT32:
13181 | integer32 = (uint32_t) tmpval;
13182 | if (hf->bitmask) {
13183 | no_of_bits = ws_count_ones(hf->bitmask);
13184 | integer32 = ws_sign_ext32(integer32, no_of_bits);
13185 | }
13186 | if (hf->display == BASE_CUSTOM) {
13187 | char lbl[ITEM_LABEL_LENGTH240];
13188 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13189 |
13190 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13190, "fmtfunc"))));
13191 | fmtfunc(lbl, (int32_t) integer32);
13192 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13193 | hf->name, lbl);
13194 | first = false0;
13195 | }
13196 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13197 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13198 | hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13199 | first = false0;
13200 | }
13201 | else if (!(flags & BMT_NO_INT0x02)) {
13202 | char buf[NUMBER_LABEL_LENGTH80];
13203 | const char *out = NULL((void*)0);
13204 |
13205 | if (!first) {
13206 | proto_item_append_text(item, ", ");
13207 | }
13208 |
13209 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13210 | out = hf_try_val_to_str((int32_t) integer32, hf);
13211 | }
13212 | if (out == NULL((void*)0)) {
13213 | out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13214 | }
13215 | proto_item_append_text(item, "%s: %s", hf->name, out);
13216 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13217 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13218 | }
13219 | first = false0;
13220 | }
13221 |
13222 | break;
13223 |
13224 | case FT_UINT40:
13225 | case FT_UINT48:
13226 | case FT_UINT56:
13227 | case FT_UINT64:
13228 | if (hf->display == BASE_CUSTOM) {
13229 | char lbl[ITEM_LABEL_LENGTH240];
13230 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13231 |
13232 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13232, "fmtfunc"))));
13233 | fmtfunc(lbl, tmpval);
13234 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13235 | hf->name, lbl);
13236 | first = false0;
13237 | }
13238 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13239 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13240 | hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13241 | first = false0;
13242 | }
13243 | else if (!(flags & BMT_NO_INT0x02)) {
13244 | char buf[NUMBER_LABEL_LENGTH80];
13245 | const char *out = NULL((void*)0);
13246 |
13247 | if (!first) {
13248 | proto_item_append_text(item, ", ");
13249 | }
13250 |
13251 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13252 | out = hf_try_val64_to_str(tmpval, hf);
13253 | }
13254 | if (out == NULL((void*)0)) {
13255 | out = hfinfo_number_value_format64(hf, buf, tmpval);
13256 | }
13257 | proto_item_append_text(item, "%s: %s", hf->name, out);
13258 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13259 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13260 | }
13261 | first = false0;
13262 | }
13263 |
13264 | break;
13265 |
13266 | case FT_INT40:
13267 | case FT_INT48:
13268 | case FT_INT56:
13269 | case FT_INT64:
13270 | if (hf->bitmask) {
13271 | no_of_bits = ws_count_ones(hf->bitmask);
13272 | tmpval = ws_sign_ext64(tmpval, no_of_bits);
13273 | }
13274 | if (hf->display == BASE_CUSTOM) {
13275 | char lbl[ITEM_LABEL_LENGTH240];
13276 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13277 |
13278 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13278, "fmtfunc"))));
13279 | fmtfunc(lbl, (int64_t) tmpval);
13280 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13281 | hf->name, lbl);
13282 | first = false0;
13283 | }
13284 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13285 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13286 | hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13287 | first = false0;
13288 | }
13289 | else if (!(flags & BMT_NO_INT0x02)) {
13290 | char buf[NUMBER_LABEL_LENGTH80];
13291 | const char *out = NULL((void*)0);
13292 |
13293 | if (!first) {
13294 | proto_item_append_text(item, ", ");
13295 | }
13296 |
13297 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13298 | out = hf_try_val64_to_str((int64_t) tmpval, hf);
13299 | }
13300 | if (out == NULL((void*)0)) {
13301 | out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13302 | }
13303 | proto_item_append_text(item, "%s: %s", hf->name, out);
13304 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13305 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13306 | }
13307 | first = false0;
13308 | }
13309 |
13310 | break;
13311 |
13312 | case FT_BOOLEAN:
13313 | if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13314 | /* If we have true/false strings, emit full - otherwise messages
13315 | might look weird */
13316 | const struct true_false_string *tfs =
13317 | (const struct true_false_string *)hf->strings;
13318 |
13319 | if (tmpval) {
13320 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13321 | hf->name, tfs->true_string);
13322 | first = false0;
13323 | } else if (!(flags & BMT_NO_FALSE0x04)) {
13324 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13325 | hf->name, tfs->false_string);
13326 | first = false0;
13327 | }
13328 | } else if (hf->bitmask & value) {
13329 | /* If the flag is set, show the name */
13330 | proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13331 | first = false0;
13332 | }
13333 | break;
13334 | default:
13335 | 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))
13336 | 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))
13337 | 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))
13338 | 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));
13339 | break;
13340 | }
13341 |
13342 | fields++;
13343 | }
13344 |
13345 | /* XXX: We don't pass the hfi into this function. Perhaps we should,
13346 | * but then again most dissectors don't set the bitmask field for
13347 | * the higher level bitmask hfi, so calculate the bitmask from the
13348 | * fields present. */
13349 | if (item) {
13350 | bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13351 | no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13352 | 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);
13353 | 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);
13354 | }
13355 | return first;
13356 | }
13357 |
13358 | /* This function will dissect a sequence of bytes that describe a
13359 | * bitmask and supply the value of that sequence through a pointer.
13360 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13361 | * to be dissected.
13362 | * This field will form an expansion under which the individual fields of the
13363 | * bitmask is dissected and displayed.
13364 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13365 | *
13366 | * fields is an array of pointers to int that lists all the fields of the
13367 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13368 | * or another integer of the same type/size as hf_hdr with a mask specified.
13369 | * This array is terminated by a NULL entry.
13370 | *
13371 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13372 | * FT_integer fields that have a value_string attached will have the
13373 | * matched string displayed on the expansion line.
13374 | */
13375 | proto_item *
13376 | proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13377 | const unsigned offset, const int hf_hdr,
13378 | const int ett, int * const *fields,
13379 | const unsigned encoding, uint64_t *retval)
13380 | {
13381 | 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);
13382 | }
13383 |
13384 | /* This function will dissect a sequence of bytes that describe a
13385 | * bitmask.
13386 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13387 | * to be dissected.
13388 | * This field will form an expansion under which the individual fields of the
13389 | * bitmask is dissected and displayed.
13390 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13391 | *
13392 | * fields is an array of pointers to int that lists all the fields of the
13393 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13394 | * or another integer of the same type/size as hf_hdr with a mask specified.
13395 | * This array is terminated by a NULL entry.
13396 | *
13397 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13398 | * FT_integer fields that have a value_string attached will have the
13399 | * matched string displayed on the expansion line.
13400 | */
13401 | proto_item *
13402 | proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13403 | const unsigned offset, const int hf_hdr,
13404 | const int ett, int * const *fields,
13405 | const unsigned encoding)
13406 | {
13407 | return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13408 | }
13409 |
13410 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13411 | * what data is appended to the header.
13412 | */
13413 | proto_item *
13414 | proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13415 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13416 | uint64_t *retval)
13417 | {
13418 | proto_item *item = NULL((void*)0);
13419 | header_field_info *hf;
13420 | unsigned len;
13421 | uint64_t value;
13422 |
13423 | 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", 13423, __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", 13423 , "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", 13423, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13424 | 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", 13424, (hf)->abbrev)));
13425 | len = ftype_wire_size(hf->type);
13426 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13427 |
13428 | if (parent_tree) {
13429 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13430 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13431 | flags, false0, false0, NULL((void*)0), value);
13432 | }
13433 |
13434 | *retval = value;
13435 | if (hf->bitmask) {
13436 | /* Mask out irrelevant portions */
13437 | *retval &= hf->bitmask;
13438 | /* Shift bits */
13439 | *retval >>= hfinfo_bitshift(hf);
13440 | }
13441 |
13442 | return item;
13443 | }
13444 |
13445 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13446 | * what data is appended to the header.
13447 | */
13448 | proto_item *
13449 | proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13450 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13451 | {
13452 | proto_item *item = NULL((void*)0);
13453 | header_field_info *hf;
13454 | unsigned len;
13455 | uint64_t value;
13456 |
13457 | 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", 13457, __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", 13457 , "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", 13457, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13458 | 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", 13458, (hf)->abbrev)));
13459 |
13460 | if (parent_tree) {
13461 | len = ftype_wire_size(hf->type);
13462 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13463 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13464 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13465 | flags, false0, false0, NULL((void*)0), value);
13466 | }
13467 |
13468 | return item;
13469 | }
13470 |
13471 | /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13472 | can't be retrieved directly from tvb) */
13473 | proto_item *
13474 | proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13475 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13476 | {
13477 | return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13478 | hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13479 | }
13480 |
13481 | /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13482 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13483 | proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13484 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13485 | {
13486 | proto_item *item = NULL((void*)0);
13487 | header_field_info *hf;
13488 | unsigned len;
13489 |
13490 | 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", 13490, __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", 13490 , "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", 13490, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13491 | 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", 13491, (hf)->abbrev)));
13492 | /* the proto_tree_add_uint/_uint64() calls below
13493 | will fail if tvb==NULL and len!=0 */
13494 | len = tvb ? ftype_wire_size(hf->type) : 0;
13495 |
13496 | if (parent_tree) {
13497 | if (len <= 4)
13498 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13499 | else
13500 | item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13501 |
13502 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13503 | flags, false0, false0, NULL((void*)0), value);
13504 | }
13505 |
13506 | return item;
13507 | }
13508 |
13509 | /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13510 | void
13511 | proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13512 | const unsigned len, int * const *fields, const unsigned encoding)
13513 | {
13514 | uint64_t value;
13515 |
13516 | if (tree) {
13517 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13518 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13519 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13520 | }
13521 | }
13522 |
13523 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13524 | proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13525 | const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13526 | {
13527 | uint64_t value;
13528 |
13529 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13530 | if (tree) {
13531 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13532 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13533 | }
13534 | if (retval) {
13535 | *retval = value;
13536 | }
13537 | }
13538 |
13539 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13540 | proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13541 | const unsigned len, int * const *fields, const uint64_t value)
13542 | {
13543 | if (tree) {
13544 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13545 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13546 | }
13547 | }
13548 |
13549 |
13550 | /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13551 | * This is intended to support bitmask fields whose lengths can vary, perhaps
13552 | * as the underlying standard evolves over time.
13553 | * With this API there is the possibility of being called to display more or
13554 | * less data than the dissector was coded to support.
13555 | * In such cases, it is assumed that bitmasks are extended on the MSb end.
13556 | * Thus when presented with "too much" or "too little" data, MSbits will be
13557 | * ignored or MSfields sacrificed.
13558 | *
13559 | * Only fields for which all defined bits are available are displayed.
13560 | */
13561 | proto_item *
13562 | proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13563 | const unsigned offset, const unsigned len, const int hf_hdr,
13564 | const int ett, int * const *fields, struct expert_field* exp,
13565 | const unsigned encoding)
13566 | {
13567 | proto_item *item = NULL((void*)0);
13568 | header_field_info *hf;
13569 | unsigned decodable_len;
13570 | unsigned decodable_offset;
13571 | uint32_t decodable_value;
13572 | uint64_t value;
13573 |
13574 | 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", 13574, __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", 13574 , "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", 13574, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf.")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13575 | 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", 13575, (hf)->abbrev)));
13576 |
13577 | decodable_offset = offset;
13578 | decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len ) : ((unsigned) ftype_wire_size(hf->type)));
13579 |
13580 | /* If we are ftype_wire_size-limited,
13581 | * make sure we decode as many LSBs as possible.
13582 | */
13583 | if (encoding == ENC_BIG_ENDIAN0x00000000) {
13584 | decodable_offset += (len - decodable_len);
13585 | }
13586 |
13587 | if (parent_tree) {
13588 | decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13589 | decodable_len, encoding);
13590 |
13591 | /* The root item covers all the bytes even if we can't decode them all */
13592 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13593 | decodable_value);
13594 | }
13595 |
13596 | if (decodable_len < len) {
13597 | /* Dissector likely requires updating for new protocol revision */
13598 | expert_add_info_format(NULL((void*)0), item, exp,
13599 | "Only least-significant %d of %d bytes decoded",
13600 | decodable_len, len);
13601 | }
13602 |
13603 | if (item) {
13604 | value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13605 | proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13606 | ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13607 | }
13608 |
13609 | return item;
13610 | }
13611 |
13612 | /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13613 | proto_item *
13614 | proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13615 | const unsigned offset, const unsigned len,
13616 | const char *name, const char *fallback,
13617 | const int ett, int * const *fields,
13618 | const unsigned encoding, const int flags)
13619 | {
13620 | proto_item *item = NULL((void*)0);
13621 | uint64_t value;
13622 |
13623 | if (parent_tree) {
13624 | item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13625 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13626 | if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13627 | flags, true1, false0, NULL((void*)0), value) && fallback) {
13628 | /* Still at first item - append 'fallback' text if any */
13629 | proto_item_append_text(item, "%s", fallback);
13630 | }
13631 | }
13632 |
13633 | return item;
13634 | }
13635 |
13636 | proto_item *
13637 | proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13638 | const unsigned bit_offset, const int no_of_bits,
13639 | const unsigned encoding)
13640 | {
13641 | header_field_info *hfinfo;
13642 | int octet_length;
13643 | unsigned octet_offset;
13644 |
13645 | 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", 13645, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13645 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13645, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13646 |
13647 | if (no_of_bits < 0) {
13648 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13649 | }
13650 | octet_length = (no_of_bits + 7) >> 3;
13651 | octet_offset = bit_offset >> 3;
13652 | test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13653 |
13654 | /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13655 | * but only after doing a bunch more work (which we can, in the common
13656 | * case, shortcut here).
13657 | */
13658 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13659 | 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", 13659 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13659, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13659, "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", 13659, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
13660 |
13661 | return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13662 | }
13663 |
13664 | /*
13665 | * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13666 | * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13667 | * Offset should be given in bits from the start of the tvb.
13668 | */
13669 |
13670 | static proto_item *
13671 | _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13672 | const unsigned bit_offset, const int no_of_bits,
13673 | uint64_t *return_value, const unsigned encoding)
13674 | {
13675 | unsigned offset;
13676 | unsigned length;
13677 | uint8_t tot_no_bits;
13678 | char *bf_str;
13679 | char lbl_str[ITEM_LABEL_LENGTH240];
13680 | uint64_t value = 0;
13681 | uint8_t *bytes = NULL((void*)0);
13682 | size_t bytes_length = 0;
13683 |
13684 | proto_item *pi;
13685 | header_field_info *hf_field;
13686 |
13687 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13688 | 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", 13688, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13688 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13688, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;;
13689 |
13690 | if (hf_field->bitmask != 0) {
13691 | 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)
13692 | " 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)
13693 | 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);
13694 | }
13695 |
13696 | if (no_of_bits < 0) {
13697 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13698 | } else if (no_of_bits == 0) {
13699 | 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)
13700 | 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);
13701 | }
13702 |
13703 | /* Byte align offset */
13704 | offset = bit_offset>>3;
13705 |
13706 | /*
13707 | * Calculate the number of octets used to hold the bits
13708 | */
13709 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13710 | length = (tot_no_bits + 7) >> 3;
13711 |
13712 | if (no_of_bits < 65) {
13713 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13714 | } else if (hf_field->type != FT_BYTES) {
13715 | 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)
13716 | 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);
13717 | return NULL((void*)0);
13718 | }
13719 |
13720 | /* Sign extend for signed types */
13721 | switch (hf_field->type) {
13722 | case FT_INT8:
13723 | case FT_INT16:
13724 | case FT_INT24:
13725 | case FT_INT32:
13726 | case FT_INT40:
13727 | case FT_INT48:
13728 | case FT_INT56:
13729 | case FT_INT64:
13730 | value = ws_sign_ext64(value, no_of_bits);
13731 | break;
13732 |
13733 | default:
13734 | break;
13735 | }
13736 |
13737 | if (return_value) {
13738 | *return_value = value;
13739 | }
13740 |
13741 | /* Coast clear. Try and fake it */
13742 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13743 | 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", 13743 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13743, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13743, "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", 13743, __func__, "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); } } };
13744 |
13745 | bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13746 |
13747 | switch (hf_field->type) {
13748 | case FT_BOOLEAN:
13749 | /* Boolean field */
13750 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13751 | "%s = %s: %s",
13752 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13753 | break;
13754 |
13755 | case FT_CHAR:
13756 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13757 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13758 | break;
13759 |
13760 | case FT_UINT8:
13761 | case FT_UINT16:
13762 | case FT_UINT24:
13763 | case FT_UINT32:
13764 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13765 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13766 | break;
13767 |
13768 | case FT_INT8:
13769 | case FT_INT16:
13770 | case FT_INT24:
13771 | case FT_INT32:
13772 | pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13773 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13774 | break;
13775 |
13776 | case FT_UINT40:
13777 | case FT_UINT48:
13778 | case FT_UINT56:
13779 | case FT_UINT64:
13780 | pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13781 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13782 | break;
13783 |
13784 | case FT_INT40:
13785 | case FT_INT48:
13786 | case FT_INT56:
13787 | case FT_INT64:
13788 | pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13789 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13790 | break;
13791 |
13792 | case FT_BYTES:
13793 | bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13794 | pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13795 | proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13796 | proto_item_set_text(pi, "%s", lbl_str);
13797 | return pi;
13798 |
13799 | /* TODO: should handle FT_UINT_BYTES ? */
13800 |
13801 | default:
13802 | 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))
13803 | 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))
13804 | 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))
13805 | 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));
13806 | return NULL((void*)0);
13807 | }
13808 |
13809 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13810 | return pi;
13811 | }
13812 |
13813 | proto_item *
13814 | proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13815 | const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13816 | uint64_t *return_value)
13817 | {
13818 | proto_item *pi;
13819 | int no_of_bits;
13820 | unsigned octet_offset;
13821 | unsigned mask_initial_bit_offset;
13822 | unsigned mask_greatest_bit_offset;
13823 | unsigned octet_length;
13824 | uint8_t i;
13825 | char bf_str[256];
13826 | char lbl_str[ITEM_LABEL_LENGTH240];
13827 | uint64_t value;
13828 | uint64_t composite_bitmask;
13829 | uint64_t composite_bitmap;
13830 |
13831 | header_field_info *hf_field;
13832 |
13833 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13834 | 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", 13834, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13834 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13834, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;;
13835 |
13836 | if (hf_field->bitmask != 0) {
13837 | 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)
13838 | " 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)
13839 | 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);
13840 | }
13841 |
13842 | mask_initial_bit_offset = bit_offset % 8;
13843 |
13844 | no_of_bits = 0;
13845 | value = 0;
13846 | i = 0;
13847 | mask_greatest_bit_offset = 0;
13848 | composite_bitmask = 0;
13849 | composite_bitmap = 0;
13850 |
13851 | while (crumb_spec[i].crumb_bit_length != 0) {
13852 | uint64_t crumb_mask, crumb_value;
13853 | uint8_t crumb_end_bit_offset;
13854 |
13855 | crumb_value = tvb_get_bits64(tvb,
13856 | bit_offset + crumb_spec[i].crumb_bit_offset,
13857 | crumb_spec[i].crumb_bit_length,
13858 | ENC_BIG_ENDIAN0x00000000);
13859 | value += crumb_value;
13860 | no_of_bits += crumb_spec[i].crumb_bit_length;
13861 | 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", 13861 , "no_of_bits <= 64", "a value larger than 64 bits cannot be represented" ))));
13862 |
13863 | /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13864 | octet containing the initial offset.
13865 | If the mask is beyond 32 bits, then give up on bit map display.
13866 | This could be improved in future, probably showing a table
13867 | of 32 or 64 bits per row */
13868 | if (mask_greatest_bit_offset < 32) {
13869 | crumb_end_bit_offset = mask_initial_bit_offset
13870 | + crumb_spec[i].crumb_bit_offset
13871 | + crumb_spec[i].crumb_bit_length;
13872 | crumb_mask = (UINT64_C(1)1UL << crumb_spec[i].crumb_bit_length) - 1;
13873 |
13874 | if (crumb_end_bit_offset > mask_greatest_bit_offset) {
13875 | mask_greatest_bit_offset = crumb_end_bit_offset;
13876 | }
13877 | /* Currently the bitmap of the crumbs are only shown if
13878 | * smaller than 32 bits. Do not bother calculating the
13879 | * mask if it is larger than that. */
13880 | if (crumb_end_bit_offset <= 32) {
13881 | composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
13882 | composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13883 | }
13884 | }
13885 | /* Shift left for the next segment */
13886 | value <<= crumb_spec[++i].crumb_bit_length;
13887 | }
13888 |
13889 | /* Sign extend for signed types */
13890 | switch (hf_field->type) {
13891 | case FT_INT8:
13892 | case FT_INT16:
13893 | case FT_INT24:
13894 | case FT_INT32:
13895 | case FT_INT40:
13896 | case FT_INT48:
13897 | case FT_INT56:
13898 | case FT_INT64:
13899 | value = ws_sign_ext64(value, no_of_bits);
13900 | break;
13901 | default:
13902 | break;
13903 | }
13904 |
13905 | if (return_value) {
13906 | *return_value = value;
13907 | }
13908 |
13909 | /* Coast clear. Try and fake it */
13910 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13911 | 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", 13911 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13911, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13911, "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", 13911, __func__, "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); } } };
13912 |
13913 | /* initialise the format string */
13914 | bf_str[0] = '\0';
13915 |
13916 | octet_offset = bit_offset >> 3;
13917 |
13918 | /* Round up mask length to nearest octet */
13919 | octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13920 | mask_greatest_bit_offset = octet_length << 3;
13921 |
13922 | /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13923 | It would be a useful enhancement to eliminate this restriction. */
13924 | if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13925 | other_decode_bitfield_value(bf_str,
13926 | (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13927 | (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13928 | mask_greatest_bit_offset);
13929 | } else {
13930 | /* If the bitmask is too large, try to describe its contents. */
13931 | snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13932 | }
13933 |
13934 | switch (hf_field->type) {
13935 | case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13936 | /* Boolean field */
13937 | return proto_tree_add_boolean_format(tree, hfindex,
13938 | tvb, octet_offset, octet_length, value,
13939 | "%s = %s: %s",
13940 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13941 | break;
13942 |
13943 | case FT_CHAR:
13944 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13945 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13946 | break;
13947 |
13948 | case FT_UINT8:
13949 | case FT_UINT16:
13950 | case FT_UINT24:
13951 | case FT_UINT32:
13952 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13953 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13954 | break;
13955 |
13956 | case FT_INT8:
13957 | case FT_INT16:
13958 | case FT_INT24:
13959 | case FT_INT32:
13960 | pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13961 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13962 | break;
13963 |
13964 | case FT_UINT40:
13965 | case FT_UINT48:
13966 | case FT_UINT56:
13967 | case FT_UINT64:
13968 | pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13969 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13970 | break;
13971 |
13972 | case FT_INT40:
13973 | case FT_INT48:
13974 | case FT_INT56:
13975 | case FT_INT64:
13976 | pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13977 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13978 | break;
13979 |
13980 | default:
13981 | 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))
13982 | 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))
13983 | 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))
13984 | 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));
13985 | return NULL((void*)0);
13986 | }
13987 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13988 | return pi;
13989 | }
13990 |
13991 | void
13992 | proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13993 | const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13994 | {
13995 | header_field_info *hfinfo;
13996 | unsigned start = bit_offset >> 3;
13997 | unsigned length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13998 |
13999 | /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
14000 | * so that we can use the tree's memory scope in calculating the string */
14001 | tvb_ensure_bytes_exist(tvb, start, length);
14002 | if (!tree) return;
14003 |
14004 | 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", 14004, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 14004 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14004, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
14005 | proto_tree_add_text_internal(tree, tvb, start, length,
14006 | "%s crumb %d of %s (decoded above)",
14007 | decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
14008 | tvb_get_bits32(tvb,
14009 | bit_offset,
14010 | crumb_spec[crumb_index].crumb_bit_length,
14011 | ENC_BIG_ENDIAN0x00000000),
14012 | ENC_BIG_ENDIAN0x00000000),
14013 | crumb_index,
14014 | hfinfo->name);
14015 | }
14016 |
14017 | proto_item *
14018 | proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14019 | const unsigned bit_offset, const int no_of_bits,
14020 | uint64_t *return_value, const unsigned encoding)
14021 | {
14022 | proto_item *item;
14023 |
14024 | if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
14025 | bit_offset, no_of_bits,
14026 | return_value, encoding))) {
14027 | 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);
14028 | 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);
14029 | }
14030 | return item;
14031 | }
14032 |
14033 | static proto_item *
14034 | _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14035 | tvbuff_t *tvb, const unsigned bit_offset,
14036 | const int no_of_bits, void *value_ptr,
14037 | const unsigned encoding, char *value_str)
14038 | {
14039 | unsigned offset;
14040 | unsigned length;
14041 | uint8_t tot_no_bits;
14042 | char *str;
14043 | uint64_t value = 0;
14044 | header_field_info *hf_field;
14045 |
14046 | /* We do not have to return a value, try to fake it as soon as possible */
14047 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14048 | 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", 14048 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14048, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14048, "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", 14048, __func__, "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); } } };
14049 |
14050 | if (hf_field->bitmask != 0) {
14051 | 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)
14052 | " 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)
14053 | 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);
14054 | }
14055 |
14056 | if (no_of_bits < 0) {
14057 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
14058 | } else if (no_of_bits == 0) {
14059 | 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)
14060 | 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);
14061 | }
14062 |
14063 | /* Byte align offset */
14064 | offset = bit_offset>>3;
14065 |
14066 | /*
14067 | * Calculate the number of octets used to hold the bits
14068 | */
14069 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
14070 | length = tot_no_bits>>3;
14071 | /* If we are using part of the next octet, increase length by 1 */
14072 | if (tot_no_bits & 0x07)
14073 | length++;
14074 |
14075 | if (no_of_bits < 65) {
14076 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
14077 | } else {
14078 | 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)
14079 | 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);
14080 | return NULL((void*)0);
14081 | }
14082 |
14083 | str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
14084 |
14085 | (void) g_strlcat(str, " = ", 256+64);
14086 | (void) g_strlcat(str, hf_field->name, 256+64);
14087 |
14088 | /*
14089 | * This function does not receive an actual value but a dimensionless pointer to that value.
14090 | * For this reason, the type of the header field is examined in order to determine
14091 | * what kind of value we should read from this address.
14092 | * The caller of this function must make sure that for the specific header field type the address of
14093 | * a compatible value is provided.
14094 | */
14095 | switch (hf_field->type) {
14096 | case FT_BOOLEAN:
14097 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14098 | "%s: %s", str, value_str);
14099 | break;
14100 |
14101 | case FT_CHAR:
14102 | case FT_UINT8:
14103 | case FT_UINT16:
14104 | case FT_UINT24:
14105 | case FT_UINT32:
14106 | return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
14107 | "%s: %s", str, value_str);
14108 | break;
14109 |
14110 | case FT_UINT40:
14111 | case FT_UINT48:
14112 | case FT_UINT56:
14113 | case FT_UINT64:
14114 | return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
14115 | "%s: %s", str, value_str);
14116 | break;
14117 |
14118 | case FT_INT8:
14119 | case FT_INT16:
14120 | case FT_INT24:
14121 | case FT_INT32:
14122 | return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
14123 | "%s: %s", str, value_str);
14124 | break;
14125 |
14126 | case FT_INT40:
14127 | case FT_INT48:
14128 | case FT_INT56:
14129 | case FT_INT64:
14130 | return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
14131 | "%s: %s", str, value_str);
14132 | break;
14133 |
14134 | case FT_FLOAT:
14135 | return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
14136 | "%s: %s", str, value_str);
14137 | break;
14138 |
14139 | default:
14140 | 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))
14141 | 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))
14142 | 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))
14143 | 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));
14144 | return NULL((void*)0);
14145 | }
14146 | }
14147 |
14148 | static proto_item *
14149 | proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14150 | tvbuff_t *tvb, const unsigned bit_offset,
14151 | const int no_of_bits, void *value_ptr,
14152 | const unsigned encoding, char *value_str)
14153 | {
14154 | proto_item *item;
14155 |
14156 | if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14157 | tvb, bit_offset, no_of_bits,
14158 | value_ptr, encoding, value_str))) {
14159 | 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);
14160 | 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);
14161 | }
14162 | return item;
14163 | }
14164 |
14165 | #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); \
14166 | va_start(ap, format)__builtin_va_start(ap, format); \
14167 | dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14168 | va_end(ap)__builtin_va_end(ap);
14169 |
14170 | proto_item *
14171 | proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14172 | tvbuff_t *tvb, const unsigned bit_offset,
14173 | const int no_of_bits, uint32_t value,
14174 | const unsigned encoding,
14175 | const char *format, ...)
14176 | {
14177 | va_list ap;
14178 | char *dst;
14179 | header_field_info *hf_field;
14180 |
14181 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14182 |
14183 | 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", 14183 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14183, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14183, "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", 14183, __func__, "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); } } };
14184 |
14185 | switch (hf_field->type) {
14186 | case FT_UINT8:
14187 | case FT_UINT16:
14188 | case FT_UINT24:
14189 | case FT_UINT32:
14190 | break;
14191 |
14192 | default:
14193 | 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)
14194 | 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);
14195 | return NULL((void*)0);
14196 | }
14197 |
14198 | 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);;
14199 |
14200 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14201 | }
14202 |
14203 | proto_item *
14204 | proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14205 | tvbuff_t *tvb, const unsigned bit_offset,
14206 | const int no_of_bits, uint64_t value,
14207 | const unsigned encoding,
14208 | const char *format, ...)
14209 | {
14210 | va_list ap;
14211 | char *dst;
14212 | header_field_info *hf_field;
14213 |
14214 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14215 |
14216 | 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", 14216 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14216, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14216, "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", 14216, __func__, "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); } } };
14217 |
14218 | switch (hf_field->type) {
14219 | case FT_UINT40:
14220 | case FT_UINT48:
14221 | case FT_UINT56:
14222 | case FT_UINT64:
14223 | break;
14224 |
14225 | default:
14226 | 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)
14227 | 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);
14228 | return NULL((void*)0);
14229 | }
14230 |
14231 | 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);;
14232 |
14233 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14234 | }
14235 |
14236 | proto_item *
14237 | proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14238 | tvbuff_t *tvb, const unsigned bit_offset,
14239 | const int no_of_bits, float value,
14240 | const unsigned encoding,
14241 | const char *format, ...)
14242 | {
14243 | va_list ap;
14244 | char *dst;
14245 | header_field_info *hf_field;
14246 |
14247 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14248 |
14249 | 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", 14249 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14249, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14249, "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", 14249, __func__, "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); } } };
14250 |
14251 | 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", 14251, ((hf_field))->abbrev))));
14252 |
14253 | 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);;
14254 |
14255 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14256 | }
14257 |
14258 | proto_item *
14259 | proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14260 | tvbuff_t *tvb, const unsigned bit_offset,
14261 | const int no_of_bits, int32_t value,
14262 | const unsigned encoding,
14263 | const char *format, ...)
14264 | {
14265 | va_list ap;
14266 | char *dst;
14267 | header_field_info *hf_field;
14268 |
14269 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14270 |
14271 | 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", 14271 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14271, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14271, "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", 14271, __func__, "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); } } };
14272 |
14273 | switch (hf_field->type) {
14274 | case FT_INT8:
14275 | case FT_INT16:
14276 | case FT_INT24:
14277 | case FT_INT32:
14278 | break;
14279 |
14280 | default:
14281 | 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)
14282 | 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);
14283 | return NULL((void*)0);
14284 | }
14285 |
14286 | 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);;
14287 |
14288 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14289 | }
14290 |
14291 | proto_item *
14292 | proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14293 | tvbuff_t *tvb, const unsigned bit_offset,
14294 | const int no_of_bits, int64_t value,
14295 | const unsigned encoding,
14296 | const char *format, ...)
14297 | {
14298 | va_list ap;
14299 | char *dst;
14300 | header_field_info *hf_field;
14301 |
14302 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14303 |
14304 | 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", 14304 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14304, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14304, "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", 14304, __func__, "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); } } };
14305 |
14306 | switch (hf_field->type) {
14307 | case FT_INT40:
14308 | case FT_INT48:
14309 | case FT_INT56:
14310 | case FT_INT64:
14311 | break;
14312 |
14313 | default:
14314 | 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)
14315 | 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);
14316 | return NULL((void*)0);
14317 | }
14318 |
14319 | 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);;
14320 |
14321 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14322 | }
14323 |
14324 | proto_item *
14325 | proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14326 | tvbuff_t *tvb, const unsigned bit_offset,
14327 | const int no_of_bits, uint64_t value,
14328 | const unsigned encoding,
14329 | const char *format, ...)
14330 | {
14331 | va_list ap;
14332 | char *dst;
14333 | header_field_info *hf_field;
14334 |
14335 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14336 |
14337 | 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", 14337 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14337, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14337, "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", 14337, __func__, "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); } } };
14338 |
14339 | 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" , 14339, ((hf_field))->abbrev))));
14340 |
14341 | 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);;
14342 |
14343 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14344 | }
14345 |
14346 | proto_item *
14347 | proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14348 | const unsigned bit_offset, const int no_of_chars)
14349 | {
14350 | proto_item *pi;
14351 | header_field_info *hfinfo;
14352 | int byte_length;
14353 | unsigned byte_offset;
14354 | char *string;
14355 |
14356 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14357 |
14358 | 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", 14358 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14358, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14358, "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", 14358, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14359 |
14360 | 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" , 14360, ((hfinfo))->abbrev))));
14361 |
14362 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14363 | byte_offset = bit_offset >> 3;
14364 |
14365 | string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14366 |
14367 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14368 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14368, "byte_length >= 0" ))));
14369 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14370 |
14371 | return pi;
14372 | }
14373 |
14374 | proto_item *
14375 | proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14376 | const unsigned bit_offset, const int no_of_chars)
14377 | {
14378 | proto_item *pi;
14379 | header_field_info *hfinfo;
14380 | int byte_length;
14381 | unsigned byte_offset;
14382 | char *string;
14383 |
14384 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14385 |
14386 | 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", 14386 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14386, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf.")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14386, "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", 14386, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14387 |
14388 | 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" , 14388, ((hfinfo))->abbrev))));
14389 |
14390 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14391 | byte_offset = bit_offset >> 3;
14392 |
14393 | string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14394 |
14395 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14396 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14396, "byte_length >= 0" ))));
14397 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14398 |
14399 | return pi;
14400 | }
14401 |
14402 | const value_string proto_checksum_vals[] = {
14403 | { PROTO_CHECKSUM_E_BAD, "Bad" },
14404 | { PROTO_CHECKSUM_E_GOOD, "Good" },
14405 | { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14406 | { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14407 | { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14408 |
14409 | { 0, NULL((void*)0) }
14410 | };
14411 |
14412 | #define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14413 |
14414 | proto_item *
14415 | proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14416 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14417 | packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14418 | {
14419 | header_field_info *hfinfo;
14420 | uint32_t checksum;
14421 | uint32_t len;
14422 | proto_item* ti = NULL((void*)0);
14423 | proto_item* ti2;
14424 | bool_Bool incorrect_checksum = true1;
14425 |
14426 | 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", 14426, __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", 14426 , "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", 14426, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14427 |
14428 | switch (hfinfo->type) {
14429 | case FT_UINT8:
14430 | len = 1;
14431 | break;
14432 | case FT_UINT16:
14433 | len = 2;
14434 | break;
14435 | case FT_UINT24:
14436 | len = 3;
14437 | break;
14438 | case FT_UINT32:
14439 | len = 4;
14440 | break;
14441 | default:
14442 | 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)
14443 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32" , hfinfo->abbrev);
14444 | }
14445 |
14446 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14447 | ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14448 | proto_item_set_generated(ti);
14449 | // Backward compatible with use of -1
14450 | if (hf_checksum_status > 0) {
14451 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14452 | proto_item_set_generated(ti2);
14453 | }
14454 | return ti;
14455 | }
14456 |
14457 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14458 | ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14459 | proto_item_set_generated(ti);
14460 | } else {
14461 | ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14462 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14463 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14464 | if (computed_checksum == 0) {
14465 | proto_item_append_text(ti, " [correct]");
14466 | // Backward compatible with use of -1
14467 | if (hf_checksum_status > 0) {
14468 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14469 | proto_item_set_generated(ti2);
14470 | }
14471 | incorrect_checksum = false0;
14472 | } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14473 | computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14474 | /* XXX - This can't distinguish between "shouldbe"
14475 | * 0x0000 and 0xFFFF unless we know whether there
14476 | * were any nonzero bits (other than the checksum).
14477 | * Protocols should not use this path if they might
14478 | * have an all zero packet.
14479 | * Some implementations put the wrong zero; maybe
14480 | * we should have a special expert info for that?
14481 | */
14482 | }
14483 | } else {
14484 | if (checksum == computed_checksum) {
14485 | proto_item_append_text(ti, " [correct]");
14486 | // Backward compatible with use of -1
14487 | if (hf_checksum_status > 0) {
14488 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14489 | proto_item_set_generated(ti2);
14490 | }
14491 | incorrect_checksum = false0;
14492 | }
14493 | }
14494 |
14495 | if (incorrect_checksum) {
14496 | // Backward compatible with use of -1
14497 | if (hf_checksum_status > 0) {
14498 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14499 | proto_item_set_generated(ti2);
14500 | }
14501 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14502 | proto_item_append_text(ti, " [incorrect]");
14503 | if (bad_checksum_expert != NULL((void*)0))
14504 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14505 | } else {
14506 | proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14507 | if (bad_checksum_expert != NULL((void*)0))
14508 | 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);
14509 | }
14510 | }
14511 | } else {
14512 | // Backward compatible with use of -1
14513 | if (hf_checksum_status > 0) {
14514 | proto_item_append_text(ti, " [unverified]");
14515 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14516 | proto_item_set_generated(ti2);
14517 | }
14518 | }
14519 | }
14520 |
14521 | return ti;
14522 | }
14523 |
14524 | proto_item *
14525 | proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14526 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14527 | packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14528 | {
14529 | header_field_info *hfinfo;
14530 | uint8_t *checksum = NULL((void*)0);
14531 | proto_item* ti = NULL((void*)0);
14532 | proto_item* ti2;
14533 | bool_Bool incorrect_checksum = true1;
14534 |
14535 | 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", 14535, __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", 14535 , "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", 14535, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf.")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14536 |
14537 | 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", 14537, ((hfinfo))->abbrev))));
14538 |
14539 | /* Make sure a NULL computed_checksum isn't dereferenced.
14540 | * If checksum_len is 0 it probably won't crash, but in the VERIFY
14541 | * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14542 | * cases the behavior is unexpected and still a programmer error;
14543 | * proto_tree_add_bytes retrieves it from the tvb, thus neither
14544 | * _NOT_PRESENT nor _GENERATED is correct.
14545 | */
14546 | 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", 14546, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)" ))));
14547 |
14548 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14549 | ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14550 | proto_item_set_generated(ti);
14551 | // Backward compatible with use of -1
14552 | if (hf_checksum_status > 0) {
14553 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14554 | proto_item_set_generated(ti2);
14555 | }
14556 | return ti;
14557 | }
14558 |
14559 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14560 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14561 | proto_item_set_generated(ti);
14562 | return ti;
14563 | }
14564 |
14565 | checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14566 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14567 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14568 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14569 | bool_Bool non_zero_flag = false0;
14570 | for (size_t index = 0; index < checksum_len; index++) {
14571 | if (computed_checksum[index]) {
14572 | non_zero_flag = true1;
14573 | break;
14574 | }
14575 | }
14576 | if (!non_zero_flag) {
14577 | proto_item_append_text(ti, " [correct]");
14578 | // Backward compatible with use of -1
14579 | if (hf_checksum_status > 0) {
14580 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14581 | proto_item_set_generated(ti2);
14582 | }
14583 | incorrect_checksum = false0;
14584 | }
14585 | } else {
14586 | if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14587 | proto_item_append_text(ti, " [correct]");
14588 | // Backward compatible with use of -1
14589 | if (hf_checksum_status > 0) {
14590 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14591 | proto_item_set_generated(ti2);
14592 | }
14593 | incorrect_checksum = false0;
14594 | }
14595 | }
14596 |
14597 | if (incorrect_checksum) {
14598 | // Backward compatible with use of -1
14599 | if (hf_checksum_status > 0) {
14600 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14601 | proto_item_set_generated(ti2);
14602 | }
14603 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14604 | proto_item_append_text(ti, " [incorrect]");
14605 | if (bad_checksum_expert != NULL((void*)0))
14606 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14607 | } else {
14608 | char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14609 | proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14610 | if (bad_checksum_expert != NULL((void*)0))
14611 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14612 | }
14613 | }
14614 | } else {
14615 | // Backward compatible with use of -1
14616 | if (hf_checksum_status > 0) {
14617 | proto_item_append_text(ti, " [unverified]");
14618 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14619 | proto_item_set_generated(ti2);
14620 | }
14621 | }
14622 |
14623 | return ti;
14624 | }
14625 |
14626 | unsigned char
14627 | proto_check_field_name(const char *field_name)
14628 | {
14629 | return module_check_valid_name(field_name, false0);
14630 | }
14631 |
14632 | unsigned char
14633 | proto_check_field_name_lower(const char *field_name)
14634 | {
14635 | return module_check_valid_name(field_name, true1);
14636 | }
14637 |
14638 | bool_Bool
14639 | tree_expanded(int tree_type)
14640 | {
14641 | if (tree_type <= 0) {
14642 | return false0;
14643 | }
14644 | 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", 14644, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14645 | return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14646 | }
14647 |
14648 | void
14649 | tree_expanded_set(int tree_type, bool_Bool value)
14650 | {
14651 | 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", 14651, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14652 |
14653 | if (value)
14654 | tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14655 | else
14656 | tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14657 | }
14658 |
14659 | /*
14660 | * Editor modelines - https://www.wireshark.org/tools/modelines.html
14661 | *
14662 | * Local variables:
14663 | * c-basic-offset: 8
14664 | * tab-width: 8
14665 | * indent-tabs-mode: t
14666 | * End:
14667 | *
14668 | * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14669 | * :indentSize=8:tabSize=8:noTabs=false:
14670 | */