### Bug Summary

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

### Annotated Source Code

Press '?' to see keyboard shortcuts

Show analyzer invocation
clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name proto.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -fno-delete-null-pointer-checks -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -ffloat16-excess-precision=fast -fbfloat16-excess-precision=fast -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/builds/wireshark/wireshark/build -fcoverage-compilation-dir=/builds/wireshark/wireshark/build -resource-dir /usr/lib/llvm-22/lib/clang/22 -isystem /usr/include/glib-2.0 -isystem /usr/lib/x86_64-linux-gnu/glib-2.0/include -isystem /builds/wireshark/wireshark/epan -isystem /builds/wireshark/wireshark/build/epan -isystem /usr/include/mit-krb5 -isystem /usr/include/lua5.5 -isystem /usr/include/libxml2 -D CARES_NO_DEPRECATED -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-22/lib/clang/22/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/16/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-nonliteral -std=gnu17 -ferror-limit 19 -fvisibility=hidden -fwrapv -fwrapv-pointer -fstrict-flex-arrays=3 -stack-protector 2 -fstack-clash-protection -fcf-protection=full -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fexceptions -fcolor-diagnostics -analyzer-output=html -faddrsig -fdwarf2-cfi-asm -o /builds/wireshark/wireshark/sbout/2026-07-08-100337-3595-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 | static int proto_register_field_init(header_field_info *hfinfo, const int parent);
397 |
398 | /* special-case header field used within proto.c */
399 | static header_field_info hfi_text_only =
400 | { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
401 | int hf_text_only;
402 |
403 | /* Structure for information about a protocol */
404 | struct _protocol {
405 | const char *name; /* long description */
406 | const char *short_name; /* short description */
407 | const char *filter_name; /* name of this protocol in filters */
408 | GPtrArray *fields; /* fields for this protocol */
409 | int proto_id; /* field ID for this protocol */
410 | bool_Bool is_enabled; /* true if protocol is enabled */
411 | bool_Bool enabled_by_default; /* true if protocol is enabled by default */
412 | bool_Bool can_toggle; /* true if is_enabled can be changed */
413 | int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
414 | For dissectors that need a protocol name so they
415 | can be added to a dissector table, but use the
416 | parent_proto_id for things like enable/disable */
417 | GList *heur_list; /* Heuristic dissectors associated with this protocol */
418 | };
419 |
420 | /* List of all protocols */
421 | static GList *protocols;
422 |
423 | /* Structure stored for deregistered g_slice */
424 | struct g_slice_data {
425 | size_t block_size;
426 | void *mem_block;
427 | };
428 |
429 | /* Deregistered fields */
430 | static GPtrArray *deregistered_fields;
431 | static GPtrArray *deregistered_data;
432 | static GPtrArray *deregistered_slice;
433 |
434 | /* indexed by prefix, contains initializers */
435 | static GHashTable* prefixes;
436 |
437 | /* Contains information about a field when a dissector calls
438 | * proto_tree_add_item. */
439 | #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)))
440 | #define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
441 |
442 | /* Contains the space for proto_nodes. */
443 | #define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void *)0); node->next = ((void*)0); \
444 | node->first_child = NULL((void*)0); \
445 | node->last_child = NULL((void*)0); \
446 | node->next = NULL((void*)0);
447 |
448 | #define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
449 | wmem_free(pool, node)
450 |
451 | /* String space for protocol and field items for the GUI */
452 | #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; \
453 | il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
454 | il->value_pos = 0; \
455 | il->value_len = 0;
456 | #define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
457 | wmem_free(pool, il);
458 |
459 | #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", 459, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 459, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 459, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex]; \
460 | if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
461 | ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 461 , __func__, "Unregistered hf! index=%d", hfindex); \
462 | 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", 462, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))); \
463 | 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", 463, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))); \
464 | hfinfo = gpa_hfinfo.hfi[hfindex];
465 |
466 | #define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
467 |
468 | /* List which stores protocols and fields that have been registered */
469 | typedef struct _gpa_hfinfo_t {
470 | uint32_t len;
471 | uint32_t allocated_len;
472 | header_field_info **hfi;
473 | } gpa_hfinfo_t;
474 |
475 | static gpa_hfinfo_t gpa_hfinfo;
476 |
477 | /* Hash table of abbreviations and IDs */
478 | static wmem_map_t *gpa_name_map;
479 | static header_field_info *same_name_hfinfo;
480 |
481 | /* Hash table protocol aliases. const char * -> const char * */
482 | static GHashTable *gpa_protocol_aliases;
483 |
484 | /*
485 | * We're called repeatedly with the same field name when sorting a column.
486 | * Cache our last gpa_name_map hit for faster lookups.
487 | */
488 | static char *last_field_name;
489 | static header_field_info *last_hfinfo;
490 |
491 | /* Points to the first element of an array of bits, indexed by
492 | a subtree item type; that array element is true if subtrees of
493 | an item of that type are to be expanded. */
494 | static uint32_t *tree_is_expanded;
495 |
496 | /* Number of elements in that array. The entry with index 0 is not used. */
497 | int num_tree_types = 1;
498 |
499 | /* Name hashtables for fast detection of duplicate names */
500 | static GHashTable* proto_names;
501 | static GHashTable* proto_short_names;
502 | static GHashTable* proto_filter_names;
503 |
504 | static const char * const reserved_filter_names[] = {
505 | /* Display filter keywords. */
506 | "eq",
507 | "ne",
508 | "all_eq",
509 | "any_eq",
510 | "all_ne",
511 | "any_ne",
512 | "gt",
513 | "ge",
514 | "lt",
515 | "le",
516 | "bitand",
517 | "bitwise_and",
518 | "contains",
519 | "matches",
520 | "not",
521 | "and",
522 | "or",
523 | "xor",
524 | "in",
525 | "any",
526 | "all",
527 | "true",
528 | "false",
529 | "nan",
530 | "inf",
531 | "infinity",
532 | NULL((void*)0)
533 | };
534 |
535 | static GHashTable *proto_reserved_filter_names;
536 | static GQueue* saved_dir_queue;
537 |
538 | static int
539 | proto_compare_name(const void *p1_arg, const void *p2_arg)
540 | {
541 | const protocol_t *p1 = (const protocol_t *)p1_arg;
542 | const protocol_t *p2 = (const protocol_t *)p2_arg;
543 |
544 | return g_ascii_strcasecmp(p1->short_name, p2->short_name);
545 | }
546 |
547 | static GSList *dissector_plugins;
548 |
549 | #ifdef HAVE_PLUGINS1
550 | void
551 | proto_register_plugin(const proto_plugin *plug)
552 | {
553 | dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
554 | }
555 | #else /* HAVE_PLUGINS */
556 | void
557 | proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
558 | {
559 | ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 559, __func__, "proto_register_plugin: built without support for binary plugins" ); } } while (0);
560 | }
561 | #endif /* HAVE_PLUGINS */
562 |
563 | static void
564 | call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
565 | {
566 | proto_plugin *plug = (proto_plugin *)data;
567 |
568 | if (plug->register_protoinfo) {
569 | plug->register_protoinfo();
570 | }
571 | }
572 |
573 | static void
574 | call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
575 | {
576 | proto_plugin *plug = (proto_plugin *)data;
577 |
578 | if (plug->register_handoff) {
579 | plug->register_handoff();
580 | }
581 | }
582 |
583 | void proto_pre_init(void)
584 | {
585 | saved_dir_queue = g_queue_new();
586 |
587 | proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 | proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
589 | proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
590 |
591 | proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
592 | for (const char* const * ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
593 | /* GHashTable has no key destructor so the cast is safe. */
594 | g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
595 | }
596 |
597 | gpa_hfinfo.len = 0;
598 | gpa_hfinfo.allocated_len = 0;
599 | gpa_hfinfo.hfi = NULL((void*)0);
600 | gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
601 | wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
602 | gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
603 | deregistered_fields = g_ptr_array_new();
604 | deregistered_data = g_ptr_array_new();
605 | deregistered_slice = g_ptr_array_new();
606 | }
607 |
608 | /* initialize data structures and register protocols and fields */
609 | void
610 | proto_init(GSList *register_all_plugin_protocols_list,
611 | GSList *register_all_plugin_handoffs_list,
612 | register_entity_func register_func, register_entity_func handoff_func,
613 | register_cb cb,
614 | void *client_data)
615 | {
616 | /* Initialize the ftype subsystem */
617 | ftypes_initialize();
618 |
619 | /* Initialize the address type subsystem */
620 | address_types_initialize();
621 |
622 | /* Register one special-case FT_TEXT_ONLY field for use when
623 | converting wireshark to new-style proto_tree. These fields
624 | are merely strings on the GUI tree; they are not filterable */
625 | hf_text_only = proto_register_field_init(&hfi_text_only, -1);
626 |
627 | /* Register the pseudo-protocols used for exceptions. */
628 | register_show_exception();
629 | register_type_length_mismatch();
630 | register_byte_array_string_decodinws_error();
631 | register_date_time_string_decodinws_error();
632 | register_string_errors();
633 | ftypes_register_pseudofields();
634 | col_register_protocol();
635 |
636 | /* Have each built-in dissector register its protocols, fields,
637 | dissector tables, and dissectors to be called through a
638 | handle, and do whatever one-time initialization it needs to
639 | do. */
640 | if (register_func != NULL((void*)0))
641 | register_func(cb, client_data);
642 |
643 | /* Now call the registration routines for all epan plugins. */
644 | for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
645 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
646 | }
647 |
648 | /* Now call the registration routines for all dissector plugins. */
649 | if (cb)
650 | (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
651 | g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
652 |
653 | /* Now call the "handoff registration" routines of all built-in
654 | dissectors; those routines register the dissector in other
655 | dissectors' handoff tables, and fetch any dissector handles
656 | they need. */
657 | if (handoff_func != NULL((void*)0))
658 | handoff_func(cb, client_data);
659 |
660 | /* Now do the same with epan plugins. */
661 | for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
662 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
663 | }
664 |
665 | /* Now do the same with dissector plugins. */
666 | if (cb)
667 | (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
668 | g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
669 |
670 | /* sort the protocols by protocol name */
671 | protocols = g_list_sort(protocols, proto_compare_name);
672 |
673 | /* sort the dissector handles in dissector tables (for -G reports
674 | * and -d error messages. The GUI sorts the handles itself.) */
675 | packet_all_tables_sort_handles();
676 |
677 | /* We've assigned all the subtree type values; allocate the array
678 | for them, and zero it out. */
679 | 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 )));
680 | }
681 |
682 | static void
683 | proto_cleanup_base(void)
684 | {
685 | protocol_t *protocol;
686 | header_field_info *hfinfo;
687 |
688 | /* Free the abbrev/ID hash table */
689 | if (gpa_name_map) {
690 | // XXX - We don't have a wmem_map_destroy, but
691 | // it does get cleaned up when epan scope is
692 | // destroyed
693 | //g_hash_table_destroy(gpa_name_map);
694 | gpa_name_map = NULL((void*)0);
695 | }
696 | if (gpa_protocol_aliases) {
697 | g_hash_table_destroy(gpa_protocol_aliases);
698 | gpa_protocol_aliases = NULL((void*)0);
699 | }
700 | 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);
701 | last_field_name = NULL((void*)0);
702 |
703 | while (protocols) {
704 | protocol = (protocol_t *)protocols->data;
705 | 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", 705 , __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", 705, "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", 705, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol-> proto_id];;
706 | 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", 706, "protocol->proto_id == hfinfo->id" ))));
707 |
708 | 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);
709 | if (protocol->parent_proto_id != -1) {
710 | // pino protocol
711 | DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 711, "protocol->fields == ((void*)0)" )))); //helpers should not have any registered fields
712 | 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" , 712, "protocol->heur_list == ((void*)0)")))); //helpers should not have a heuristic list
713 | } else {
714 | if (protocol->fields) {
715 | g_ptr_array_free(protocol->fields, true1);
716 | }
717 | g_list_free(protocol->heur_list);
718 | }
719 | protocols = g_list_remove(protocols, protocol);
720 | g_free(protocol)(__builtin_object_size ((protocol), 0) != ((size_t) - 1)) ? g_free_sized (protocol, __builtin_object_size ((protocol), 0)) : (g_free) (protocol);
721 | }
722 |
723 | if (proto_names) {
724 | g_hash_table_destroy(proto_names);
725 | proto_names = NULL((void*)0);
726 | }
727 |
728 | if (proto_short_names) {
729 | g_hash_table_destroy(proto_short_names);
730 | proto_short_names = NULL((void*)0);
731 | }
732 |
733 | if (proto_filter_names) {
734 | g_hash_table_destroy(proto_filter_names);
735 | proto_filter_names = NULL((void*)0);
736 | }
737 |
738 | if (proto_reserved_filter_names) {
739 | g_hash_table_destroy(proto_reserved_filter_names);
740 | proto_reserved_filter_names = NULL((void*)0);
741 | }
742 |
743 | if (gpa_hfinfo.allocated_len) {
744 | gpa_hfinfo.len = 0;
745 | gpa_hfinfo.allocated_len = 0;
746 | 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);
747 | gpa_hfinfo.hfi = NULL((void*)0);
748 | }
749 |
750 | if (deregistered_fields) {
751 | g_ptr_array_free(deregistered_fields, true1);
752 | deregistered_fields = NULL((void*)0);
753 | }
754 |
755 | if (deregistered_data) {
756 | g_ptr_array_free(deregistered_data, true1);
757 | deregistered_data = NULL((void*)0);
758 | }
759 |
760 | if (deregistered_slice) {
761 | g_ptr_array_free(deregistered_slice, true1);
762 | deregistered_slice = NULL((void*)0);
763 | }
764 |
765 | 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);
766 | tree_is_expanded = NULL((void*)0);
767 |
768 | if (prefixes)
769 | g_hash_table_destroy(prefixes);
770 |
771 | if (saved_dir_queue != NULL((void*)0)) {
772 | g_queue_clear_full(saved_dir_queue, g_free);
773 | g_queue_free(saved_dir_queue);
774 | saved_dir_queue = NULL((void*)0);
775 | }
776 | }
777 |
778 | void
779 | proto_cleanup(void)
780 | {
781 | proto_free_deregistered_fields();
782 | proto_cleanup_base();
783 |
784 | g_slist_free(dissector_plugins);
785 | dissector_plugins = NULL((void*)0);
786 | }
787 |
788 | static bool_Bool
789 | ws_pushd(const char* dir)
790 | {
791 | //Save the current working directory
792 | const char* save_wd = get_current_working_dir();
793 | if (save_wd != NULL((void*)0))
794 | g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
795 |
796 | //Change to the new one
797 | #ifdef _WIN32
798 | SetCurrentDirectory(utf_8to16(dir));
799 | return true1;
800 | #else
801 | return (chdir(dir) == 0);
802 | #endif
803 | }
804 |
805 | static bool_Bool
806 | ws_popd(void)
807 | {
808 | int ret = 0;
809 | char* saved_wd = g_queue_pop_head(saved_dir_queue);
810 | if (saved_wd == NULL((void*)0))
811 | return false0;
812 |
813 | //Restore the previous one
814 | #ifdef _WIN32
815 | SetCurrentDirectory(utf_8to16(saved_wd));
816 | #else
817 | ret = chdir(saved_wd);
818 | #endif
819 | 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);
820 | return (ret == 0);
821 | }
822 |
823 | void
824 | proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
825 | {
826 | if (ws_pushd(dir))
827 | {
828 | func(param);
829 | ws_popd();
830 | }
831 | }
832 |
833 | static bool_Bool
834 | // NOLINTNEXTLINE(misc-no-recursion)
835 | proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
836 | void *data)
837 | {
838 | proto_node *pnode = tree;
839 | proto_node *child;
840 | proto_node *current;
841 |
842 | if (func(pnode, data))
843 | return true1;
844 |
845 | child = pnode->first_child;
846 | while (child != NULL((void*)0)) {
847 | /*
848 | * The routine we call might modify the child, e.g. by
849 | * freeing it, so we get the child's successor before
850 | * calling that routine.
851 | */
852 | current = child;
853 | child = current->next;
854 | // We recurse here, but we're limited by prefs.gui_max_tree_depth
855 | if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
856 | return true1;
857 | }
858 |
859 | return false0;
860 | }
861 |
862 | void
863 | proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
864 | void *data)
865 | {
866 | proto_node *node = tree;
867 | proto_node *current;
868 |
869 | if (!node)
870 | return;
871 |
872 | node = node->first_child;
873 | while (node != NULL((void*)0)) {
874 | current = node;
875 | node = current->next;
876 | func((proto_tree *)current, data);
877 | }
878 | }
879 |
880 | static void
881 | free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
882 | {
883 | GPtrArray *ptrs = (GPtrArray *)value;
884 | int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
885 | header_field_info *hfinfo;
886 |
887 | 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", 887, __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", 887, "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", 887, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
888 | if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
889 | /* when a field is referenced by a filter this also
890 | affects the refcount for the parent protocol so we need
891 | to adjust the refcount for the parent as well
892 | */
893 | if (hfinfo->parent != -1) {
894 | header_field_info *parent_hfinfo;
895 | 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", 895 , __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", 895, "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", 895, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)" , "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo ->parent];;
896 | parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
897 | }
898 | hfinfo->ref_type = HF_REF_TYPE_NONE;
899 | }
900 |
901 | g_ptr_array_free(ptrs, true1);
902 | }
903 |
904 | static void
905 | proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
906 | {
907 | field_info *finfo = PNODE_FINFO(node)((node)->finfo);
908 |
909 | proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
910 |
911 | if (finfo) {
912 | // The fvalue_t structure was allocated using fvalue_new_pool()
913 | // (see new_field_info()) and will be reclaimed when the pool is
914 | // freed, so we only release the type-specific data it owns here.
915 | fvalue_cleanup(finfo->value);
916 | finfo->value = NULL((void*)0);
917 | }
918 | }
919 |
920 | void
921 | proto_tree_reset(proto_tree *tree)
922 | {
923 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
924 |
925 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
926 |
927 | /* free tree data */
928 | if (tree_data->interesting_hfids) {
929 | /* Free all the GPtrArray's in the interesting_hfids hash. */
930 | g_hash_table_foreach(tree_data->interesting_hfids,
931 | free_GPtrArray_value, NULL((void*)0));
932 |
933 | /* And then remove all values. */
934 | g_hash_table_remove_all(tree_data->interesting_hfids);
935 | }
936 |
937 | /* Reset track of the number of children */
938 | tree_data->count = 0;
939 |
940 | /* Reset our loop checks */
941 | tree_data->idle_count_ds_tvb = NULL((void*)0);
942 | tree_data->max_start = 0;
943 | tree_data->start_idle_count = 0;
944 |
945 | PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void *)0); tree->next = ((void*)0);;
946 | }
947 |
948 | /* frees the resources that the dissection a proto_tree uses */
949 | void
950 | proto_tree_free(proto_tree *tree)
951 | {
952 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
953 |
954 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
955 |
956 | /* free tree data */
957 | if (tree_data->interesting_hfids) {
958 | /* Free all the GPtrArray's in the interesting_hfids hash. */
959 | g_hash_table_foreach(tree_data->interesting_hfids,
960 | free_GPtrArray_value, NULL((void*)0));
961 |
962 | /* And then destroy the hash. */
963 | g_hash_table_destroy(tree_data->interesting_hfids);
964 | }
965 |
966 | 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);
967 |
968 | g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else (void) ((proto_tree*) 0 == (tree)); } while (0);
969 | }
970 |
971 | /* Is the parsing being done for a visible proto_tree or an invisible one?
972 | * By setting this correctly, the proto_tree creation is sped up by not
973 | * having to call vsnprintf and copy strings around.
974 | */
975 | bool_Bool
976 | proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
977 | {
978 | bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
979 |
980 | PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
981 |
982 | return old_visible;
983 | }
984 |
985 | void
986 | proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
987 | {
988 | if (tree)
989 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
990 | }
991 |
992 | /* Assume dissector set only its protocol fields.
993 | This function is called by dissectors and allows the speeding up of filtering
994 | in wireshark; if this function returns false it is safe to reset tree to NULL
995 | and thus skip calling most of the expensive proto_tree_add_...()
996 | functions.
997 | If the tree is visible we implicitly assume the field is referenced.
998 | */
999 | bool_Bool
1000 | proto_field_is_referenced(proto_tree *tree, int proto_id)
1001 | {
1002 | register header_field_info *hfinfo;
1003 |
1004 |
1005 | if (!tree)
1006 | return false0;
1007 |
1008 | if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1009 | return true1;
1010 |
1011 | 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", 1011, __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", 1011, "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", 1011, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
1012 | if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1013 | return true1;
1014 |
1015 | if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1016 | return true1;
1017 |
1018 | return false0;
1019 | }
1020 |
1021 |
1022 | /* Finds a record in the hfinfo array by id. */
1023 | header_field_info *
1024 | proto_registrar_get_nth(unsigned hfindex)
1025 | {
1026 | register header_field_info *hfinfo;
1027 |
1028 | 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", 1028, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1028, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1028, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
1029 | return hfinfo;
1030 | }
1031 |
1032 |
1033 | /* Prefix initialization
1034 | * this allows for a dissector to register a display filter name prefix
1035 | * so that it can delay the initialization of the hf array as long as
1036 | * possible.
1037 | */
1038 |
1039 | /* compute a hash for the part before the dot of a display filter */
1040 | static unsigned
1041 | prefix_hash (const void *key) {
1042 | /* end the string at the dot and compute its hash */
1043 | char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1044 | char* c = copy;
1045 | unsigned tmp;
1046 |
1047 | for (; *c; c++) {
1048 | if (*c == '.') {
1049 | *c = 0;
1050 | break;
1051 | }
1052 | }
1053 |
1054 | tmp = wmem_str_hash(copy);
1055 | g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized (copy, __builtin_object_size ((copy), 0)) : (g_free) (copy);
1056 | return tmp;
1057 | }
1058 |
1059 | /* are both strings equal up to the end or the dot? */
1060 | static gboolean
1061 | prefix_equal (const void *ap, const void *bp) {
1062 | const char* a = (const char *)ap;
1063 | const char* b = (const char *)bp;
1064 |
1065 | do {
1066 | char ac = *a++;
1067 | char bc = *b++;
1068 |
1069 | if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1070 |
1071 | if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1072 | if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1073 |
1074 | if (ac != bc) return FALSE(0);
1075 | } while (1);
1076 |
1077 | return FALSE(0);
1078 | }
1079 |
1080 | /* Register a new prefix for "delayed" initialization of field arrays */
1081 | void
1082 | proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1083 | if (! prefixes ) {
1084 | prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1085 | }
1086 |
1087 | g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1088 | }
1089 |
1090 | /* helper to call all prefix initializers */
1091 | static gboolean
1092 | initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1093 | ((prefix_initializer_t)v)((const char *)k);
1094 | return TRUE(!(0));
1095 | }
1096 |
1097 | /** Initialize every remaining uninitialized prefix. */
1098 | void
1099 | proto_initialize_all_prefixes(void) {
1100 | g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1101 | }
1102 |
1103 | /* Finds a record in the hfinfo array by name.
1104 | * If it fails to find it in the already registered fields,
1105 | * it tries to find and call an initializer in the prefixes
1106 | * table and if so it looks again.
1107 | */
1108 |
1109 | header_field_info *
1110 | proto_registrar_get_byname(const char *field_name)
1111 | {
1112 | header_field_info *hfinfo;
1113 | prefix_initializer_t pi;
1114 |
1115 | if (!field_name)
1116 | return NULL((void*)0);
1117 |
1118 | if (g_strcmp0(field_name, last_field_name) == 0) {
1119 | return last_hfinfo;
1120 | }
1121 |
1122 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1123 |
1124 | if (hfinfo) {
1125 | 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);
1126 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1127 | last_hfinfo = hfinfo;
1128 | return hfinfo;
1129 | }
1130 |
1131 | if (!prefixes)
1132 | return NULL((void*)0);
1133 |
1134 | if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1135 | pi(field_name);
1136 | g_hash_table_remove(prefixes, field_name);
1137 | } else {
1138 | return NULL((void*)0);
1139 | }
1140 |
1141 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1142 |
1143 | if (hfinfo) {
1144 | 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);
1145 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1146 | last_hfinfo = hfinfo;
1147 | }
1148 | return hfinfo;
1149 | }
1150 |
1151 | header_field_info*
1152 | proto_registrar_get_byalias(const char *alias_name)
1153 | {
1154 | if (!alias_name) {
1155 | return NULL((void*)0);
1156 | }
1157 |
1158 | /* Find our aliased protocol. */
1159 | char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1160 | char *dot = strchr(an_copy, '.');
1161 | if (dot) {
1162 | *dot = '\0';
1163 | }
1164 | const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1165 | if (!proto_pfx) {
1166 | 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);
1167 | return NULL((void*)0);
1168 | }
1169 |
1170 | /* Construct our aliased field and look it up. */
1171 | GString *filter_name = g_string_new(proto_pfx);
1172 | if (dot) {
1173 | g_string_append_printf(filter_name, ".%s", dot+1);
1174 | }
1175 | header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1176 | 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);
1177 | 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)))));
1178 |
1179 | return hfinfo;
1180 | }
1181 |
1182 | int
1183 | proto_registrar_get_id_byname(const char *field_name)
1184 | {
1185 | header_field_info *hfinfo;
1186 |
1187 | hfinfo = proto_registrar_get_byname(field_name);
1188 |
1189 | if (!hfinfo)
1190 | return -1;
1191 |
1192 | return hfinfo->id;
1193 | }
1194 |
1195 | static int
1196 | label_strcat_flags(const header_field_info *hfinfo)
1197 | {
1198 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1199 | return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1200 |
1201 | return 0;
1202 | }
1203 |
1204 | static char *
1205 | format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1206 | const uint8_t *bytes, unsigned length, size_t max_str_len)
1207 | {
1208 | char *str = NULL((void*)0);
1209 | const uint8_t *p;
1210 | bool_Bool is_printable;
1211 |
1212 | if (bytes) {
1213 | if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1214 | /*
1215 | * If all bytes are valid and printable UTF-8, show the
1216 | * bytes as a string - in quotes to indicate that it's
1217 | * a string.
1218 | */
1219 | if (isprint_utf8_string((const char*)bytes, length)) {
1220 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1221 | (int)length, bytes);
1222 | return str;
1223 | }
1224 | } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1225 | /*
1226 | * Check whether all bytes are printable.
1227 | */
1228 | is_printable = true1;
1229 | for (p = bytes; p < bytes+length; p++) {
1230 | if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1231 | /* Not printable. */
1232 | is_printable = false0;
1233 | break;
1234 | }
1235 | }
1236 |
1237 | /*
1238 | * If all bytes are printable ASCII, show the bytes
1239 | * as a string - in quotes to indicate that it's
1240 | * a string.
1241 | */
1242 | if (is_printable) {
1243 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1244 | (int)length, bytes);
1245 | return str;
1246 | }
1247 | }
1248 |
1249 | /*
1250 | * Either it's not printable ASCII, or we don't care whether
1251 | * it's printable ASCII; show it as hex bytes.
1252 | */
1253 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1254 | case SEP_DOT:
1255 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1256 | break;
1257 | case SEP_DASH:
1258 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1259 | break;
1260 | case SEP_COLON:
1261 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1262 | break;
1263 | case SEP_SPACE:
1264 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1265 | break;
1266 | case BASE_NONE:
1267 | default:
1268 | if (prefs.display_byte_fields_with_spaces) {
1269 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1270 | } else {
1271 | str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1272 | }
1273 | break;
1274 | }
1275 | }
1276 | else {
1277 | if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1278 | str = wmem_strdup(scope, "<none>");
1279 | } else {
1280 | str = wmem_strdup(scope, "<MISSING>");
1281 | }
1282 | }
1283 | return str;
1284 | }
1285 |
1286 | static char *
1287 | format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1288 | const uint8_t *bytes, unsigned length)
1289 | {
1290 | return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1291 | }
1292 |
1293 | static void
1294 | ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1295 | {
1296 | subtree_lvl *pushed_tree;
1297 |
1298 | 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" , 1298, "ptvc->pushed_tree_max <= 256-8"))));
1299 | ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1300 |
1301 | pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1302 | DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1302, "pushed_tree != ((void*)0)" ))));
1303 | ptvc->pushed_tree = pushed_tree;
1304 | }
1305 |
1306 | static void
1307 | ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1308 | {
1309 | ptvc->pushed_tree = NULL((void*)0);
1310 | ptvc->pushed_tree_max = 0;
1311 | 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", 1311, "ptvc->pushed_tree_index == 0" ))));
1312 | ptvc->pushed_tree_index = 0;
1313 | }
1314 |
1315 | /* Allocates an initializes a ptvcursor_t with 3 variables:
1316 | * proto_tree, tvbuff, and offset. */
1317 | ptvcursor_t *
1318 | ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1319 | {
1320 | ptvcursor_t *ptvc;
1321 |
1322 | ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1323 | ptvc->scope = scope;
1324 | ptvc->tree = tree;
1325 | ptvc->tvb = tvb;
1326 | ptvc->offset = offset;
1327 | ptvc->pushed_tree = NULL((void*)0);
1328 | ptvc->pushed_tree_max = 0;
1329 | ptvc->pushed_tree_index = 0;
1330 | return ptvc;
1331 | }
1332 |
1333 |
1334 | /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1335 | void
1336 | ptvcursor_free(ptvcursor_t *ptvc)
1337 | {
1338 | ptvcursor_free_subtree_levels(ptvc);
1339 | wmem_free(ptvc->scope, ptvc);
1340 | }
1341 |
1342 | /* Returns tvbuff. */
1343 | tvbuff_t *
1344 | ptvcursor_tvbuff(ptvcursor_t *ptvc)
1345 | {
1346 | return ptvc->tvb;
1347 | }
1348 |
1349 | /* Returns current offset. */
1350 | unsigned
1351 | ptvcursor_current_offset(ptvcursor_t *ptvc)
1352 | {
1353 | return ptvc->offset;
1354 | }
1355 |
1356 | proto_tree *
1357 | ptvcursor_tree(ptvcursor_t *ptvc)
1358 | {
1359 | if (!ptvc)
1360 | return NULL((void*)0);
1361 |
1362 | return ptvc->tree;
1363 | }
1364 |
1365 | void
1366 | ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1367 | {
1368 | ptvc->tree = tree;
1369 | }
1370 |
1371 | /* creates a subtree, sets it as the working tree and pushes the old working tree */
1372 | proto_tree *
1373 | ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1374 | {
1375 | subtree_lvl *subtree;
1376 | if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1377 | ptvcursor_new_subtree_levels(ptvc);
1378 |
1379 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1380 | subtree->tree = ptvc->tree;
1381 | subtree->it= NULL((void*)0);
1382 | ptvc->pushed_tree_index++;
1383 | return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1384 | }
1385 |
1386 | /* pops a subtree */
1387 | void
1388 | ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1389 | {
1390 | subtree_lvl *subtree;
1391 |
1392 | if (ptvc->pushed_tree_index <= 0)
1393 | return;
1394 |
1395 | ptvc->pushed_tree_index--;
1396 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1397 | if (subtree->it != NULL((void*)0))
1398 | proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1399 |
1400 | ptvc->tree = subtree->tree;
1401 | }
1402 |
1403 | /* saves the current tvb offset and the item in the current subtree level */
1404 | static void
1405 | ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1406 | {
1407 | subtree_lvl *subtree;
1408 |
1409 | 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", 1409, "ptvc->pushed_tree_index > 0" ))));
1410 |
1411 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1412 | subtree->it = it;
1413 | subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1414 | }
1415 |
1416 | /* Creates a subtree and adds it to the cursor as the working tree but does not
1417 | * save the old working tree */
1418 | proto_tree *
1419 | ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1420 | {
1421 | ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1422 | return ptvc->tree;
1423 | }
1424 |
1425 | static proto_tree *
1426 | ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1427 | {
1428 | ptvcursor_push_subtree(ptvc, it, ett_subtree);
1429 | if (length == SUBTREE_UNDEFINED_LENGTH-1)
1430 | ptvcursor_subtree_set_item(ptvc, it);
1431 | return ptvcursor_tree(ptvc);
1432 | }
1433 |
1434 | /* Add an item to the tree and create a subtree
1435 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1436 | * In this case, when the subtree will be closed, the parent item length will
1437 | * be equal to the advancement of the cursor since the creation of the subtree.
1438 | */
1439 | proto_tree *
1440 | ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1441 | const unsigned encoding, int ett_subtree)
1442 | {
1443 | proto_item *it;
1444 |
1445 | it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1446 | return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1447 | }
1448 |
1449 | static proto_item *
1450 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1451 |
1452 | /* Add a text node 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 item length will be equal
1455 | * to the advancement of the cursor since the creation of the subtree.
1456 | */
1457 | proto_tree *
1458 | ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1459 | int ett_subtree, const char *format, ...)
1460 | {
1461 | proto_item *pi;
1462 | va_list ap;
1463 | header_field_info *hfinfo;
1464 | proto_tree *tree;
1465 |
1466 | tree = ptvcursor_tree(ptvc);
1467 |
1468 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1469 |
1470 | 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", 1470 , __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", 1470, "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", 1470, "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", 1470, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1471 |
1472 | pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1473 | ptvcursor_current_offset(ptvc), length);
1474 |
1475 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1475, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1476 |
1477 | va_start(ap, format)__builtin_va_start(ap, format);
1478 | proto_tree_set_representation(pi, format, ap);
1479 | va_end(ap)__builtin_va_end(ap);
1480 |
1481 | return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1482 | }
1483 |
1484 | /* Add a text-only node, leaving it to our caller to fill the text in */
1485 | static proto_item *
1486 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1487 | {
1488 | proto_item *pi;
1489 |
1490 | if (tree == NULL((void*)0))
1491 | return NULL((void*)0);
1492 |
1493 | pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1494 |
1495 | return pi;
1496 | }
1497 |
1498 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1499 | proto_item *
1500 | proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length,
1501 | const char *format, ...)
1502 | {
1503 | proto_item *pi;
1504 | va_list ap;
1505 | header_field_info *hfinfo;
1506 |
1507 | tvb_ensure_bytes_exist(tvb, start, length);
1508 |
1509 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1510 |
1511 | 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", 1511 , __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", 1511, "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", 1511, "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", 1511, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1512 |
1513 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1514 |
1515 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1515, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1516 |
1517 | va_start(ap, format)__builtin_va_start(ap, format);
1518 | proto_tree_set_representation(pi, format, ap);
1519 | va_end(ap)__builtin_va_end(ap);
1520 |
1521 | return pi;
1522 | }
1523 |
1524 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1525 | proto_item *
1526 | proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1527 | unsigned length, const char *format, va_list ap)
1528 | {
1529 | proto_item *pi;
1530 | header_field_info *hfinfo;
1531 |
1532 | /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1533 | * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1534 | * the length to be what's in the tvbuff if length is -1, and the
1535 | * minimum of length and what's in the tvbuff if not.
1536 | */
1537 |
1538 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1539 |
1540 | 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", 1540 , __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", 1540, "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", 1540, "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", 1540, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1541 |
1542 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1543 |
1544 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1544, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1545 |
1546 | proto_tree_set_representation(pi, format, ap);
1547 |
1548 | return pi;
1549 | }
1550 |
1551 | /* Add a text-only node that creates a subtree underneath.
1552 | */
1553 | proto_tree *
1554 | proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1555 | {
1556 | return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1557 | }
1558 |
1559 | /* Add a text-only node that creates a subtree underneath.
1560 | */
1561 | proto_tree *
1562 | proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1563 | {
1564 | proto_tree *pt;
1565 | proto_item *pi;
1566 | va_list ap;
1567 |
1568 | if (length == -1) {
1569 | length = tvb_captured_length_remaining(tvb, start);
1570 | }
1571 |
1572 | va_start(ap, format)__builtin_va_start(ap, format);
1573 | pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1574 | va_end(ap)__builtin_va_end(ap);
1575 |
1576 | if (tree_item != NULL((void*)0))
1577 | *tree_item = pi;
1578 |
1579 | pt = proto_item_add_subtree(pi, idx);
1580 |
1581 | return pt;
1582 | }
1583 |
1584 | /* Add a text-only node for debugging purposes. The caller doesn't need
1585 | * to worry about tvbuff, start, or length. Debug message gets sent to
1586 | * STDOUT, too */
1587 | proto_item *
1588 | proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1589 | {
1590 | proto_item *pi;
1591 | va_list ap;
1592 |
1593 | pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1594 |
1595 | if (pi) {
1596 | va_start(ap, format)__builtin_va_start(ap, format);
1597 | proto_tree_set_representation(pi, format, ap);
1598 | va_end(ap)__builtin_va_end(ap);
1599 | }
1600 | va_start(ap, format)__builtin_va_start(ap, format);
1601 | vprintf(format, ap);
1602 | va_end(ap)__builtin_va_end(ap);
1603 | printf("\n");
1604 |
1605 | return pi;
1606 | }
1607 |
1608 | proto_item *
1609 | proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1610 | {
1611 | proto_item *pi;
1612 | header_field_info *hfinfo;
1613 |
1614 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1615 |
1616 | 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", 1616 , __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", 1616, "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", 1616, "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", 1616, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1617 |
1618 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1619 |
1620 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1620, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1621 |
1622 | proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1623 |
1624 | return pi;
1625 | }
1626 |
1627 | proto_item *
1628 | proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length)
1629 | {
1630 | proto_item *pi;
1631 | header_field_info *hfinfo;
1632 | char *str;
1633 |
1634 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1635 |
1636 | 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", 1636 , __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", 1636, "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", 1636, "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", 1636, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1637 |
1638 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1639 |
1640 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1640, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1641 |
1642 | str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1643 | proto_item_set_text(pi, "%s", str);
1644 | wmem_free(NULL((void*)0), str);
1645 |
1646 | return pi;
1647 | }
1648 |
1649 | void proto_report_dissector_bug(const char *format, ...)
1650 | {
1651 | va_list args;
1652 |
1653 | if (wireshark_abort_on_dissector_bug) {
1654 | /*
1655 | * Try to have the error message show up in the crash
1656 | * information.
1657 | */
1658 | va_start(args, format)__builtin_va_start(args, format);
1659 | ws_vadd_crash_info(format, args);
1660 | va_end(args)__builtin_va_end(args);
1661 |
1662 | /*
1663 | * Print the error message.
1664 | */
1665 | va_start(args, format)__builtin_va_start(args, format);
1666 | vfprintf(stderrstderr, format, args);
1667 | va_end(args)__builtin_va_end(args);
1668 | putc('\n', stderrstderr);
1669 |
1670 | /*
1671 | * And crash.
1672 | */
1673 | abort();
1674 | } else {
1675 | va_start(args, format)__builtin_va_start(args, format);
1676 | VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1677 | va_end(args)__builtin_va_end(args);
1678 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1678 , __func__, "assertion \"not reached\" failed"); /* GCC 12 with ASAN needs this. */
1679 | }
1680 | }
1681 |
1682 | /* We could probably get away with changing is_error to a minimum length value. */
1683 | static void
1684 | report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1685 | {
1686 | if (is_error) {
1687 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1688 | } else {
1689 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1690 | }
1691 |
1692 | if (is_error) {
1693 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1694 | }
1695 | }
1696 |
1697 | static uint32_t
1698 | get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1699 | {
1700 | uint32_t value;
1701 | bool_Bool length_error;
1702 |
1703 | switch (length) {
1704 |
1705 | case 1:
1706 | value = tvb_get_uint8(tvb, offset);
1707 | if (encoding & ENC_ZIGBEE0x40000000) {
1708 | if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1709 | value = 0;
1710 | }
1711 | }
1712 | break;
1713 |
1714 | case 2:
1715 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1716 | : tvb_get_ntohs(tvb, offset);
1717 | if (encoding & ENC_ZIGBEE0x40000000) {
1718 | if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1719 | value = 0;
1720 | }
1721 | }
1722 | break;
1723 |
1724 | case 3:
1725 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1726 | : tvb_get_ntoh24(tvb, offset);
1727 | break;
1728 |
1729 | case 4:
1730 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1731 | : tvb_get_ntohl(tvb, offset);
1732 | break;
1733 |
1734 | default:
1735 | if (length < 1) {
1736 | length_error = true1;
1737 | value = 0;
1738 | } else {
1739 | length_error = false0;
1740 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1741 | : tvb_get_ntohl(tvb, offset);
1742 | }
1743 | report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1744 | break;
1745 | }
1746 | return value;
1747 | }
1748 |
1749 | static inline uint64_t
1750 | get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1751 | {
1752 | uint64_t value;
1753 |
1754 | value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1755 |
1756 | if (length < 1 || length > 8) {
1757 | report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1758 | }
1759 |
1760 | return value;
1761 | }
1762 |
1763 | static int32_t
1764 | get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1765 | {
1766 | int32_t value;
1767 | bool_Bool length_error;
1768 |
1769 | switch (length) {
1770 |
1771 | case 1:
1772 | value = tvb_get_int8(tvb, offset);
1773 | break;
1774 |
1775 | case 2:
1776 | value = encoding ? tvb_get_letohis(tvb, offset)
1777 | : tvb_get_ntohis(tvb, offset);
1778 | break;
1779 |
1780 | case 3:
1781 | value = encoding ? tvb_get_letohi24(tvb, offset)
1782 | : tvb_get_ntohi24(tvb, offset);
1783 | break;
1784 |
1785 | case 4:
1786 | value = encoding ? tvb_get_letohil(tvb, offset)
1787 | : tvb_get_ntohil(tvb, offset);
1788 | break;
1789 |
1790 | default:
1791 | if (length < 1) {
1792 | length_error = true1;
1793 | value = 0;
1794 | } else {
1795 | length_error = false0;
1796 | value = encoding ? tvb_get_letohil(tvb, offset)
1797 | : tvb_get_ntohil(tvb, offset);
1798 | }
1799 | report_type_length_mismatch(tree, "a signed integer", length, length_error);
1800 | break;
1801 | }
1802 | return value;
1803 | }
1804 |
1805 | /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1806 | * be cast-able as a int64_t. This is weird, but what the code has always done.
1807 | */
1808 | static inline uint64_t
1809 | get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1810 | {
1811 | uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1812 |
1813 | switch (length) {
1814 | case 7:
1815 | value = ws_sign_ext64(value, 56);
1816 | break;
1817 | case 6:
1818 | value = ws_sign_ext64(value, 48);
1819 | break;
1820 | case 5:
1821 | value = ws_sign_ext64(value, 40);
1822 | break;
1823 | case 4:
1824 | value = ws_sign_ext64(value, 32);
1825 | break;
1826 | case 3:
1827 | value = ws_sign_ext64(value, 24);
1828 | break;
1829 | case 2:
1830 | value = ws_sign_ext64(value, 16);
1831 | break;
1832 | case 1:
1833 | value = ws_sign_ext64(value, 8);
1834 | break;
1835 | }
1836 |
1837 | return value;
1838 | }
1839 |
1840 | /* For FT_STRING */
1841 | static inline const uint8_t *
1842 | get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1843 | int length, unsigned *ret_length, const unsigned encoding)
1844 | {
1845 | if (length == -1) {
1846 | *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1847 | } else {
1848 | *ret_length = length;
1849 | }
1850 | return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1851 | }
1852 |
1853 | /* For FT_STRINGZ */
1854 | static inline const uint8_t *
1855 | get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1856 | unsigned start, int length, unsigned *ret_length, const unsigned encoding)
1857 | {
1858 | const uint8_t *value;
1859 |
1860 | if (length < -1) {
1861 | report_type_length_mismatch(tree, "a string", length, true1);
1862 | }
1863 |
1864 | /* XXX - Ideally, every "null-terminated string which fits into a
1865 | * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1866 | * as appropriate, not a FT_STRINGZ. If so, then we could always call
1867 | * tvb_get_stringz_enc here. Failing that, we could treat length 0
1868 | * as unknown length as well (since there is a trailing '\0', the real
1869 | * length is never zero), allowing switching to unsigned lengths.
1870 | */
1871 | if (length == -1) {
1872 | /* This can throw an exception */
1873 | value = tvb_get_stringz_enc(scope, tvb, start, ret_length, encoding);
1874 | } else {
1875 | /* In this case, length signifies the length of the string.
1876 | *
1877 | * This could either be a null-padded string, which doesn't
1878 | * necessarily have a '\0' at the end, or a null-terminated
1879 | * string, with a trailing '\0'. (Yes, there are cases
1880 | * where you have a string that's both counted and null-
1881 | * terminated.)
1882 | *
1883 | * In the first case, we must allocate a buffer of length
1884 | * "length+1", to make room for a trailing '\0'.
1885 | *
1886 | * In the second case, we don't assume that there is a
1887 | * trailing '\0' there, as the packet might be malformed.
1888 | * (XXX - should we throw an exception if there's no
1889 | * trailing '\0'?) Therefore, we allocate a buffer of
1890 | * length "length+1", and put in a trailing '\0', just to
1891 | * be safe.
1892 | *
1893 | * (XXX - this would change if we made string values counted
1894 | * rather than null-terminated.)
1895 | */
1896 | *ret_length = length;
1897 | value = tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1898 | }
1899 | return value;
1900 | }
1901 |
1902 | /* For FT_UINT_STRING */
1903 | static inline const uint8_t *
1904 | get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1905 | tvbuff_t *tvb, unsigned start, int length, unsigned *ret_length,
1906 | const unsigned encoding)
1907 | {
1908 | uint32_t n;
1909 | const uint8_t *value;
1910 |
1911 | /* I believe it's ok if this is called with a NULL tree */
1912 | n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1913 | value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1914 | *ret_length = length + n;
1915 | return value;
1916 | }
1917 |
1918 | /* For FT_STRINGZPAD */
1919 | static inline const uint8_t *
1920 | get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1921 | int length, unsigned *ret_length, const unsigned encoding)
1922 | {
1923 | /*
1924 | * XXX - currently, string values are null-
1925 | * terminated, so a "zero-padded" string
1926 | * isn't special. If we represent string
1927 | * values as something that includes a counted
1928 | * array of bytes, we'll need to strip the
1929 | * trailing NULs.
1930 | */
1931 | if (length == -1) {
1932 | *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1933 | } else {
1934 | *ret_length = length;
1935 | }
1936 | return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1937 | }
1938 |
1939 | /* For FT_STRINGZTRUNC */
1940 | static inline const uint8_t *
1941 | get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1942 | int length, unsigned *ret_length, const unsigned encoding)
1943 | {
1944 | /*
1945 | * XXX - currently, string values are null-
1946 | * terminated, so a "zero-truncated" string
1947 | * isn't special. If we represent string
1948 | * values as something that includes a counted
1949 | * array of bytes, we'll need to strip everything
1950 | * starting with the terminating NUL.
1951 | */
1952 | if (length == -1) {
1953 | *ret_length = tvb_ensure_captured_length_remaining(tvb, start);
1954 | } else {
1955 | *ret_length = length;
1956 | }
1957 | return tvb_get_string_enc(scope, tvb, start, *ret_length, encoding);
1958 | }
1959 |
1960 | /*
1961 | * Deltas between the epochs for various non-UN*X time stamp formats and
1962 | * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1963 | * stamp format.
1964 | */
1965 |
1966 | /*
1967 | * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1968 | * XXX - if it's OK if this is unsigned, can we just use
1969 | * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1970 | */
1971 | #define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1972 |
1973 | /*
1974 | * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1975 | */
1976 | #define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1977 |
1978 | /* this can be called when there is no tree, so tree may be null */
1979 | static void
1980 | get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1981 | const int length, const unsigned encoding, nstime_t *time_stamp,
1982 | const bool_Bool is_relative)
1983 | {
1984 | uint32_t tmpsecs;
1985 | uint64_t tmp64secs;
1986 | uint64_t todusecs;
1987 |
1988 | switch (encoding) {
1989 |
1990 | case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1991 | /*
1992 | * If the length is 16, 8-byte seconds, followed
1993 | * by 8-byte fractional time in nanoseconds,
1994 | * both big-endian.
1995 | *
1996 | * If the length is 12, 8-byte seconds, followed
1997 | * by 4-byte fractional time in nanoseconds,
1998 | * both big-endian.
1999 | *
2000 | * If the length is 8, 4-byte seconds, followed
2001 | * by 4-byte fractional time in nanoseconds,
2002 | * both big-endian.
2003 | *
2004 | * For absolute times, the seconds are seconds
2005 | * since the UN*X epoch.
2006 | */
2007 | if (length == 16) {
2008 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2009 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2010 | } else if (length == 12) {
2011 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2012 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2013 | } else if (length == 8) {
2014 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2015 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2016 | } else if (length == 4) {
2017 | /*
2018 | * Backwards compatibility.
2019 | * ENC_TIME_SECS_NSECS is 0; using
2020 | * ENC_BIG_ENDIAN by itself with a 4-byte
2021 | * time-in-seconds value was done in the
2022 | * past.
2023 | */
2024 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2025 | time_stamp->nsecs = 0;
2026 | } else {
2027 | time_stamp->secs = 0;
2028 | time_stamp->nsecs = 0;
2029 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2030 | }
2031 | break;
2032 |
2033 | case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2034 | /*
2035 | * If the length is 16, 8-byte seconds, followed
2036 | * by 8-byte fractional time in nanoseconds,
2037 | * both little-endian.
2038 | *
2039 | * If the length is 12, 8-byte seconds, followed
2040 | * by 4-byte fractional time in nanoseconds,
2041 | * both little-endian.
2042 | *
2043 | * If the length is 8, 4-byte seconds, followed
2044 | * by 4-byte fractional time in nanoseconds,
2045 | * both little-endian.
2046 | *
2047 | * For absolute times, the seconds are seconds
2048 | * since the UN*X epoch.
2049 | */
2050 | if (length == 16) {
2051 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2052 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2053 | } else if (length == 12) {
2054 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2055 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2056 | } else if (length == 8) {
2057 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2058 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2059 | } else if (length == 4) {
2060 | /*
2061 | * Backwards compatibility.
2062 | * ENC_TIME_SECS_NSECS is 0; using
2063 | * ENC_LITTLE_ENDIAN by itself with a 4-byte
2064 | * time-in-seconds value was done in the
2065 | * past.
2066 | */
2067 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2068 | time_stamp->nsecs = 0;
2069 | } else {
2070 | time_stamp->secs = 0;
2071 | time_stamp->nsecs = 0;
2072 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2073 | }
2074 | break;
2075 |
2076 | case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2077 | /*
2078 | * NTP time stamp, big-endian.
2079 | * Only supported for absolute times.
2080 | */
2081 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2081, "!is_relative" ))));
2082 |
2083 | /* We need a temporary variable here so the unsigned math
2084 | * works correctly (for years > 2036 according to RFC 2030
2085 | * chapter 3).
2086 | *
2087 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2088 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2089 | * If bit 0 is not set, the time is in the range 2036-2104 and
2090 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2091 | */
2092 | tmpsecs = tvb_get_ntohl(tvb, start);
2093 | if ((tmpsecs & 0x80000000) != 0)
2094 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2095 | else
2096 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2097 |
2098 | if (length == 8) {
2099 | tmp64secs = tvb_get_ntoh64(tvb, start);
2100 | if (tmp64secs == 0) {
2101 | //This is "NULL" time
2102 | time_stamp->secs = 0;
2103 | time_stamp->nsecs = 0;
2104 | } else {
2105 | /*
2106 | * Convert 1/2^32s of a second to
2107 | * nanoseconds.
2108 | */
2109 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2110 | }
2111 | } else if (length == 4) {
2112 | /*
2113 | * Backwards compatibility.
2114 | */
2115 | if (tmpsecs == 0) {
2116 | //This is "NULL" time
2117 | time_stamp->secs = 0;
2118 | }
2119 | time_stamp->nsecs = 0;
2120 | } else {
2121 | time_stamp->secs = 0;
2122 | time_stamp->nsecs = 0;
2123 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2124 | }
2125 | break;
2126 |
2127 | case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2128 | /*
2129 | * NTP time stamp, little-endian.
2130 | * Only supported for absolute times.
2131 | *
2132 | * NTP doesn't use this, because it's an Internet format
2133 | * and hence big-endian. Any implementation must decide
2134 | * whether the NTP timestamp is a 64-bit unsigned fixed
2135 | * point number (RFC 1305, RFC 4330) or a 64-bit struct
2136 | * with a 32-bit unsigned seconds field followed by a
2137 | * 32-bit fraction field (cf. RFC 5905, which obsoletes
2138 | * the previous two).
2139 | *
2140 | * XXX: We do the latter, but no dissector uses this format.
2141 | * OTOH, ERF timestamps do the former, so perhaps we
2142 | * should switch the interpretation so that packet-erf.c
2143 | * could use this directly?
2144 | */
2145 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2145, "!is_relative" ))));
2146 |
2147 | /* We need a temporary variable here so the unsigned math
2148 | * works correctly (for years > 2036 according to RFC 2030
2149 | * chapter 3).
2150 | *
2151 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2152 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2153 | * If bit 0 is not set, the time is in the range 2036-2104 and
2154 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2155 | */
2156 | tmpsecs = tvb_get_letohl(tvb, start);
2157 | if ((tmpsecs & 0x80000000) != 0)
2158 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2159 | else
2160 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2161 |
2162 | if (length == 8) {
2163 | tmp64secs = tvb_get_letoh64(tvb, start);
2164 | if (tmp64secs == 0) {
2165 | //This is "NULL" time
2166 | time_stamp->secs = 0;
2167 | time_stamp->nsecs = 0;
2168 | } else {
2169 | /*
2170 | * Convert 1/2^32s of a second to
2171 | * nanoseconds.
2172 | */
2173 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2174 | }
2175 | } else if (length == 4) {
2176 | /*
2177 | * Backwards compatibility.
2178 | */
2179 | if (tmpsecs == 0) {
2180 | //This is "NULL" time
2181 | time_stamp->secs = 0;
2182 | }
2183 | time_stamp->nsecs = 0;
2184 | } else {
2185 | time_stamp->secs = 0;
2186 | time_stamp->nsecs = 0;
2187 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2188 | }
2189 | break;
2190 |
2191 | case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2192 | /*
2193 | * S/3x0 and z/Architecture TOD clock time stamp,
2194 | * big-endian. The epoch is January 1, 1900,
2195 | * 00:00:00 (proleptic?) UTC.
2196 | *
2197 | * Only supported for absolute times.
2198 | */
2199 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2199, "!is_relative" ))));
2200 | DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2200, "length == 8" ))));
2201 |
2202 | if (length == 8) {
2203 | todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2204 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2205 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2206 | } else {
2207 | time_stamp->secs = 0;
2208 | time_stamp->nsecs = 0;
2209 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2210 | }
2211 | break;
2212 |
2213 | case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2214 | /*
2215 | * S/3x0 and z/Architecture TOD clock time stamp,
2216 | * little-endian. The epoch is January 1, 1900,
2217 | * 00:00:00 (proleptic?) UTC.
2218 | *
2219 | * Only supported for absolute times.
2220 | */
2221 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2221, "!is_relative" ))));
2222 |
2223 | if (length == 8) {
2224 | todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2225 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2226 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2227 | } else {
2228 | time_stamp->secs = 0;
2229 | time_stamp->nsecs = 0;
2230 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2231 | }
2232 | break;
2233 |
2234 | case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2235 | /*
2236 | * Time stamp using the same seconds/fraction format
2237 | * as NTP, but with the origin of the time stamp being
2238 | * the UNIX epoch rather than the NTP epoch; big-
2239 | * endian.
2240 | *
2241 | * Only supported for absolute times.
2242 | */
2243 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2243, "!is_relative" ))));
2244 |
2245 | if (length == 8) {
2246 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2247 | /*
2248 | * Convert 1/2^32s of a second to nanoseconds.
2249 | */
2250 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2251 | } else {
2252 | time_stamp->secs = 0;
2253 | time_stamp->nsecs = 0;
2254 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2255 | }
2256 | break;
2257 |
2258 | case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2259 | /*
2260 | * Time stamp using the same seconds/fraction format
2261 | * as NTP, but with the origin of the time stamp being
2262 | * the UNIX epoch rather than the NTP epoch; little-
2263 | * endian.
2264 | *
2265 | * Only supported for absolute times.
2266 | *
2267 | * The RTPS specification explicitly supports Little
2268 | * Endian encoding. In one place, it states that its
2269 | * Time_t representation "is the one defined by ...
2270 | * RFC 1305", but in another explicitly defines it as
2271 | * a struct consisting of an 32 bit unsigned seconds
2272 | * field and a 32 bit unsigned fraction field, not a 64
2273 | * bit fixed point, so we do that here.
2274 | * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2275 | */
2276 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2276, "!is_relative" ))));
2277 |
2278 | if (length == 8) {
2279 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2280 | /*
2281 | * Convert 1/2^32s of a second to nanoseconds.
2282 | */
2283 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2284 | } else {
2285 | time_stamp->secs = 0;
2286 | time_stamp->nsecs = 0;
2287 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2288 | }
2289 | break;
2290 |
2291 | case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2292 | /*
2293 | * MIP6 time stamp, big-endian.
2294 | * A 64-bit unsigned integer field containing a timestamp. The
2295 | * value indicates the number of seconds since January 1, 1970,
2296 | * 00:00 UTC, by using a fixed point format. In this format, the
2297 | * integer number of seconds is contained in the first 48 bits of
2298 | * the field, and the remaining 16 bits indicate the number of
2299 | * 1/65536 fractions of a second.
2300 |
2301 | * Only supported for absolute times.
2302 | */
2303 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2303, "!is_relative" ))));
2304 |
2305 | if (length == 8) {
2306 | /* We need a temporary variable here so the casting and fractions
2307 | * of a second work correctly.
2308 | */
2309 | tmp64secs = tvb_get_ntoh48(tvb, start);
2310 | tmpsecs = tvb_get_ntohs(tvb, start + 6);
2311 | tmpsecs <<= 16;
2312 |
2313 | if ((tmp64secs == 0) && (tmpsecs == 0)) {
2314 | //This is "NULL" time
2315 | time_stamp->secs = 0;
2316 | time_stamp->nsecs = 0;
2317 | } else {
2318 | time_stamp->secs = (time_t)tmp64secs;
2319 | time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2320 | }
2321 | } else {
2322 | time_stamp->secs = 0;
2323 | time_stamp->nsecs = 0;
2324 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2325 | }
2326 | break;
2327 |
2328 | case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2329 | /*
2330 | * If the length is 16, 8-byte seconds, followed
2331 | * by 8-byte fractional time in microseconds,
2332 | * both big-endian.
2333 | *
2334 | * If the length is 12, 8-byte seconds, followed
2335 | * by 4-byte fractional time in microseconds,
2336 | * both big-endian.
2337 | *
2338 | * If the length is 8, 4-byte seconds, followed
2339 | * by 4-byte fractional time in microseconds,
2340 | * both big-endian.
2341 | *
2342 | * For absolute times, the seconds are seconds
2343 | * since the UN*X epoch.
2344 | */
2345 | if (length == 16) {
2346 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2347 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2348 | } else if (length == 12) {
2349 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2350 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2351 | } else if (length == 8) {
2352 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2353 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2354 | } else {
2355 | time_stamp->secs = 0;
2356 | time_stamp->nsecs = 0;
2357 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2358 | }
2359 | break;
2360 |
2361 | case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2362 | /*
2363 | * If the length is 16, 8-byte seconds, followed
2364 | * by 8-byte fractional time in microseconds,
2365 | * both little-endian.
2366 | *
2367 | * If the length is 12, 8-byte seconds, followed
2368 | * by 4-byte fractional time in microseconds,
2369 | * both little-endian.
2370 | *
2371 | * If the length is 8, 4-byte seconds, followed
2372 | * by 4-byte fractional time in microseconds,
2373 | * both little-endian.
2374 | *
2375 | * For absolute times, the seconds are seconds
2376 | * since the UN*X epoch.
2377 | */
2378 | if (length == 16) {
2379 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2380 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2381 | } else if (length == 12) {
2382 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2383 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2384 | } else if (length == 8) {
2385 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2386 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2387 | } else {
2388 | time_stamp->secs = 0;
2389 | time_stamp->nsecs = 0;
2390 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2391 | }
2392 | break;
2393 |
2394 | case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2395 | case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2396 | /*
2397 | * Seconds, 1 to 8 bytes.
2398 | * For absolute times, it's seconds since the
2399 | * UN*X epoch.
2400 | */
2401 | if (length >= 1 && length <= 8) {
2402 | time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2403 | time_stamp->nsecs = 0;
2404 | } else {
2405 | time_stamp->secs = 0;
2406 | time_stamp->nsecs = 0;
2407 | report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2408 | }
2409 | break;
2410 |
2411 | case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2412 | case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2413 | /*
2414 | * Milliseconds, 1 to 8 bytes.
2415 | * For absolute times, it's milliseconds since the
2416 | * UN*X epoch.
2417 | */
2418 | if (length >= 1 && length <= 8) {
2419 | uint64_t msecs;
2420 |
2421 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2422 | time_stamp->secs = (time_t)(msecs / 1000);
2423 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2424 | } else {
2425 | time_stamp->secs = 0;
2426 | time_stamp->nsecs = 0;
2427 | report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2428 | }
2429 | break;
2430 |
2431 | case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2432 | case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2433 | /*
2434 | * Microseconds, 1 to 8 bytes.
2435 | * For absolute times, it's microseconds since the
2436 | * UN*X epoch.
2437 | */
2438 | if (length >= 1 && length <= 8) {
2439 | uint64_t usecs;
2440 |
2441 | usecs = get_uint64_value(tree, tvb, start, length, encoding);
2442 | time_stamp->secs = (time_t)(usecs / 1000000);
2443 | time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2444 | } else {
2445 | time_stamp->secs = 0;
2446 | time_stamp->nsecs = 0;
2447 | report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2448 | }
2449 | break;
2450 |
2451 | case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2452 | case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2453 | /*
2454 | * nanoseconds, 1 to 8 bytes.
2455 | * For absolute times, it's nanoseconds since the
2456 | * UN*X epoch.
2457 | */
2458 |
2459 | if (length >= 1 && length <= 8) {
2460 | uint64_t nsecs;
2461 |
2462 | nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2463 | time_stamp->secs = (time_t)(nsecs / 1000000000);
2464 | time_stamp->nsecs = (int)(nsecs % 1000000000);
2465 | } else {
2466 | time_stamp->secs = 0;
2467 | time_stamp->nsecs = 0;
2468 | report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2469 | }
2470 | break;
2471 |
2472 | case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2473 | /*
2474 | * 1/64ths of a second since the UN*X epoch,
2475 | * big-endian.
2476 | *
2477 | * Only supported for absolute times.
2478 | */
2479 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2479, "!is_relative" ))));
2480 |
2481 | if (length == 8) {
2482 | /*
2483 | * The upper 48 bits are seconds since the
2484 | * UN*X epoch.
2485 | */
2486 | time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2487 | /*
2488 | * The lower 16 bits are 1/2^16s of a second;
2489 | * convert them to nanoseconds.
2490 | *
2491 | * XXX - this may give the impression of higher
2492 | * precision than you actually get.
2493 | */
2494 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2495 | } else {
2496 | time_stamp->secs = 0;
2497 | time_stamp->nsecs = 0;
2498 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2499 | }
2500 | break;
2501 |
2502 | case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2503 | /*
2504 | * 1/64ths of a second since the UN*X epoch,
2505 | * little-endian.
2506 | *
2507 | * Only supported for absolute times.
2508 | */
2509 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2509, "!is_relative" ))));
2510 |
2511 | if (length == 8) {
2512 | /*
2513 | * XXX - this is assuming that, if anybody
2514 | * were ever to use this format - RFC 3971
2515 | * doesn't, because that's an Internet
2516 | * protocol, and those use network byte
2517 | * order, i.e. big-endian - they'd treat it
2518 | * as a 64-bit count of 1/2^16s of a second,
2519 | * putting the upper 48 bits at the end.
2520 | *
2521 | * The lower 48 bits are seconds since the
2522 | * UN*X epoch.
2523 | */
2524 | time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2525 | /*
2526 | * The upper 16 bits are 1/2^16s of a second;
2527 | * convert them to nanoseconds.
2528 | *
2529 | * XXX - this may give the impression of higher
2530 | * precision than you actually get.
2531 | */
2532 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2533 | } else {
2534 | time_stamp->secs = 0;
2535 | time_stamp->nsecs = 0;
2536 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2537 | }
2538 | break;
2539 |
2540 | case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2541 | /*
2542 | * NTP time stamp, with 1-second resolution (i.e.,
2543 | * seconds since the NTP epoch), big-endian.
2544 | * Only supported for absolute times.
2545 | */
2546 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2546, "!is_relative" ))));
2547 |
2548 | if (length == 4) {
2549 | /*
2550 | * We need a temporary variable here so the unsigned math
2551 | * works correctly (for years > 2036 according to RFC 2030
2552 | * chapter 3).
2553 | *
2554 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2555 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2556 | * If bit 0 is not set, the time is in the range 2036-2104 and
2557 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2558 | */
2559 | tmpsecs = tvb_get_ntohl(tvb, start);
2560 | if ((tmpsecs & 0x80000000) != 0)
2561 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2562 | else
2563 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2564 | time_stamp->nsecs = 0;
2565 | } else {
2566 | time_stamp->secs = 0;
2567 | time_stamp->nsecs = 0;
2568 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2569 | }
2570 | break;
2571 |
2572 | case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2573 | /*
2574 | * NTP time stamp, with 1-second resolution (i.e.,
2575 | * seconds since the NTP epoch), little-endian.
2576 | * Only supported for absolute times.
2577 | */
2578 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2578, "!is_relative" ))));
2579 |
2580 | /*
2581 | * We need a temporary variable here so the unsigned math
2582 | * works correctly (for years > 2036 according to RFC 2030
2583 | * chapter 3).
2584 | *
2585 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2586 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2587 | * If bit 0 is not set, the time is in the range 2036-2104 and
2588 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2589 | */
2590 | if (length == 4) {
2591 | tmpsecs = tvb_get_letohl(tvb, start);
2592 | if ((tmpsecs & 0x80000000) != 0)
2593 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2594 | else
2595 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2596 | time_stamp->nsecs = 0;
2597 | } else {
2598 | time_stamp->secs = 0;
2599 | time_stamp->nsecs = 0;
2600 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2601 | }
2602 | break;
2603 |
2604 | case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2605 | /*
2606 | * Milliseconds, 6 to 8 bytes.
2607 | * For absolute times, it's milliseconds since the
2608 | * NTP epoch.
2609 | *
2610 | * ETSI TS 129.274 8.119 defines this as:
2611 | * "a 48 bit unsigned integer in network order format
2612 | * ...encoded as the number of milliseconds since
2613 | * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2614 | * rounded value of 1000 x the value of the 64-bit
2615 | * timestamp (Seconds + (Fraction / (1<<32))) defined
2616 | * in clause 6 of IETF RFC 5905."
2617 | *
2618 | * Taken literally, the part after "i.e." would
2619 | * mean that the value rolls over before reaching
2620 | * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2621 | * when the 64 bit timestamp rolls over, and we have
2622 | * to pick an NTP Era equivalence class to support
2623 | * (such as 1968-01-20 to 2104-02-06).
2624 | *
2625 | * OTOH, the extra room might be used to store Era
2626 | * information instead, in which case times until
2627 | * 10819-08-03 can be represented with 6 bytes without
2628 | * ambiguity. We handle both implementations, and assume
2629 | * that times before 1968-01-20 are not represented.
2630 | *
2631 | * Only 6 bytes or more makes sense as an absolute
2632 | * time. 5 bytes or fewer could express a span of
2633 | * less than 35 years, either 1900-1934 or 2036-2070.
2634 | */
2635 | if (length >= 6 && length <= 8) {
2636 | uint64_t msecs;
2637 |
2638 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2639 | tmp64secs = (msecs / 1000);
2640 | /*
2641 | * Assume that times in the first half of NTP
2642 | * Era 0 really represent times in the NTP
2643 | * Era 1.
2644 | */
2645 | if (tmp64secs >= 0x80000000)
2646 | time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2647 | else
2648 | time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2649 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2650 | }
2651 | else {
2652 | time_stamp->secs = 0;
2653 | time_stamp->nsecs = 0;
2654 | report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2655 | }
2656 | break;
2657 |
2658 | case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2659 | /*
2660 | * MP4 file time stamps, big-endian.
2661 | * Only supported for absolute times.
2662 | */
2663 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2663, "!is_relative" ))));
2664 |
2665 | if (length == 8) {
2666 | tmp64secs = tvb_get_ntoh64(tvb, start);
2667 | time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2668 | time_stamp->nsecs = 0;
2669 | } else if (length == 4) {
2670 | tmpsecs = tvb_get_ntohl(tvb, start);
2671 | time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2672 | time_stamp->nsecs = 0;
2673 | } else {
2674 | time_stamp->secs = 0;
2675 | time_stamp->nsecs = 0;
2676 | report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2677 | }
2678 | break;
2679 |
2680 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2681 | /*
2682 | * Zigbee ZCL time stamps, big-endian.
2683 | * Only supported for absolute times.
2684 | */
2685 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2685, "!is_relative" ))));
2686 |
2687 | if (length == 8) {
2688 | tmp64secs = tvb_get_ntoh64(tvb, start);
2689 | 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))) {
2690 | /* There are several other possible choices for what to do
2691 | * with overflow; make sure to coordinate with whatever
2692 | * packet-zbee-zcl.h does. */
2693 | 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))))));
2694 | }
2695 | time_stamp->nsecs = 0;
2696 | } else if (length == 4) {
2697 | tmpsecs = tvb_get_ntohl(tvb, start);
2698 | 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))) {
2699 | 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))))));
2700 | }
2701 | time_stamp->nsecs = 0;
2702 | } else {
2703 | time_stamp->secs = 0;
2704 | time_stamp->nsecs = 0;
2705 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2706 | }
2707 | break;
2708 |
2709 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2710 | /*
2711 | * Zigbee ZCL time stamps, little-endian.
2712 | * Only supported for absolute times.
2713 | */
2714 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2714, "!is_relative" ))));
2715 |
2716 | if (length == 8) {
2717 | tmp64secs = tvb_get_letoh64(tvb, start);
2718 | 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))) {
2719 | 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))))));
2720 | }
2721 | time_stamp->nsecs = 0;
2722 | } else if (length == 4) {
2723 | tmpsecs = tvb_get_letohl(tvb, start);
2724 | 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))) {
2725 | 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))))));
2726 | }
2727 | time_stamp->nsecs = 0;
2728 | } else {
2729 | time_stamp->secs = 0;
2730 | time_stamp->nsecs = 0;
2731 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2732 | }
2733 | break;
2734 |
2735 | default:
2736 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 2736));
2737 | break;
2738 | }
2739 | }
2740 |
2741 | static void
2742 | tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2743 | {
2744 | const header_field_info *hfinfo = fi->hfinfo;
2745 |
2746 | if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2747 | GPtrArray *ptrs = NULL((void*)0);
2748 |
2749 | if (tree_data->interesting_hfids == NULL((void*)0)) {
2750 | /* Initialize the hash because we now know that it is needed */
2751 | tree_data->interesting_hfids =
2752 | g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2753 | } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2754 | ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2755 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2756 | }
2757 |
2758 | if (!ptrs) {
2759 | /* First element triggers the creation of pointer array */
2760 | ptrs = g_ptr_array_new();
2761 | g_hash_table_insert(tree_data->interesting_hfids,
2762 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2763 | }
2764 |
2765 | g_ptr_array_add(ptrs, fi);
2766 | }
2767 | }
2768 |
2769 |
2770 | /*
2771 | * Validates that field length bytes are available starting from
2772 | * start (pos/neg). Throws an exception if they aren't.
2773 | */
2774 | static void
2775 | test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2776 | unsigned start, int length, const unsigned encoding)
2777 | {
2778 | int size = length;
2779 |
2780 | if (!tvb)
2781 | return;
2782 |
2783 | if ((hfinfo->type == FT_STRINGZ) ||
2784 | ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2785 | (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 ))))) {
2786 | /* If we're fetching until the end of the TVB, only validate
2787 | * that the offset is within range.
2788 | */
2789 | if (length == -1)
2790 | size = 0;
2791 | }
2792 |
2793 | tvb_ensure_bytes_exist(tvb, start, size);
2794 | }
2795 |
2796 | static void
2797 | detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2798 | {
2799 | bool_Bool found_stray_character = false0;
2800 |
2801 | if (!string)
2802 | return;
2803 |
2804 | switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2805 | case ENC_ASCII0x00000000:
2806 | case ENC_UTF_80x00000002:
2807 | for (int i = (int)strlen(string); i < length; i++) {
2808 | if (string[i] != '\0') {
2809 | found_stray_character = true1;
2810 | break;
2811 | }
2812 | }
2813 | break;
2814 |
2815 | default:
2816 | break;
2817 | }
2818 |
2819 | if (found_stray_character) {
2820 | expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2821 | }
2822 | }
2823 |
2824 | /* Add an item to a proto_tree, using the text label registered to that item;
2825 | the item is extracted from the tvbuff handed to it. */
2826 | static proto_item *
2827 | proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2828 | tvbuff_t *tvb, unsigned start, int length,
2829 | unsigned encoding)
2830 | {
2831 | proto_item *pi;
2832 | uint32_t value, n;
2833 | uint64_t value64;
2834 | ws_in4_addr ipv4_value;
2835 | float floatval;
2836 | double doubleval;
2837 | const char *stringval = NULL((void*)0);
2838 | nstime_t time_stamp;
2839 | bool_Bool length_error;
2840 | unsigned item_length;
2841 |
2842 | // new_fi->value is allocated from the packet-scoped pool (see
2843 | // new_field_info()), so if a tvbuff accessor below throws before the
2844 | // node is added to the tree the fvalue_t structure is still reclaimed
2845 | // when the pool is freed; no explicit cleanup handler is needed. This
2846 | // relies on the invariant that the type-specific data an fvalue owns
2847 | // (byte arrays, string buffers, ...) is only allocated *after* the
2848 | // throwing tvbuff read that produced it succeeds, so nothing that would
2849 | // need fvalue_cleanup() is ever leaked on the exception path.
2850 | switch (new_fi->hfinfo->type) {
2851 | case FT_NONE:
2852 | /* no value to set for FT_NONE */
2853 | break;
2854 |
2855 | case FT_PROTOCOL:
2856 | /* Set the protocol_tvb via the start offset, but include
2857 | * rest of the ds_tvb so that if finfo_set_len is called
2858 | * later it can be lengthened as much as possible. */
2859 | 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);
2860 | break;
2861 |
2862 | case FT_BYTES:
2863 | proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2864 | break;
2865 |
2866 | case FT_UINT_BYTES:
2867 | n = get_uint_value(tree, tvb, start, length, encoding);
2868 | proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2869 |
2870 | /* Instead of calling proto_item_set_len(), since we don't yet
2871 | * have a proto_item, we set the field_info's length ourselves. */
2872 | new_fi->length = n + length;
2873 | break;
2874 |
2875 | case FT_BOOLEAN:
2876 | /*
2877 | * Map all non-zero values to little-endian for
2878 | * backwards compatibility.
2879 | */
2880 | if (encoding)
2881 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2882 | proto_tree_set_boolean(new_fi,
2883 | get_uint64_value(tree, tvb, start, length, encoding));
2884 | break;
2885 |
2886 | case FT_CHAR:
2887 | /* XXX - make these just FT_UINT? */
2888 | case FT_UINT8:
2889 | case FT_UINT16:
2890 | case FT_UINT24:
2891 | case FT_UINT32:
2892 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2893 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2894 | value = (uint32_t)value64;
2895 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2896 | new_fi->flags |= FI_VARINT0x00040000;
2897 | }
2898 | }
2899 | else {
2900 | /*
2901 | * Map all non-zero values to little-endian for
2902 | * backwards compatibility.
2903 | */
2904 | if (encoding)
2905 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2906 |
2907 | value = get_uint_value(tree, tvb, start, length, encoding);
2908 | }
2909 | proto_tree_set_uint(new_fi, value);
2910 | break;
2911 |
2912 | case FT_UINT40:
2913 | case FT_UINT48:
2914 | case FT_UINT56:
2915 | case FT_UINT64:
2916 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2917 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2918 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2919 | new_fi->flags |= FI_VARINT0x00040000;
2920 | }
2921 | }
2922 | else {
2923 | /*
2924 | * Map all other non-zero values to little-endian for
2925 | * backwards compatibility.
2926 | */
2927 | if (encoding)
2928 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2929 |
2930 | value64 = get_uint64_value(tree, tvb, start, length, encoding);
2931 | }
2932 | proto_tree_set_uint64(new_fi, value64);
2933 | break;
2934 |
2935 | /* XXX - make these just FT_INT? */
2936 | case FT_INT8:
2937 | case FT_INT16:
2938 | case FT_INT24:
2939 | case FT_INT32:
2940 | /*
2941 | * Map all non-zero values to little-endian for
2942 | * backwards compatibility.
2943 | */
2944 | if (encoding)
2945 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2946 | proto_tree_set_int(new_fi,
2947 | get_int_value(tree, tvb, start, length, encoding));
2948 | break;
2949 |
2950 | case FT_INT40:
2951 | case FT_INT48:
2952 | case FT_INT56:
2953 | case FT_INT64:
2954 | /*
2955 | * Map all non-zero values to little-endian for
2956 | * backwards compatibility.
2957 | */
2958 | if (encoding)
2959 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2960 | proto_tree_set_int64(new_fi,
2961 | get_int64_value(tree, tvb, start, length, encoding));
2962 | break;
2963 |
2964 | case FT_IPv4:
2965 | /*
2966 | * Map all non-zero values to little-endian for
2967 | * backwards compatibility.
2968 | */
2969 | if (encoding)
2970 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2971 | if (length != FT_IPv4_LEN4) {
2972 | length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2973 | report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2974 | }
2975 | ipv4_value = tvb_get_ipv4(tvb, start);
2976 | /*
2977 | * NOTE: to support code written when
2978 | * proto_tree_add_item() took a bool as its
2979 | * last argument, with false meaning "big-endian"
2980 | * and true meaning "little-endian", we treat any
2981 | * non-zero value of "encoding" as meaning
2982 | * "little-endian".
2983 | */
2984 | 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);
2985 | break;
2986 |
2987 | case FT_IPXNET:
2988 | if (length != FT_IPXNET_LEN4) {
2989 | length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2990 | report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2991 | }
2992 | proto_tree_set_ipxnet(new_fi,
2993 | get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2994 | break;
2995 |
2996 | case FT_IPv6:
2997 | if (length != FT_IPv6_LEN16) {
2998 | length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2999 | report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
3000 | }
3001 | proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
3002 | break;
3003 |
3004 | case FT_FCWWN:
3005 | if (length != FT_FCWWN_LEN8) {
3006 | length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
3007 | report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
3008 | }
3009 | proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
3010 | break;
3011 |
3012 | case FT_AX25:
3013 | if (length != 7) {
3014 | length_error = length < 7 ? true1 : false0;
3015 | report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3016 | }
3017 | proto_tree_set_ax25_tvb(new_fi, tvb, start);
3018 | break;
3019 |
3020 | case FT_VINES:
3021 | if (length != VINES_ADDR_LEN6) {
3022 | length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3023 | report_type_length_mismatch(tree, "a Vines address", length, length_error);
3024 | }
3025 | proto_tree_set_vines_tvb(new_fi, tvb, start);
3026 | break;
3027 |
3028 | case FT_ETHER:
3029 | if (length != FT_ETHER_LEN6) {
3030 | length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3031 | report_type_length_mismatch(tree, "a MAC address", length, length_error);
3032 | }
3033 | proto_tree_set_ether_tvb(new_fi, tvb, start);
3034 | break;
3035 |
3036 | case FT_EUI64:
3037 | /*
3038 | * Map all non-zero values to little-endian for
3039 | * backwards compatibility.
3040 | */
3041 | if (encoding)
3042 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3043 | if (length != FT_EUI64_LEN8) {
3044 | length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3045 | report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3046 | }
3047 | proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3048 | break;
3049 | case FT_GUID:
3050 | /*
3051 | * Map all non-zero values to little-endian for
3052 | * backwards compatibility.
3053 | */
3054 | if (encoding)
3055 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3056 | if (length != FT_GUID_LEN16) {
3057 | length_error = length < FT_GUID_LEN16 ? true1 : false0;
3058 | report_type_length_mismatch(tree, "a GUID", length, length_error);
3059 | }
3060 | proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3061 | break;
3062 |
3063 | case FT_OID:
3064 | case FT_REL_OID:
3065 | proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3066 | break;
3067 |
3068 | case FT_SYSTEM_ID:
3069 | proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3070 | break;
3071 |
3072 | case FT_FLOAT:
3073 | /*
3074 | * NOTE: to support code written when
3075 | * proto_tree_add_item() took a bool as its
3076 | * last argument, with false meaning "big-endian"
3077 | * and true meaning "little-endian", we treat any
3078 | * non-zero value of "encoding" as meaning
3079 | * "little-endian".
3080 | *
3081 | * At some point in the future, we might
3082 | * support non-IEEE-binary floating-point
3083 | * formats in the encoding as well
3084 | * (IEEE decimal, System/3x0, VAX).
3085 | */
3086 | if (encoding)
3087 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3088 | if (length != 4) {
3089 | length_error = length < 4 ? true1 : false0;
3090 | report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3091 | }
3092 | if (encoding)
3093 | floatval = tvb_get_letohieee_float(tvb, start);
3094 | else
3095 | floatval = tvb_get_ntohieee_float(tvb, start);
3096 | proto_tree_set_float(new_fi, floatval);
3097 | break;
3098 |
3099 | case FT_DOUBLE:
3100 | /*
3101 | * NOTE: to support code written when
3102 | * proto_tree_add_item() took a bool as its
3103 | * last argument, with false meaning "big-endian"
3104 | * and true meaning "little-endian", we treat any
3105 | * non-zero value of "encoding" as meaning
3106 | * "little-endian".
3107 | *
3108 | * At some point in the future, we might
3109 | * support non-IEEE-binary floating-point
3110 | * formats in the encoding as well
3111 | * (IEEE decimal, System/3x0, VAX).
3112 | */
3113 | if (encoding == true1)
3114 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3115 | if (length != 8) {
3116 | length_error = length < 8 ? true1 : false0;
3117 | report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3118 | }
3119 | if (encoding)
3120 | doubleval = tvb_get_letohieee_double(tvb, start);
3121 | else
3122 | doubleval = tvb_get_ntohieee_double(tvb, start);
3123 | proto_tree_set_double(new_fi, doubleval);
3124 | break;
3125 |
3126 | case FT_STRING:
3127 | stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3128 | tvb, start, length, &item_length, encoding);
3129 | proto_tree_set_string(new_fi, stringval);
3130 |
3131 | /* Instead of calling proto_item_set_len(), since we
3132 | * don't yet have a proto_item, we set the
3133 | * field_info's length ourselves.
3134 | *
3135 | * XXX - our caller can't use that length to
3136 | * advance an offset unless they arrange that
3137 | * there always be a protocol tree into which
3138 | * we're putting this item.
3139 | */
3140 | new_fi->length = item_length;
3141 | break;
3142 |
3143 | case FT_STRINGZ:
3144 | stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3145 | tree, tvb, start, length, &item_length, encoding);
3146 | proto_tree_set_string(new_fi, stringval);
3147 |
3148 | /* Instead of calling proto_item_set_len(),
3149 | * since we don't yet have a proto_item, we
3150 | * set the field_info's length ourselves.
3151 | *
3152 | * XXX - our caller can't use that length to
3153 | * advance an offset unless they arrange that
3154 | * there always be a protocol tree into which
3155 | * we're putting this item.
3156 | */
3157 | new_fi->length = item_length;
3158 | break;
3159 |
3160 | case FT_UINT_STRING:
3161 | /*
3162 | * NOTE: to support code written when
3163 | * proto_tree_add_item() took a bool as its
3164 | * last argument, with false meaning "big-endian"
3165 | * and true meaning "little-endian", if the
3166 | * encoding value is true, treat that as
3167 | * ASCII with a little-endian length.
3168 | *
3169 | * This won't work for code that passes
3170 | * arbitrary non-zero values; that code
3171 | * will need to be fixed.
3172 | */
3173 | if (encoding == true1)
3174 | encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3175 | stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3176 | tree, tvb, start, length, &item_length, encoding);
3177 | proto_tree_set_string(new_fi, stringval);
3178 |
3179 | /* Instead of calling proto_item_set_len(), since we
3180 | * don't yet have a proto_item, we set the
3181 | * field_info's length ourselves.
3182 | *
3183 | * XXX - our caller can't use that length to
3184 | * advance an offset unless they arrange that
3185 | * there always be a protocol tree into which
3186 | * we're putting this item.
3187 | */
3188 | new_fi->length = item_length;
3189 | break;
3190 |
3191 | case FT_STRINGZPAD:
3192 | stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3193 | tvb, start, length, &item_length, encoding);
3194 | proto_tree_set_string(new_fi, stringval);
3195 |
3196 | /* Instead of calling proto_item_set_len(), since we
3197 | * don't yet have a proto_item, we set the
3198 | * field_info's length ourselves.
3199 | *
3200 | * XXX - our caller can't use that length to
3201 | * advance an offset unless they arrange that
3202 | * there always be a protocol tree into which
3203 | * we're putting this item.
3204 | */
3205 | new_fi->length = item_length;
3206 | break;
3207 |
3208 | case FT_STRINGZTRUNC:
3209 | stringval = (const char*)get_stringztrunc_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_ABSOLUTE_TIME:
3226 | /*
3227 | * Absolute times can be in any of a number of
3228 | * formats, and they can be big-endian or
3229 | * little-endian.
3230 | *
3231 | * Historically FT_TIMEs were only timespecs;
3232 | * the only question was whether they were stored
3233 | * in big- or little-endian format.
3234 | *
3235 | * For backwards compatibility, we interpret an
3236 | * encoding of 1 as meaning "little-endian timespec",
3237 | * so that passing true is interpreted as that.
3238 | */
3239 | if (encoding == true1)
3240 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3241 |
3242 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3243 |
3244 | proto_tree_set_time(new_fi, &time_stamp);
3245 | break;
3246 |
3247 | case FT_RELATIVE_TIME:
3248 | /*
3249 | * Relative times can be in any of a number of
3250 | * formats, and they can be big-endian or
3251 | * little-endian.
3252 | *
3253 | * Historically FT_TIMEs were only timespecs;
3254 | * the only question was whether they were stored
3255 | * in big- or little-endian format.
3256 | *
3257 | * For backwards compatibility, we interpret an
3258 | * encoding of 1 as meaning "little-endian timespec",
3259 | * so that passing true is interpreted as that.
3260 | */
3261 | if (encoding == true1)
3262 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3263 |
3264 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3265 |
3266 | proto_tree_set_time(new_fi, &time_stamp);
3267 | break;
3268 | case FT_IEEE_11073_SFLOAT:
3269 | if (encoding)
3270 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3271 | if (length != 2) {
3272 | length_error = length < 2 ? true1 : false0;
3273 | report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3274 | }
3275 |
3276 | fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3277 |
3278 | break;
3279 | case FT_IEEE_11073_FLOAT:
3280 | if (encoding)
3281 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3282 | if (length != 4) {
3283 | length_error = length < 4 ? true1 : false0;
3284 | report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3285 | }
3286 | fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3287 |
3288 | break;
3289 | default:
3290 | 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))
3291 | 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))
3292 | 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))
3293 | 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));
3294 | break;
3295 | }
3296 | 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);
3297 |
3298 | /* Don't add new node to proto_tree until now so that any exceptions
3299 | * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3300 | /* XXX. wouldn't be better to add this item to tree, with some special
3301 | * flag (FI_EXCEPTION?) to know which item caused exception? For
3302 | * strings and bytes, we would have to set new_fi->value to something
3303 | * non-NULL, or otherwise ensure that proto_item_fill_display_label
3304 | * could handle NULL values. */
3305 | pi = proto_tree_add_node(tree, new_fi);
3306 |
3307 | switch (new_fi->hfinfo->type) {
3308 |
3309 | case FT_STRING:
3310 | /* XXX: trailing stray character detection should be done
3311 | * _before_ conversion to UTF-8, because conversion can change
3312 | * the length, or else get_string_length should return a value
3313 | * for the "length in bytes of the string after conversion
3314 | * including internal nulls." (Noting that we do, for other
3315 | * reasons, still need the "length in bytes in the field",
3316 | * especially for FT_STRINGZ.)
3317 | *
3318 | * This is true even for ASCII and UTF-8, because
3319 | * substituting REPLACEMENT CHARACTERS for illegal characters
3320 | * can also do so (and for UTF-8 possibly even make the
3321 | * string _shorter_).
3322 | */
3323 | detect_trailing_stray_characters(encoding, stringval, item_length, pi);
3324 | break;
3325 |
3326 | default:
3327 | break;
3328 | }
3329 |
3330 | return pi;
3331 | }
3332 |
3333 | proto_item *
3334 | proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3335 | const unsigned start, unsigned length,
3336 | const unsigned encoding, int32_t *retval)
3337 | {
3338 | header_field_info *hfinfo;
3339 | field_info *new_fi;
3340 | int32_t value;
3341 |
3342 | 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", 3342, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3342, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3342, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3343 |
3344 | switch (hfinfo->type) {
3345 | case FT_INT8:
3346 | case FT_INT16:
3347 | case FT_INT24:
3348 | case FT_INT32:
3349 | break;
3350 | case FT_INT64:
3351 | 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)
3352 | hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3353 | default:
3354 | 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)
3355 | hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3356 | }
3357 |
3358 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3359 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3360 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3361 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3362 | *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3363 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3364 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3365 |
3366 | if (encoding & ENC_STRING0x07000000) {
3367 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3368 | }
3369 | /* I believe it's ok if this is called with a NULL tree */
3370 | value = get_int_value(tree, tvb, start, length, encoding);
3371 |
3372 | if (retval) {
3373 | int no_of_bits;
3374 | *retval = value;
3375 | if (hfinfo->bitmask) {
3376 | /* Mask out irrelevant portions */
3377 | *retval &= (uint32_t)(hfinfo->bitmask);
3378 | /* Shift bits */
3379 | *retval >>= hfinfo_bitshift(hfinfo);
3380 | }
3381 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3382 | *retval = ws_sign_ext32(*retval, no_of_bits);
3383 | }
3384 |
3385 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3386 |
3387 | 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", 3387 , __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", 3387, "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", 3387, "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", 3387, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3388 |
3389 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3390 |
3391 | proto_tree_set_int(new_fi, value);
3392 |
3393 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3394 |
3395 | return proto_tree_add_node(tree, new_fi);
3396 | }
3397 |
3398 | proto_item *
3399 | proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3400 | const unsigned start, unsigned length,
3401 | const unsigned encoding, uint32_t *retval)
3402 | {
3403 | header_field_info *hfinfo;
3404 | field_info *new_fi;
3405 | uint32_t value;
3406 |
3407 | 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", 3407, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3407, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3407, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3408 |
3409 | switch (hfinfo->type) {
3410 | case FT_CHAR:
3411 | case FT_UINT8:
3412 | case FT_UINT16:
3413 | case FT_UINT24:
3414 | case FT_UINT32:
3415 | break;
3416 | default:
3417 | 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)
3418 | 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);
3419 | }
3420 |
3421 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3422 | {if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3423 | if (retval) {if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3424 | *retval = 0;if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3425 | }if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3426 | return NULL;if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3427 | }if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); }
3428 | )if (length == 0) { { if (retval) { *retval = 0; } return ((void *)0); }; return ((void*)0); };
3429 |
3430 | if (encoding & ENC_STRING0x07000000) {
3431 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3432 | }
3433 | /* I believe it's ok if this is called with a NULL tree */
3434 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3435 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3436 | uint64_t temp64;
3437 | tvb_get_varint(tvb, start, length, &temp64, encoding);
3438 | value = (uint32_t)temp64;
3439 | } else {
3440 | value = get_uint_value(tree, tvb, start, length, encoding);
3441 | }
3442 |
3443 | if (retval) {
3444 | *retval = value;
3445 | if (hfinfo->bitmask) {
3446 | /* Mask out irrelevant portions */
3447 | *retval &= (uint32_t)(hfinfo->bitmask);
3448 | /* Shift bits */
3449 | *retval >>= hfinfo_bitshift(hfinfo);
3450 | }
3451 | }
3452 |
3453 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3454 |
3455 | 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", 3455 , __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", 3455, "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", 3455, "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", 3455, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3456 |
3457 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3458 |
3459 | proto_tree_set_uint(new_fi, value);
3460 |
3461 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3462 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3463 | new_fi->flags |= FI_VARINT0x00040000;
3464 | }
3465 | return proto_tree_add_node(tree, new_fi);
3466 | }
3467 |
3468 | proto_item *
3469 | proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3470 | const unsigned start, unsigned length,
3471 | const unsigned encoding, uint32_t *retval)
3472 | {
3473 | return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3474 | }
3475 |
3476 | proto_item *
3477 | proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3478 | const unsigned start, unsigned length,
3479 | const unsigned encoding, uint8_t *retval)
3480 | {
3481 | /* TODO: further restrict by hfinfo->type ? */
3482 | uint32_t val32;
3483 | proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3484 | *retval = (uint8_t)val32;
3485 | return item;
3486 | }
3487 |
3488 | proto_item *
3489 | proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3490 | const unsigned start, unsigned length,
3491 | const unsigned encoding, uint16_t *retval)
3492 | {
3493 | /* TODO: further restrict by hfinfo->type ? */
3494 | uint32_t val32;
3495 | proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3496 | *retval = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3497 | return item;
3498 | }
3499 |
3500 |
3501 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3502 | * and returns proto_item* and uint value retrieved*/
3503 | proto_item *
3504 | ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3505 | const unsigned encoding, uint32_t *retval)
3506 | {
3507 | field_info *new_fi;
3508 | header_field_info *hfinfo;
3509 | unsigned item_length;
3510 | unsigned offset;
3511 | uint32_t value;
3512 |
3513 | offset = ptvc->offset;
3514 | 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", 3514, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3514, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3514, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3515 |
3516 | switch (hfinfo->type) {
3517 | case FT_CHAR:
3518 | case FT_UINT8:
3519 | case FT_UINT16:
3520 | case FT_UINT24:
3521 | case FT_UINT32:
3522 | break;
3523 | default:
3524 | 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)
3525 | 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);
3526 | }
3527 |
3528 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3529 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3530 |
3531 | /* I believe it's ok if this is called with a NULL tree */
3532 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3533 | value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3534 |
3535 | if (retval) {
3536 | *retval = value;
3537 | if (hfinfo->bitmask) {
3538 | /* Mask out irrelevant portions */
3539 | *retval &= (uint32_t)(hfinfo->bitmask);
3540 | /* Shift bits */
3541 | *retval >>= hfinfo_bitshift(hfinfo);
3542 | }
3543 | }
3544 |
3545 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3546 |
3547 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3548 |
3549 | /* Coast clear. Try and fake it */
3550 | 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", 3550 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3550, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3550, "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", 3550, __func__, "Adding %s would put more than %d 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); } } };
3551 |
3552 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3553 |
3554 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3555 | offset, length, encoding);
3556 | }
3557 |
3558 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3559 | * and returns proto_item* and int value retrieved*/
3560 | proto_item *
3561 | ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3562 | const unsigned encoding, int32_t *retval)
3563 | {
3564 | field_info *new_fi;
3565 | header_field_info *hfinfo;
3566 | unsigned item_length;
3567 | unsigned offset;
3568 | uint32_t value;
3569 |
3570 | offset = ptvc->offset;
3571 | 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", 3571, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3571, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3571, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3572 |
3573 | switch (hfinfo->type) {
3574 | case FT_INT8:
3575 | case FT_INT16:
3576 | case FT_INT24:
3577 | case FT_INT32:
3578 | break;
3579 | default:
3580 | 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)
3581 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
3582 | }
3583 |
3584 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3585 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3586 |
3587 | /* I believe it's ok if this is called with a NULL tree */
3588 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3589 | value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3590 |
3591 | if (retval) {
3592 | int no_of_bits;
3593 | *retval = value;
3594 | if (hfinfo->bitmask) {
3595 | /* Mask out irrelevant portions */
3596 | *retval &= (uint32_t)(hfinfo->bitmask);
3597 | /* Shift bits */
3598 | *retval >>= hfinfo_bitshift(hfinfo);
3599 | }
3600 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3601 | *retval = ws_sign_ext32(*retval, no_of_bits);
3602 | }
3603 |
3604 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3605 |
3606 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3607 |
3608 | /* Coast clear. Try and fake it */
3609 | 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", 3609 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3609, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3609, "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", 3609, __func__, "Adding %s would put more than %d 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); } } };
3610 |
3611 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3612 |
3613 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3614 | offset, length, encoding);
3615 | }
3616 |
3617 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3618 | * and returns proto_item* and string value retrieved */
3619 | proto_item*
3620 | ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3621 | {
3622 | header_field_info *hfinfo;
3623 | field_info *new_fi;
3624 | const uint8_t *value;
3625 | unsigned item_length;
3626 | unsigned offset;
3627 |
3628 | offset = ptvc->offset;
3629 |
3630 | 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", 3630 , __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", 3630, "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", 3630, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hf];;
3631 |
3632 | switch (hfinfo->type) {
3633 | case FT_STRING:
3634 | value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3635 | break;
3636 | case FT_STRINGZ:
3637 | value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3638 | break;
3639 | case FT_UINT_STRING:
3640 | value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3641 | break;
3642 | case FT_STRINGZPAD:
3643 | value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3644 | break;
3645 | case FT_STRINGZTRUNC:
3646 | value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3647 | break;
3648 | default:
3649 | 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)
3650 | 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);
3651 | }
3652 |
3653 | if (retval)
3654 | *retval = value;
3655 |
3656 | ptvcursor_advance(ptvc, item_length);
3657 |
3658 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3659 |
3660 | 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", 3660, __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", 3660, "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", 3660, "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", 3660 , __func__, "Adding %s would put more than %d 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); } } };
3661 |
3662 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3663 |
3664 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3665 | offset, length, encoding);
3666 | }
3667 |
3668 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3669 | * and returns proto_item* and boolean value retrieved */
3670 | proto_item*
3671 | ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3672 | {
3673 | header_field_info *hfinfo;
3674 | field_info *new_fi;
3675 | unsigned item_length;
3676 | unsigned offset;
3677 | uint64_t value, bitval;
3678 |
3679 | offset = ptvc->offset;
3680 | 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", 3680, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3680, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3680, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3681 |
3682 | if (hfinfo->type != FT_BOOLEAN) {
3683 | 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)
3684 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3685 | }
3686 |
3687 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3688 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3689 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3690 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3691 | *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3692 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3693 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3694 |
3695 | if (encoding & ENC_STRING0x07000000) {
3696 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3697 | }
3698 |
3699 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3700 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3701 |
3702 | /* I believe it's ok if this is called with a NULL tree */
3703 | value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3704 |
3705 | if (retval) {
3706 | bitval = value;
3707 | if (hfinfo->bitmask) {
3708 | /* Mask out irrelevant portions */
3709 | bitval &= hfinfo->bitmask;
3710 | }
3711 | *retval = (bitval != 0);
3712 | }
3713 |
3714 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3715 |
3716 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3717 |
3718 | 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", 3718, __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", 3718, "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", 3718, "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", 3718 , __func__, "Adding %s would put more than %d 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); } } };
3719 |
3720 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3721 |
3722 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3723 | offset, length, encoding);
3724 | }
3725 |
3726 | proto_item *
3727 | proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3728 | const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval)
3729 | {
3730 | header_field_info *hfinfo;
3731 | field_info *new_fi;
3732 | uint64_t value;
3733 |
3734 | 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", 3734, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3734, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3734, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3735 |
3736 | switch (hfinfo->type) {
3737 | case FT_UINT40:
3738 | case FT_UINT48:
3739 | case FT_UINT56:
3740 | case FT_UINT64:
3741 | break;
3742 | default:
3743 | 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)
3744 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64" , hfinfo->abbrev);
3745 | }
3746 |
3747 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3748 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3749 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3750 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3751 | *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3752 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3753 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3754 |
3755 | if (encoding & ENC_STRING0x07000000) {
3756 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3757 | }
3758 | /* I believe it's ok if this is called with a NULL tree */
3759 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3760 | tvb_get_varint(tvb, start, length, &value, encoding);
3761 | } else {
3762 | value = get_uint64_value(tree, tvb, start, length, encoding);
3763 | }
3764 |
3765 | if (retval) {
3766 | *retval = value;
3767 | if (hfinfo->bitmask) {
3768 | /* Mask out irrelevant portions */
3769 | *retval &= hfinfo->bitmask;
3770 | /* Shift bits */
3771 | *retval >>= hfinfo_bitshift(hfinfo);
3772 | }
3773 | }
3774 |
3775 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3776 |
3777 | 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", 3777 , __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", 3777, "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", 3777, "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", 3777, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3778 |
3779 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3780 |
3781 | proto_tree_set_uint64(new_fi, value);
3782 |
3783 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3784 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3785 | new_fi->flags |= FI_VARINT0x00040000;
3786 | }
3787 |
3788 | return proto_tree_add_node(tree, new_fi);
3789 | }
3790 |
3791 | proto_item *
3792 | proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3793 | const unsigned start, unsigned length, const unsigned encoding, int64_t *retval)
3794 | {
3795 | header_field_info *hfinfo;
3796 | field_info *new_fi;
3797 | int64_t value;
3798 |
3799 | 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", 3799, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3799, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3799, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3800 |
3801 | switch (hfinfo->type) {
3802 | case FT_INT40:
3803 | case FT_INT48:
3804 | case FT_INT56:
3805 | case FT_INT64:
3806 | break;
3807 | default:
3808 | 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)
3809 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
3810 | }
3811 |
3812 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3813 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3814 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3815 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3816 | *retval = 0;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3817 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3818 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3819 |
3820 | if (encoding & ENC_STRING0x07000000) {
3821 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3822 | }
3823 | /* I believe it's ok if this is called with a NULL tree */
3824 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3825 | tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3826 | }
3827 | else {
3828 | value = get_int64_value(tree, tvb, start, length, encoding);
3829 | }
3830 |
3831 | if (retval) {
3832 | *retval = value;
3833 | }
3834 |
3835 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3836 |
3837 | 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", 3837 , __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", 3837, "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", 3837, "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", 3837, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3838 |
3839 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3840 |
3841 | proto_tree_set_int64(new_fi, value);
3842 |
3843 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3844 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3845 | new_fi->flags |= FI_VARINT0x00040000;
3846 | }
3847 |
3848 | return proto_tree_add_node(tree, new_fi);
3849 | }
3850 |
3851 | proto_item *
3852 | proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3853 | const unsigned start, unsigned length, const unsigned encoding, uint64_t *retval, unsigned *lenretval)
3854 | {
3855 | header_field_info *hfinfo;
3856 | field_info *new_fi;
3857 | uint64_t value;
3858 |
3859 | 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", 3859, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3859, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3859, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3860 |
3861 | 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 )))) {
3862 | 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)
3863 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT" , hfinfo->abbrev);
3864 | }
3865 |
3866 | if (!(encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3867 | REPORT_DISSECTOR_BUG("Encoding must be a VARINT")proto_report_dissector_bug("Encoding must be a VARINT");
3868 | }
3869 |
3870 | if (encoding & ENC_STRING0x07000000) {
3871 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3872 | }
3873 |
3874 | /* tvb_get_varint clamps the max length to FT_VARINT_MAX_LEN (10)
3875 | * It also handles length 0, setting both return values to 0.
3876 | * XXX - Should the max length be affected by the field type and/or
3877 | * encoding, e.g. 5 for FT_[U]INT32?
3878 | * XXX - Should there be separate _varint and _varuint versions to
3879 | * avoid the changing the sign when casting the return value?
3880 | * XXX - Do we even need the length parameter? Every user of this
3881 | * function passes in -1 or FT_VARINT_MAX_LEN. We could have a
3882 | * separate function, but unlike some field types, variable length
3883 | * is the typical case here, not the exception, and the typical
3884 | * case should have the shorter, more convenient function name.
3885 | * Having the length makes the signature more similar to other
3886 | * functions, though. */
3887 | length = tvb_get_varint(tvb, start, length, &value, encoding);
3888 |
3889 | if (retval) {
3890 | *retval = value;
3891 | if (hfinfo->bitmask) {
3892 | /* Mask out irrelevant portions */
3893 | *retval &= hfinfo->bitmask;
3894 | /* Shift bits */
3895 | *retval >>= hfinfo_bitshift(hfinfo);
3896 | }
3897 | }
3898 |
3899 | if (lenretval) {
3900 | *lenretval = length;
3901 | }
3902 |
3903 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3904 |
3905 | TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3905 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3905, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3905, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3905, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
3906 |
3907 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3908 |
3909 | proto_tree_set_uint64(new_fi, value);
3910 |
3911 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3912 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3913 | new_fi->flags |= FI_VARINT0x00040000;
3914 | }
3915 |
3916 | return proto_tree_add_node(tree, new_fi);
3917 |
3918 | }
3919 |
3920 | proto_item *
3921 | proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3922 | const unsigned start, unsigned length,
3923 | const unsigned encoding, bool_Bool *retval)
3924 | {
3925 | header_field_info *hfinfo;
3926 | field_info *new_fi;
3927 | uint64_t value, bitval;
3928 |
3929 | PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 3929, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3929, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3929, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3930 |
3931 | if (hfinfo->type != FT_BOOLEAN) {
3932 | 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)
3933 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3934 | }
3935 |
3936 | CHECK_FOR_ZERO_LENGTH_AND_CLEANUP(length,if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3937 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3938 | if(retval)if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3939 | {if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3940 | *retval = false;if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3941 | }if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); }
3942 | } )if (length == 0) { { if(retval) { *retval = 0; } }; return (( void*)0); };
3943 |
3944 | if (encoding & ENC_STRING0x07000000) {
3945 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3946 | }
3947 | /* I believe it's ok if this is called with a NULL tree */
3948 | value = get_uint64_value(tree, tvb, start, length, encoding);
3949 |
3950 | if (retval) {
3951 | bitval = value;
3952 | if (hfinfo->bitmask) {
3953 | /* Mask out irrelevant portions */
3954 | bitval &= hfinfo->bitmask;
3955 | }
3956 | *retval = (bitval != 0);
3957 | }
3958 |
3959 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3960 |
3961 | TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3961 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3961, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3961, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3961, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
3962 |
3963 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3964 |
3965 | proto_tree_set_boolean(new_fi, value);
3966 |
3967 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3968 |
3969 | return proto_tree_add_node(tree, new_fi);
3970 | }
3971 |
3972 | proto_item *
3973 | proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3974 | const unsigned start, unsigned length,
3975 | const unsigned encoding, float *retval)
3976 | {
3977 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3978 | field_info *new_fi;
3979 | float value;
3980 |
3981 | 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", 3981, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3982 |
3983 | if (hfinfo->type != FT_FLOAT) {
3984 | 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);
3985 | }
3986 |
3987 | if (length != 4) {
3988 | report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3989 | }
3990 |
3991 | /* treat any nonzero encoding as little endian for backwards compatibility */
3992 | value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3993 | if (retval) {
3994 | *retval = value;
3995 | }
3996 |
3997 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3998 |
3999 | TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3999 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3999, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3999, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 3999, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4000 |
4001 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4002 | if (encoding) {
4003 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4004 | }
4005 |
4006 | proto_tree_set_float(new_fi, value);
4007 |
4008 | return proto_tree_add_node(tree, new_fi);
4009 | }
4010 |
4011 | proto_item *
4012 | proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4013 | const unsigned start, unsigned length,
4014 | const unsigned encoding, double *retval)
4015 | {
4016 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4017 | field_info *new_fi;
4018 | double value;
4019 |
4020 | 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", 4020, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4021 |
4022 | if (hfinfo->type != FT_DOUBLE) {
4023 | 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);
4024 | }
4025 |
4026 | if (length != 8) {
4027 | report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4028 | }
4029 |
4030 | /* treat any nonzero encoding as little endian for backwards compatibility */
4031 | value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4032 | if (retval) {
4033 | *retval = value;
4034 | }
4035 |
4036 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4037 |
4038 | 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", 4038 , __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", 4038, "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", 4038, "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", 4038, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4039 |
4040 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4041 | if (encoding) {
4042 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4043 | }
4044 |
4045 | proto_tree_set_double(new_fi, value);
4046 |
4047 | return proto_tree_add_node(tree, new_fi);
4048 | }
4049 |
4050 | proto_item *
4051 | proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4052 | const unsigned start, unsigned length,
4053 | const unsigned encoding, ws_in4_addr *retval)
4054 | {
4055 | header_field_info *hfinfo;
4056 | field_info *new_fi;
4057 | ws_in4_addr value;
4058 |
4059 | 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", 4059, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4059, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4059, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4060 |
4061 | switch (hfinfo->type) {
4062 | case FT_IPv4:
4063 | break;
4064 | default:
4065 | 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)
4066 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4", hfinfo->abbrev);
4067 | }
4068 |
4069 | if (length != FT_IPv4_LEN4)
4070 | 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)
4071 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4" , length);
4072 |
4073 | if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4074 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4075 | }
4076 |
4077 | /*
4078 | * NOTE: to support code written when proto_tree_add_item() took
4079 | * a bool as its last argument, with false meaning "big-endian"
4080 | * and true meaning "little-endian", we treat any non-zero value
4081 | * of "encoding" as meaning "little-endian".
4082 | */
4083 | value = tvb_get_ipv4(tvb, start);
4084 | if (encoding)
4085 | 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))));
4086 |
4087 | if (retval) {
4088 | *retval = value;
4089 | }
4090 |
4091 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4092 |
4093 | 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", 4093 , __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", 4093, "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", 4093, "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", 4093, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4094 |
4095 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4096 |
4097 | proto_tree_set_ipv4(new_fi, value);
4098 |
4099 | new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4100 | return proto_tree_add_node(tree, new_fi);
4101 | }
4102 |
4103 | proto_item *
4104 | proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4105 | const unsigned start, unsigned length,
4106 | const unsigned encoding, ws_in6_addr *addr)
4107 | {
4108 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4109 | field_info *new_fi;
4110 |
4111 | 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", 4111, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4112 |
4113 | switch (hfinfo->type) {
4114 | case FT_IPv6:
4115 | break;
4116 | default:
4117 | 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)
4118 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6", hfinfo->abbrev);
4119 | }
4120 |
4121 | if (length != FT_IPv6_LEN16)
4122 | 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)
4123 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6" , length);
4124 |
4125 | if (encoding) {
4126 | 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" );
4127 | }
4128 |
4129 | tvb_get_ipv6(tvb, start, addr);
4130 |
4131 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4132 |
4133 | 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", 4133 , __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", 4133, "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", 4133, "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", 4133, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4134 |
4135 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4136 |
4137 | proto_tree_set_ipv6(new_fi, addr);
4138 |
4139 | return proto_tree_add_node(tree, new_fi);
4140 | }
4141 |
4142 | proto_item *
4143 | proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4144 | const unsigned start, unsigned length, const unsigned encoding, uint8_t *retval) {
4145 |
4146 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4147 | field_info *new_fi;
4148 |
4149 | 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", 4149, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4150 |
4151 | switch (hfinfo->type) {
4152 | case FT_ETHER:
4153 | break;
4154 | default:
4155 | 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)
4156 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER" , hfinfo->abbrev);
4157 | }
4158 |
4159 | if (length != FT_ETHER_LEN6)
4160 | 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)
4161 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether" , length);
4162 |
4163 | if (encoding) {
4164 | 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" );
4165 | }
4166 |
4167 | tvb_memcpy(tvb, retval, start, length);
4168 |
4169 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4170 |
4171 | 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", 4171 , __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", 4171, "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", 4171, "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", 4171, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4172 |
4173 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4174 |
4175 | proto_tree_set_ether(new_fi, retval);
4176 |
4177 | return proto_tree_add_node(tree, new_fi);
4178 | }
4179 |
4180 |
4181 | proto_item *
4182 | proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4183 | tvbuff_t *tvb,
4184 | const unsigned start, int length,
4185 | const unsigned encoding,
4186 | wmem_allocator_t *scope,
4187 | const uint8_t **retval,
4188 | unsigned *lenretval)
4189 | {
4190 | proto_item *pi;
4191 | header_field_info *hfinfo;
4192 | field_info *new_fi;
4193 | const uint8_t *value;
4194 |
4195 | 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", 4195, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4195, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4195, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4196 |
4197 | switch (hfinfo->type) {
4198 | case FT_STRING:
4199 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4200 | break;
4201 | case FT_STRINGZ:
4202 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4203 | break;
4204 | case FT_UINT_STRING:
4205 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4206 | break;
4207 | case FT_STRINGZPAD:
4208 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4209 | break;
4210 | case FT_STRINGZTRUNC:
4211 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4212 | break;
4213 | default:
4214 | 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)
4215 | 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);
4216 | }
4217 |
4218 | if (retval)
4219 | *retval = value;
4220 |
4221 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4222 |
4223 | 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", 4223 , __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", 4223, "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", 4223, "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", 4223, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4224 |
4225 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4226 |
4227 | proto_tree_set_string(new_fi, (const char*)value);
4228 |
4229 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4230 |
4231 | pi = proto_tree_add_node(tree, new_fi);
4232 |
4233 | switch (hfinfo->type) {
4234 |
4235 | case FT_STRINGZ:
4236 | case FT_STRINGZPAD:
4237 | case FT_STRINGZTRUNC:
4238 | case FT_UINT_STRING:
4239 | break;
4240 |
4241 | case FT_STRING:
4242 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4243 | break;
4244 |
4245 | default:
4246 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4246 , __func__, "assertion \"not reached\" failed");
4247 | }
4248 |
4249 | return pi;
4250 | }
4251 |
4252 | proto_item *
4253 | proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4254 | const unsigned start, int length,
4255 | const unsigned encoding, wmem_allocator_t *scope,
4256 | const uint8_t **retval)
4257 | {
4258 | unsigned item_length; // Param cannot be NULL in function below
4259 | return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4260 | tvb, start, length, encoding, scope, retval, &item_length);
4261 | }
4262 |
4263 | proto_item *
4264 | proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4265 | tvbuff_t *tvb,
4266 | const unsigned start, int length,
4267 | const unsigned encoding,
4268 | wmem_allocator_t *scope,
4269 | char **retval,
4270 | unsigned *lenretval)
4271 | {
4272 | proto_item *pi;
4273 | header_field_info *hfinfo;
4274 | field_info *new_fi;
4275 | const uint8_t *value;
4276 | uint32_t n = 0;
4277 |
4278 | 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", 4278, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4278, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4278, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4279 |
4280 | switch (hfinfo->type) {
4281 | case FT_STRING:
4282 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4283 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4284 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4285 | break;
4286 | case FT_STRINGZ:
4287 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4288 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4289 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4290 | break;
4291 | case FT_UINT_STRING:
4292 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4293 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4294 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4295 | break;
4296 | case FT_STRINGZPAD:
4297 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4298 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4299 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4300 | break;
4301 | case FT_STRINGZTRUNC:
4302 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4303 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4304 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4305 | break;
4306 | case FT_BYTES:
4307 | tvb_ensure_bytes_exist(tvb, start, length);
4308 | value = tvb_get_ptr(tvb, start, length);
4309 | *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4310 | *lenretval = length;
4311 | break;
4312 | case FT_UINT_BYTES:
4313 | n = get_uint_value(tree, tvb, start, length, encoding);
4314 | tvb_ensure_bytes_exist(tvb, start + length, n);
4315 | value = tvb_get_ptr(tvb, start + length, n);
4316 | *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4317 | *lenretval = length + n;
4318 | break;
4319 | default:
4320 | 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)
4321 | 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);
4322 | }
4323 |
4324 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4325 |
4326 | 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", 4326 , __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", 4326, "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", 4326, "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", 4326, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4327 |
4328 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4329 |
4330 | switch (hfinfo->type) {
4331 |
4332 | case FT_STRING:
4333 | case FT_STRINGZ:
4334 | case FT_UINT_STRING:
4335 | case FT_STRINGZPAD:
4336 | case FT_STRINGZTRUNC:
4337 | proto_tree_set_string(new_fi, (const char*)value);
4338 | break;
4339 |
4340 | case FT_BYTES:
4341 | proto_tree_set_bytes(new_fi, value, length);
4342 | break;
4343 |
4344 | case FT_UINT_BYTES:
4345 | proto_tree_set_bytes(new_fi, value, n);
4346 | break;
4347 |
4348 | default:
4349 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4349 , __func__, "assertion \"not reached\" failed");
4350 | }
4351 |
4352 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4353 |
4354 | pi = proto_tree_add_node(tree, new_fi);
4355 |
4356 | switch (hfinfo->type) {
4357 |
4358 | case FT_STRINGZ:
4359 | case FT_STRINGZPAD:
4360 | case FT_STRINGZTRUNC:
4361 | case FT_UINT_STRING:
4362 | break;
4363 |
4364 | case FT_STRING:
4365 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4366 | break;
4367 |
4368 | case FT_BYTES:
4369 | case FT_UINT_BYTES:
4370 | break;
4371 |
4372 | default:
4373 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4373 , __func__, "assertion \"not reached\" failed");
4374 | }
4375 |
4376 | return pi;
4377 | }
4378 |
4379 | proto_item *
4380 | proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4381 | tvbuff_t *tvb,
4382 | const unsigned start, int length,
4383 | const unsigned encoding,
4384 | wmem_allocator_t *scope,
4385 | char **retval)
4386 | {
4387 | unsigned item_length; // Param cannot be NULL in function below
4388 | return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4389 | tvb, start, length, encoding, scope, retval, &item_length);
4390 | }
4391 |
4392 | proto_item *
4393 | proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4394 | tvbuff_t *tvb,
4395 | const unsigned start, int length, const unsigned encoding,
4396 | wmem_allocator_t *scope, char **retval)
4397 | {
4398 | header_field_info *hfinfo;
4399 | field_info *new_fi;
4400 | nstime_t time_stamp;
4401 | int flags;
4402 |
4403 | 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", 4403, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4403, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4403, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4404 |
4405 | switch (hfinfo->type) {
4406 | case FT_ABSOLUTE_TIME:
4407 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4408 | flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4409 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4410 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4411 | }
4412 | *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4413 | break;
4414 | case FT_RELATIVE_TIME:
4415 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4416 | *retval = rel_time_to_secs_str(scope, &time_stamp);
4417 | break;
4418 | default:
4419 | 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)
4420 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME" , hfinfo->abbrev);
4421 | }
4422 |
4423 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4424 |
4425 | 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", 4425 , __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", 4425, "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", 4425, "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", 4425, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4426 |
4427 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4428 |
4429 | switch (hfinfo->type) {
4430 |
4431 | case FT_ABSOLUTE_TIME:
4432 | case FT_RELATIVE_TIME:
4433 | proto_tree_set_time(new_fi, &time_stamp);
4434 | break;
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 | return proto_tree_add_node(tree, new_fi);
4442 | }
4443 |
4444 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
4445 | and returns proto_item* */
4446 | proto_item *
4447 | ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4448 | const unsigned encoding)
4449 | {
4450 | field_info *new_fi;
4451 | header_field_info *hfinfo;
4452 | int item_length;
4453 | unsigned offset;
4454 |
4455 | offset = ptvc->offset;
4456 | 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", 4456, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4456, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4456, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4457 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4458 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4459 |
4460 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4461 |
4462 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4463 |
4464 | /* Coast clear. Try and fake it */
4465 | 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", 4465 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4465, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4465, "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", 4465, __func__, "Adding %s would put more than %d 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); } } };
4466 |
4467 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4468 |
4469 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4470 | offset, length, encoding);
4471 | }
4472 |
4473 | /* Add an item to a proto_tree, using the text label registered to that item;
4474 | the item is extracted from the tvbuff handed to it. */
4475 | proto_item *
4476 | proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4477 | const unsigned start, int length, const unsigned encoding)
4478 | {
4479 | field_info *new_fi;
4480 | int item_length;
4481 |
4482 | 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", 4482, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4483 |
4484 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4485 | test_length(hfinfo, tvb, start, item_length, encoding);
4486 |
4487 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4488 |
4489 | 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", 4489 , __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", 4489, "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", 4489, "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", 4489, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4490 |
4491 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4492 |
4493 | return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4494 | }
4495 |
4496 | proto_item *
4497 | proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4498 | const unsigned start, int length, const unsigned encoding)
4499 | {
4500 | register header_field_info *hfinfo;
4501 |
4502 | 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", 4502, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4502, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4502, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4503 | return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4504 | }
4505 |
4506 | /* Add an item to a proto_tree, using the text label registered to that item;
4507 | the item is extracted from the tvbuff handed to it.
4508 |
4509 | Return the length of the item through the pointer. */
4510 | proto_item *
4511 | proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4512 | tvbuff_t *tvb, const unsigned start,
4513 | int length, const unsigned encoding,
4514 | unsigned *lenretval)
4515 | {
4516 | field_info *new_fi;
4517 | int item_length;
4518 | proto_item *item;
4519 |
4520 | 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", 4520, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4521 |
4522 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4523 | test_length(hfinfo, tvb, start, item_length, encoding);
4524 |
4525 | if (!tree) {
4526 | /*
4527 | * We need to get the correct item length here.
4528 | * That's normally done by proto_tree_new_item(),
4529 | * but we won't be calling it.
4530 | */
4531 | *lenretval = get_full_length(hfinfo, tvb, start, length,
4532 | item_length, encoding);
4533 | return NULL((void*)0);
4534 | }
4535 |
4536 | TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfinfo->id, hfinfo, {((tree)->tree_data)->count++; if((hfinfo->id == 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4543 , __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", 4543, "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", 4543, "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", 4543 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4537 | /*((tree)->tree_data)->count++; if((hfinfo->id == 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4543 , __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", 4543, "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", 4543, "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", 4543 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4538 | * 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", 4543 , __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", 4543, "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", 4543, "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", 4543 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4539 | * 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", 4543 , __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", 4543, "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", 4543, "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", 4543 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4540 | */((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", 4543 , __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", 4543, "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", 4543, "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", 4543 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4541 | *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", 4543 , __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", 4543, "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", 4543, "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", 4543 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4542 | 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", 4543 , __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", 4543, "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", 4543, "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", 4543 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4543 | })((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", 4543 , __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", 4543, "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", 4543, "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", 4543 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } };
4544 |
4545 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4546 |
4547 | item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4548 | *lenretval = new_fi->length;
4549 | return item;
4550 | }
4551 |
4552 | proto_item *
4553 | proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4554 | const unsigned start, int length,
4555 | const unsigned encoding, unsigned *lenretval)
4556 | {
4557 | register header_field_info *hfinfo;
4558 |
4559 | 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", 4559, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4559, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4559, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4560 | return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4561 | }
4562 |
4563 | /* which FT_ types can use proto_tree_add_bytes_item() */
4564 | static inline bool_Bool
4565 | validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4566 | {
4567 | return (type == FT_BYTES ||
4568 | type == FT_UINT_BYTES ||
4569 | type == FT_OID ||
4570 | type == FT_REL_OID ||
4571 | type == FT_SYSTEM_ID );
4572 | }
4573 |
4574 | /* Note: this does no validation that the byte array of an FT_OID or
4575 | FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4576 | so I think it's ok to continue not validating it?
4577 | */
4578 | proto_item *
4579 | proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4580 | const unsigned start, unsigned length,
4581 | const unsigned encoding,
4582 | GByteArray *retval, unsigned *endoff, int *err)
4583 | {
4584 | field_info *new_fi;
4585 | GByteArray *bytes = retval;
4586 | GByteArray *created_bytes = NULL((void*)0);
4587 | bool_Bool failed = false0;
4588 | uint32_t n = 0;
4589 | header_field_info *hfinfo;
4590 | bool_Bool generate = (bytes || tree) ? true1 : false0;
4591 |
4592 | 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", 4592, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4592, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4592, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4593 |
4594 | 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", 4594, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4595 |
4596 | 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", 4597, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))))
4597 | "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", 4597, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))));
4598 |
4599 | if (length == 0) {
4600 | return NULL((void*)0);
4601 | }
4602 |
4603 | if (encoding & ENC_STR_NUM0x01000000) {
4604 | 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" );
4605 | }
4606 |
4607 | if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4608 | if (hfinfo->type == FT_UINT_BYTES) {
4609 | /* can't decode FT_UINT_BYTES from strings */
4610 | 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")
4611 | "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");
4612 | }
4613 |
4614 | unsigned hex_encoding = encoding;
4615 | if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4616 | /* If none of the separator values are used,
4617 | * assume no separator (the common case). */
4618 | hex_encoding |= ENC_SEP_NONE0x00010000;
4619 | #if 0
4620 | 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")
4621 | "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");
4622 | #endif
4623 | }
4624 |
4625 | if (!bytes) {
4626 | /* caller doesn't care about return value, but we need it to
4627 | call tvb_get_string_bytes() and set the tree later */
4628 | bytes = created_bytes = g_byte_array_new();
4629 | }
4630 |
4631 | /*
4632 | * bytes might be NULL after this, but can't add expert
4633 | * error until later; if it's NULL, just note that
4634 | * it failed.
4635 | */
4636 | bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4637 | if (bytes == NULL((void*)0))
4638 | failed = true1;
4639 | }
4640 | else if (generate) {
4641 | tvb_ensure_bytes_exist(tvb, start, length);
4642 |
4643 | if (hfinfo->type == FT_UINT_BYTES) {
4644 | n = length; /* n is now the "header" length */
4645 | length = get_uint_value(tree, tvb, start, n, encoding);
4646 | /* length is now the value's length; only store the value in the array */
4647 | tvb_ensure_bytes_exist(tvb, start + n, length);
4648 | if (!bytes) {
4649 | /* caller doesn't care about return value, but
4650 | * we may need it to set the tree later */
4651 | bytes = created_bytes = g_byte_array_new();
4652 | }
4653 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4654 | }
4655 | else if (length > 0) {
4656 | if (!bytes) {
4657 | /* caller doesn't care about return value, but
4658 | * we may need it to set the tree later */
4659 | bytes = created_bytes = g_byte_array_new();
4660 | }
4661 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4662 | }
4663 |
4664 | if (endoff)
4665 | *endoff = start + n + length;
4666 | }
4667 |
4668 | if (err)
4669 | *err = failed ? EINVAL22 : 0;
4670 |
4671 | 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); }
4672 | {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4673 | 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); }
4674 | 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); }
4675 | 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); }
4676 | bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4677 | } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); };
4678 |
4679 | 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", 4685 , __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", 4685, "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", 4685, "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", 4685 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4680 | {((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", 4685 , __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", 4685, "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", 4685, "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", 4685 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4681 | 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", 4685 , __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", 4685, "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", 4685, "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", 4685 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4682 | 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", 4685 , __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", 4685, "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", 4685, "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", 4685 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4683 | 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", 4685 , __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", 4685, "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", 4685, "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", 4685 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4684 | 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", 4685 , __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", 4685, "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", 4685, "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", 4685 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4685 | } )((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", 4685 , __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", 4685, "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", 4685, "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", 4685 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } };
4686 |
4687 | /* n will be zero except when it's a FT_UINT_BYTES */
4688 | new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4689 |
4690 | if (encoding & ENC_STRING0x07000000) {
4691 | if (failed)
4692 | expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4693 |
4694 | if (bytes)
4695 | proto_tree_set_bytes_gbytearray(new_fi, bytes);
4696 | else
4697 | proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4698 |
4699 | if (created_bytes)
4700 | g_byte_array_free(created_bytes, true1);
4701 | }
4702 | else {
4703 | /* n will be zero except when it's a FT_UINT_BYTES */
4704 | proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4705 |
4706 | /* XXX: If we have a non-NULL tree but NULL retval, we don't
4707 | * use the byte array created above in this case.
4708 | */
4709 | if (created_bytes)
4710 | g_byte_array_free(created_bytes, true1);
4711 |
4712 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4713 | (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);
4714 | }
4715 |
4716 | return proto_tree_add_node(tree, new_fi);
4717 | }
4718 |
4719 |
4720 | proto_item *
4721 | proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4722 | const unsigned start, const unsigned length,
4723 | const unsigned encoding,
4724 | nstime_t *retval, unsigned *endoff, int *err)
4725 | {
4726 | field_info *new_fi;
4727 | nstime_t time_stamp;
4728 | int saved_err = 0;
4729 | header_field_info *hfinfo;
4730 |
4731 | 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", 4731, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4731, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4731, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4732 |
4733 | 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", 4733, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4734 |
4735 | if (length == 0) {
4736 | if(retval) {
4737 | nstime_set_zero(retval);
4738 | }
4739 | return NULL((void*)0);
4740 | }
4741 |
4742 | nstime_set_zero(&time_stamp);
4743 |
4744 | if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4745 | 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", 4745, ((hfinfo))->abbrev))));
4746 | /* The only string format that could be a relative time is
4747 | * ENC_ISO_8601_TIME, and that is treated as an absolute time
4748 | * relative to "now" currently.
4749 | */
4750 | if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4751 | saved_err = EINVAL22;
4752 | }
4753 | else {
4754 | 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", 4754, ((hfinfo))->abbrev))));
4755 | const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4756 |
4757 | tvb_ensure_bytes_exist(tvb, start, length);
4758 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4759 | if (endoff) *endoff = start + length;
4760 | }
4761 |
4762 | if (err) *err = saved_err;
4763 |
4764 | if (retval) {
4765 | retval->secs = time_stamp.secs;
4766 | retval->nsecs = time_stamp.nsecs;
4767 | }
4768 |
4769 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4770 |
4771 | 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", 4771 , __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", 4771, "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", 4771, "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", 4771, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4772 |
4773 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4774 |
4775 | proto_tree_set_time(new_fi, &time_stamp);
4776 |
4777 | if (encoding & ENC_STRING0x07000000) {
4778 | if (saved_err)
4779 | expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4780 | }
4781 | else {
4782 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4783 | (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);
4784 | }
4785 |
4786 | return proto_tree_add_node(tree, new_fi);
4787 | }
4788 |
4789 | /* Add a FT_NONE to a proto_tree */
4790 | proto_item *
4791 | proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4792 | const unsigned start, int length, const char *format,
4793 | ...)
4794 | {
4795 | proto_item *pi;
4796 | va_list ap;
4797 | header_field_info *hfinfo;
4798 |
4799 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4800 |
4801 | 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", 4801 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4801, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4801, "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", 4801, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4802 |
4803 | 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", 4803 , ((hfinfo))->abbrev))));
4804 |
4805 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4806 |
4807 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4807, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4808 |
4809 | va_start(ap, format)__builtin_va_start(ap, format);
4810 | proto_tree_set_representation(pi, format, ap);
4811 | va_end(ap)__builtin_va_end(ap);
4812 |
4813 | /* no value to set for FT_NONE */
4814 | return pi;
4815 | }
4816 |
4817 | /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4818 | * offset, and returns proto_item* */
4819 | proto_item *
4820 | ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4821 | const unsigned encoding)
4822 | {
4823 | proto_item *item;
4824 |
4825 | item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4826 | length, encoding);
4827 |
4828 | return item;
4829 | }
4830 |
4831 | /* Advance the ptvcursor's offset within its tvbuff without
4832 | * adding anything to the proto_tree. */
4833 | void
4834 | ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4835 | {
4836 | if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc ->offset))) {
4837 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4838 | }
4839 | }
4840 |
4841 |
4842 | static void
4843 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4844 | {
4845 | ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full( "Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4845, __func__, "assertion failed: %s" , "length >= 0"); } while (0);
4846 | fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4847 | }
4848 |
4849 | /* Add a FT_PROTOCOL to a proto_tree */
4850 | proto_item *
4851 | proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4852 | unsigned start, int length, const char *format, ...)
4853 | {
4854 | proto_item *pi;
4855 | field_info *new_fi;
4856 | tvbuff_t *protocol_tvb;
4857 | va_list ap;
4858 | header_field_info *hfinfo;
4859 | char* protocol_rep;
4860 |
4861 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4862 |
4863 | 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", 4863 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4863, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4863, "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", 4863, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4864 |
4865 | 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" , 4865, ((hfinfo))->abbrev))));
4866 |
4867 | /*
4868 | * This can throw an exception when it calls get_hfi_length before
4869 | * it allocates anything, if length is nonzero and start is past
4870 | * the end of the tvb. Afterwards it can't throw an exception,
4871 | * as length is clamped to the captured length remaining.
4872 | */
4873 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4874 | new_fi = PNODE_FINFO(pi)((pi)->finfo);
4875 | /* Start the protocol_tvb at the correct start offset, but allow it
4876 | * to be lengthened later via finfo_set_len. */
4877 | protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4878 |
4879 | va_start(ap, format)__builtin_va_start(ap, format);
4880 | protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4881 | proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4882 | 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);
4883 | va_end(ap)__builtin_va_end(ap);
4884 |
4885 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4885, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4886 |
4887 | va_start(ap, format)__builtin_va_start(ap, format);
4888 | proto_tree_set_representation(pi, format, ap);
4889 | va_end(ap)__builtin_va_end(ap);
4890 |
4891 | return pi;
4892 | }
4893 |
4894 | /* Add a FT_BYTES to a proto_tree */
4895 | proto_item *
4896 | proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4897 | int length, const uint8_t *start_ptr)
4898 | {
4899 | proto_item *pi;
4900 | header_field_info *hfinfo;
4901 | int item_length;
4902 |
4903 | 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", 4903, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4903, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4903, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4904 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4905 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4906 |
4907 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4908 |
4909 | 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", 4909 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4909, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4909, "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", 4909, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4910 |
4911 | 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", 4911, ((hfinfo))->abbrev))));
4912 |
4913 | if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4914 | start_ptr = tvb_get_ptr(tvb, start, length);
4915 |
4916 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4917 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4918 |
4919 | return pi;
4920 | }
4921 |
4922 | /* Add a FT_BYTES to a proto_tree */
4923 | proto_item *
4924 | proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4925 | int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4926 | {
4927 | proto_item *pi;
4928 | header_field_info *hfinfo;
4929 | int item_length;
4930 |
4931 | 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", 4931, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4931, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4931, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4932 | get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4933 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4934 |
4935 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4936 |
4937 | 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", 4937 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4937, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4937, "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", 4937, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4938 |
4939 | 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", 4939, ((hfinfo))->abbrev))));
4940 |
4941 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4942 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4943 |
4944 | return pi;
4945 | }
4946 |
4947 | proto_item *
4948 | proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4949 | unsigned start, int length,
4950 | const uint8_t *start_ptr,
4951 | const char *format, ...)
4952 | {
4953 | proto_item *pi;
4954 | va_list ap;
4955 |
4956 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4957 |
4958 | 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; };
4959 |
4960 | va_start(ap, format)__builtin_va_start(ap, format);
4961 | proto_tree_set_representation_value(pi, format, ap);
4962 | va_end(ap)__builtin_va_end(ap);
4963 |
4964 | return pi;
4965 | }
4966 |
4967 | proto_item *
4968 | proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4969 | unsigned start, int length, const uint8_t *start_ptr,
4970 | const char *format, ...)
4971 | {
4972 | proto_item *pi;
4973 | va_list ap;
4974 |
4975 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4976 |
4977 | 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; };
4978 |
4979 | va_start(ap, format)__builtin_va_start(ap, format);
4980 | proto_tree_set_representation(pi, format, ap);
4981 | va_end(ap)__builtin_va_end(ap);
4982 |
4983 | return pi;
4984 | }
4985 |
4986 | static void
4987 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4988 | {
4989 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4989, "length >= 0" ))));
4990 | 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", 4990, "start_ptr != ((void*)0) || length == 0" ))));
4991 |
4992 | fvalue_set_bytes_data(fi->value, start_ptr, length);
4993 | }
4994 |
4995 |
4996 | static void
4997 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
4998 | {
4999 | tvb_ensure_bytes_exist(tvb, offset, length);
5000 | proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
5001 | }
5002 |
5003 | static void
5004 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
5005 | {
5006 | GByteArray *bytes;
5007 |
5008 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5008, "value != ((void*)0)" ))));
5009 |
5010 | bytes = byte_array_dup(value);
5011 |
5012 | fvalue_set_byte_array(fi->value, bytes);
5013 | }
5014 |
5015 | /* Add a FT_*TIME to a proto_tree */
5016 | proto_item *
5017 | proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5018 | unsigned length, const nstime_t *value_ptr)
5019 | {
5020 | proto_item *pi;
5021 | header_field_info *hfinfo;
5022 |
5023 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5024 |
5025 | 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", 5025 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5025, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5025, "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", 5025, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5026 |
5027 | 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", 5027, ((hfinfo))->abbrev))));
5028 |
5029 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5030 | proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5031 |
5032 | return pi;
5033 | }
5034 |
5035 | proto_item *
5036 | proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5037 | unsigned start, unsigned length, nstime_t *value_ptr,
5038 | const char *format, ...)
5039 | {
5040 | proto_item *pi;
5041 | va_list ap;
5042 |
5043 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5044 | if (pi != tree) {
5045 | va_start(ap, format)__builtin_va_start(ap, format);
5046 | proto_tree_set_representation_value(pi, format, ap);
5047 | va_end(ap)__builtin_va_end(ap);
5048 | }
5049 |
5050 | return pi;
5051 | }
5052 |
5053 | proto_item *
5054 | proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5055 | unsigned start, unsigned length, nstime_t *value_ptr,
5056 | const char *format, ...)
5057 | {
5058 | proto_item *pi;
5059 | va_list ap;
5060 |
5061 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5062 | if (pi != tree) {
5063 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5063, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5064 |
5065 | va_start(ap, format)__builtin_va_start(ap, format);
5066 | proto_tree_set_representation(pi, format, ap);
5067 | va_end(ap)__builtin_va_end(ap);
5068 | }
5069 |
5070 | return pi;
5071 | }
5072 |
5073 | /* Set the FT_*TIME value */
5074 | static void
5075 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5076 | {
5077 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5077, "value_ptr != ((void*)0)" ))));
5078 |
5079 | fvalue_set_time(fi->value, value_ptr);
5080 | }
5081 |
5082 | /* Add a FT_IPXNET to a proto_tree */
5083 | proto_item *
5084 | proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5085 | unsigned length, uint32_t value)
5086 | {
5087 | proto_item *pi;
5088 | header_field_info *hfinfo;
5089 |
5090 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5091 |
5092 | 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", 5092 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5092, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5092, "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", 5092, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5093 |
5094 | 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" , 5094, ((hfinfo))->abbrev))));
5095 |
5096 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5097 | proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5098 |
5099 | return pi;
5100 | }
5101 |
5102 | proto_item *
5103 | proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5104 | unsigned start, unsigned length, uint32_t value,
5105 | const char *format, ...)
5106 | {
5107 | proto_item *pi;
5108 | va_list ap;
5109 |
5110 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5111 | if (pi != tree) {
5112 | va_start(ap, format)__builtin_va_start(ap, format);
5113 | proto_tree_set_representation_value(pi, format, ap);
5114 | va_end(ap)__builtin_va_end(ap);
5115 | }
5116 |
5117 | return pi;
5118 | }
5119 |
5120 | proto_item *
5121 | proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5122 | unsigned start, unsigned length, uint32_t value,
5123 | const char *format, ...)
5124 | {
5125 | proto_item *pi;
5126 | va_list ap;
5127 |
5128 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5129 | if (pi != tree) {
5130 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5130, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5131 |
5132 | va_start(ap, format)__builtin_va_start(ap, format);
5133 | proto_tree_set_representation(pi, format, ap);
5134 | va_end(ap)__builtin_va_end(ap);
5135 | }
5136 |
5137 | return pi;
5138 | }
5139 |
5140 | /* Set the FT_IPXNET value */
5141 | static void
5142 | proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5143 | {
5144 | fvalue_set_uinteger(fi->value, value);
5145 | }
5146 |
5147 | /* Add a FT_IPv4 to a proto_tree */
5148 | proto_item *
5149 | proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5150 | unsigned length, ws_in4_addr value)
5151 | {
5152 | proto_item *pi;
5153 | header_field_info *hfinfo;
5154 |
5155 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5156 |
5157 | 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", 5157 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5157, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5157, "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", 5157, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5158 |
5159 | 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", 5159 , ((hfinfo))->abbrev))));
5160 |
5161 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5162 | proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5163 |
5164 | return pi;
5165 | }
5166 |
5167 | proto_item *
5168 | proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5169 | unsigned start, unsigned length, ws_in4_addr value,
5170 | const char *format, ...)
5171 | {
5172 | proto_item *pi;
5173 | va_list ap;
5174 |
5175 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5176 | if (pi != tree) {
5177 | va_start(ap, format)__builtin_va_start(ap, format);
5178 | proto_tree_set_representation_value(pi, format, ap);
5179 | va_end(ap)__builtin_va_end(ap);
5180 | }
5181 |
5182 | return pi;
5183 | }
5184 |
5185 | proto_item *
5186 | proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5187 | unsigned start, unsigned length, ws_in4_addr value,
5188 | const char *format, ...)
5189 | {
5190 | proto_item *pi;
5191 | va_list ap;
5192 |
5193 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5194 | if (pi != tree) {
5195 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5195, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5196 |
5197 | va_start(ap, format)__builtin_va_start(ap, format);
5198 | proto_tree_set_representation(pi, format, ap);
5199 | va_end(ap)__builtin_va_end(ap);
5200 | }
5201 |
5202 | return pi;
5203 | }
5204 |
5205 | /* Set the FT_IPv4 value */
5206 | static void
5207 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5208 | {
5209 | ipv4_addr_and_mask ipv4;
5210 | ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5211 | fvalue_set_ipv4(fi->value, &ipv4);
5212 | }
5213 |
5214 | /* Add a FT_IPv6 to a proto_tree */
5215 | proto_item *
5216 | proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5217 | unsigned length, const ws_in6_addr *value)
5218 | {
5219 | proto_item *pi;
5220 | header_field_info *hfinfo;
5221 |
5222 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5223 |
5224 | 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", 5224 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5224, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5224, "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", 5224, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5225 |
5226 | 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", 5226 , ((hfinfo))->abbrev))));
5227 |
5228 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5229 | proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5230 |
5231 | return pi;
5232 | }
5233 |
5234 | proto_item *
5235 | proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5236 | unsigned start, unsigned length,
5237 | const ws_in6_addr *value_ptr,
5238 | const char *format, ...)
5239 | {
5240 | proto_item *pi;
5241 | va_list ap;
5242 |
5243 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5244 | if (pi != tree) {
5245 | va_start(ap, format)__builtin_va_start(ap, format);
5246 | proto_tree_set_representation_value(pi, format, ap);
5247 | va_end(ap)__builtin_va_end(ap);
5248 | }
5249 |
5250 | return pi;
5251 | }
5252 |
5253 | proto_item *
5254 | proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5255 | unsigned start, unsigned length,
5256 | const ws_in6_addr *value_ptr,
5257 | const char *format, ...)
5258 | {
5259 | proto_item *pi;
5260 | va_list ap;
5261 |
5262 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5263 | if (pi != tree) {
5264 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5264, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5265 |
5266 | va_start(ap, format)__builtin_va_start(ap, format);
5267 | proto_tree_set_representation(pi, format, ap);
5268 | va_end(ap)__builtin_va_end(ap);
5269 | }
5270 |
5271 | return pi;
5272 | }
5273 |
5274 | /* Set the FT_IPv6 value */
5275 | static void
5276 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5277 | {
5278 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5278, "value != ((void*)0)" ))));
5279 | ipv6_addr_and_prefix ipv6;
5280 | ipv6.addr = *value;
5281 | ipv6.prefix = 128;
5282 | fvalue_set_ipv6(fi->value, &ipv6);
5283 | }
5284 |
5285 | static void
5286 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5287 | {
5288 | proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5289 | }
5290 |
5291 | /* Set the FT_FCWWN value */
5292 | static void
5293 | proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5294 | {
5295 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5295, "value_ptr != ((void*)0)" ))));
5296 | fvalue_set_fcwwn(fi->value, value_ptr);
5297 | }
5298 |
5299 | static void
5300 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5301 | {
5302 | proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5303 | }
5304 |
5305 | /* Add a FT_GUID to a proto_tree */
5306 | proto_item *
5307 | proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5308 | unsigned length, const e_guid_t *value_ptr)
5309 | {
5310 | proto_item *pi;
5311 | header_field_info *hfinfo;
5312 |
5313 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5314 |
5315 | 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", 5315 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5315, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5315, "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", 5315, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5316 |
5317 | 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", 5317 , ((hfinfo))->abbrev))));
5318 |
5319 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5320 | proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5321 |
5322 | return pi;
5323 | }
5324 |
5325 | proto_item *
5326 | proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5327 | unsigned start, unsigned length,
5328 | const e_guid_t *value_ptr,
5329 | const char *format, ...)
5330 | {
5331 | proto_item *pi;
5332 | va_list ap;
5333 |
5334 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5335 | if (pi != tree) {
5336 | va_start(ap, format)__builtin_va_start(ap, format);
5337 | proto_tree_set_representation_value(pi, format, ap);
5338 | va_end(ap)__builtin_va_end(ap);
5339 | }
5340 |
5341 | return pi;
5342 | }
5343 |
5344 | proto_item *
5345 | proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5346 | unsigned start, unsigned length, const e_guid_t *value_ptr,
5347 | const char *format, ...)
5348 | {
5349 | proto_item *pi;
5350 | va_list ap;
5351 |
5352 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5353 | if (pi != tree) {
5354 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5354, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5355 |
5356 | va_start(ap, format)__builtin_va_start(ap, format);
5357 | proto_tree_set_representation(pi, format, ap);
5358 | va_end(ap)__builtin_va_end(ap);
5359 | }
5360 |
5361 | return pi;
5362 | }
5363 |
5364 | /* Set the FT_GUID value */
5365 | static void
5366 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5367 | {
5368 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5368, "value_ptr != ((void*)0)" ))));
5369 | fvalue_set_guid(fi->value, value_ptr);
5370 | }
5371 |
5372 | static void
5373 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5374 | const unsigned encoding)
5375 | {
5376 | e_guid_t guid;
5377 |
5378 | tvb_get_guid(tvb, start, &guid, encoding);
5379 | proto_tree_set_guid(fi, &guid);
5380 | }
5381 |
5382 | /* Add a FT_OID to a proto_tree */
5383 | proto_item *
5384 | proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5385 | unsigned length, const uint8_t* value_ptr)
5386 | {
5387 | proto_item *pi;
5388 | header_field_info *hfinfo;
5389 |
5390 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5391 |
5392 | TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5392 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5392, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5392, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5392, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5393 |
5394 | 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", 5394 , ((hfinfo))->abbrev))));
5395 |
5396 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5397 | proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5398 |
5399 | return pi;
5400 | }
5401 |
5402 | proto_item *
5403 | proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5404 | unsigned start, unsigned length,
5405 | const uint8_t* value_ptr,
5406 | const char *format, ...)
5407 | {
5408 | proto_item *pi;
5409 | va_list ap;
5410 |
5411 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5412 | if (pi != tree) {
5413 | va_start(ap, format)__builtin_va_start(ap, format);
5414 | proto_tree_set_representation_value(pi, format, ap);
5415 | va_end(ap)__builtin_va_end(ap);
5416 | }
5417 |
5418 | return pi;
5419 | }
5420 |
5421 | proto_item *
5422 | proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5423 | unsigned start, unsigned length, const uint8_t* value_ptr,
5424 | const char *format, ...)
5425 | {
5426 | proto_item *pi;
5427 | va_list ap;
5428 |
5429 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5430 | if (pi != tree) {
5431 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5431, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5432 |
5433 | va_start(ap, format)__builtin_va_start(ap, format);
5434 | proto_tree_set_representation(pi, format, ap);
5435 | va_end(ap)__builtin_va_end(ap);
5436 | }
5437 |
5438 | return pi;
5439 | }
5440 |
5441 | /* Set the FT_OID value */
5442 | static void
5443 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5444 | {
5445 | GByteArray *bytes;
5446 |
5447 | 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", 5447, "value_ptr != ((void*)0) || length == 0" ))));
5448 |
5449 | bytes = g_byte_array_new();
5450 | if (length > 0) {
5451 | g_byte_array_append(bytes, value_ptr, length);
5452 | }
5453 | fvalue_set_byte_array(fi->value, bytes);
5454 | }
5455 |
5456 | static void
5457 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5458 | {
5459 | proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5460 | }
5461 |
5462 | /* Set the FT_SYSTEM_ID value */
5463 | static void
5464 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5465 | {
5466 | GByteArray *bytes;
5467 |
5468 | 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", 5468, "value_ptr != ((void*)0) || length == 0" ))));
5469 |
5470 | bytes = g_byte_array_new();
5471 | if (length > 0) {
5472 | g_byte_array_append(bytes, value_ptr, length);
5473 | }
5474 | fvalue_set_byte_array(fi->value, bytes);
5475 | }
5476 |
5477 | static void
5478 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5479 | {
5480 | proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5481 | }
5482 |
5483 | /* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5484 | * proto_tree. Creates own copy of string, and frees it when the proto_tree
5485 | * is destroyed. */
5486 | proto_item *
5487 | proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5488 | int length, const char* value)
5489 | {
5490 | proto_item *pi;
5491 | header_field_info *hfinfo;
5492 | int item_length;
5493 |
5494 | 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", 5494, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5494, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5494, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
5495 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5496 | /*
5497 | * Special case - if the length is 0, skip the test, so that
5498 | * we can have an empty string right after the end of the
5499 | * packet. (This handles URL-encoded forms where the last field
5500 | * has no value so the form ends right after the =.)
5501 | *
5502 | * XXX - length zero makes sense for FT_STRING, and more or less
5503 | * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5504 | * for FT_STRINGZ (except that a number of fields that should be
5505 | * one of the others are actually registered as FT_STRINGZ.)
5506 | */
5507 | if (item_length != 0)
5508 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5509 |
5510 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5511 |
5512 | 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", 5512 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5512, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5512, "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", 5512, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5513 |
5514 | 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", 5514, ((hfinfo))->abbrev))));
5515 |
5516 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5517 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5517, "length >= 0" ))));
5518 |
5519 | 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", 5519, __func__, value, -1, __uni_endptr); } } while (0); } } while (0);
5520 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5521 |
5522 | return pi;
5523 | }
5524 |
5525 | proto_item *
5526 | proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5527 | unsigned start, int length, const char* value,
5528 | const char *format,
5529 | ...)
5530 | {
5531 | proto_item *pi;
5532 | va_list ap;
5533 |
5534 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5535 | if (pi != tree) {
5536 | va_start(ap, format)__builtin_va_start(ap, format);
5537 | proto_tree_set_representation_value(pi, format, ap);
5538 | va_end(ap)__builtin_va_end(ap);
5539 | }
5540 |
5541 | return pi;
5542 | }
5543 |
5544 | proto_item *
5545 | proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5546 | unsigned start, int length, const char* value,
5547 | const char *format, ...)
5548 | {
5549 | proto_item *pi;
5550 | va_list ap;
5551 |
5552 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5553 | if (pi != tree) {
5554 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5554, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5555 |
5556 | va_start(ap, format)__builtin_va_start(ap, format);
5557 | proto_tree_set_representation(pi, format, ap);
5558 | va_end(ap)__builtin_va_end(ap);
5559 | }
5560 |
5561 | return pi;
5562 | }
5563 |
5564 | /* Set the FT_STRING value */
5565 | static void
5566 | proto_tree_set_string(field_info *fi, const char* value)
5567 | {
5568 | if (value) {
5569 | fvalue_set_string(fi->value, value);
5570 | } else {
5571 | /*
5572 | * XXX - why is a null value for a string field
5573 | * considered valid?
5574 | */
5575 | fvalue_set_string(fi->value, "[ Null ]");
5576 | }
5577 | }
5578 |
5579 | /* Set the FT_AX25 value */
5580 | static void
5581 | proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5582 | {
5583 | fvalue_set_ax25(fi->value, value);
5584 | }
5585 |
5586 | static void
5587 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5588 | {
5589 | proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5590 | }
5591 |
5592 | /* Set the FT_VINES value */
5593 | static void
5594 | proto_tree_set_vines(field_info *fi, const uint8_t* value)
5595 | {
5596 | fvalue_set_vines(fi->value, value);
5597 | }
5598 |
5599 | static void
5600 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5601 | {
5602 | proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5603 | }
5604 |
5605 | /* Add a FT_ETHER to a proto_tree */
5606 | proto_item *
5607 | proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5608 | unsigned length, const uint8_t* value)
5609 | {
5610 | proto_item *pi;
5611 | header_field_info *hfinfo;
5612 |
5613 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5614 |
5615 | 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", 5615 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5615, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5615, "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", 5615, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5616 |
5617 | 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", 5617, ((hfinfo))->abbrev))));
5618 |
5619 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5620 | proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5621 |
5622 | return pi;
5623 | }
5624 |
5625 | proto_item *
5626 | proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5627 | unsigned start, unsigned length, const uint8_t* value,
5628 | const char *format, ...)
5629 | {
5630 | proto_item *pi;
5631 | va_list ap;
5632 |
5633 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5634 | if (pi != tree) {
5635 | va_start(ap, format)__builtin_va_start(ap, format);
5636 | proto_tree_set_representation_value(pi, format, ap);
5637 | va_end(ap)__builtin_va_end(ap);
5638 | }
5639 |
5640 | return pi;
5641 | }
5642 |
5643 | proto_item *
5644 | proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5645 | unsigned start, unsigned length, const uint8_t* value,
5646 | const char *format, ...)
5647 | {
5648 | proto_item *pi;
5649 | va_list ap;
5650 |
5651 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5652 | if (pi != tree) {
5653 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5653, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5654 |
5655 | va_start(ap, format)__builtin_va_start(ap, format);
5656 | proto_tree_set_representation(pi, format, ap);
5657 | va_end(ap)__builtin_va_end(ap);
5658 | }
5659 |
5660 | return pi;
5661 | }
5662 |
5663 | /* Set the FT_ETHER value */
5664 | static void
5665 | proto_tree_set_ether(field_info *fi, const uint8_t* value)
5666 | {
5667 | fvalue_set_ether(fi->value, value);
5668 | }
5669 |
5670 | static void
5671 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5672 | {
5673 | proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5674 | }
5675 |
5676 | /* Add a FT_BOOLEAN to a proto_tree */
5677 | proto_item *
5678 | proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5679 | unsigned length, uint64_t value)
5680 | {
5681 | proto_item *pi;
5682 | header_field_info *hfinfo;
5683 |
5684 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5685 |
5686 | 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", 5686 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5686, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5686, "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", 5686, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5687 |
5688 | 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" , 5688, ((hfinfo))->abbrev))));
5689 |
5690 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5691 | proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5692 |
5693 | return pi;
5694 | }
5695 |
5696 | proto_item *
5697 | proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5698 | tvbuff_t *tvb, unsigned start, unsigned length,
5699 | uint64_t value, const char *format, ...)
5700 | {
5701 | proto_item *pi;
5702 | va_list ap;
5703 |
5704 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5705 | if (pi != tree) {
5706 | va_start(ap, format)__builtin_va_start(ap, format);
5707 | proto_tree_set_representation_value(pi, format, ap);
5708 | va_end(ap)__builtin_va_end(ap);
5709 | }
5710 |
5711 | return pi;
5712 | }
5713 |
5714 | proto_item *
5715 | proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5716 | unsigned start, unsigned length, uint64_t value,
5717 | const char *format, ...)
5718 | {
5719 | proto_item *pi;
5720 | va_list ap;
5721 |
5722 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5723 | if (pi != tree) {
5724 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5724, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5725 |
5726 | va_start(ap, format)__builtin_va_start(ap, format);
5727 | proto_tree_set_representation(pi, format, ap);
5728 | va_end(ap)__builtin_va_end(ap);
5729 | }
5730 |
5731 | return pi;
5732 | }
5733 |
5734 | /* Set the FT_BOOLEAN value */
5735 | static void
5736 | proto_tree_set_boolean(field_info *fi, uint64_t value)
5737 | {
5738 | proto_tree_set_uint64(fi, value);
5739 | }
5740 |
5741 | /* Generate, into "buf", a string showing the bits of a bitfield.
5742 | Return a pointer to the character after that string. */
5743 | static char *
5744 | other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5745 | {
5746 | int i = 0;
5747 | uint64_t bit;
5748 | char *p;
5749 |
5750 | p = buf;
5751 |
5752 | /* This is a devel error. It is safer to stop here. */
5753 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5753, "width >= 1" ))));
5754 |
5755 | bit = UINT64_C(1)1UL << (width - 1);
5756 | for (;;) {
5757 | if (mask & bit) {
5758 | /* This bit is part of the field. Show its value. */
5759 | if (val & bit)
5760 | *p++ = '1';
5761 | else
5762 | *p++ = '0';
5763 | } else {
5764 | /* This bit is not part of the field. */
5765 | *p++ = '.';
5766 | }
5767 | bit >>= 1;
5768 | i++;
5769 | if (i >= width)
5770 | break;
5771 | if (i % 4 == 0)
5772 | *p++ = ' ';
5773 | }
5774 | *p = '\0';
5775 | return p;
5776 | }
5777 |
5778 | static char *
5779 | decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5780 | {
5781 | char *p;
5782 |
5783 | p = other_decode_bitfield_value(buf, val, mask, width);
5784 | p = g_stpcpy(p, " = ");
5785 |
5786 | return p;
5787 | }
5788 |
5789 | static char *
5790 | other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5791 | {
5792 | int i = 0;
5793 | uint64_t bit;
5794 | char *p;
5795 |
5796 | p = buf;
5797 |
5798 | /* This is a devel error. It is safer to stop here. */
5799 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5799, "width >= 1" ))));
5800 |
5801 | bit = UINT64_C(1)1UL << (width - 1);
5802 | for (;;) {
5803 | if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5804 | (mask & bit)) {
5805 | /* This bit is part of the field. Show its value. */
5806 | if (val & bit)
5807 | *p++ = '1';
5808 | else
5809 | *p++ = '0';
5810 | } else {
5811 | /* This bit is not part of the field. */
5812 | *p++ = '.';
5813 | }
5814 | bit >>= 1;
5815 | i++;
5816 | if (i >= width)
5817 | break;
5818 | if (i % 4 == 0)
5819 | *p++ = ' ';
5820 | }
5821 |
5822 | *p = '\0';
5823 | return p;
5824 | }
5825 |
5826 | static char *
5827 | decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5828 | {
5829 | char *p;
5830 |
5831 | p = other_decode_bitfield_varint_value(buf, val, mask, width);
5832 | p = g_stpcpy(p, " = ");
5833 |
5834 | return p;
5835 | }
5836 |
5837 | /* Add a FT_FLOAT to a proto_tree */
5838 | proto_item *
5839 | proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5840 | unsigned length, float value)
5841 | {
5842 | proto_item *pi;
5843 | header_field_info *hfinfo;
5844 |
5845 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5846 |
5847 | 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", 5847 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5847, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5847, "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", 5847, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5848 |
5849 | 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", 5849, ((hfinfo))->abbrev))));
5850 |
5851 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5852 | proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5853 |
5854 | return pi;
5855 | }
5856 |
5857 | proto_item *
5858 | proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5859 | unsigned start, unsigned length, float value,
5860 | const char *format, ...)
5861 | {
5862 | proto_item *pi;
5863 | va_list ap;
5864 |
5865 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5866 | if (pi != tree) {
5867 | va_start(ap, format)__builtin_va_start(ap, format);
5868 | proto_tree_set_representation_value(pi, format, ap);
5869 | va_end(ap)__builtin_va_end(ap);
5870 | }
5871 |
5872 | return pi;
5873 | }
5874 |
5875 | proto_item *
5876 | proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5877 | unsigned start, unsigned length, float value,
5878 | const char *format, ...)
5879 | {
5880 | proto_item *pi;
5881 | va_list ap;
5882 |
5883 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5884 | if (pi != tree) {
5885 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5885, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5886 |
5887 | va_start(ap, format)__builtin_va_start(ap, format);
5888 | proto_tree_set_representation(pi, format, ap);
5889 | va_end(ap)__builtin_va_end(ap);
5890 | }
5891 |
5892 | return pi;
5893 | }
5894 |
5895 | /* Set the FT_FLOAT value */
5896 | static void
5897 | proto_tree_set_float(field_info *fi, float value)
5898 | {
5899 | fvalue_set_floating(fi->value, value);
5900 | }
5901 |
5902 | /* Add a FT_DOUBLE to a proto_tree */
5903 | proto_item *
5904 | proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5905 | unsigned length, double value)
5906 | {
5907 | proto_item *pi;
5908 | header_field_info *hfinfo;
5909 |
5910 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5911 |
5912 | 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", 5912 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5912, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5912, "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", 5912, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5913 |
5914 | 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" , 5914, ((hfinfo))->abbrev))));
5915 |
5916 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5917 | proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5918 |
5919 | return pi;
5920 | }
5921 |
5922 | proto_item *
5923 | proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5924 | unsigned start, unsigned length, double value,
5925 | const char *format, ...)
5926 | {
5927 | proto_item *pi;
5928 | va_list ap;
5929 |
5930 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5931 | if (pi != tree) {
5932 | va_start(ap, format)__builtin_va_start(ap, format);
5933 | proto_tree_set_representation_value(pi, format, ap);
5934 | va_end(ap)__builtin_va_end(ap);
5935 | }
5936 |
5937 | return pi;
5938 | }
5939 |
5940 | proto_item *
5941 | proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5942 | unsigned start, unsigned length, double value,
5943 | const char *format, ...)
5944 | {
5945 | proto_item *pi;
5946 | va_list ap;
5947 |
5948 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5949 | if (pi != tree) {
5950 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5950, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5951 |
5952 | va_start(ap, format)__builtin_va_start(ap, format);
5953 | proto_tree_set_representation(pi, format, ap);
5954 | va_end(ap)__builtin_va_end(ap);
5955 | }
5956 |
5957 | return pi;
5958 | }
5959 |
5960 | /* Set the FT_DOUBLE value */
5961 | static void
5962 | proto_tree_set_double(field_info *fi, double value)
5963 | {
5964 | fvalue_set_floating(fi->value, value);
5965 | }
5966 |
5967 | /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5968 | proto_item *
5969 | proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5970 | unsigned length, uint32_t value)
5971 | {
5972 | proto_item *pi = NULL((void*)0);
5973 | header_field_info *hfinfo;
5974 |
5975 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5976 |
5977 | 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", 5977 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5977, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5977, "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", 5977, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5978 |
5979 | switch (hfinfo->type) {
5980 | case FT_CHAR:
5981 | case FT_UINT8:
5982 | case FT_UINT16:
5983 | case FT_UINT24:
5984 | case FT_UINT32:
5985 | case FT_FRAMENUM:
5986 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5987 | proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5988 | break;
5989 |
5990 | default:
5991 | 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)
5992 | 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);
5993 | }
5994 |
5995 | return pi;
5996 | }
5997 |
5998 | proto_item *
5999 | proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6000 | unsigned start, unsigned length, uint32_t value,
6001 | const char *format, ...)
6002 | {
6003 | proto_item *pi;
6004 | va_list ap;
6005 |
6006 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6007 | if (pi != tree) {
6008 | va_start(ap, format)__builtin_va_start(ap, format);
6009 | proto_tree_set_representation_value(pi, format, ap);
6010 | va_end(ap)__builtin_va_end(ap);
6011 | }
6012 |
6013 | return pi;
6014 | }
6015 |
6016 | proto_item *
6017 | proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6018 | unsigned start, unsigned length, uint32_t value,
6019 | const char *format, ...)
6020 | {
6021 | proto_item *pi;
6022 | va_list ap;
6023 |
6024 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
6025 | if (pi != tree) {
6026 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6026, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6027 |
6028 | va_start(ap, format)__builtin_va_start(ap, format);
6029 | proto_tree_set_representation(pi, format, ap);
6030 | va_end(ap)__builtin_va_end(ap);
6031 | }
6032 |
6033 | return pi;
6034 | }
6035 |
6036 | /* Set the FT_UINT{8,16,24,32} value */
6037 | static void
6038 | proto_tree_set_uint(field_info *fi, uint32_t value)
6039 | {
6040 | const header_field_info *hfinfo;
6041 | uint32_t integer;
6042 |
6043 | hfinfo = fi->hfinfo;
6044 | integer = value;
6045 |
6046 | if (hfinfo->bitmask) {
6047 | /* Mask out irrelevant portions */
6048 | integer &= (uint32_t)(hfinfo->bitmask);
6049 |
6050 | /* Shift bits */
6051 | integer >>= hfinfo_bitshift(hfinfo);
6052 |
6053 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6054 | 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);
6055 | }
6056 |
6057 | fvalue_set_uinteger(fi->value, integer);
6058 | }
6059 |
6060 | /* Add FT_UINT{40,48,56,64} to a proto_tree */
6061 | proto_item *
6062 | proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6063 | unsigned length, uint64_t value)
6064 | {
6065 | proto_item *pi = NULL((void*)0);
6066 | header_field_info *hfinfo;
6067 |
6068 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6069 |
6070 | 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", 6070 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6070, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6070, "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", 6070, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6071 |
6072 | switch (hfinfo->type) {
6073 | case FT_UINT40:
6074 | case FT_UINT48:
6075 | case FT_UINT56:
6076 | case FT_UINT64:
6077 | case FT_FRAMENUM:
6078 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6079 | proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6080 | break;
6081 |
6082 | default:
6083 | 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)
6084 | 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);
6085 | }
6086 |
6087 | return pi;
6088 | }
6089 |
6090 | proto_item *
6091 | proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6092 | unsigned start, unsigned length, uint64_t value,
6093 | const char *format, ...)
6094 | {
6095 | proto_item *pi;
6096 | va_list ap;
6097 |
6098 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6099 | if (pi != tree) {
6100 | va_start(ap, format)__builtin_va_start(ap, format);
6101 | proto_tree_set_representation_value(pi, format, ap);
6102 | va_end(ap)__builtin_va_end(ap);
6103 | }
6104 |
6105 | return pi;
6106 | }
6107 |
6108 | proto_item *
6109 | proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6110 | unsigned start, unsigned length, uint64_t value,
6111 | const char *format, ...)
6112 | {
6113 | proto_item *pi;
6114 | va_list ap;
6115 |
6116 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6117 | if (pi != tree) {
6118 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6118, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6119 |
6120 | va_start(ap, format)__builtin_va_start(ap, format);
6121 | proto_tree_set_representation(pi, format, ap);
6122 | va_end(ap)__builtin_va_end(ap);
6123 | }
6124 |
6125 | return pi;
6126 | }
6127 |
6128 | /* Set the FT_UINT{40,48,56,64} value */
6129 | static void
6130 | proto_tree_set_uint64(field_info *fi, uint64_t value)
6131 | {
6132 | const header_field_info *hfinfo;
6133 | uint64_t integer;
6134 |
6135 | hfinfo = fi->hfinfo;
6136 | integer = value;
6137 |
6138 | if (hfinfo->bitmask) {
6139 | /* Mask out irrelevant portions */
6140 | integer &= hfinfo->bitmask;
6141 |
6142 | /* Shift bits */
6143 | integer >>= hfinfo_bitshift(hfinfo);
6144 |
6145 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6146 | 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);
6147 | }
6148 |
6149 | fvalue_set_uinteger64(fi->value, integer);
6150 | }
6151 |
6152 | /* Add FT_INT{8,16,24,32} to a proto_tree */
6153 | proto_item *
6154 | proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6155 | unsigned length, int32_t value)
6156 | {
6157 | proto_item *pi = NULL((void*)0);
6158 | header_field_info *hfinfo;
6159 |
6160 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6161 |
6162 | 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", 6162 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6162, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6162, "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", 6162, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6163 |
6164 | switch (hfinfo->type) {
6165 | case FT_INT8:
6166 | case FT_INT16:
6167 | case FT_INT24:
6168 | case FT_INT32:
6169 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6170 | proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6171 | break;
6172 |
6173 | default:
6174 | 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)
6175 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
6176 | }
6177 |
6178 | return pi;
6179 | }
6180 |
6181 | proto_item *
6182 | proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6183 | unsigned start, unsigned length, int32_t value,
6184 | const char *format, ...)
6185 | {
6186 | proto_item *pi;
6187 | va_list ap;
6188 |
6189 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6190 | if (pi != tree) {
6191 | va_start(ap, format)__builtin_va_start(ap, format);
6192 | proto_tree_set_representation_value(pi, format, ap);
6193 | va_end(ap)__builtin_va_end(ap);
6194 | }
6195 |
6196 | return pi;
6197 | }
6198 |
6199 | proto_item *
6200 | proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6201 | unsigned start, unsigned length, int32_t value,
6202 | const char *format, ...)
6203 | {
6204 | proto_item *pi;
6205 | va_list ap;
6206 |
6207 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6208 | if (pi != tree) {
6209 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6209, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6210 |
6211 | va_start(ap, format)__builtin_va_start(ap, format);
6212 | proto_tree_set_representation(pi, format, ap);
6213 | va_end(ap)__builtin_va_end(ap);
6214 | }
6215 |
6216 | return pi;
6217 | }
6218 |
6219 | /* Set the FT_INT{8,16,24,32} value */
6220 | static void
6221 | proto_tree_set_int(field_info *fi, int32_t value)
6222 | {
6223 | const header_field_info *hfinfo;
6224 | uint32_t integer;
6225 | int no_of_bits;
6226 |
6227 | hfinfo = fi->hfinfo;
6228 | integer = (uint32_t) value;
6229 |
6230 | if (hfinfo->bitmask) {
6231 | /* Mask out irrelevant portions */
6232 | integer &= (uint32_t)(hfinfo->bitmask);
6233 |
6234 | /* Shift bits */
6235 | integer >>= hfinfo_bitshift(hfinfo);
6236 |
6237 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6238 | integer = ws_sign_ext32(integer, no_of_bits);
6239 |
6240 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6241 | 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);
6242 | }
6243 |
6244 | fvalue_set_sinteger(fi->value, integer);
6245 | }
6246 |
6247 | /* Add FT_INT{40,48,56,64} to a proto_tree */
6248 | proto_item *
6249 | proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6250 | unsigned length, int64_t value)
6251 | {
6252 | proto_item *pi = NULL((void*)0);
6253 | header_field_info *hfinfo;
6254 |
6255 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6256 |
6257 | 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", 6257 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6257, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6257, "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", 6257, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6258 |
6259 | switch (hfinfo->type) {
6260 | case FT_INT40:
6261 | case FT_INT48:
6262 | case FT_INT56:
6263 | case FT_INT64:
6264 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6265 | proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6266 | break;
6267 |
6268 | default:
6269 | 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)
6270 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
6271 | }
6272 |
6273 | return pi;
6274 | }
6275 |
6276 | proto_item *
6277 | proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6278 | unsigned start, unsigned length, int64_t value,
6279 | const char *format, ...)
6280 | {
6281 | proto_item *pi;
6282 | va_list ap;
6283 |
6284 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6285 | if (pi != tree) {
6286 | va_start(ap, format)__builtin_va_start(ap, format);
6287 | proto_tree_set_representation_value(pi, format, ap);
6288 | va_end(ap)__builtin_va_end(ap);
6289 | }
6290 |
6291 | return pi;
6292 | }
6293 |
6294 | /* Set the FT_INT{40,48,56,64} value */
6295 | static void
6296 | proto_tree_set_int64(field_info *fi, int64_t value)
6297 | {
6298 | const header_field_info *hfinfo;
6299 | uint64_t integer;
6300 | int no_of_bits;
6301 |
6302 | hfinfo = fi->hfinfo;
6303 | integer = value;
6304 |
6305 | if (hfinfo->bitmask) {
6306 | /* Mask out irrelevant portions */
6307 | integer &= hfinfo->bitmask;
6308 |
6309 | /* Shift bits */
6310 | integer >>= hfinfo_bitshift(hfinfo);
6311 |
6312 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6313 | integer = ws_sign_ext64(integer, no_of_bits);
6314 |
6315 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6316 | FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth (hfinfo)) & 63) << 12)); } while(0);
6317 | }
6318 |
6319 | fvalue_set_sinteger64(fi->value, integer);
6320 | }
6321 |
6322 | proto_item *
6323 | proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6324 | unsigned start, unsigned length, int64_t value,
6325 | const char *format, ...)
6326 | {
6327 | proto_item *pi;
6328 | va_list ap;
6329 |
6330 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6331 | if (pi != tree) {
6332 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6332, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6333 |
6334 | va_start(ap, format)__builtin_va_start(ap, format);
6335 | proto_tree_set_representation(pi, format, ap);
6336 | va_end(ap)__builtin_va_end(ap);
6337 | }
6338 |
6339 | return pi;
6340 | }
6341 |
6342 | /* Add a FT_EUI64 to a proto_tree */
6343 | proto_item *
6344 | proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6345 | unsigned length, const uint64_t value)
6346 | {
6347 | proto_item *pi;
6348 | header_field_info *hfinfo;
6349 |
6350 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6351 |
6352 | 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", 6352 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6352, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6352, "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", 6352, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6353 |
6354 | 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", 6354, ((hfinfo))->abbrev))));
6355 |
6356 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
6357 | proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6358 |
6359 | return pi;
6360 | }
6361 |
6362 | proto_item *
6363 | proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6364 | unsigned start, unsigned length, const uint64_t value,
6365 | const char *format, ...)
6366 | {
6367 | proto_item *pi;
6368 | va_list ap;
6369 |
6370 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6371 | if (pi != tree) {
6372 | va_start(ap, format)__builtin_va_start(ap, format);
6373 | proto_tree_set_representation_value(pi, format, ap);
6374 | va_end(ap)__builtin_va_end(ap);
6375 | }
6376 |
6377 | return pi;
6378 | }
6379 |
6380 | proto_item *
6381 | proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6382 | unsigned start, unsigned length, const uint64_t value,
6383 | const char *format, ...)
6384 | {
6385 | proto_item *pi;
6386 | va_list ap;
6387 |
6388 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6389 | if (pi != tree) {
6390 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6390, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6391 |
6392 | va_start(ap, format)__builtin_va_start(ap, format);
6393 | proto_tree_set_representation(pi, format, ap);
6394 | va_end(ap)__builtin_va_end(ap);
6395 | }
6396 |
6397 | return pi;
6398 | }
6399 |
6400 | /* Set the FT_EUI64 value */
6401 | static void
6402 | proto_tree_set_eui64(field_info *fi, const uint64_t value)
6403 | {
6404 | uint8_t v[FT_EUI64_LEN8];
6405 | phtonu64(v, value);
6406 | fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6407 | }
6408 |
6409 | static void
6410 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6411 | {
6412 | if (encoding)
6413 | {
6414 | proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6415 | } else {
6416 | proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6417 | }
6418 | }
6419 |
6420 | proto_item *
6421 | proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6422 | const mac_hf_list_t *list_generic,
6423 | int idx, tvbuff_t *tvb,
6424 | proto_tree *tree, unsigned offset)
6425 | {
6426 | uint8_t addr[6];
6427 | const char *addr_name = NULL((void*)0);
6428 | const char *oui_name = NULL((void*)0);
6429 | proto_item *addr_item = NULL((void*)0);
6430 | proto_tree *addr_tree = NULL((void*)0);
6431 | proto_item *ret_val = NULL((void*)0);
6432 |
6433 | if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6434 | return NULL((void*)0);
6435 | }
6436 |
6437 | /* Resolve what we can of the address */
6438 | tvb_memcpy(tvb, addr, offset, sizeof addr);
6439 | if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6440 | addr_name = get_ether_name(addr);
6441 | }
6442 | if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6443 | oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6444 | }
6445 |
6446 | /* Add the item for the specific address type */
6447 | ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6448 | if (idx >= 0) {
6449 | addr_tree = proto_item_add_subtree(ret_val, idx);
6450 | }
6451 | else {
6452 | addr_tree = tree;
6453 | }
6454 |
6455 | if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6456 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6457 | tvb, offset, 6, addr_name);
6458 | proto_item_set_generated(addr_item);
6459 | proto_item_set_hidden(addr_item);
6460 | }
6461 |
6462 | if (list_specific->hf_oui != NULL((void*)0)) {
6463 | addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6464 | proto_item_set_generated(addr_item);
6465 | proto_item_set_hidden(addr_item);
6466 |
6467 | if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6468 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6469 | proto_item_set_generated(addr_item);
6470 | proto_item_set_hidden(addr_item);
6471 | }
6472 | }
6473 |
6474 | if (list_specific->hf_lg != NULL((void*)0)) {
6475 | proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6476 | }
6477 | if (list_specific->hf_ig != NULL((void*)0)) {
6478 | proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6479 | }
6480 |
6481 | /* Were we given a list for generic address fields? If not, stop here */
6482 | if (list_generic == NULL((void*)0)) {
6483 | return ret_val;
6484 | }
6485 |
6486 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6487 | proto_item_set_hidden(addr_item);
6488 |
6489 | if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6490 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6491 | tvb, offset, 6, addr_name);
6492 | proto_item_set_generated(addr_item);
6493 | proto_item_set_hidden(addr_item);
6494 | }
6495 |
6496 | if (list_generic->hf_oui != NULL((void*)0)) {
6497 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6498 | proto_item_set_generated(addr_item);
6499 | proto_item_set_hidden(addr_item);
6500 |
6501 | if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6502 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6503 | proto_item_set_generated(addr_item);
6504 | proto_item_set_hidden(addr_item);
6505 | }
6506 | }
6507 |
6508 | if (list_generic->hf_lg != NULL((void*)0)) {
6509 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6510 | proto_item_set_hidden(addr_item);
6511 | }
6512 | if (list_generic->hf_ig != NULL((void*)0)) {
6513 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6514 | proto_item_set_hidden(addr_item);
6515 | }
6516 | return ret_val;
6517 | }
6518 |
6519 | static proto_item *
6520 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6521 | {
6522 | proto_node *pnode, *tnode, *sibling;
6523 | field_info *tfi;
6524 | unsigned depth = 1;
6525 |
6526 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6526, __func__, "assertion failed: %s", "tree" ); } while (0);
6527 |
6528 | /*
6529 | * Restrict our depth. proto_tree_traverse_pre_order and
6530 | * proto_tree_traverse_post_order (and possibly others) are recursive
6531 | * so we need to be mindful of our stack size.
6532 | */
6533 | if (tree->first_child == NULL((void*)0)) {
6534 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6535 | depth++;
6536 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6537 | 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__)), 6540)))
6538 | "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__)), 6540)))
6539 | 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__)), 6540)))
6540 | 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__)), 6540)));
6541 | }
6542 | }
6543 | }
6544 |
6545 | /*
6546 | * Make sure "tree" is ready to have subtrees under it, by
6547 | * checking whether it's been given an ett_ value.
6548 | *
6549 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6550 | * node of the protocol tree. That node is not displayed,
6551 | * so it doesn't need an ett_ value to remember whether it
6552 | * was expanded.
6553 | */
6554 | tnode = tree;
6555 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6556 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6557 | 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" , 6558)
6558 | 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" , 6558);
6559 | /* XXX - is it safe to continue here? */
6560 | }
6561 |
6562 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6563 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6564 | pnode->parent = tnode;
6565 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6566 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6567 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6568 |
6569 | if (tnode->last_child != NULL((void*)0)) {
6570 | sibling = tnode->last_child;
6571 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6571, "sibling->next == ((void*)0)" ))));
6572 | sibling->next = pnode;
6573 | } else
6574 | tnode->first_child = pnode;
6575 | tnode->last_child = pnode;
6576 |
6577 | /* We should not be adding a fake node for an interesting field */
6578 | 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", 6578, __func__, "assertion failed: %s" , "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT" ); } while (0);
6579 |
6580 | /* XXX - Should the proto_item have a header_field_info member, at least
6581 | * for faked items, to know what hfi was faked? (Some dissectors look at
6582 | * the tree items directly.)
6583 | */
6584 | return (proto_item *)pnode;
6585 | }
6586 |
6587 | /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6588 | static proto_item *
6589 | proto_tree_add_node(proto_tree *tree, field_info *fi)
6590 | {
6591 | proto_node *pnode, *tnode, *sibling;
6592 | field_info *tfi;
6593 | unsigned depth = 1;
6594 |
6595 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6595, __func__, "assertion failed: %s", "tree" ); } while (0);
6596 |
6597 | /*
6598 | * Restrict our depth. proto_tree_traverse_pre_order and
6599 | * proto_tree_traverse_post_order (and possibly others) are recursive
6600 | * so we need to be mindful of our stack size.
6601 | */
6602 | if (tree->first_child == NULL((void*)0)) {
6603 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6604 | depth++;
6605 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6606 | /* The fvalue_t is pool-allocated; just release the
6607 | * type-specific data it owns (see new_field_info()). */
6608 | fvalue_cleanup(fi->value);
6609 | fi->value = NULL((void*)0);
6610 | 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__)), 6613)))
6611 | "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__)), 6613)))
6612 | 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__)), 6613)))
6613 | 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__)), 6613)));
6614 | }
6615 | }
6616 | }
6617 |
6618 | /*
6619 | * Make sure "tree" is ready to have subtrees under it, by
6620 | * checking whether it's been given an ett_ value.
6621 | *
6622 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6623 | * node of the protocol tree. That node is not displayed,
6624 | * so it doesn't need an ett_ value to remember whether it
6625 | * was expanded.
6626 | */
6627 | tnode = tree;
6628 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6629 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6630 | /* Since we are not adding fi to a node, its fvalue won't get
6631 | * cleaned up by proto_tree_free_node(), so release the
6632 | * type-specific data it owns now. The fvalue_t structure itself
6633 | * is pool-allocated (see new_field_info()).
6634 | */
6635 | fvalue_cleanup(fi->value);
6636 | fi->value = NULL((void*)0);
6637 | 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", 6638)
6638 | 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", 6638);
6639 | /* XXX - is it safe to continue here? */
6640 | }
6641 |
6642 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6643 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6644 | pnode->parent = tnode;
6645 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6646 | PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6647 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6648 |
6649 | if (tnode->last_child != NULL((void*)0)) {
6650 | sibling = tnode->last_child;
6651 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6651, "sibling->next == ((void*)0)" ))));
6652 | sibling->next = pnode;
6653 | } else
6654 | tnode->first_child = pnode;
6655 | tnode->last_child = pnode;
6656 |
6657 | tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6658 |
6659 | return (proto_item *)pnode;
6660 | }
6661 |
6662 |
6663 | /* Generic way to allocate field_info and add to proto_tree.
6664 | * Sets *pfi to address of newly-allocated field_info struct */
6665 | static proto_item *
6666 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6667 | int *length)
6668 | {
6669 | proto_item *pi;
6670 | field_info *fi;
6671 | int item_length;
6672 |
6673 | get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6674 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6675 | pi = proto_tree_add_node(tree, fi);
6676 |
6677 | return pi;
6678 | }
6679 |
6680 | /* Generic way to allocate field_info and add to proto_tree with unsigned length.
6681 | * Eventually this should replace the other function.
6682 | * Sets *pfi to address of newly-allocated field_info struct */
6683 | static proto_item *
6684 | proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6685 | unsigned *length)
6686 | {
6687 | proto_item *pi;
6688 | field_info *fi;
6689 | unsigned item_length;
6690 |
6691 | get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6692 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6693 | pi = proto_tree_add_node(tree, fi);
6694 |
6695 | return pi;
6696 | }
6697 |
6698 | static void
6699 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6700 | int *item_length, const unsigned encoding)
6701 | {
6702 | int length_remaining;
6703 |
6704 | /*
6705 | * We only allow a null tvbuff if the item has a zero length,
6706 | * i.e. if there's no data backing it.
6707 | */
6708 | 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", 6708, "tvb != ((void*)0) || *length == 0" ))));
6709 |
6710 | /*
6711 | * XXX - in some protocols, there are 32-bit unsigned length
6712 | * fields, so lengths in protocol tree and tvbuff routines
6713 | * should really be unsigned. We should have, for those
6714 | * field types for which "to the end of the tvbuff" makes sense,
6715 | * additional routines that take no length argument and
6716 | * add fields that run to the end of the tvbuff.
6717 | */
6718 | if (*length == -1) {
6719 | /*
6720 | * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6721 | * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6722 | * of -1 means "set the length to what remains in the
6723 | * tvbuff".
6724 | *
6725 | * The assumption is either that
6726 | *
6727 | * 1) the length of the item can only be determined
6728 | * by dissection (typically true of items with
6729 | * subitems, which are probably FT_NONE or
6730 | * FT_PROTOCOL)
6731 | *
6732 | * or
6733 | *
6734 | * 2) if the tvbuff is "short" (either due to a short
6735 | * snapshot length or due to lack of reassembly of
6736 | * fragments/segments/whatever), we want to display
6737 | * what's available in the field (probably FT_BYTES
6738 | * or FT_STRING) and then throw an exception later
6739 | *
6740 | * or
6741 | *
6742 | * 3) the field is defined to be "what's left in the
6743 | * packet"
6744 | *
6745 | * so we set the length to what remains in the tvbuff so
6746 | * that, if we throw an exception while dissecting, it
6747 | * has what is probably the right value.
6748 | *
6749 | * For FT_STRINGZ, it means "the string is null-terminated,
6750 | * not null-padded; set the length to the actual length
6751 | * of the string", and if the tvbuff if short, we just
6752 | * throw an exception.
6753 | *
6754 | * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6755 | * it means "find the end of the string",
6756 | * and if the tvbuff if short, we just throw an exception.
6757 | *
6758 | * It's not valid for any other type of field. For those
6759 | * fields, we treat -1 the same way we treat other
6760 | * negative values - we assume the length is a Really
6761 | * Big Positive Number, and throw a ReportedBoundsError
6762 | * exception, under the assumption that the Really Big
6763 | * Length would run past the end of the packet.
6764 | */
6765 | 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 )))) {
6766 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6767 | /*
6768 | * Leave the length as -1, so our caller knows
6769 | * it was -1.
6770 | */
6771 | *item_length = *length;
6772 | return;
6773 | } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6774 | switch (tvb_get_uint8(tvb, start) >> 6)
6775 | {
6776 | case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6777 | *item_length = 1;
6778 | break;
6779 | case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6780 | *item_length = 2;
6781 | break;
6782 | case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6783 | *item_length = 4;
6784 | break;
6785 | case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6786 | *item_length = 8;
6787 | break;
6788 | }
6789 | }
6790 | }
6791 |
6792 | switch (hfinfo->type) {
6793 |
6794 | case FT_PROTOCOL:
6795 | case FT_NONE:
6796 | case FT_BYTES:
6797 | case FT_STRING:
6798 | case FT_STRINGZPAD:
6799 | case FT_STRINGZTRUNC:
6800 | /*
6801 | * We allow FT_PROTOCOLs to be zero-length -
6802 | * for example, an ONC RPC NULL procedure has
6803 | * neither arguments nor reply, so the
6804 | * payload for that protocol is empty.
6805 | *
6806 | * We also allow the others to be zero-length -
6807 | * because that's the way the code has been for a
6808 | * long, long time.
6809 | *
6810 | * However, we want to ensure that the start
6811 | * offset is not *past* the byte past the end
6812 | * of the tvbuff: we throw an exception in that
6813 | * case.
6814 | */
6815 | *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6816 | DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6816, "*length >= 0" ))));
6817 | break;
6818 |
6819 | case FT_STRINGZ:
6820 | /*
6821 | * Leave the length as -1, so our caller knows
6822 | * it was -1.
6823 | */
6824 | break;
6825 |
6826 | default:
6827 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6828 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 6828));
6829 | }
6830 | *item_length = *length;
6831 | } else {
6832 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6833 | /*
6834 | * These types are for interior nodes of the
6835 | * tree, and don't have data associated with
6836 | * them; if the length is negative (XXX - see
6837 | * above) or goes past the end of the tvbuff,
6838 | * cut it short at the end of the tvbuff.
6839 | * That way, if this field is selected in
6840 | * Wireshark, we don't highlight stuff past
6841 | * the end of the data.
6842 | *
6843 | * If we don't have a tvb, then length must be zero,
6844 | * per the DISSECTOR_ASSERT() above.
6845 | *
6846 | * If we do have a tvb, and the length requested is
6847 | * nonzero, we want to ensure that the start offset
6848 | * is not *past* the byte past the end of the tvbuff
6849 | * data: we throw an exception in that case as above.
6850 | */
6851 | if (tvb && *length) {
6852 | length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6853 | if (*length < 0 ||
6854 | (*length > 0 &&
6855 | (length_remaining < *length)))
6856 | *length = length_remaining;
6857 | }
6858 | }
6859 | *item_length = *length;
6860 | if (*item_length < 0) {
6861 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6862 | }
6863 | }
6864 | }
6865 |
6866 | static void
6867 | get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6868 | unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6869 | {
6870 | unsigned length_remaining;
6871 |
6872 | /*
6873 | * We only allow a null tvbuff if the item has a zero length,
6874 | * i.e. if there's no data backing it.
6875 | */
6876 | 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", 6876, "tvb != ((void*)0) || *length == 0" ))));
6877 |
6878 |
6879 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6880 | /*
6881 | * These types are for interior nodes of the
6882 | * tree, and don't have data associated with
6883 | * them; if the length is negative (XXX - see
6884 | * above) or goes past the end of the tvbuff,
6885 | * cut it short at the end of the tvbuff.
6886 | * That way, if this field is selected in
6887 | * Wireshark, we don't highlight stuff past
6888 | * the end of the data.
6889 | *
6890 | * If we don't have a tvb, then length must be zero,
6891 | * per the DISSECTOR_ASSERT() above.
6892 | *
6893 | * If we do have a tvb, and the length requested is
6894 | * nonzero, we want to ensure that the start offset
6895 | * is not *past* the byte past the end of the tvbuff
6896 | * data: we throw an exception in that case as above.
6897 | * (If the length requested is zero, then it's quite
6898 | * likely that the start offset is the byte past the
6899 | * end, but that's ok.)
6900 | */
6901 | if (tvb && *length) {
6902 | length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6903 | if (length_remaining < *length) {
6904 | *length = length_remaining;
6905 | }
6906 | }
6907 | }
6908 | *item_length = *length;
6909 | }
6910 |
6911 | static int
6912 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6913 | int length, unsigned item_length, const int encoding)
6914 | {
6915 | uint32_t n;
6916 |
6917 | /*
6918 | * We need to get the correct item length here.
6919 | * That's normally done by proto_tree_new_item(),
6920 | * but we won't be calling it.
6921 | */
6922 | switch (hfinfo->type) {
6923 |
6924 | case FT_NONE:
6925 | case FT_PROTOCOL:
6926 | case FT_BYTES:
6927 | /*
6928 | * The length is the specified length.
6929 | */
6930 | break;
6931 |
6932 | case FT_UINT_BYTES:
6933 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6934 | item_length += n;
6935 | if ((int)item_length < length) {
6936 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6937 | }
6938 | break;
6939 |
6940 | /* XXX - make these just FT_UINT? */
6941 | case FT_UINT8:
6942 | case FT_UINT16:
6943 | case FT_UINT24:
6944 | case FT_UINT32:
6945 | case FT_UINT40:
6946 | case FT_UINT48:
6947 | case FT_UINT56:
6948 | case FT_UINT64:
6949 | /* XXX - make these just FT_INT? */
6950 | case FT_INT8:
6951 | case FT_INT16:
6952 | case FT_INT24:
6953 | case FT_INT32:
6954 | case FT_INT40:
6955 | case FT_INT48:
6956 | case FT_INT56:
6957 | case FT_INT64:
6958 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6959 | if (length < -1) {
6960 | report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6961 | }
6962 | if (length == -1) {
6963 | uint64_t dummy;
6964 | /* This can throw an exception */
6965 | /* XXX - do this without fetching the varint? */
6966 | length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6967 | if (length == 0) {
6968 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6969 | }
6970 | }
6971 | item_length = length;
6972 | break;
6973 | }
6974 |
6975 | /*
6976 | * The length is the specified length.
6977 | */
6978 | break;
6979 |
6980 | case FT_BOOLEAN:
6981 | case FT_CHAR:
6982 | case FT_IPv4:
6983 | case FT_IPXNET:
6984 | case FT_IPv6:
6985 | case FT_FCWWN:
6986 | case FT_AX25:
6987 | case FT_VINES:
6988 | case FT_ETHER:
6989 | case FT_EUI64:
6990 | case FT_GUID:
6991 | case FT_OID:
6992 | case FT_REL_OID:
6993 | case FT_SYSTEM_ID:
6994 | case FT_FLOAT:
6995 | case FT_DOUBLE:
6996 | case FT_STRING:
6997 | /*
6998 | * The length is the specified length.
6999 | */
7000 | break;
7001 |
7002 | case FT_STRINGZ:
7003 | if (length < -1) {
7004 | report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
7005 | }
7006 | if (length == -1) {
7007 | /* This can throw an exception */
7008 | item_length = tvb_strsize_enc(tvb, start, encoding);
7009 | }
7010 | break;
7011 |
7012 | case FT_UINT_STRING:
7013 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
7014 | item_length += n;
7015 | if ((int)item_length < length) {
7016 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
7017 | }
7018 | break;
7019 |
7020 | case FT_STRINGZPAD:
7021 | case FT_STRINGZTRUNC:
7022 | case FT_ABSOLUTE_TIME:
7023 | case FT_RELATIVE_TIME:
7024 | case FT_IEEE_11073_SFLOAT:
7025 | case FT_IEEE_11073_FLOAT:
7026 | /*
7027 | * The length is the specified length.
7028 | */
7029 | break;
7030 |
7031 | default:
7032 | 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 ))
7033 | 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 ))
7034 | 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 ))
7035 | 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 ));
7036 | break;
7037 | }
7038 | return item_length;
7039 | }
7040 |
7041 | // This was arbitrarily chosen, but if you're adding 50K items to the tree
7042 | // without advancing the offset you should probably take a long, hard look
7043 | // at what you're doing.
7044 | // We *could* make this a configurable option, but I (Gerald) would like to
7045 | // avoid adding yet another nerd knob.
7046 | # define PROTO_TREE_MAX_IDLE50000 50000
7047 | static field_info *
7048 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7049 | const unsigned start, const int item_length)
7050 | {
7051 | field_info *fi;
7052 |
7053 | FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo ->pool)), sizeof(field_info)));
7054 |
7055 | fi->hfinfo = hfinfo;
7056 | fi->start = start;
7057 | fi->start += (tvb)?tvb_raw_offset(tvb):0;
7058 | /* add the data source tvbuff */
7059 | fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7060 |
7061 | // If our start offset hasn't advanced after adding many items it probably
7062 | // means we're in a large or infinite loop.
7063 | if (fi->start > 0) {
7064 | if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7065 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7066 | if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7067 | if (wireshark_abort_on_too_many_items) {
7068 | 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", 7069 , __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)
7069 | hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7069 , __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000);
7070 | }
7071 | /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7072 | * but if not, we should hit the max item error earlier,
7073 | * so we shouldn't need to reset the tree count to
7074 | * ensure that the exception handler can add the item. */
7075 | 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)))
7076 | 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)))
7077 | "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)))
7078 | 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)));
7079 | }
7080 | } else {
7081 | PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7082 | PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7083 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7084 | }
7085 | }
7086 | fi->length = item_length;
7087 | fi->tree_type = -1;
7088 | fi->flags = 0;
7089 | if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7090 | /* If the tree is not visible, set the item hidden, unless we
7091 | * need the representation or length and can't fake them.
7092 | */
7093 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7094 | FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); } while(0);
7095 | }
7096 | }
7097 | fi->value = fvalue_new_pool(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), fi->hfinfo->type);
7098 | fi->rep = NULL((void*)0);
7099 |
7100 | fi->appendix_start = 0;
7101 | fi->appendix_length = 0;
7102 |
7103 | fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7104 | fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7105 |
7106 | return fi;
7107 | }
7108 |
7109 | static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7110 | {
7111 | if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7112 | return 0;
7113 | }
7114 |
7115 | /* Search for field name */
7116 | char *ptr = strstr(representation, hfinfo->name);
7117 | if (!ptr) {
7118 | return 0;
7119 | }
7120 |
7121 | /* Check if field name ends with the ": " delimiter */
7122 | ptr += strlen(hfinfo->name);
7123 | if (strncmp(ptr, ": ", 2) == 0) {
7124 | ptr += 2;
7125 | }
7126 |
7127 | /* Return offset to after field name */
7128 | return ptr - representation;
7129 | }
7130 |
7131 | static size_t label_find_name_pos(const item_label_t *rep)
7132 | {
7133 | size_t name_pos = 0;
7134 |
7135 | /* If the value_pos is too small or too large, we can't find the expected format */
7136 | if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7137 | return 0;
7138 | }
7139 |
7140 | /* Check if the format looks like "label: value", then set name_pos before ':'. */
7141 | if (rep->representation[rep->value_pos-2] == ':') {
7142 | name_pos = rep->value_pos - 2;
7143 | }
7144 |
7145 | return name_pos;
7146 | }
7147 |
7148 | /* If the protocol tree is to be visible, set the representation of a
7149 | proto_tree entry with the name of the field for the item and with
7150 | the value formatted with the supplied printf-style format and
7151 | argument list. */
7152 | static void
7153 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7154 | {
7155 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 7155, __func__, "assertion failed: %s", "pi" ); } while (0);
7156 |
7157 | /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7158 | * items string representation */
7159 | if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7160 | size_t name_pos, ret = 0;
7161 | char *str;
7162 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7163 | const header_field_info *hf;
7164 |
7165 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7165, "fi"))));
7166 |
7167 | hf = fi->hfinfo;
7168 |
7169 | 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;;
7170 | 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)))) {
7171 | uint64_t val;
7172 | char *p;
7173 |
7174 | 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))
7175 | val = fvalue_get_uinteger(fi->value);
7176 | else
7177 | val = fvalue_get_uinteger64(fi->value);
7178 |
7179 | val <<= hfinfo_bitshift(hf);
7180 |
7181 | p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7182 | ret = (p - fi->rep->representation);
7183 | }
7184 |
7185 | /* put in the hf name */
7186 | 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);
7187 |
7188 | ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const uint8_t*)": ", 0);
7189 | /* If possible, Put in the value of the string */
7190 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7191 | 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" , 7191, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7192 | fi->rep->value_pos = ret;
7193 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7194 | if (ret >= ITEM_LABEL_LENGTH240) {
7195 | /* Uh oh, we don't have enough room. Tell the user
7196 | * that the field is truncated.
7197 | */
7198 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7199 | }
7200 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7201 | }
7202 | }
7203 |
7204 | /* If the protocol tree is to be visible, set the representation of a
7205 | proto_tree entry with the representation formatted with the supplied
7206 | printf-style format and argument list. */
7207 | static void
7208 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7209 | {
7210 | size_t ret; /*tmp return value */
7211 | char *str;
7212 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7213 |
7214 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7214, "fi"))));
7215 |
7216 | if (!proto_item_is_hidden(pi)) {
7217 | 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;;
7218 |
7219 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7220 | 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" , 7220, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7221 | fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7222 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7223 | if (ret >= ITEM_LABEL_LENGTH240) {
7224 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7225 | size_t name_pos = label_find_name_pos(fi->rep);
7226 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7227 | }
7228 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7229 | }
7230 | }
7231 |
7232 | static int
7233 | proto_strlcpy(char *dest, const char *src, size_t dest_size)
7234 | {
7235 | if (dest_size == 0) return 0;
7236 |
7237 | size_t res = g_strlcpy(dest, src, dest_size);
7238 |
7239 | /* At most dest_size - 1 characters will be copied
7240 | * (unless dest_size is 0). */
7241 | if (res >= dest_size)
7242 | res = dest_size - 1;
7243 | return (int) res;
7244 | }
7245 |
7246 | static header_field_info *
7247 | hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7248 | {
7249 | header_field_info *dup_hfinfo;
7250 |
7251 | if (hfinfo->same_name_prev_id == -1)
7252 | return NULL((void*)0);
7253 | 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", 7253 , __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", 7253, "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", 7253, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo ->same_name_prev_id];;
7254 | return dup_hfinfo;
7255 | }
7256 |
7257 | static void
7258 | hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7259 | {
7260 | 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);
7261 | last_field_name = NULL((void*)0);
7262 |
7263 | if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7264 | /* No hfinfo with the same name */
7265 | wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7266 | return;
7267 | }
7268 |
7269 | if (hfinfo->same_name_next) {
7270 | hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7271 | }
7272 |
7273 | if (hfinfo->same_name_prev_id != -1) {
7274 | header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7275 | same_name_prev->same_name_next = hfinfo->same_name_next;
7276 | if (!hfinfo->same_name_next) {
7277 | /* It's always the latest added hfinfo which is stored in gpa_name_map */
7278 | wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7279 | }
7280 | }
7281 | }
7282 |
7283 | int
7284 | proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7285 | {
7286 | const header_field_info *hfinfo = finfo->hfinfo;
7287 | int label_len = 0;
7288 | char *tmp_str;
7289 | const char *str;
7290 | const uint8_t *bytes;
7291 | uint32_t number;
7292 | uint64_t number64;
7293 | const char *hf_str_val;
7294 | char number_buf[NUMBER_LABEL_LENGTH80];
7295 | const char *number_out;
7296 | address addr;
7297 | const ipv4_addr_and_mask *ipv4;
7298 | const ipv6_addr_and_prefix *ipv6;
7299 |
7300 | switch (hfinfo->type) {
7301 |
7302 | case FT_NONE:
7303 | case FT_PROTOCOL:
7304 | return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7305 |
7306 | case FT_UINT_BYTES:
7307 | case FT_BYTES:
7308 | tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7309 | hfinfo,
7310 | fvalue_get_bytes_data(finfo->value),
7311 | (unsigned)fvalue_length2(finfo->value),
7312 | label_str_size);
7313 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7314 | wmem_free(NULL((void*)0), tmp_str);
7315 | break;
7316 |
7317 | case FT_ABSOLUTE_TIME:
7318 | {
7319 | const nstime_t *value = fvalue_get_time(finfo->value);
7320 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7321 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7322 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7323 | }
7324 | if (hfinfo->strings) {
7325 | const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7326 | if (time_string != NULL((void*)0)) {
7327 | label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7328 | break;
7329 | }
7330 | }
7331 | tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7332 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7333 | wmem_free(NULL((void*)0), tmp_str);
7334 | break;
7335 | }
7336 |
7337 | case FT_RELATIVE_TIME:
7338 | tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7339 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7340 | wmem_free(NULL((void*)0), tmp_str);
7341 | break;
7342 |
7343 | case FT_BOOLEAN:
7344 | number64 = fvalue_get_uinteger64(finfo->value);
7345 | label_len = proto_strlcpy(display_label_str,
7346 | tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7347 | break;
7348 |
7349 | case FT_CHAR:
7350 | number = fvalue_get_uinteger(finfo->value);
7351 |
7352 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7353 | char tmp[ITEM_LABEL_LENGTH240];
7354 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7355 |
7356 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7356, "fmtfunc"))));
7357 | fmtfunc(tmp, number);
7358 |
7359 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7360 |
7361 | } else if (hfinfo->strings) {
7362 | number_out = hf_try_val_to_str(number, hfinfo);
7363 |
7364 | if (!number_out) {
7365 | number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7366 | }
7367 |
7368 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7369 |
7370 | } else {
7371 | number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7372 |
7373 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7374 | }
7375 |
7376 | break;
7377 |
7378 | /* XXX - make these just FT_NUMBER? */
7379 | case FT_INT8:
7380 | case FT_INT16:
7381 | case FT_INT24:
7382 | case FT_INT32:
7383 | case FT_UINT8:
7384 | case FT_UINT16:
7385 | case FT_UINT24:
7386 | case FT_UINT32:
7387 | case FT_FRAMENUM:
7388 | hf_str_val = NULL((void*)0);
7389 | 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 )) ?
7390 | (uint32_t) fvalue_get_sinteger(finfo->value) :
7391 | fvalue_get_uinteger(finfo->value);
7392 |
7393 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7394 | char tmp[ITEM_LABEL_LENGTH240];
7395 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7396 |
7397 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7397, "fmtfunc"))));
7398 | fmtfunc(tmp, number);
7399 |
7400 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7401 |
7402 | } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7403 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7404 | number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7405 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7406 | hf_str_val = hf_try_val_to_str(number, hfinfo);
7407 | if (hf_str_val)
7408 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7409 | } else {
7410 | number_out = hf_try_val_to_str(number, hfinfo);
7411 |
7412 | if (!number_out) {
7413 | number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7414 | }
7415 |
7416 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7417 | }
7418 | } else {
7419 | number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7420 |
7421 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7422 | }
7423 |
7424 | break;
7425 |
7426 | case FT_INT40:
7427 | case FT_INT48:
7428 | case FT_INT56:
7429 | case FT_INT64:
7430 | case FT_UINT40:
7431 | case FT_UINT48:
7432 | case FT_UINT56:
7433 | case FT_UINT64:
7434 | hf_str_val = NULL((void*)0);
7435 | 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 )) ?
7436 | (uint64_t) fvalue_get_sinteger64(finfo->value) :
7437 | fvalue_get_uinteger64(finfo->value);
7438 |
7439 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7440 | char tmp[ITEM_LABEL_LENGTH240];
7441 | custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7442 |
7443 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 7443, "fmtfunc64" ))));
7444 | fmtfunc64(tmp, number64);
7445 |
7446 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7447 | } else if (hfinfo->strings) {
7448 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7449 | number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7450 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7451 | hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7452 | if (hf_str_val)
7453 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7454 | } else {
7455 | number_out = hf_try_val64_to_str(number64, hfinfo);
7456 |
7457 | if (!number_out)
7458 | number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7459 |
7460 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7461 | }
7462 | } else {
7463 | number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7464 |
7465 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7466 | }
7467 |
7468 | break;
7469 |
7470 | case FT_EUI64:
7471 | set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7472 | tmp_str = address_to_display(NULL((void*)0), &addr);
7473 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7474 | wmem_free(NULL((void*)0), tmp_str);
7475 | break;
7476 |
7477 | case FT_IPv4:
7478 | ipv4 = fvalue_get_ipv4(finfo->value);
7479 | //XXX: Should we ignore the mask?
7480 | set_address_ipv4(&addr, ipv4);
7481 | tmp_str = address_to_display(NULL((void*)0), &addr);
7482 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7483 | wmem_free(NULL((void*)0), tmp_str);
7484 | free_address(&addr);
7485 | break;
7486 |
7487 | case FT_IPv6:
7488 | ipv6 = fvalue_get_ipv6(finfo->value);
7489 | set_address_ipv6(&addr, ipv6);
7490 | tmp_str = address_to_display(NULL((void*)0), &addr);
7491 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7492 | wmem_free(NULL((void*)0), tmp_str);
7493 | free_address(&addr);
7494 | break;
7495 |
7496 | case FT_FCWWN:
7497 | set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7498 | tmp_str = address_to_display(NULL((void*)0), &addr);
7499 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7500 | wmem_free(NULL((void*)0), tmp_str);
7501 | break;
7502 |
7503 | case FT_ETHER:
7504 | set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7505 | tmp_str = address_to_display(NULL((void*)0), &addr);
7506 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7507 | wmem_free(NULL((void*)0), tmp_str);
7508 | break;
7509 |
7510 | case FT_GUID:
7511 | tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7512 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7513 | wmem_free(NULL((void*)0), tmp_str);
7514 | break;
7515 |
7516 | case FT_REL_OID:
7517 | bytes = fvalue_get_bytes_data(finfo->value);
7518 | tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7519 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7520 | wmem_free(NULL((void*)0), tmp_str);
7521 | break;
7522 |
7523 | case FT_OID:
7524 | bytes = fvalue_get_bytes_data(finfo->value);
7525 | tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7526 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7527 | wmem_free(NULL((void*)0), tmp_str);
7528 | break;
7529 |
7530 | case FT_SYSTEM_ID:
7531 | bytes = fvalue_get_bytes_data(finfo->value);
7532 | tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7533 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7534 | wmem_free(NULL((void*)0), tmp_str);
7535 | break;
7536 |
7537 | case FT_FLOAT:
7538 | case FT_DOUBLE:
7539 | label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7540 | break;
7541 |
7542 | case FT_IEEE_11073_SFLOAT:
7543 | case FT_IEEE_11073_FLOAT:
7544 | label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7545 | break;
7546 |
7547 | case FT_STRING:
7548 | case FT_STRINGZ:
7549 | case FT_UINT_STRING:
7550 | case FT_STRINGZPAD:
7551 | case FT_STRINGZTRUNC:
7552 | str = fvalue_get_string(finfo->value);
7553 | label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7554 | if (label_len >= label_str_size) {
7555 | /* Truncation occurred. Get the real length
7556 | * copied (not including '\0') */
7557 | label_len = label_str_size ? label_str_size - 1 : 0;
7558 | }
7559 | break;
7560 |
7561 | default:
7562 | /* First try ftype string representation */
7563 | tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7564 | if (!tmp_str) {
7565 | /* Default to show as bytes */
7566 | bytes = fvalue_get_bytes_data(finfo->value);
7567 | tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo-> value), 36);
7568 | }
7569 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7570 | wmem_free(NULL((void*)0), tmp_str);
7571 | break;
7572 | }
7573 | return label_len;
7574 | }
7575 |
7576 | const char *
7577 | proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7578 | char *result, char *expr, const int size)
7579 | {
7580 | int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7581 | GPtrArray *finfos;
7582 | field_info *finfo = NULL((void*)0);
7583 | header_field_info* hfinfo;
7584 | const char *abbrev = NULL((void*)0);
7585 |
7586 | char *str;
7587 | col_custom_t *field_idx;
7588 | int field_id;
7589 | int ii = 0;
7590 |
7591 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7591, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7592 | while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7593 | field_id = field_idx->field_id;
7594 | if (field_id == 0) {
7595 | GPtrArray *fvals = NULL((void*)0);
7596 | bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7597 | if (fvals != NULL((void*)0)) {
7598 |
7599 | // XXX - Handling occurrences is unusual when more
7600 | // than one field is involved, e.g. there's four
7601 | // results for tcp.port + tcp.port. We may really
7602 | // want to apply it to the operands, not the output.
7603 | // Note that occurrences are not quite the same as
7604 | // the layer operator (should the grammar support
7605 | // both?)
7606 | /* Calculate single index or set outer boundaries */
7607 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7608 | if (occurrence < 0) {
7609 | i = occurrence + len;
7610 | last = i;
7611 | } else if (occurrence > 0) {
7612 | i = occurrence - 1;
7613 | last = i;
7614 | } else {
7615 | i = 0;
7616 | last = len - 1;
7617 | }
7618 | if (i < 0 || i >= len) {
7619 | g_ptr_array_unref(fvals);
7620 | continue;
7621 | }
7622 | for (; i <= last; i++) {
7623 | /* XXX - We could have a "resolved" result
7624 | * for types where the value depends only
7625 | * on the type, e.g. FT_IPv4, and not on
7626 | * hfinfo->strings. Supporting the latter
7627 | * requires knowing which hfinfo matched
7628 | * if there are multiple with the same
7629 | * abbreviation. In any case, we need to
7630 | * know the expected return type of the
7631 | * field expression.
7632 | */
7633 | str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7634 | if (offset_r && (offset_r < (size - 1)))
7635 | result[offset_r++] = ',';
7636 | if (offset_e && (offset_e < (size - 1)))
7637 | expr[offset_e++] = ',';
7638 | offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7639 | // col_{add,append,set}_* calls ws_label_strcpy
7640 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7641 |
7642 | g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized (str, __builtin_object_size ((str), 0)) : (g_free) (str);
7643 | }
7644 | g_ptr_array_unref(fvals);
7645 | } else if (passed) {
7646 | // XXX - Occurrence doesn't make sense for a test
7647 | // output, it should be applied to the operands.
7648 | if (offset_r && (offset_r < (size - 1)))
7649 | result[offset_r++] = ',';
7650 | if (offset_e && (offset_e < (size - 1)))
7651 | expr[offset_e++] = ',';
7652 | /* Prevent multiple check marks */
7653 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7654 | offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7655 | } else {
7656 | result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7657 | }
7658 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7659 | offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7660 | } else {
7661 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7662 | }
7663 | }
7664 | continue;
7665 | }
7666 | 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", 7666 , __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", 7666, "(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", 7666, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7667 |
7668 | /* do we need to rewind ? */
7669 | if (!hfinfo)
7670 | return "";
7671 |
7672 | if (occurrence < 0) {
7673 | /* Search other direction */
7674 | while (hfinfo->same_name_prev_id != -1) {
7675 | 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", 7675 , __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", 7675, "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", 7675, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7676 | }
7677 | }
7678 |
7679 | prev_len = 0; /* Reset handled occurrences */
7680 |
7681 | while (hfinfo) {
7682 | finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7683 |
7684 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7685 | if (occurrence < 0) {
7686 | hfinfo = hfinfo->same_name_next;
7687 | } else {
7688 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7689 | }
7690 | continue;
7691 | }
7692 |
7693 | /* Are there enough occurrences of the field? */
7694 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7695 | if (occurrence < 0) {
7696 | hfinfo = hfinfo->same_name_next;
7697 | } else {
7698 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7699 | }
7700 | prev_len += len;
7701 | continue;
7702 | }
7703 |
7704 | /* Calculate single index or set outer boundaries */
7705 | if (occurrence < 0) {
7706 | i = occurrence + len + prev_len;
7707 | last = i;
7708 | } else if (occurrence > 0) {
7709 | i = occurrence - 1 - prev_len;
7710 | last = i;
7711 | } else {
7712 | i = 0;
7713 | last = len - 1;
7714 | }
7715 |
7716 | prev_len += len; /* Count handled occurrences */
7717 |
7718 | while (i <= last) {
7719 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7720 |
7721 | if (offset_r && (offset_r < (size - 1)))
7722 | result[offset_r++] = ',';
7723 |
7724 | if (display_details) {
7725 | char representation[ITEM_LABEL_LENGTH240];
7726 | size_t offset = 0;
7727 |
7728 | if (finfo->rep && finfo->rep->value_len) {
7729 | (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7730 | MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo-> rep->value_len + 1) : (240)));
7731 | } else {
7732 | proto_item_fill_label(finfo, representation, &offset);
7733 | }
7734 | offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7735 | } else {
7736 | switch (hfinfo->type) {
7737 |
7738 | case FT_NONE:
7739 | case FT_PROTOCOL:
7740 | /* Prevent multiple check marks */
7741 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7742 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7743 | } else {
7744 | result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7745 | }
7746 | break;
7747 |
7748 | default:
7749 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7750 | break;
7751 | }
7752 | }
7753 |
7754 | if (offset_e && (offset_e < (size - 1)))
7755 | expr[offset_e++] = ',';
7756 |
7757 | 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 )))) {
7758 | const char *hf_str_val;
7759 | /* Integer types with BASE_NONE never get the numeric value. */
7760 | if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16 || (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32 )) {
7761 | hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7762 | } 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 )) {
7763 | hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7764 | } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48 || (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64 )) {
7765 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7766 | } else { // if (FT_IS_UINT64(hfinfo->type)) {
7767 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7768 | }
7769 | snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7770 | offset_e = (int)strlen(expr);
7771 | } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7772 | /* Prevent multiple check marks */
7773 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7774 | offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7775 | } else {
7776 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7777 | }
7778 | } else {
7779 | str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7780 | // col_{add,append,set}_* calls ws_label_strcpy
7781 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7782 | wmem_free(NULL((void*)0), str);
7783 | }
7784 | i++;
7785 | }
7786 |
7787 | /* XXX: Why is only the first abbreviation returned for a multifield
7788 | * custom column? */
7789 | if (!abbrev) {
7790 | /* Store abbrev for return value */
7791 | abbrev = hfinfo->abbrev;
7792 | }
7793 |
7794 | if (occurrence == 0) {
7795 | /* Fetch next hfinfo with same name (abbrev) */
7796 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7797 | } else {
7798 | hfinfo = NULL((void*)0);
7799 | }
7800 | }
7801 | }
7802 |
7803 | if (offset_r >= (size - 1)) {
7804 | mark_truncated(result, 0, size, NULL((void*)0));
7805 | }
7806 | if (offset_e >= (size - 1)) {
7807 | mark_truncated(expr, 0, size, NULL((void*)0));
7808 | }
7809 | return abbrev ? abbrev : "";
7810 | }
7811 |
7812 | char *
7813 | proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7814 | {
7815 | int len, prev_len, last, i;
7816 | GPtrArray *finfos;
7817 | field_info *finfo = NULL((void*)0);
7818 | header_field_info* hfinfo;
7819 |
7820 | char *filter = NULL((void*)0);
7821 | GPtrArray *filter_array;
7822 |
7823 | col_custom_t *col_custom;
7824 | int field_id;
7825 |
7826 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7826, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7827 | filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7828 | for (GSList *iter = field_ids; iter; iter = iter->next) {
7829 | col_custom = (col_custom_t*)iter->data;
7830 | field_id = col_custom->field_id;
7831 | if (field_id == 0) {
7832 | GPtrArray *fvals = NULL((void*)0);
7833 | bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7834 | if (fvals != NULL((void*)0)) {
7835 | // XXX - Handling occurrences is unusual when more
7836 | // than one field is involved, e.g. there's four
7837 | // results for tcp.port + tcp.port. We really
7838 | // want to apply it to the operands, not the output.
7839 | /* Calculate single index or set outer boundaries */
7840 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7841 | if (occurrence < 0) {
7842 | i = occurrence + len;
7843 | last = i;
7844 | } else if (occurrence > 0) {
7845 | i = occurrence - 1;
7846 | last = i;
7847 | } else {
7848 | i = 0;
7849 | last = len - 1;
7850 | }
7851 | if (i < 0 || i >= len) {
7852 | g_ptr_array_unref(fvals);
7853 | continue;
7854 | }
7855 | for (; i <= last; i++) {
7856 | /* XXX - Should multiple values for one
7857 | * field use set membership to reduce
7858 | * verbosity, here and below? */
7859 | char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7860 | filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7861 | wmem_free(NULL((void*)0), str);
7862 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7863 | g_ptr_array_add(filter_array, filter);
7864 | }
7865 | }
7866 | g_ptr_array_unref(fvals);
7867 | } else if (passed) {
7868 | filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7869 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7870 | g_ptr_array_add(filter_array, filter);
7871 | }
7872 | } else {
7873 | filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7874 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7875 | g_ptr_array_add(filter_array, filter);
7876 | }
7877 | }
7878 | continue;
7879 | }
7880 |
7881 | 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", 7881 , __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", 7881, "(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", 7881, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7882 |
7883 | /* do we need to rewind ? */
7884 | if (!hfinfo)
7885 | return NULL((void*)0);
7886 |
7887 | if (occurrence < 0) {
7888 | /* Search other direction */
7889 | while (hfinfo->same_name_prev_id != -1) {
7890 | 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", 7890 , __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", 7890, "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", 7890, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7891 | }
7892 | }
7893 |
7894 | prev_len = 0; /* Reset handled occurrences */
7895 |
7896 | while (hfinfo) {
7897 | finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7898 |
7899 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7900 | if (occurrence < 0) {
7901 | hfinfo = hfinfo->same_name_next;
7902 | } else {
7903 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7904 | }
7905 | continue;
7906 | }
7907 |
7908 | /* Are there enough occurrences of the field? */
7909 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7910 | if (occurrence < 0) {
7911 | hfinfo = hfinfo->same_name_next;
7912 | } else {
7913 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7914 | }
7915 | prev_len += len;
7916 | continue;
7917 | }
7918 |
7919 | /* Calculate single index or set outer boundaries */
7920 | if (occurrence < 0) {
7921 | i = occurrence + len + prev_len;
7922 | last = i;
7923 | } else if (occurrence > 0) {
7924 | i = occurrence - 1 - prev_len;
7925 | last = i;
7926 | } else {
7927 | i = 0;
7928 | last = len - 1;
7929 | }
7930 |
7931 | prev_len += len; /* Count handled occurrences */
7932 |
7933 | while (i <= last) {
7934 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7935 |
7936 | filter = proto_construct_match_selected_string(finfo, edt);
7937 | if (filter) {
7938 | /* Only add the same expression once (especially for FT_PROTOCOL).
7939 | * The ptr array doesn't have NULL entries so g_str_equal is fine.
7940 | */
7941 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7942 | g_ptr_array_add(filter_array, filter);
7943 | }
7944 | }
7945 | i++;
7946 | }
7947 |
7948 | if (occurrence == 0) {
7949 | /* Fetch next hfinfo with same name (abbrev) */
7950 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7951 | } else {
7952 | hfinfo = NULL((void*)0);
7953 | }
7954 | }
7955 | }
7956 |
7957 | g_ptr_array_add(filter_array, NULL((void*)0));
7958 |
7959 | /* XXX: Should this be || or && ? */
7960 | char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7961 |
7962 | g_ptr_array_free(filter_array, true1);
7963 |
7964 | return output;
7965 | }
7966 |
7967 | /* Set text of proto_item after having already been created. */
7968 | void
7969 | proto_item_set_text(proto_item *pi, const char *format, ...)
7970 | {
7971 | field_info *fi = NULL((void*)0);
7972 | va_list ap;
7973 |
7974 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7975 |
7976 | fi = PITEM_FINFO(pi)((pi)->finfo);
7977 | if (fi == NULL((void*)0))
7978 | return;
7979 |
7980 | if (fi->rep) {
7981 | ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep );;
7982 | fi->rep = NULL((void*)0);
7983 | }
7984 |
7985 | va_start(ap, format)__builtin_va_start(ap, format);
7986 | proto_tree_set_representation(pi, format, ap);
7987 | va_end(ap)__builtin_va_end(ap);
7988 | }
7989 |
7990 | /* Append to text of proto_item after having already been created. */
7991 | void
7992 | proto_item_append_text(proto_item *pi, const char *format, ...)
7993 | {
7994 | field_info *fi = NULL((void*)0);
7995 | size_t curlen;
7996 | char *str;
7997 | va_list ap;
7998 |
7999 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
8000 |
8001 | fi = PITEM_FINFO(pi)((pi)->finfo);
8002 | if (fi == NULL((void*)0)) {
8003 | return;
8004 | }
8005 |
8006 | if (!proto_item_is_hidden(pi)) {
8007 | /*
8008 | * If we don't already have a representation,
8009 | * generate the default representation.
8010 | */
8011 | if (fi->rep == NULL((void*)0)) {
8012 | 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;;
8013 | proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
8014 | /* Check for special case append value to FT_NONE or FT_PROTOCOL */
8015 | if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
8016 | (strncmp(format, ": ", 2) == 0)) {
8017 | fi->rep->value_pos += 2;
8018 | }
8019 | }
8020 | if (fi->rep) {
8021 | curlen = strlen(fi->rep->representation);
8022 | /* curlen doesn't include the \0 byte.
8023 | * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
8024 | * the representation has already been truncated (of an up
8025 | * to 4 byte UTF-8 character) or is just at the maximum length
8026 | * unless we search for " [truncated]" (which may not be
8027 | * at the start.)
8028 | * It's safer to do nothing.
8029 | */
8030 | if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8031 | va_start(ap, format)__builtin_va_start(ap, format);
8032 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8033 | va_end(ap)__builtin_va_end(ap);
8034 | 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" , 8034, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
8035 | /* Keep fi->rep->value_pos */
8036 | curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8037 | if (curlen >= ITEM_LABEL_LENGTH240) {
8038 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8039 | size_t name_pos = label_find_name_pos(fi->rep);
8040 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8041 | }
8042 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8043 | }
8044 | }
8045 | }
8046 | }
8047 |
8048 | /* Prepend to text of proto_item after having already been created. */
8049 | void
8050 | proto_item_prepend_text(proto_item *pi, const char *format, ...)
8051 | {
8052 | field_info *fi = NULL((void*)0);
8053 | size_t pos;
8054 | char representation[ITEM_LABEL_LENGTH240];
8055 | char *str;
8056 | va_list ap;
8057 |
8058 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
8059 |
8060 | fi = PITEM_FINFO(pi)((pi)->finfo);
8061 | if (fi == NULL((void*)0)) {
8062 | return;
8063 | }
8064 |
8065 | if (!proto_item_is_hidden(pi)) {
8066 | /*
8067 | * If we don't already have a representation,
8068 | * generate the default representation.
8069 | */
8070 | if (fi->rep == NULL((void*)0)) {
8071 | 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;;
8072 | proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8073 | } else
8074 | (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8075 |
8076 | va_start(ap, format)__builtin_va_start(ap, format);
8077 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8078 | va_end(ap)__builtin_va_end(ap);
8079 | 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" , 8079, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
8080 | fi->rep->value_pos += strlen(str);
8081 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8082 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8083 | /* XXX: As above, if the old representation is close to the label
8084 | * length, it might already be marked as truncated. */
8085 | if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8086 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8087 | size_t name_pos = label_find_name_pos(fi->rep);
8088 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8089 | }
8090 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8091 | }
8092 | }
8093 |
8094 | static void
8095 | finfo_set_len(field_info *fi, const unsigned length)
8096 | {
8097 | unsigned length_remaining;
8098 |
8099 | length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8100 | if (length > length_remaining)
8101 | fi->length = length_remaining;
8102 | else
8103 | fi->length = length;
8104 |
8105 | /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8106 | if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8107 | fvalue_set_protocol_length(fi->value, fi->length);
8108 | }
8109 |
8110 | /*
8111 | * You cannot just make the "len" field of a GByteArray
8112 | * larger, if there's no data to back that length;
8113 | * you can only make it smaller.
8114 | */
8115 | if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8116 | GBytes *bytes = fvalue_get_bytes(fi->value);
8117 | size_t size;
8118 | const void *data = g_bytes_get_data(bytes, &size);
8119 | if ((size_t)fi->length <= size) {
8120 | fvalue_set_bytes_data(fi->value, data, fi->length);
8121 | }
8122 | g_bytes_unref(bytes);
8123 | }
8124 | }
8125 |
8126 | void
8127 | proto_item_set_len(proto_item *pi, const unsigned length)
8128 | {
8129 | field_info *fi;
8130 |
8131 | if (pi == NULL((void*)0))
8132 | return;
8133 |
8134 | fi = PITEM_FINFO(pi)((pi)->finfo);
8135 | if (fi == NULL((void*)0))
8136 | return;
8137 |
8138 | finfo_set_len(fi, length);
8139 | }
8140 |
8141 | /*
8142 | * Sets the length of the item based on its start and on the specified
8143 | * offset, which is the offset past the end of the item; as the start
8144 | * in the item is relative to the beginning of the data source tvbuff,
8145 | * we need to pass in a tvbuff - the end offset is relative to the beginning
8146 | * of that tvbuff.
8147 | */
8148 | void
8149 | proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8150 | {
8151 | field_info *fi;
8152 | unsigned length;
8153 |
8154 | if (pi == NULL((void*)0))
8155 | return;
8156 |
8157 | fi = PITEM_FINFO(pi)((pi)->finfo);
8158 | if (fi == NULL((void*)0))
8159 | return;
8160 |
8161 | if (G_LIKELY(tvb)(tvb)) {
8162 | 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" , 8162, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))));
8163 | end += tvb_raw_offset(tvb);
8164 | } else {
8165 | 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", 8165, "((void*)0) == fi->ds_tvb" ))));
8166 | }
8167 | DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8167, "end >= fi->start" ))));
8168 | length = end - fi->start;
8169 |
8170 | finfo_set_len(fi, length);
8171 | }
8172 |
8173 | unsigned
8174 | proto_item_get_len(const proto_item *pi)
8175 | {
8176 | /* XXX - The only use case where this is really guaranteed to work is
8177 | * increasing the length of an item (which has no effect if the item
8178 | * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8179 | *
8180 | * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8181 | *
8182 | * Should there be a macro or function to do that, and possibly this
8183 | * be deprecated? As a bonus, we could handle overflow.
8184 | */
8185 | field_info *fi;
8186 |
8187 | if (!pi)
8188 | return 0;
8189 | fi = PITEM_FINFO(pi)((pi)->finfo);
8190 | if (fi) {
8191 | return fi->length;
8192 | }
8193 | return 0;
8194 | }
8195 |
8196 | void
8197 | proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8198 | if (!ti) {
8199 | return;
8200 | }
8201 | 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);
8202 | 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);
8203 | }
8204 |
8205 | char *
8206 | proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8207 | {
8208 | field_info *fi;
8209 |
8210 | if (!pi)
8211 | return wmem_strdup(scope, "");
8212 | fi = PITEM_FINFO(pi)((pi)->finfo);
8213 | if (!fi)
8214 | return wmem_strdup(scope, "");
8215 | DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8215, "fi->hfinfo != ((void*)0)" ))));
8216 | return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8217 | }
8218 |
8219 | proto_tree *
8220 | proto_tree_create_root(packet_info *pinfo)
8221 | {
8222 | proto_node *pnode;
8223 |
8224 | /* Initialize the proto_node */
8225 | pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof (proto_tree) : 1)));
8226 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
8227 | pnode->parent = NULL((void*)0);
8228 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8229 | 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)));
8230 |
8231 | /* Make sure we can access pinfo everywhere */
8232 | pnode->tree_data->pinfo = pinfo;
8233 |
8234 | /* Don't initialize the tree_data_t. Wait until we know we need it */
8235 | pnode->tree_data->interesting_hfids = NULL((void*)0);
8236 |
8237 | /* Set the default to false so it's easier to
8238 | * find errors; if we expect to see the protocol tree
8239 | * but for some reason the default 'visible' is not
8240 | * changed, then we'll find out very quickly. */
8241 | pnode->tree_data->visible = false0;
8242 |
8243 | /* Make sure that we fake protocols (if possible) */
8244 | pnode->tree_data->fake_protocols = true1;
8245 |
8246 | /* Keep track of the number of children */
8247 | pnode->tree_data->count = 0;
8248 |
8249 | /* Initialize our loop checks */
8250 | pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8251 | pnode->tree_data->max_start = 0;
8252 | pnode->tree_data->start_idle_count = 0;
8253 |
8254 | return (proto_tree *)pnode;
8255 | }
8256 |
8257 |
8258 | /* "prime" a proto_tree with a single hfid that a dfilter
8259 | * is interested in. */
8260 | void
8261 | proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8262 | {
8263 | header_field_info *hfinfo;
8264 |
8265 | 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", 8265, __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", 8265, "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", 8265, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8266 | /* this field is referenced by a filter so increase the refcount.
8267 | also increase the refcount for the parent, i.e the protocol.
8268 | Don't increase the refcount if we're already printing the
8269 | type, as that is a superset of direct reference.
8270 | */
8271 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8272 | hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8273 | }
8274 | /* only increase the refcount if there is a parent.
8275 | if this is a protocol and not a field then parent will be -1
8276 | and there is no parent to add any refcounting for.
8277 | */
8278 | if (hfinfo->parent != -1) {
8279 | header_field_info *parent_hfinfo;
8280 | 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", 8280 , __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", 8280, "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", 8280, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8281 |
8282 | /* Mark parent as indirectly referenced unless it is already directly
8283 | * referenced, i.e. the user has specified the parent in a filter.
8284 | */
8285 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8286 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8287 | }
8288 | }
8289 |
8290 | /* "prime" a proto_tree with a single hfid that a dfilter
8291 | * is interested in. */
8292 | void
8293 | proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8294 | {
8295 | header_field_info *hfinfo;
8296 |
8297 | 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", 8297, __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", 8297, "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", 8297, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8298 | /* this field is referenced by an (output) filter so increase the refcount.
8299 | also increase the refcount for the parent, i.e the protocol.
8300 | */
8301 | hfinfo->ref_type = HF_REF_TYPE_PRINT;
8302 | /* only increase the refcount if there is a parent.
8303 | if this is a protocol and not a field then parent will be -1
8304 | and there is no parent to add any refcounting for.
8305 | */
8306 | if (hfinfo->parent != -1) {
8307 | header_field_info *parent_hfinfo;
8308 | 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", 8308 , __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", 8308, "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", 8308, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8309 |
8310 | /* Mark parent as indirectly referenced unless it is already directly
8311 | * referenced, i.e. the user has specified the parent in a filter.
8312 | */
8313 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8314 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8315 | }
8316 | }
8317 |
8318 | proto_tree *
8319 | proto_item_add_subtree(proto_item *pi, const int idx) {
8320 | field_info *fi;
8321 |
8322 | if (!pi)
8323 | return NULL((void*)0);
8324 |
8325 | 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", 8325, "idx >= 0 && idx < num_tree_types" ))));
8326 |
8327 | fi = PITEM_FINFO(pi)((pi)->finfo);
8328 | if (!fi)
8329 | return (proto_tree *)pi;
8330 |
8331 | fi->tree_type = idx;
8332 |
8333 | return (proto_tree *)pi;
8334 | }
8335 |
8336 | proto_tree *
8337 | proto_item_get_subtree(proto_item *pi) {
8338 | field_info *fi;
8339 |
8340 | if (!pi)
8341 | return NULL((void*)0);
8342 | fi = PITEM_FINFO(pi)((pi)->finfo);
8343 | if ( (fi) && (fi->tree_type == -1) )
8344 | return NULL((void*)0);
8345 | return (proto_tree *)pi;
8346 | }
8347 |
8348 | proto_item *
8349 | proto_item_get_parent(const proto_item *ti) {
8350 | if (!ti)
8351 | return NULL((void*)0);
8352 | return ti->parent;
8353 | }
8354 |
8355 | proto_item *
8356 | proto_item_get_parent_nth(proto_item *ti, int gen) {
8357 | if (!ti)
8358 | return NULL((void*)0);
8359 | while (gen--) {
8360 | ti = ti->parent;
8361 | if (!ti)
8362 | return NULL((void*)0);
8363 | }
8364 | return ti;
8365 | }
8366 |
8367 |
8368 | proto_item *
8369 | proto_tree_get_parent(proto_tree *tree) {
8370 | if (!tree)
8371 | return NULL((void*)0);
8372 | return (proto_item *)tree;
8373 | }
8374 |
8375 | proto_tree *
8376 | proto_tree_get_parent_tree(proto_tree *tree) {
8377 | if (!tree)
8378 | return NULL((void*)0);
8379 |
8380 | /* we're the root tree, there's no parent
8381 | return ourselves so the caller has at least a tree to attach to */
8382 | if (!tree->parent)
8383 | return tree;
8384 |
8385 | return (proto_tree *)tree->parent;
8386 | }
8387 |
8388 | proto_tree *
8389 | proto_tree_get_root(proto_tree *tree) {
8390 | if (!tree)
8391 | return NULL((void*)0);
8392 | while (tree->parent) {
8393 | tree = tree->parent;
8394 | }
8395 | return tree;
8396 | }
8397 |
8398 | void
8399 | proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8400 | proto_item *item_to_move)
8401 | {
8402 | /* This function doesn't generate any values. It only reorganizes the protocol tree
8403 | * so we can bail out immediately if it isn't visible. */
8404 | if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8405 | return;
8406 |
8407 | 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", 8407, "item_to_move->parent == tree" ))));
8408 | 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", 8408, "fixed_item->parent == tree" ))));
8409 |
8410 | /*** cut item_to_move out ***/
8411 |
8412 | /* is item_to_move the first? */
8413 | if (tree->first_child == item_to_move) {
8414 | /* simply change first child to next */
8415 | tree->first_child = item_to_move->next;
8416 |
8417 | 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", 8417, "tree->last_child != item_to_move" ))));
8418 | } else {
8419 | proto_item *curr_item;
8420 | /* find previous and change it's next */
8421 | for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8422 | if (curr_item->next == item_to_move) {
8423 | break;
8424 | }
8425 | }
8426 |
8427 | DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 8427, "curr_item" ))));
8428 |
8429 | curr_item->next = item_to_move->next;
8430 |
8431 | /* fix last_child if required */
8432 | if (tree->last_child == item_to_move) {
8433 | tree->last_child = curr_item;
8434 | }
8435 | }
8436 |
8437 | /*** insert to_move after fixed ***/
8438 | item_to_move->next = fixed_item->next;
8439 | fixed_item->next = item_to_move;
8440 | if (tree->last_child == fixed_item) {
8441 | tree->last_child = item_to_move;
8442 | }
8443 | }
8444 |
8445 | void
8446 | proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8447 | const unsigned length)
8448 | {
8449 | field_info *fi;
8450 |
8451 | if (tree == NULL((void*)0))
8452 | return;
8453 |
8454 | fi = PTREE_FINFO(tree)((tree)->finfo);
8455 | if (fi == NULL((void*)0))
8456 | return;
8457 |
8458 | /* We don't store a separate data source tvb for the appendix, so
8459 | * it must be from the same data source. (XXX - Are there any
8460 | * situations where it makes sense to have an appendix from a
8461 | * different data source?) */
8462 | if (G_LIKELY(tvb)(tvb)) {
8463 | 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" , 8463, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))));
8464 | start += tvb_raw_offset(tvb);
8465 | } else {
8466 | 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", 8466, "((void*)0) == fi->ds_tvb" ))));
8467 | }
8468 |
8469 | /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8470 | * main body? */
8471 |
8472 | fi->appendix_start = start;
8473 | fi->appendix_length = length;
8474 | }
8475 |
8476 | static void
8477 | check_protocol_filter_name_or_fail(const char *filter_name)
8478 | {
8479 | /* Require at least two characters. */
8480 | if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8481 | 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);
8482 | }
8483 |
8484 | if (proto_check_field_name(filter_name) != '\0') {
8485 | 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)
8486 | " 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)
8487 | " 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);
8488 | }
8489 |
8490 | /* Check that it doesn't match some very common numeric forms. */
8491 | if (filter_name[0] == '0' &&
8492 | (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8493 | filter_name[1] == 'b' || filter_name[1] == 'B')) {
8494 | 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])
8495 | 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]);
8496 | }
8497 |
8498 | /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8499 |
8500 | /* Check that it contains at least one letter. */
8501 | bool_Bool have_letter = false0;
8502 | for (const char *s = filter_name; *s != '\0'; s++) {
8503 | if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8504 | have_letter = true1;
8505 | break;
8506 | }
8507 | }
8508 | if (!have_letter) {
8509 | 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)
8510 | filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z." , filter_name);
8511 | }
8512 |
8513 | /* Check for reserved keywords. */
8514 | if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8515 | 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)
8516 | " 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);
8517 | }
8518 | }
8519 |
8520 | int
8521 | proto_register_protocol(const char *name, const char *short_name,
8522 | const char *filter_name)
8523 | {
8524 | protocol_t *protocol;
8525 | header_field_info *hfinfo;
8526 |
8527 | check_protocol_filter_name_or_fail(filter_name);
8528 |
8529 | /*
8530 | * Add this protocol to the list of known protocols;
8531 | * the list is sorted by protocol short name.
8532 | */
8533 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8534 | protocol->name = name;
8535 | protocol->short_name = short_name;
8536 | protocol->filter_name = filter_name;
8537 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8538 | protocol->is_enabled = true1; /* protocol is enabled by default */
8539 | protocol->enabled_by_default = true1; /* see previous comment */
8540 | protocol->can_toggle = true1;
8541 | protocol->parent_proto_id = -1;
8542 | protocol->heur_list = NULL((void*)0);
8543 |
8544 | /* List will be sorted later by name, when all protocols completed registering */
8545 | protocols = g_list_prepend(protocols, protocol);
8546 | /*
8547 | * Make sure there's not already a protocol with any of those
8548 | * names. Crash if there is, as that's an error in the code
8549 | * or an inappropriate plugin.
8550 | * This situation has to be fixed to not register more than one
8551 | * protocol with the same name.
8552 | */
8553 | if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8554 | /* ws_error will terminate the program */
8555 | 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)
8556 | " 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);
8557 | }
8558 | if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8559 | 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)
8560 | " 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);
8561 | }
8562 | if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8563 | 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)
8564 | " 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);
8565 | }
8566 |
8567 | /* Here we allocate a new header_field_info struct */
8568 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info ) > 0 ? sizeof (header_field_info) : 1)));
8569 | hfinfo->name = name;
8570 | hfinfo->abbrev = filter_name;
8571 | hfinfo->type = FT_PROTOCOL;
8572 | hfinfo->display = BASE_NONE;
8573 | hfinfo->strings = protocol;
8574 | hfinfo->bitmask = 0;
8575 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8576 | hfinfo->blurb = NULL((void*)0);
8577 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8578 |
8579 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8580 | return protocol->proto_id;
8581 | }
8582 |
8583 | int
8584 | proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8585 | {
8586 | protocol_t *protocol;
8587 | header_field_info *hfinfo;
8588 |
8589 | /*
8590 | * Helper protocols don't need the strict rules as a "regular" protocol
8591 | * Just register it in a list and make a hf_ field from it
8592 | */
8593 | if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8594 | 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);
8595 | }
8596 |
8597 | if (parent_proto <= 0) {
8598 | 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)
8599 | " 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);
8600 | }
8601 |
8602 | check_protocol_filter_name_or_fail(filter_name);
8603 |
8604 | /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8605 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8606 | protocol->name = name;
8607 | protocol->short_name = short_name;
8608 | protocol->filter_name = filter_name;
8609 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8610 |
8611 | /* Enabling and toggling is really determined by parent protocol,
8612 | but provide default values here */
8613 | protocol->is_enabled = true1;
8614 | protocol->enabled_by_default = true1;
8615 | protocol->can_toggle = true1;
8616 |
8617 | protocol->parent_proto_id = parent_proto;
8618 | protocol->heur_list = NULL((void*)0);
8619 |
8620 | /* List will be sorted later by name, when all protocols completed registering */
8621 | protocols = g_list_prepend(protocols, protocol);
8622 |
8623 | /* Here we allocate a new header_field_info struct */
8624 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info ) > 0 ? sizeof (header_field_info) : 1)));
8625 | hfinfo->name = name;
8626 | hfinfo->abbrev = filter_name;
8627 | hfinfo->type = field_type;
8628 | hfinfo->display = BASE_NONE;
8629 | if (field_type == FT_BYTES) {
8630 | hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8631 | }
8632 | hfinfo->strings = protocol;
8633 | hfinfo->bitmask = 0;
8634 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8635 | hfinfo->blurb = NULL((void*)0);
8636 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8637 |
8638 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8639 | return protocol->proto_id;
8640 | }
8641 |
8642 | bool_Bool
8643 | proto_deregister_protocol(const char *short_name)
8644 | {
8645 | protocol_t *protocol;
8646 | header_field_info *hfinfo;
8647 | int proto_id;
8648 | unsigned i;
8649 |
8650 | proto_id = proto_get_id_by_short_name(short_name);
8651 | protocol = find_protocol_by_id(proto_id);
8652 | if (protocol == NULL((void*)0))
8653 | return false0;
8654 |
8655 | g_hash_table_remove(proto_names, protocol->name);
8656 | g_hash_table_remove(proto_short_names, (void *)short_name);
8657 | g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8658 |
8659 | if (protocol->fields) {
8660 | for (i = 0; i < protocol->fields->len; i++) {
8661 | hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8662 | hfinfo_remove_from_gpa_name_map(hfinfo);
8663 | expert_deregister_expertinfo(hfinfo->abbrev);
8664 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8665 | }
8666 | g_ptr_array_free(protocol->fields, true1);
8667 | protocol->fields = NULL((void*)0);
8668 | }
8669 |
8670 | g_list_free(protocol->heur_list);
8671 |
8672 | /* Remove this protocol from the list of known protocols */
8673 | protocols = g_list_remove(protocols, protocol);
8674 |
8675 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8676 | wmem_map_remove(gpa_name_map, protocol->filter_name);
8677 |
8678 | 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);
8679 | last_field_name = NULL((void*)0);
8680 |
8681 | return true1;
8682 | }
8683 |
8684 | void
8685 | proto_register_alias(const int proto_id, const char *alias_name)
8686 | {
8687 | protocol_t *protocol;
8688 |
8689 | protocol = find_protocol_by_id(proto_id);
8690 | if (alias_name && protocol) {
8691 | g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8692 | }
8693 | }
8694 |
8695 | /*
8696 | * Routines to use to iterate over the protocols.
8697 | * The argument passed to the iterator routines is an opaque cookie to
8698 | * their callers; it's the GList pointer for the current element in
8699 | * the list.
8700 | * The ID of the protocol is returned, or -1 if there is no protocol.
8701 | */
8702 | int
8703 | proto_get_first_protocol(void **cookie)
8704 | {
8705 | protocol_t *protocol;
8706 |
8707 | if (protocols == NULL((void*)0))
8708 | return -1;
8709 | *cookie = protocols;
8710 | protocol = (protocol_t *)protocols->data;
8711 | return protocol->proto_id;
8712 | }
8713 |
8714 | int
8715 | proto_get_data_protocol(void *cookie)
8716 | {
8717 | GList *list_item = (GList *)cookie;
8718 |
8719 | protocol_t *protocol = (protocol_t *)list_item->data;
8720 | return protocol->proto_id;
8721 | }
8722 |
8723 | int
8724 | proto_get_next_protocol(void **cookie)
8725 | {
8726 | GList *list_item = (GList *)*cookie;
8727 | protocol_t *protocol;
8728 |
8729 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8730 | if (list_item == NULL((void*)0))
8731 | return -1;
8732 | *cookie = list_item;
8733 | protocol = (protocol_t *)list_item->data;
8734 | return protocol->proto_id;
8735 | }
8736 |
8737 | header_field_info *
8738 | proto_get_first_protocol_field(const int proto_id, void **cookie)
8739 | {
8740 | protocol_t *protocol = find_protocol_by_id(proto_id);
8741 |
8742 | if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8743 | return NULL((void*)0);
8744 |
8745 | *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8746 | return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8747 | }
8748 |
8749 | header_field_info *
8750 | proto_get_next_protocol_field(const int proto_id, void **cookie)
8751 | {
8752 | protocol_t *protocol = find_protocol_by_id(proto_id);
8753 | unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8754 |
8755 | i++;
8756 |
8757 | if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8758 | return NULL((void*)0);
8759 |
8760 | *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8761 | return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8762 | }
8763 |
8764 | protocol_t *
8765 | find_protocol_by_id(const int proto_id)
8766 | {
8767 | header_field_info *hfinfo;
8768 |
8769 | if (proto_id <= 0)
8770 | return NULL((void*)0);
8771 |
8772 | 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", 8772, __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", 8772, "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", 8772, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
8773 | if (hfinfo->type != FT_PROTOCOL) {
8774 | 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", 8774, "hfinfo->display & 0x00004000" ))));
8775 | }
8776 | return (protocol_t *)hfinfo->strings;
8777 | }
8778 |
8779 | int
8780 | proto_get_id(const protocol_t *protocol)
8781 | {
8782 | return protocol->proto_id;
8783 | }
8784 |
8785 | bool_Bool
8786 | proto_name_already_registered(const char *name)
8787 | {
8788 | DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 8788, "name", "No name present"))));
8789 |
8790 | if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8791 | return true1;
8792 | return false0;
8793 | }
8794 |
8795 | int
8796 | proto_get_id_by_filter_name(const char *filter_name)
8797 | {
8798 | const protocol_t *protocol = NULL((void*)0);
8799 |
8800 | 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", 8800, "filter_name", "No filter name present"))));
8801 |
8802 | protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8803 |
8804 | if (protocol == NULL((void*)0))
8805 | return -1;
8806 | return protocol->proto_id;
8807 | }
8808 |
8809 | int
8810 | proto_get_id_by_short_name(const char *short_name)
8811 | {
8812 | const protocol_t *protocol = NULL((void*)0);
8813 |
8814 | 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", 8814, "short_name", "No short name present"))));
8815 |
8816 | protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8817 |
8818 | if (protocol == NULL((void*)0))
8819 | return -1;
8820 | return protocol->proto_id;
8821 | }
8822 |
8823 | const char *
8824 | proto_get_protocol_name(const int proto_id)
8825 | {
8826 | protocol_t *protocol;
8827 |
8828 | protocol = find_protocol_by_id(proto_id);
8829 |
8830 | if (protocol == NULL((void*)0))
8831 | return NULL((void*)0);
8832 | return protocol->name;
8833 | }
8834 |
8835 | const char *
8836 | proto_get_protocol_short_name(const protocol_t *protocol)
8837 | {
8838 | if (protocol == NULL((void*)0))
8839 | return "(none)";
8840 | return protocol->short_name;
8841 | }
8842 |
8843 | const char *
8844 | proto_get_protocol_long_name(const protocol_t *protocol)
8845 | {
8846 | if (protocol == NULL((void*)0))
8847 | return "(none)";
8848 | return protocol->name;
8849 | }
8850 |
8851 | const char *
8852 | proto_get_protocol_filter_name(const int proto_id)
8853 | {
8854 | protocol_t *protocol;
8855 |
8856 | protocol = find_protocol_by_id(proto_id);
8857 | if (protocol == NULL((void*)0))
8858 | return "(none)";
8859 | return protocol->filter_name;
8860 | }
8861 |
8862 | void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8863 | {
8864 | heur_dtbl_entry_t* heuristic_dissector;
8865 |
8866 | if (protocol == NULL((void*)0))
8867 | return;
8868 |
8869 | heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8870 | if (heuristic_dissector != NULL((void*)0))
8871 | {
8872 | protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8873 | }
8874 | }
8875 |
8876 | void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8877 | {
8878 | if (protocol == NULL((void*)0))
8879 | return;
8880 |
8881 | g_list_foreach(protocol->heur_list, func, user_data);
8882 | }
8883 |
8884 | void
8885 | proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8886 | bool_Bool *is_tcp, bool_Bool *is_udp,
8887 | bool_Bool *is_sctp, bool_Bool *is_tls,
8888 | bool_Bool *is_rtp,
8889 | bool_Bool *is_lte_rlc)
8890 | {
8891 | wmem_list_frame_t *protos = wmem_list_head(layers);
8892 | int proto_id;
8893 | const char *proto_name;
8894 |
8895 | /* Walk the list of a available protocols in the packet and
8896 | attempt to find "major" ones. */
8897 | /* It might make more sense to assemble and return a bitfield. */
8898 | while (protos != NULL((void*)0))
8899 | {
8900 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8901 | proto_name = proto_get_protocol_filter_name(proto_id);
8902 |
8903 | if (is_ip && ((!strcmp(proto_name, "ip")) ||
8904 | (!strcmp(proto_name, "ipv6")))) {
8905 | *is_ip = true1;
8906 | } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8907 | *is_tcp = true1;
8908 | } else if (is_udp && !strcmp(proto_name, "udp")) {
8909 | *is_udp = true1;
8910 | } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8911 | *is_sctp = true1;
8912 | } else if (is_tls && !strcmp(proto_name, "tls")) {
8913 | *is_tls = true1;
8914 | } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8915 | *is_rtp = true1;
8916 | } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8917 | *is_lte_rlc = true1;
8918 | }
8919 |
8920 | protos = wmem_list_frame_next(protos);
8921 | }
8922 | }
8923 |
8924 | bool_Bool
8925 | proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8926 | {
8927 | wmem_list_frame_t *protos = wmem_list_head(layers);
8928 | int proto_id;
8929 | const char *name;
8930 |
8931 | /* Walk the list of a available protocols in the packet and
8932 | attempt to find the specified protocol. */
8933 | while (protos != NULL((void*)0))
8934 | {
8935 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8936 | name = proto_get_protocol_filter_name(proto_id);
8937 |
8938 | if (!strcmp(name, proto_name))
8939 | {
8940 | return true1;
8941 | }
8942 |
8943 | protos = wmem_list_frame_next(protos);
8944 | }
8945 |
8946 | return false0;
8947 | }
8948 |
8949 | char *
8950 | proto_list_layers(const packet_info *pinfo)
8951 | {
8952 | wmem_strbuf_t *buf;
8953 | wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8954 |
8955 | buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8956 |
8957 | /* Walk the list of layers in the packet and
8958 | return a string of all entries. */
8959 | while (layers != NULL((void*)0))
8960 | {
8961 | wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8962 |
8963 | layers = wmem_list_frame_next(layers);
8964 | if (layers != NULL((void*)0)) {
8965 | wmem_strbuf_append_c(buf, ':');
8966 | }
8967 | }
8968 |
8969 | return wmem_strbuf_finalize(buf);
8970 | }
8971 |
8972 | uint8_t
8973 | proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8974 | {
8975 | int *proto_layer_num_ptr;
8976 |
8977 | proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8978 | if (proto_layer_num_ptr == NULL((void*)0)) {
8979 | return 0;
8980 | }
8981 |
8982 | return (uint8_t)*proto_layer_num_ptr;
8983 | }
8984 |
8985 | bool_Bool
8986 | proto_is_pino(const protocol_t *protocol)
8987 | {
8988 | return (protocol->parent_proto_id != -1);
8989 | }
8990 |
8991 | bool_Bool
8992 | // NOLINTNEXTLINE(misc-no-recursion)
8993 | proto_is_protocol_enabled(const protocol_t *protocol)
8994 | {
8995 | if (protocol == NULL((void*)0))
8996 | return false0;
8997 |
8998 | //parent protocol determines enable/disable for helper dissectors
8999 | if (proto_is_pino(protocol))
9000 | return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
9001 |
9002 | return protocol->is_enabled;
9003 | }
9004 |
9005 | bool_Bool
9006 | // NOLINTNEXTLINE(misc-no-recursion)
9007 | proto_is_protocol_enabled_by_default(const protocol_t *protocol)
9008 | {
9009 | //parent protocol determines enable/disable for helper dissectors
9010 | if (proto_is_pino(protocol))
9011 | return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
9012 |
9013 | return protocol->enabled_by_default;
9014 | }
9015 |
9016 | bool_Bool
9017 | // NOLINTNEXTLINE(misc-no-recursion)
9018 | proto_can_toggle_protocol(const int proto_id)
9019 | {
9020 | protocol_t *protocol;
9021 |
9022 | protocol = find_protocol_by_id(proto_id);
9023 | //parent protocol determines toggling for helper dissectors
9024 | if (proto_is_pino(protocol))
9025 | return proto_can_toggle_protocol(protocol->parent_proto_id);
9026 |
9027 | return protocol->can_toggle;
9028 | }
9029 |
9030 | void
9031 | proto_disable_by_default(const int proto_id)
9032 | {
9033 | protocol_t *protocol;
9034 |
9035 | protocol = find_protocol_by_id(proto_id);
9036 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9036, "protocol->can_toggle" ))));
9037 | 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", 9037, "proto_is_pino(protocol) == 0" ))));
9038 | protocol->is_enabled = false0;
9039 | protocol->enabled_by_default = false0;
9040 | }
9041 |
9042 | void
9043 | proto_set_decoding(const int proto_id, const bool_Bool enabled)
9044 | {
9045 | protocol_t *protocol;
9046 |
9047 | protocol = find_protocol_by_id(proto_id);
9048 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9048, "protocol->can_toggle" ))));
9049 | 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", 9049, "proto_is_pino(protocol) == 0" ))));
9050 | protocol->is_enabled = enabled;
9051 | }
9052 |
9053 | void
9054 | proto_disable_all(void)
9055 | {
9056 | /* This doesn't explicitly disable heuristic protocols,
9057 | * but the heuristic doesn't get called if the parent
9058 | * protocol isn't enabled.
9059 | */
9060 | protocol_t *protocol;
9061 | GList *list_item = protocols;
9062 |
9063 | if (protocols == NULL((void*)0))
9064 | return;
9065 |
9066 | while (list_item) {
9067 | protocol = (protocol_t *)list_item->data;
9068 | if (protocol->can_toggle) {
9069 | protocol->is_enabled = false0;
9070 | }
9071 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
9072 | }
9073 | }
9074 |
9075 | static void
9076 | heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9077 | {
9078 | heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9079 |
9080 | heur->enabled = heur->enabled_by_default;
9081 | }
9082 |
9083 | void
9084 | proto_reenable_all(void)
9085 | {
9086 | protocol_t *protocol;
9087 | GList *list_item = protocols;
9088 |
9089 | if (protocols == NULL((void*)0))
9090 | return;
9091 |
9092 | while (list_item) {
9093 | protocol = (protocol_t *)list_item->data;
9094 | if (protocol->can_toggle)
9095 | protocol->is_enabled = protocol->enabled_by_default;
9096 | proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9097 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
9098 | }
9099 | }
9100 |
9101 | void
9102 | proto_set_cant_toggle(const int proto_id)
9103 | {
9104 | protocol_t *protocol;
9105 |
9106 | protocol = find_protocol_by_id(proto_id);
9107 | protocol->can_toggle = false0;
9108 | }
9109 |
9110 | static int
9111 | proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9112 | {
9113 | g_ptr_array_add(proto->fields, hfi);
9114 |
9115 | return proto_register_field_init(hfi, parent);
9116 | }
9117 |
9118 | /* for use with static arrays only, since we don't allocate our own copies
9119 | of the header_field_info struct contained within the hf_register_info struct */
9120 | void
9121 | proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9122 | {
9123 | hf_register_info *ptr = hf;
9124 | protocol_t *proto;
9125 | int i;
9126 |
9127 | proto = find_protocol_by_id(parent);
9128 |
9129 | /* if (proto == NULL) - error or return? */
9130 |
9131 | if (proto->fields == NULL((void*)0)) {
9132 | /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9133 | * GLib introduced g_ptr_array_new_from_array, which might have
9134 | * given a reason to actually use it. (#17774)
9135 | */
9136 | proto->fields = g_ptr_array_sized_new(num_records);
9137 | }
9138 |
9139 | for (i = 0; i < num_records; i++, ptr++) {
9140 | /*
9141 | * Make sure we haven't registered this yet.
9142 | * Most fields have variables associated with them that
9143 | * are initialized to 0; some are initialized to -1 (which
9144 | * was the standard before 4.4).
9145 | *
9146 | * XXX - Since this is called almost 300000 times at startup,
9147 | * it might be nice to compare to only 0 and require
9148 | * dissectors to pass in zero for unregistered fields.
9149 | */
9150 | if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9151 | REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev)
9152 | "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)
9153 | ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev);
9154 | return;
9155 | }
9156 |
9157 | *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9158 | }
9159 | }
9160 |
9161 | /* deregister already registered fields */
9162 | void
9163 | proto_deregister_field (const int parent, int hf_id)
9164 | {
9165 | header_field_info *hfi;
9166 | protocol_t *proto;
9167 | unsigned i;
9168 |
9169 | 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);
9170 | last_field_name = NULL((void*)0);
9171 |
9172 | if (hf_id == -1 || hf_id == 0)
9173 | return;
9174 |
9175 | proto = find_protocol_by_id (parent);
9176 | if (!proto || proto->fields == NULL((void*)0)) {
9177 | return;
9178 | }
9179 |
9180 | for (i = 0; i < proto->fields->len; i++) {
9181 | hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9182 | if (hfi->id == hf_id) {
9183 | /* Found the hf_id in this protocol */
9184 | wmem_map_remove(gpa_name_map, hfi->abbrev);
9185 | g_ptr_array_remove_index_fast(proto->fields, i);
9186 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9187 | return;
9188 | }
9189 | }
9190 | }
9191 |
9192 | /* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9193 | void
9194 | proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9195 | {
9196 | header_field_info *hfinfo;
9197 | protocol_t *proto;
9198 |
9199 | 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);
9200 | last_field_name = NULL((void*)0);
9201 |
9202 | proto = find_protocol_by_id(parent);
9203 | if (proto && proto->fields && proto->fields->len > 0) {
9204 | unsigned i = proto->fields->len;
9205 | do {
9206 | i--;
9207 |
9208 | hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9209 | 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) )) {
9210 | hfinfo_remove_from_gpa_name_map(hfinfo);
9211 | expert_deregister_expertinfo(hfinfo->abbrev);
9212 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9213 | g_ptr_array_remove_index_fast(proto->fields, i);
9214 | }
9215 | } while (i > 0);
9216 | }
9217 | }
9218 |
9219 | void
9220 | proto_add_deregistered_data (void *data)
9221 | {
9222 | g_ptr_array_add(deregistered_data, data);
9223 | }
9224 |
9225 | void
9226 | proto_add_deregistered_slice (size_t block_size, void *mem_block)
9227 | {
9228 | 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)));
9229 |
9230 | slice_data->block_size = block_size;
9231 | slice_data->mem_block = mem_block;
9232 |
9233 | g_ptr_array_add(deregistered_slice, slice_data);
9234 | }
9235 |
9236 | void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9237 | {
9238 | if (field_strings == NULL((void*)0)) {
9239 | return;
9240 | }
9241 |
9242 | switch (field_type) {
9243 | case FT_FRAMENUM:
9244 | /* This is just an integer represented as a pointer */
9245 | break;
9246 | case FT_PROTOCOL: {
9247 | protocol_t *protocol = (protocol_t *)field_strings;
9248 | 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);
9249 | break;
9250 | }
9251 | case FT_BOOLEAN: {
9252 | true_false_string *tf = (true_false_string *)field_strings;
9253 | 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);
9254 | 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);
9255 | break;
9256 | }
9257 | case FT_UINT40:
9258 | case FT_INT40:
9259 | case FT_UINT48:
9260 | case FT_INT48:
9261 | case FT_UINT56:
9262 | case FT_INT56:
9263 | case FT_UINT64:
9264 | case FT_INT64: {
9265 | if (field_display & BASE_UNIT_STRING0x00001000) {
9266 | unit_name_string *unit = (unit_name_string *)field_strings;
9267 | 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);
9268 | 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);
9269 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9270 | range_string *rs = (range_string *)field_strings;
9271 | while (rs->strptr) {
9272 | 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 );
9273 | rs++;
9274 | }
9275 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9276 | val64_string_ext *vse = (val64_string_ext *)field_strings;
9277 | val64_string *vs = (val64_string *)vse->_vs_p;
9278 | while (vs->strptr) {
9279 | 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 );
9280 | vs++;
9281 | }
9282 | val64_string_ext_free(vse);
9283 | field_strings = NULL((void*)0);
9284 | } else if (field_display == BASE_CUSTOM) {
9285 | /* this will be a pointer to a function, don't free that */
9286 | field_strings = NULL((void*)0);
9287 | } else {
9288 | val64_string *vs64 = (val64_string *)field_strings;
9289 | while (vs64->strptr) {
9290 | 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);
9291 | vs64++;
9292 | }
9293 | }
9294 | break;
9295 | }
9296 | case FT_CHAR:
9297 | case FT_UINT8:
9298 | case FT_INT8:
9299 | case FT_UINT16:
9300 | case FT_INT16:
9301 | case FT_UINT24:
9302 | case FT_INT24:
9303 | case FT_UINT32:
9304 | case FT_INT32:
9305 | case FT_FLOAT:
9306 | case FT_DOUBLE: {
9307 | if (field_display & BASE_UNIT_STRING0x00001000) {
9308 | unit_name_string *unit = (unit_name_string *)field_strings;
9309 | 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);
9310 | 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);
9311 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9312 | range_string *rs = (range_string *)field_strings;
9313 | while (rs->strptr) {
9314 | 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 );
9315 | rs++;
9316 | }
9317 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9318 | value_string_ext *vse = (value_string_ext *)field_strings;
9319 | value_string *vs = (value_string *)vse->_vs_p;
9320 | while (vs->strptr) {
9321 | 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 );
9322 | vs++;
9323 | }
9324 | value_string_ext_free(vse);
9325 | field_strings = NULL((void*)0);
9326 | } else if (field_display == BASE_CUSTOM) {
9327 | /* this will be a pointer to a function, don't free that */
9328 | field_strings = NULL((void*)0);
9329 | } else {
9330 | value_string *vs = (value_string *)field_strings;
9331 | while (vs->strptr) {
9332 | 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 );
9333 | vs++;
9334 | }
9335 | }
9336 | break;
9337 | default:
9338 | break;
9339 | }
9340 | }
9341 |
9342 | if (field_type != FT_FRAMENUM) {
9343 | 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 );
9344 | }
9345 | }
9346 |
9347 | static void
9348 | free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9349 | {
9350 | header_field_info *hfi = (header_field_info *) data;
9351 | int hf_id = hfi->id;
9352 |
9353 | 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 );
9354 | 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 );
9355 | 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 );
9356 |
9357 | proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9358 |
9359 | if (hfi->parent == -1)
9360 | 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);
9361 |
9362 | gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9363 | }
9364 |
9365 | static void
9366 | free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9367 | {
9368 | g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized (data, __builtin_object_size ((data), 0)) : (g_free) (data);
9369 | }
9370 |
9371 | static void
9372 | free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9373 | {
9374 | struct g_slice_data *slice_data = (struct g_slice_data *)data;
9375 |
9376 | g_slice_free1(slice_data->block_size, slice_data->mem_block);
9377 | 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);
9378 | }
9379 |
9380 | /* free deregistered fields and data */
9381 | void
9382 | proto_free_deregistered_fields (void)
9383 | {
9384 | expert_free_deregistered_expertinfos();
9385 |
9386 | g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9387 | g_ptr_array_free(deregistered_fields, true1);
9388 | deregistered_fields = g_ptr_array_new();
9389 |
9390 | g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9391 | g_ptr_array_free(deregistered_data, true1);
9392 | deregistered_data = g_ptr_array_new();
9393 |
9394 | g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9395 | g_ptr_array_free(deregistered_slice, true1);
9396 | deregistered_slice = g_ptr_array_new();
9397 | }
9398 |
9399 | static const value_string hf_display[] = {
9400 | { BASE_NONE, "BASE_NONE" },
9401 | { BASE_DEC, "BASE_DEC" },
9402 | { BASE_HEX, "BASE_HEX" },
9403 | { BASE_OCT, "BASE_OCT" },
9404 | { BASE_DEC_HEX, "BASE_DEC_HEX" },
9405 | { BASE_HEX_DEC, "BASE_HEX_DEC" },
9406 | { BASE_CUSTOM, "BASE_CUSTOM" },
9407 | { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9408 | { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9409 | { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9410 | { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9411 | { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9412 | { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9413 | { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9414 | { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9415 | { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9416 | { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9417 | { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9418 | { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9419 | { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9420 | { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9421 | { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9422 | { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9423 | { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9424 | { BASE_PT_UDP, "BASE_PT_UDP" },
9425 | { BASE_PT_TCP, "BASE_PT_TCP" },
9426 | { BASE_PT_DCCP, "BASE_PT_DCCP" },
9427 | { BASE_PT_SCTP, "BASE_PT_SCTP" },
9428 | { BASE_OUI, "BASE_OUI" },
9429 | { 0, NULL((void*)0) } };
9430 |
9431 | const char* proto_field_display_to_string(int field_display)
9432 | {
9433 | return val_to_str_const(field_display, hf_display, "Unknown");
9434 | }
9435 |
9436 | static inline port_type
9437 | display_to_port_type(field_display_e e)
9438 | {
9439 | switch (e) {
9440 | case BASE_PT_UDP:
9441 | return PT_UDP;
9442 | case BASE_PT_TCP:
9443 | return PT_TCP;
9444 | case BASE_PT_DCCP:
9445 | return PT_DCCP;
9446 | case BASE_PT_SCTP:
9447 | return PT_SCTP;
9448 | default:
9449 | break;
9450 | }
9451 | return PT_NONE;
9452 | }
9453 |
9454 | /* temporary function containing assert part for easier profiling */
9455 | static void
9456 | tmp_fld_check_assert(header_field_info *hfinfo)
9457 | {
9458 | char* tmp_str;
9459 |
9460 | /* The field must have a name (with length > 0) */
9461 | if (!hfinfo->name || !hfinfo->name[0]) {
9462 | if (hfinfo->abbrev)
9463 | /* Try to identify the field */
9464 | 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)
9465 | hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name" , hfinfo->abbrev);
9466 | else
9467 | /* Hum, no luck */
9468 | 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)" );
9469 | }
9470 |
9471 | /* fields with an empty string for an abbreviation aren't filterable */
9472 | if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9473 | 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);
9474 |
9475 | /* TODO: This check is a significant percentage of startup time (~10%),
9476 | although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9477 | It might be nice to have a way to disable this check when, e.g.,
9478 | running TShark many times with the same configuration. */
9479 | /* Check that the filter name (abbreviation) is legal;
9480 | * it must contain only alphanumerics, '-', "_", and ".". */
9481 | unsigned char c;
9482 | c = module_check_valid_name(hfinfo->abbrev, false0);
9483 | if (c) {
9484 | if (c == '.') {
9485 | 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);
9486 | } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9487 | 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);
9488 | } else {
9489 | 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);
9490 | }
9491 | }
9492 |
9493 | /* These types of fields are allowed to have value_strings,
9494 | * true_false_strings or a protocol_t struct
9495 | */
9496 | if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9497 | switch (hfinfo->type) {
9498 |
9499 | /*
9500 | * These types are allowed to support display value_strings,
9501 | * value64_strings, the extended versions of the previous
9502 | * two, range strings, or unit strings.
9503 | */
9504 | case FT_CHAR:
9505 | case FT_UINT8:
9506 | case FT_UINT16:
9507 | case FT_UINT24:
9508 | case FT_UINT32:
9509 | case FT_UINT40:
9510 | case FT_UINT48:
9511 | case FT_UINT56:
9512 | case FT_UINT64:
9513 | case FT_INT8:
9514 | case FT_INT16:
9515 | case FT_INT24:
9516 | case FT_INT32:
9517 | case FT_INT40:
9518 | case FT_INT48:
9519 | case FT_INT56:
9520 | case FT_INT64:
9521 | case FT_BOOLEAN:
9522 | case FT_PROTOCOL:
9523 | break;
9524 |
9525 | /*
9526 | * This is allowed to have a value of type
9527 | * enum ft_framenum_type to indicate what relationship
9528 | * the frame in question has to the frame in which
9529 | * the field is put.
9530 | */
9531 | case FT_FRAMENUM:
9532 | break;
9533 |
9534 | /*
9535 | * These types are allowed to support only unit strings.
9536 | */
9537 | case FT_FLOAT:
9538 | case FT_DOUBLE:
9539 | case FT_IEEE_11073_SFLOAT:
9540 | case FT_IEEE_11073_FLOAT:
9541 | if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9542 | 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))
9543 | " (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))
9544 | 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));
9545 | }
9546 | break;
9547 |
9548 | /*
9549 | * These types are allowed to support display
9550 | * time_value_strings.
9551 | */
9552 | case FT_ABSOLUTE_TIME:
9553 | if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9554 | hfinfo->display & BASE_EXT_STRING0x00000200 ||
9555 | hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9556 | hfinfo->display & BASE_UNIT_STRING0x00001000) {
9557 | 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))
9558 | " (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))
9559 | 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));
9560 | }
9561 | break;
9562 |
9563 | /*
9564 | * This type is only allowed to support a string if it's
9565 | * a protocol (for pinos).
9566 | */
9567 | case FT_BYTES:
9568 | if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9569 | 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))
9570 | " (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))
9571 | 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));
9572 | }
9573 | break;
9574 |
9575 | default:
9576 | 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))
9577 | " (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))
9578 | 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));
9579 | }
9580 | }
9581 |
9582 | /* TODO: This check may slow down startup, and output quite a few warnings.
9583 | It would be good to be able to enable this (and possibly other checks?)
9584 | in non-release builds. */
9585 | #ifdef ENABLE_CHECK_FILTER
9586 | /* Check for duplicate value_string values.
9587 | There are lots that have the same value *and* string, so for now only
9588 | report those that have same value but different string. */
9589 | if ((hfinfo->strings != NULL((void*)0)) &&
9590 | !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9591 | !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9592 | !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9593 | (
9594 | (hfinfo->type == FT_CHAR) ||
9595 | (hfinfo->type == FT_UINT8) ||
9596 | (hfinfo->type == FT_UINT16) ||
9597 | (hfinfo->type == FT_UINT24) ||
9598 | (hfinfo->type == FT_UINT32) ||
9599 | (hfinfo->type == FT_INT8) ||
9600 | (hfinfo->type == FT_INT16) ||
9601 | (hfinfo->type == FT_INT24) ||
9602 | (hfinfo->type == FT_INT32) )) {
9603 |
9604 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9605 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9606 | const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9607 | CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9608 | } else {
9609 | const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9610 | CHECK_HF_VALUE(value_string, "u", start_values);
9611 | }
9612 | } else {
9613 | const value_string *start_values = (const value_string*)hfinfo->strings;
9614 | CHECK_HF_VALUE(value_string, "u", start_values);
9615 | }
9616 | }
9617 |
9618 | if (hfinfo->type == FT_BOOLEAN) {
9619 | const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9620 | if (tfs) {
9621 | if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9622 | ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9624 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string)
9623 | hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9624 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string)
9624 | tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9624 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string);
9625 | }
9626 | }
9627 | }
9628 |
9629 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9630 | const range_string *rs = (const range_string*)(hfinfo->strings);
9631 | if (rs) {
9632 | const range_string *this_it = rs;
9633 |
9634 | do {
9635 | if (this_it->value_max < this_it->value_min) {
9636 | 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" , 9640, __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)
9637 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9640, __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)
9638 | this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9640, __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)
9639 | this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9640, __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)
9640 | this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9640, __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);
9641 | ++this_it;
9642 | continue;
9643 | }
9644 |
9645 | for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9646 | /* Not OK if this one is completely hidden by an earlier one! */
9647 | if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9648 | 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" , 9654, __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)
9649 | "(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" , 9654, __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)
9650 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9654, __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)
9651 | prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9654, __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)
9652 | prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9654, __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)
9653 | this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9654, __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)
9654 | this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9654, __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);
9655 | }
9656 | }
9657 | ++this_it;
9658 | } while (this_it->strptr);
9659 | }
9660 | }
9661 | #endif
9662 |
9663 | switch (hfinfo->type) {
9664 |
9665 | case FT_CHAR:
9666 | /* Require the char type to have BASE_HEX, BASE_OCT,
9667 | * BASE_CUSTOM, or BASE_NONE as its base.
9668 | *
9669 | * If the display value is BASE_NONE and there is a
9670 | * strings conversion then the dissector writer is
9671 | * telling us that the field's numerical value is
9672 | * meaningless; we'll avoid showing the value to the
9673 | * user.
9674 | */
9675 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9676 | case BASE_HEX:
9677 | case BASE_OCT:
9678 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9679 | break;
9680 | case BASE_NONE:
9681 | if (hfinfo->strings == NULL((void*)0))
9682 | 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 ))
9683 | " 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 ))
9684 | " 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 ))
9685 | 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 ))
9686 | 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 ));
9687 | break;
9688 | default:
9689 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9690 | 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)
9691 | " 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)
9692 | 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)
9693 | 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);
9694 | //wmem_free(NULL, tmp_str);
9695 | }
9696 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9697 | 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 ))
9698 | 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 ))
9699 | 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 ));
9700 | }
9701 | break;
9702 | case FT_INT8:
9703 | case FT_INT16:
9704 | case FT_INT24:
9705 | case FT_INT32:
9706 | case FT_INT40:
9707 | case FT_INT48:
9708 | case FT_INT56:
9709 | case FT_INT64:
9710 | /* Hexadecimal and octal are, in printf() and everywhere
9711 | * else, unsigned so don't allow dissectors to register a
9712 | * signed field to be displayed unsigned. (Else how would
9713 | * we display negative values?)
9714 | */
9715 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9716 | case BASE_HEX:
9717 | case BASE_OCT:
9718 | case BASE_DEC_HEX:
9719 | case BASE_HEX_DEC:
9720 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9721 | 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)
9722 | 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)
9723 | 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);
9724 | //wmem_free(NULL, tmp_str);
9725 | }
9726 | /* FALL THROUGH */
9727 | case FT_UINT8:
9728 | case FT_UINT16:
9729 | case FT_UINT24:
9730 | case FT_UINT32:
9731 | case FT_UINT40:
9732 | case FT_UINT48:
9733 | case FT_UINT56:
9734 | case FT_UINT64:
9735 | 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 ))) {
9736 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9737 | if (hfinfo->type != FT_UINT16) {
9738 | 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))
9739 | 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))
9740 | 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));
9741 | }
9742 | if (hfinfo->strings != NULL((void*)0)) {
9743 | 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)
9744 | 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)
9745 | 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);
9746 | }
9747 | if (hfinfo->bitmask != 0) {
9748 | 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)
9749 | 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)
9750 | 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);
9751 | }
9752 | wmem_free(NULL((void*)0), tmp_str);
9753 | break;
9754 | }
9755 |
9756 | if (hfinfo->display == BASE_OUI) {
9757 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9758 | 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) {
9759 | 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))
9760 | 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))
9761 | 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));
9762 | }
9763 | if (hfinfo->strings != NULL((void*)0)) {
9764 | 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)
9765 | 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)
9766 | 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);
9767 | }
9768 | /* It can be a FT_UINT24 with a 0 bitmask, or
9769 | * larger with a bitmask with 24 bits set. */
9770 | if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9771 | 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)
9772 | 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)
9773 | 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);
9774 | }
9775 | wmem_free(NULL((void*)0), tmp_str);
9776 | break;
9777 | }
9778 |
9779 | /* Require integral types (other than frame number,
9780 | * which is always displayed in decimal) to have a
9781 | * number base.
9782 | *
9783 | * If the display value is BASE_NONE and there is a
9784 | * strings conversion then the dissector writer is
9785 | * telling us that the field's numerical value is
9786 | * meaningless; we'll avoid showing the value to the
9787 | * user.
9788 | */
9789 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9790 | case BASE_DEC:
9791 | case BASE_HEX:
9792 | case BASE_OCT:
9793 | case BASE_DEC_HEX:
9794 | case BASE_HEX_DEC:
9795 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9796 | break;
9797 | case BASE_NONE:
9798 | if (hfinfo->strings == NULL((void*)0)) {
9799 | 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 ))
9800 | " 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 ))
9801 | " 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 ))
9802 | 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 ))
9803 | 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 ));
9804 | }
9805 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9806 | 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 ))
9807 | " 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 ))
9808 | " 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 ))
9809 | 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 ))
9810 | 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 ));
9811 | }
9812 | break;
9813 |
9814 | default:
9815 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9816 | 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)
9817 | " 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)
9818 | 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)
9819 | 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);
9820 | //wmem_free(NULL, tmp_str);
9821 | }
9822 | break;
9823 | case FT_BYTES:
9824 | case FT_UINT_BYTES:
9825 | /* Require bytes to have a "display type" that could
9826 | * add a character between displayed bytes.
9827 | */
9828 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9829 | case BASE_NONE:
9830 | case SEP_DOT:
9831 | case SEP_DASH:
9832 | case SEP_COLON:
9833 | case SEP_SPACE:
9834 | break;
9835 | default:
9836 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9837 | 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)
9838 | 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);
9839 | //wmem_free(NULL, tmp_str);
9840 | }
9841 | if (hfinfo->bitmask != 0)
9842 | 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 ))
9843 | 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 ))
9844 | 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 ));
9845 | //allowed to support string if its a protocol (for pinos)
9846 | if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9847 | 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 ))
9848 | 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 ))
9849 | 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 ));
9850 | break;
9851 |
9852 | case FT_PROTOCOL:
9853 | case FT_FRAMENUM:
9854 | if (hfinfo->display != BASE_NONE) {
9855 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9856 | 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)
9857 | 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)
9858 | 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);
9859 | //wmem_free(NULL, tmp_str);
9860 | }
9861 | if (hfinfo->bitmask != 0)
9862 | 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 ))
9863 | 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 ))
9864 | 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 ));
9865 | break;
9866 |
9867 | case FT_BOOLEAN:
9868 | break;
9869 |
9870 | case FT_ABSOLUTE_TIME:
9871 | if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL && ((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)) {
9872 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9873 | 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)
9874 | 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);
9875 | //wmem_free(NULL, tmp_str);
9876 | }
9877 | if (hfinfo->bitmask != 0)
9878 | 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 ))
9879 | 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 ))
9880 | 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 ));
9881 | break;
9882 |
9883 | case FT_STRING:
9884 | case FT_STRINGZ:
9885 | case FT_UINT_STRING:
9886 | case FT_STRINGZPAD:
9887 | case FT_STRINGZTRUNC:
9888 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9889 | case BASE_NONE:
9890 | case BASE_STR_WSP:
9891 | break;
9892 |
9893 | default:
9894 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9895 | 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)
9896 | " 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)
9897 | 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)
9898 | 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);
9899 | //wmem_free(NULL, tmp_str);
9900 | }
9901 |
9902 | if (hfinfo->bitmask != 0)
9903 | 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 ))
9904 | 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 ))
9905 | 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 ));
9906 | if (hfinfo->strings != NULL((void*)0))
9907 | 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 ))
9908 | 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 ))
9909 | 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 ));
9910 | break;
9911 |
9912 | case FT_IPv4:
9913 | switch (hfinfo->display) {
9914 | case BASE_NONE:
9915 | case BASE_NETMASK:
9916 | break;
9917 |
9918 | default:
9919 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9920 | 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)
9921 | " 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)
9922 | 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)
9923 | 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);
9924 | //wmem_free(NULL, tmp_str);
9925 | break;
9926 | }
9927 | break;
9928 | case FT_FLOAT:
9929 | case FT_DOUBLE:
9930 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9931 | case BASE_NONE:
9932 | case BASE_DEC:
9933 | case BASE_HEX:
9934 | case BASE_EXP:
9935 | case BASE_CUSTOM:
9936 | break;
9937 | default:
9938 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9939 | 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)
9940 | " 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)
9941 | 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)
9942 | 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);
9943 | //wmem_free(NULL, tmp_str);
9944 | }
9945 | if (hfinfo->bitmask != 0)
9946 | 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 ))
9947 | 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 ))
9948 | 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 ));
9949 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9950 | 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 ))
9951 | 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 ))
9952 | 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 ));
9953 | break;
9954 | case FT_IEEE_11073_SFLOAT:
9955 | case FT_IEEE_11073_FLOAT:
9956 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9957 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9958 | 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)
9959 | 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)
9960 | 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)
9961 | 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);
9962 | //wmem_free(NULL, tmp_str);
9963 | }
9964 | if (hfinfo->bitmask != 0)
9965 | REPORT_DISSECTOR_BUG("Field '%s' (%s) is an %s but has a bitmask",proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask" , hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type ))
9966 | hfinfo->name, hfinfo->abbrev,proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask" , hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type ))
9967 | ftype_name(hfinfo->type))proto_report_dissector_bug("Field '%s' (%s) is an %s but has a bitmask" , hfinfo->name, hfinfo->abbrev, ftype_name(hfinfo->type ));
9968 | if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9969 | 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 ))
9970 | 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 ))
9971 | 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 ));
9972 | break;
9973 | default:
9974 | if (hfinfo->display != BASE_NONE) {
9975 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9976 | 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)
9977 | 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)
9978 | 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)
9979 | 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);
9980 | //wmem_free(NULL, tmp_str);
9981 | }
9982 | if (hfinfo->bitmask != 0)
9983 | 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 ))
9984 | 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 ))
9985 | 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 ));
9986 | if (hfinfo->strings != NULL((void*)0))
9987 | 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 ))
9988 | 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 ))
9989 | 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 ));
9990 | break;
9991 | }
9992 | }
9993 |
9994 | static void
9995 | register_type_length_mismatch(void)
9996 | {
9997 | static ei_register_info ei[] = {
9998 | { &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)}} }},
9999 | { &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)}} }},
10000 | };
10001 |
10002 | expert_module_t* expert_type_length_mismatch;
10003 |
10004 | proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
10005 |
10006 | expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
10007 | expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10008 |
10009 | /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
10010 | disabling them makes no sense. */
10011 | proto_set_cant_toggle(proto_type_length_mismatch);
10012 | }
10013 |
10014 | static void
10015 | register_byte_array_string_decodinws_error(void)
10016 | {
10017 | static ei_register_info ei[] = {
10018 | { &ei_byte_array_string_decoding_failed_error,
10019 | { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10020 | "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)}}
10021 | }
10022 | },
10023 | };
10024 |
10025 | expert_module_t* expert_byte_array_string_decoding_error;
10026 |
10027 | proto_byte_array_string_decoding_error =
10028 | proto_register_protocol("Byte Array-String Decoding Error",
10029 | "Byte Array-string decoding error",
10030 | "_ws.byte_array_string.decoding_error");
10031 |
10032 | expert_byte_array_string_decoding_error =
10033 | expert_register_protocol(proto_byte_array_string_decoding_error);
10034 | expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10035 |
10036 | /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10037 | disabling them makes no sense. */
10038 | proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10039 | }
10040 |
10041 | static void
10042 | register_date_time_string_decodinws_error(void)
10043 | {
10044 | static ei_register_info ei[] = {
10045 | { &ei_date_time_string_decoding_failed_error,
10046 | { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10047 | "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)}}
10048 | }
10049 | },
10050 | };
10051 |
10052 | expert_module_t* expert_date_time_string_decoding_error;
10053 |
10054 | proto_date_time_string_decoding_error =
10055 | proto_register_protocol("Date and Time-String Decoding Error",
10056 | "Date and Time-string decoding error",
10057 | "_ws.date_time_string.decoding_error");
10058 |
10059 | expert_date_time_string_decoding_error =
10060 | expert_register_protocol(proto_date_time_string_decoding_error);
10061 | expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10062 |
10063 | /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10064 | disabling them makes no sense. */
10065 | proto_set_cant_toggle(proto_date_time_string_decoding_error);
10066 | }
10067 |
10068 | static void
10069 | register_string_errors(void)
10070 | {
10071 | static ei_register_info ei[] = {
10072 | { &ei_string_trailing_characters,
10073 | { "_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)}} }
10074 | },
10075 | };
10076 |
10077 | expert_module_t* expert_string_errors;
10078 |
10079 | proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10080 |
10081 | expert_string_errors = expert_register_protocol(proto_string_errors);
10082 | expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10083 |
10084 | /* "String Errors" isn't really a protocol, it's an error indication;
10085 | disabling them makes no sense. */
10086 | proto_set_cant_toggle(proto_string_errors);
10087 | }
10088 |
10089 | static int
10090 | proto_register_field_init(header_field_info *hfinfo, const int parent)
10091 | {
10092 |
10093 | tmp_fld_check_assert(hfinfo);
10094 |
10095 | hfinfo->parent = parent;
10096 | hfinfo->same_name_next = NULL((void*)0);
10097 | hfinfo->same_name_prev_id = -1;
10098 |
10099 | /* if we always add and never delete, then id == len - 1 is correct */
10100 | if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10101 | if (!gpa_hfinfo.hfi) {
10102 | gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10103 | gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10104 | /* The entry with index 0 is not used. */
10105 | gpa_hfinfo.hfi[0] = NULL((void*)0);
10106 | gpa_hfinfo.len = 1;
10107 | } else {
10108 | gpa_hfinfo.allocated_len += 1000;
10109 | gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10110 | sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10111 | /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10112 | }
10113 | }
10114 | gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10115 | gpa_hfinfo.len++;
10116 | hfinfo->id = gpa_hfinfo.len - 1;
10117 |
10118 | /* if we have real names, enter this field in the name tree */
10119 | /* Already checked in tmp_fld_check_assert */
10120 | /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10121 | {
10122 |
10123 | header_field_info *same_name_next_hfinfo;
10124 |
10125 | /* We allow multiple hfinfo's to be registered under the same
10126 | * abbreviation. This was done for X.25, as, depending
10127 | * on whether it's modulo-8 or modulo-128 operation,
10128 | * some bitfield fields may be in different bits of
10129 | * a byte, and we want to be able to refer to that field
10130 | * with one name regardless of whether the packets
10131 | * are modulo-8 or modulo-128 packets. */
10132 |
10133 | /* wmem_map_insert - if key is already present the previous
10134 | * hfinfo with the same key/name is returned, otherwise NULL */
10135 | same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10136 | if (same_name_hfinfo) {
10137 | /* There's already a field with this name.
10138 | * Put the current field *before* that field
10139 | * in the list of fields with this name, Thus,
10140 | * we end up with an effectively
10141 | * doubly-linked-list of same-named hfinfo's,
10142 | * with the head of the list (stored in the
10143 | * hash) being the last seen hfinfo.
10144 | */
10145 | same_name_next_hfinfo =
10146 | same_name_hfinfo->same_name_next;
10147 |
10148 | hfinfo->same_name_next = same_name_next_hfinfo;
10149 | if (same_name_next_hfinfo)
10150 | same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10151 |
10152 | same_name_hfinfo->same_name_next = hfinfo;
10153 | hfinfo->same_name_prev_id = same_name_hfinfo->id;
10154 | #ifdef ENABLE_CHECK_FILTER
10155 | while (same_name_hfinfo) {
10156 | if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10157 | 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", 10157 , __func__, "'%s' exists multiple times with incompatible types: %s and %s" , hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name( same_name_hfinfo->type));
10158 | same_name_hfinfo = same_name_hfinfo->same_name_next;
10159 | }
10160 | #endif
10161 | }
10162 | }
10163 |
10164 | return hfinfo->id;
10165 | }
10166 |
10167 | void
10168 | proto_register_subtree_array(int * const *indices, const int num_indices)
10169 | {
10170 | int i;
10171 | int *const *ptr = indices;
10172 |
10173 | /*
10174 | * If we've already allocated the array of tree types, expand
10175 | * it; this lets plugins such as mate add tree types after
10176 | * the initial startup. (If we haven't already allocated it,
10177 | * we don't allocate it; on the first pass, we just assign
10178 | * ett values and keep track of how many we've assigned, and
10179 | * when we're finished registering all dissectors we allocate
10180 | * the array, so that we do only one allocation rather than
10181 | * wasting CPU time and memory by growing the array for each
10182 | * dissector that registers ett values.)
10183 | */
10184 | if (tree_is_expanded != NULL((void*)0)) {
10185 | tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10186 |
10187 | /* set new items to 0 */
10188 | /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10189 | for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10190 | tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10191 | }
10192 |
10193 | /*
10194 | * Assign "num_indices" subtree numbers starting at "num_tree_types",
10195 | * returning the indices through the pointers in the array whose
10196 | * first element is pointed to by "indices", and update
10197 | * "num_tree_types" appropriately.
10198 | */
10199 | for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10200 | if (**ptr != -1 && **ptr != 0) {
10201 | 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.")
10202 | " 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.")
10203 | " 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.")
10204 | " 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.");
10205 | }
10206 | **ptr = num_tree_types;
10207 | }
10208 | }
10209 |
10210 | static void
10211 | mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10212 | {
10213 | static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10214 | const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10215 | char *last_char;
10216 |
10217 | /* ..... field_name: dataaaaaaaaaaaaa
10218 | * |
10219 | * ^^^^^ name_pos
10220 | *
10221 | * ..... field_name […]: dataaaaaaaaaaaaa
10222 | *
10223 | * name_pos==0 means that we have only data or only a field_name
10224 | */
10225 |
10226 | ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10226, __func__, "assertion failed: %s" , "size > trunc_len"); } while (0);
10227 |
10228 | if (name_pos >= size - trunc_len) {
10229 | /* No room for trunc_str after the field_name, put it first. */
10230 | name_pos = 0;
10231 | }
10232 |
10233 | memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10234 | if (name_pos == 0) {
10235 | /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10236 | memcpy(label_str, trunc_str + 1, trunc_len);
10237 | } else {
10238 | memcpy(label_str + name_pos, trunc_str, trunc_len);
10239 | }
10240 | /* in general, label_str is UTF-8
10241 | we can truncate it only at the beginning of a new character
10242 | we go backwards from the byte right after our buffer and
10243 | find the next starting byte of a UTF-8 character, this is
10244 | where we cut
10245 | there's no need to use g_utf8_find_prev_char(), the search
10246 | will always succeed since we copied trunc_str into the
10247 | buffer */
10248 | /* g_utf8_prev_char does not deference the memory address
10249 | * passed in (until after decrementing it, so it is perfectly
10250 | * legal to pass in a pointer one past the last element.
10251 | */
10252 | last_char = g_utf8_prev_char(label_str + size);
10253 | *last_char = '\0';
10254 | /* This is unnecessary (above always terminates), but try to
10255 | * convince Coverity to avoid dozens of false positives. */
10256 | label_str[size - 1] = '\0';
10257 |
10258 | if (value_pos && *value_pos > 0) {
10259 | if (name_pos == 0) {
10260 | *value_pos += trunc_len;
10261 | } else {
10262 | /* Move one back to include trunc_str in the value. */
10263 | *value_pos -= 1;
10264 | }
10265 | }
10266 |
10267 | /* Check if value_pos is past label_str. */
10268 | if (value_pos && *value_pos >= size) {
10269 | *value_pos = size - 1;
10270 | }
10271 | }
10272 |
10273 | static void
10274 | label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10275 | {
10276 | mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10277 | }
10278 |
10279 | static size_t
10280 | label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10281 | {
10282 | size_t name_pos;
10283 |
10284 | /* "%s: %s", hfinfo->name, text */
10285 | 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);
10286 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10287 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10288 | if (value_pos) {
10289 | *value_pos = pos;
10290 | }
10291 | pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10292 | }
10293 |
10294 | if (pos >= ITEM_LABEL_LENGTH240) {
10295 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10296 | label_mark_truncated(label_str, name_pos, value_pos);
10297 | }
10298 |
10299 | return pos;
10300 | }
10301 |
10302 | static size_t
10303 | label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10304 | {
10305 | size_t name_pos;
10306 |
10307 | /* "%s: %s (%s)", hfinfo->name, text, descr */
10308 | 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);
10309 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10310 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10311 | if (value_pos) {
10312 | *value_pos = pos;
10313 | }
10314 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10315 | 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);
10316 | 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);
10317 | } else {
10318 | 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);
10319 | pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10320 | 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);
10321 | pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10322 | }
10323 | }
10324 |
10325 | if (pos >= ITEM_LABEL_LENGTH240) {
10326 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10327 | label_mark_truncated(label_str, name_pos, value_pos);
10328 | }
10329 |
10330 | return pos;
10331 | }
10332 |
10333 | void
10334 | proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10335 | {
10336 | const header_field_info *hfinfo;
10337 | const char *str;
10338 | const uint8_t *bytes;
10339 | uint32_t integer;
10340 | const ipv4_addr_and_mask *ipv4;
10341 | const ipv6_addr_and_prefix *ipv6;
10342 | const e_guid_t *guid;
10343 | char *name;
10344 | address addr;
10345 | char *addr_str;
10346 | char *tmp;
10347 |
10348 | if (!label_str) {
10349 | ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10349, __func__, "NULL label_str passed to proto_item_fill_label." ); } } while (0);
10350 | return;
10351 | }
10352 |
10353 | label_str[0]= '\0';
10354 |
10355 | if (!fi) {
10356 | return;
10357 | }
10358 |
10359 | hfinfo = fi->hfinfo;
10360 |
10361 | switch (hfinfo->type) {
10362 | case FT_NONE:
10363 | case FT_PROTOCOL:
10364 | (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10365 | if (value_pos) {
10366 | *value_pos = strlen(hfinfo->name);
10367 | }
10368 | break;
10369 |
10370 | case FT_BOOLEAN:
10371 | fill_label_boolean(fi, label_str, value_pos);
10372 | break;
10373 |
10374 | case FT_BYTES:
10375 | case FT_UINT_BYTES:
10376 | tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10377 | fvalue_get_bytes_data(fi->value),
10378 | (unsigned)fvalue_length2(fi->value));
10379 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10380 | wmem_free(NULL((void*)0), tmp);
10381 | break;
10382 |
10383 | case FT_CHAR:
10384 | if (hfinfo->bitmask) {
10385 | fill_label_bitfield_char(fi, label_str, value_pos);
10386 | } else {
10387 | fill_label_char(fi, label_str, value_pos);
10388 | }
10389 | break;
10390 |
10391 | /* Four types of integers to take care of:
10392 | * Bitfield, with val_string
10393 | * Bitfield, w/o val_string
10394 | * Non-bitfield, with val_string
10395 | * Non-bitfield, w/o val_string
10396 | */
10397 | case FT_UINT8:
10398 | case FT_UINT16:
10399 | case FT_UINT24:
10400 | case FT_UINT32:
10401 | if (hfinfo->bitmask) {
10402 | fill_label_bitfield(fi, label_str, value_pos, false0);
10403 | } else {
10404 | fill_label_number(fi, label_str, value_pos, false0);
10405 | }
10406 | break;
10407 |
10408 | case FT_FRAMENUM:
10409 | fill_label_number(fi, label_str, value_pos, false0);
10410 | break;
10411 |
10412 | case FT_UINT40:
10413 | case FT_UINT48:
10414 | case FT_UINT56:
10415 | case FT_UINT64:
10416 | if (hfinfo->bitmask) {
10417 | fill_label_bitfield64(fi, label_str, value_pos, false0);
10418 | } else {
10419 | fill_label_number64(fi, label_str, value_pos, false0);
10420 | }
10421 | break;
10422 |
10423 | case FT_INT8:
10424 | case FT_INT16:
10425 | case FT_INT24:
10426 | case FT_INT32:
10427 | if (hfinfo->bitmask) {
10428 | fill_label_bitfield(fi, label_str, value_pos, true1);
10429 | } else {
10430 | fill_label_number(fi, label_str, value_pos, true1);
10431 | }
10432 | break;
10433 |
10434 | case FT_INT40:
10435 | case FT_INT48:
10436 | case FT_INT56:
10437 | case FT_INT64:
10438 | if (hfinfo->bitmask) {
10439 | fill_label_bitfield64(fi, label_str, value_pos, true1);
10440 | } else {
10441 | fill_label_number64(fi, label_str, value_pos, true1);
10442 | }
10443 | break;
10444 |
10445 | case FT_FLOAT:
10446 | case FT_DOUBLE:
10447 | fill_label_float(fi, label_str, value_pos);
10448 | break;
10449 |
10450 | case FT_ABSOLUTE_TIME:
10451 | {
10452 | const nstime_t *value = fvalue_get_time(fi->value);
10453 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10454 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10455 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10456 | }
10457 | if (hfinfo->strings) {
10458 | /*
10459 | * Table of time values to be displayed
10460 | * specially.
10461 | */
10462 | const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10463 | if (time_string != NULL((void*)0)) {
10464 | label_fill(label_str, 0, hfinfo, time_string, value_pos);
10465 | break;
10466 | }
10467 | }
10468 | tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10469 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10470 | wmem_free(NULL((void*)0), tmp);
10471 | break;
10472 | }
10473 | case FT_RELATIVE_TIME:
10474 | tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10475 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10476 | wmem_free(NULL((void*)0), tmp);
10477 | break;
10478 |
10479 | case FT_IPXNET:
10480 | integer = fvalue_get_uinteger(fi->value);
10481 | tmp = get_ipxnet_name(NULL((void*)0), integer);
10482 | addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10483 | label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10484 | wmem_free(NULL((void*)0), tmp);
10485 | wmem_free(NULL((void*)0), addr_str);
10486 | break;
10487 |
10488 | case FT_VINES:
10489 | addr.type = AT_VINES;
10490 | addr.len = VINES_ADDR_LEN6;
10491 | addr.data = fvalue_get_bytes_data(fi->value);
10492 |
10493 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10494 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10495 | wmem_free(NULL((void*)0), addr_str);
10496 | break;
10497 |
10498 | case FT_ETHER:
10499 | bytes = fvalue_get_bytes_data(fi->value);
10500 |
10501 | addr.type = AT_ETHER;
10502 | addr.len = 6;
10503 | addr.data = bytes;
10504 |
10505 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10506 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10507 | wmem_free(NULL((void*)0), addr_str);
10508 | break;
10509 |
10510 | case FT_IPv4:
10511 | ipv4 = fvalue_get_ipv4(fi->value);
10512 | set_address_ipv4(&addr, ipv4);
10513 |
10514 | if (hfinfo->display == BASE_NETMASK) {
10515 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10516 | } else {
10517 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10518 | }
10519 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10520 | wmem_free(NULL((void*)0), addr_str);
10521 | free_address(&addr);
10522 | break;
10523 |
10524 | case FT_IPv6:
10525 | ipv6 = fvalue_get_ipv6(fi->value);
10526 | set_address_ipv6(&addr, ipv6);
10527 |
10528 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10529 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10530 | wmem_free(NULL((void*)0), addr_str);
10531 | free_address(&addr);
10532 | break;
10533 |
10534 | case FT_FCWWN:
10535 | bytes = fvalue_get_bytes_data(fi->value);
10536 | addr.type = AT_FCWWN;
10537 | addr.len = FCWWN_ADDR_LEN8;
10538 | addr.data = bytes;
10539 |
10540 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10541 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10542 | wmem_free(NULL((void*)0), addr_str);
10543 | break;
10544 |
10545 | case FT_GUID:
10546 | guid = fvalue_get_guid(fi->value);
10547 | tmp = guid_to_str(NULL((void*)0), guid);
10548 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10549 | wmem_free(NULL((void*)0), tmp);
10550 | break;
10551 |
10552 | case FT_OID:
10553 | bytes = fvalue_get_bytes_data(fi->value);
10554 | name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10555 | tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10556 | if (name) {
10557 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10558 | wmem_free(NULL((void*)0), name);
10559 | } else {
10560 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10561 | }
10562 | wmem_free(NULL((void*)0), tmp);
10563 | break;
10564 |
10565 | case FT_REL_OID:
10566 | bytes = fvalue_get_bytes_data(fi->value);
10567 | name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10568 | tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10569 | if (name) {
10570 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10571 | wmem_free(NULL((void*)0), name);
10572 | } else {
10573 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10574 | }
10575 | wmem_free(NULL((void*)0), tmp);
10576 | break;
10577 |
10578 | case FT_SYSTEM_ID:
10579 | bytes = fvalue_get_bytes_data(fi->value);
10580 | tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10581 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10582 | wmem_free(NULL((void*)0), tmp);
10583 | break;
10584 |
10585 | case FT_EUI64:
10586 | bytes = fvalue_get_bytes_data(fi->value);
10587 | addr.type = AT_EUI64;
10588 | addr.len = EUI64_ADDR_LEN8;
10589 | addr.data = bytes;
10590 |
10591 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10592 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10593 | wmem_free(NULL((void*)0), addr_str);
10594 | break;
10595 | case FT_STRING:
10596 | case FT_STRINGZ:
10597 | case FT_UINT_STRING:
10598 | case FT_STRINGZPAD:
10599 | case FT_STRINGZTRUNC:
10600 | case FT_AX25:
10601 | str = fvalue_get_string(fi->value);
10602 | label_fill(label_str, 0, hfinfo, str, value_pos);
10603 | break;
10604 |
10605 | case FT_IEEE_11073_SFLOAT:
10606 | case FT_IEEE_11073_FLOAT:
10607 | fill_label_ieee_11073_float(fi, label_str, value_pos);
10608 | break;
10609 |
10610 | default:
10611 | 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 ))
10612 | 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 ))
10613 | 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 ))
10614 | 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 ));
10615 | break;
10616 | }
10617 | }
10618 |
10619 | static void
10620 | fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10621 | {
10622 | char *p;
10623 | unsigned bitfield_byte_length = 0;
10624 | int bitwidth;
10625 | uint64_t unshifted_value;
10626 | uint64_t value;
10627 |
10628 | const header_field_info *hfinfo = fi->hfinfo;
10629 |
10630 | value = fvalue_get_uinteger64(fi->value);
10631 | if (hfinfo->bitmask) {
10632 | /* Figure out the bit width */
10633 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10634 |
10635 | /* Un-shift bits */
10636 | unshifted_value = value;
10637 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10638 |
10639 | /* Create the bitfield first */
10640 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10641 | bitfield_byte_length = (unsigned) (p - label_str);
10642 | }
10643 |
10644 | /* Fill in the textual info */
10645 | label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10646 | }
10647 |
10648 | static const char *
10649 | hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10650 | {
10651 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10652 | return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10653 |
10654 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10655 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10656 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10657 | else
10658 | return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10659 | }
10660 |
10661 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10662 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10663 |
10664 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10665 | return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10666 |
10667 | return try_val_to_str(value, (const value_string *) hfinfo->strings);
10668 | }
10669 |
10670 | static const char *
10671 | hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10672 | {
10673 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10674 | if (hfinfo->display & BASE_EXT_STRING0x00000200)
10675 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10676 | else
10677 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10678 | }
10679 |
10680 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10681 | return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10682 |
10683 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10684 | return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10685 |
10686 | /* If this is reached somebody registered a 64-bit field with a 32-bit
10687 | * value-string, which isn't right. */
10688 | 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)
10689 | hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string" , hfinfo->abbrev);
10690 |
10691 | /* This is necessary to squelch MSVC errors; is there
10692 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10693 | never returns? */
10694 | return NULL((void*)0);
10695 | }
10696 |
10697 | static const char *
10698 | hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10699 | {
10700 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10701 | return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10702 |
10703 | 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);
10704 |
10705 | /* This is necessary to squelch MSVC errors; is there
10706 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10707 | never returns? */
10708 | return NULL((void*)0);
10709 | }
10710 |
10711 | static const char *
10712 | hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10713 | {
10714 | const char *str = hf_try_val_to_str(value, hfinfo);
10715 |
10716 | return (str) ? str : unknown_str;
10717 | }
10718 |
10719 | static const char *
10720 | hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10721 | {
10722 | const char *str = hf_try_val64_to_str(value, hfinfo);
10723 |
10724 | return (str) ? str : unknown_str;
10725 | }
10726 |
10727 | /* Fills data for bitfield chars with val_strings */
10728 | static void
10729 | fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10730 | {
10731 | char *p;
10732 | unsigned bitfield_byte_length;
10733 | int bitwidth;
10734 | uint32_t unshifted_value;
10735 | uint32_t value;
10736 |
10737 | char buf[32];
10738 | const char *out;
10739 |
10740 | const header_field_info *hfinfo = fi->hfinfo;
10741 |
10742 | /* Figure out the bit width */
10743 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10744 |
10745 | /* Un-shift bits */
10746 | value = fvalue_get_uinteger(fi->value);
10747 |
10748 | unshifted_value = value;
10749 | if (hfinfo->bitmask) {
10750 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10751 | }
10752 |
10753 | /* Create the bitfield first */
10754 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10755 | bitfield_byte_length = (unsigned) (p - label_str);
10756 |
10757 | /* Fill in the textual info using stored (shifted) value */
10758 | if (hfinfo->display == BASE_CUSTOM) {
10759 | char tmp[ITEM_LABEL_LENGTH240];
10760 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10761 |
10762 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10762, "fmtfunc"))));
10763 | fmtfunc(tmp, value);
10764 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10765 | }
10766 | else if (hfinfo->strings) {
10767 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10768 |
10769 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10770 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10771 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10772 | else
10773 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10774 | }
10775 | else {
10776 | out = hfinfo_char_value_format(hfinfo, buf, value);
10777 |
10778 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10779 | }
10780 | }
10781 |
10782 | /* Fills data for bitfield ints with val_strings */
10783 | static void
10784 | fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10785 | {
10786 | char *p;
10787 | unsigned bitfield_byte_length;
10788 | int bitwidth;
10789 | uint32_t value, unshifted_value;
10790 | char buf[NUMBER_LABEL_LENGTH80];
10791 | const char *out;
10792 |
10793 | const header_field_info *hfinfo = fi->hfinfo;
10794 |
10795 | /* Figure out the bit width */
10796 | if (fi->flags & FI_VARINT0x00040000)
10797 | bitwidth = fi->length*8;
10798 | else
10799 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10800 |
10801 | /* Un-shift bits */
10802 | if (is_signed)
10803 | value = fvalue_get_sinteger(fi->value);
10804 | else
10805 | value = fvalue_get_uinteger(fi->value);
10806 |
10807 | unshifted_value = value;
10808 | if (hfinfo->bitmask) {
10809 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10810 | }
10811 |
10812 | /* Create the bitfield first */
10813 | if (fi->flags & FI_VARINT0x00040000)
10814 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10815 | else
10816 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10817 | bitfield_byte_length = (unsigned) (p - label_str);
10818 |
10819 | /* Fill in the textual info using stored (shifted) value */
10820 | if (hfinfo->display == BASE_CUSTOM) {
10821 | char tmp[ITEM_LABEL_LENGTH240];
10822 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10823 |
10824 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10824, "fmtfunc"))));
10825 | fmtfunc(tmp, value);
10826 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10827 | }
10828 | else if (hfinfo->strings) {
10829 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10830 |
10831 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10832 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10833 | /*
10834 | * Unique values only display value_string string
10835 | * if there is a match. Otherwise it's just a number
10836 | */
10837 | if (val_str) {
10838 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10839 | } else {
10840 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10841 | }
10842 | } else {
10843 | if (val_str == NULL((void*)0))
10844 | val_str = "Unknown";
10845 |
10846 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10847 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10848 | else
10849 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10850 | }
10851 | }
10852 | else {
10853 | out = hfinfo_number_value_format(hfinfo, buf, value);
10854 |
10855 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10856 | }
10857 | }
10858 |
10859 | static void
10860 | fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10861 | {
10862 | char *p;
10863 | unsigned bitfield_byte_length;
10864 | int bitwidth;
10865 | uint64_t value, unshifted_value;
10866 | char buf[NUMBER_LABEL_LENGTH80];
10867 | const char *out;
10868 |
10869 | const header_field_info *hfinfo = fi->hfinfo;
10870 |
10871 | /* Figure out the bit width */
10872 | if (fi->flags & FI_VARINT0x00040000)
10873 | bitwidth = fi->length*8;
10874 | else
10875 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10876 |
10877 | /* Un-shift bits */
10878 | if (is_signed)
10879 | value = fvalue_get_sinteger64(fi->value);
10880 | else
10881 | value = fvalue_get_uinteger64(fi->value);
10882 |
10883 | unshifted_value = value;
10884 | if (hfinfo->bitmask) {
10885 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10886 | }
10887 |
10888 | /* Create the bitfield first */
10889 | if (fi->flags & FI_VARINT0x00040000)
10890 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10891 | else
10892 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10893 | bitfield_byte_length = (unsigned) (p - label_str);
10894 |
10895 | /* Fill in the textual info using stored (shifted) value */
10896 | if (hfinfo->display == BASE_CUSTOM) {
10897 | char tmp[ITEM_LABEL_LENGTH240];
10898 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10899 |
10900 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 10900, "fmtfunc64" ))));
10901 | fmtfunc64(tmp, value);
10902 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10903 | }
10904 | else if (hfinfo->strings) {
10905 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
10906 |
10907 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
10908 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10909 | /*
10910 | * Unique values only display value_string string
10911 | * if there is a match. Otherwise it's just a number
10912 | */
10913 | if (val_str) {
10914 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10915 | } else {
10916 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10917 | }
10918 | } else {
10919 | if (val_str == NULL((void*)0))
10920 | val_str = "Unknown";
10921 |
10922 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10923 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10924 | else
10925 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10926 | }
10927 | }
10928 | else {
10929 | out = hfinfo_number_value_format64(hfinfo, buf, value);
10930 |
10931 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10932 | }
10933 | }
10934 |
10935 | static void
10936 | fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10937 | {
10938 | const header_field_info *hfinfo = fi->hfinfo;
10939 | uint32_t value;
10940 |
10941 | char buf[32];
10942 | const char *out;
10943 |
10944 | value = fvalue_get_uinteger(fi->value);
10945 |
10946 | /* Fill in the textual info */
10947 | if (hfinfo->display == BASE_CUSTOM) {
10948 | char tmp[ITEM_LABEL_LENGTH240];
10949 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10950 |
10951 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10951, "fmtfunc"))));
10952 | fmtfunc(tmp, value);
10953 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10954 | }
10955 | else if (hfinfo->strings) {
10956 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10957 |
10958 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10959 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10960 | }
10961 | else {
10962 | out = hfinfo_char_value_format(hfinfo, buf, value);
10963 |
10964 | label_fill(label_str, 0, hfinfo, out, value_pos);
10965 | }
10966 | }
10967 |
10968 | static void
10969 | fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10970 | {
10971 | const header_field_info *hfinfo = fi->hfinfo;
10972 | uint32_t value;
10973 |
10974 | char buf[NUMBER_LABEL_LENGTH80];
10975 | const char *out;
10976 |
10977 | if (is_signed)
10978 | value = fvalue_get_sinteger(fi->value);
10979 | else
10980 | value = fvalue_get_uinteger(fi->value);
10981 |
10982 | /* Fill in the textual info */
10983 | if (hfinfo->display == BASE_CUSTOM) {
10984 | char tmp[ITEM_LABEL_LENGTH240];
10985 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10986 |
10987 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10987, "fmtfunc"))));
10988 | fmtfunc(tmp, value);
10989 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10990 | }
10991 | else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10992 | /*
10993 | * It makes no sense to have a value-string table for a
10994 | * frame-number field - they're just integers giving
10995 | * the ordinal frame number.
10996 | */
10997 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10998 |
10999 | out = hfinfo_number_vals_format(hfinfo, buf, value);
11000 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11001 | /*
11002 | * Unique values only display value_string string
11003 | * if there is a match. Otherwise it's just a number
11004 | */
11005 | if (val_str) {
11006 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11007 | } else {
11008 | label_fill(label_str, 0, hfinfo, out, value_pos);
11009 | }
11010 | } else {
11011 | if (val_str == NULL((void*)0))
11012 | val_str = "Unknown";
11013 |
11014 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11015 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
11016 | else
11017 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11018 | }
11019 | }
11020 | 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 ))) {
11021 | char tmp[ITEM_LABEL_LENGTH240];
11022 |
11023 | port_with_resolution_to_str_buf(tmp, sizeof(tmp),
11024 | display_to_port_type((field_display_e)hfinfo->display), value);
11025 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
11026 | }
11027 | else {
11028 | out = hfinfo_number_value_format(hfinfo, buf, value);
11029 |
11030 | label_fill(label_str, 0, hfinfo, out, value_pos);
11031 | }
11032 | }
11033 |
11034 | static void
11035 | fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11036 | {
11037 | const header_field_info *hfinfo = fi->hfinfo;
11038 | uint64_t value;
11039 |
11040 | char buf[NUMBER_LABEL_LENGTH80];
11041 | const char *out;
11042 |
11043 | if (is_signed)
11044 | value = fvalue_get_sinteger64(fi->value);
11045 | else
11046 | value = fvalue_get_uinteger64(fi->value);
11047 |
11048 | /* Fill in the textual info */
11049 | if (hfinfo->display == BASE_CUSTOM) {
11050 | char tmp[ITEM_LABEL_LENGTH240];
11051 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11052 |
11053 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 11053, "fmtfunc64" ))));
11054 | fmtfunc64(tmp, value);
11055 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
11056 | }
11057 | else if (hfinfo->strings) {
11058 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
11059 |
11060 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
11061 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11062 | /*
11063 | * Unique values only display value_string string
11064 | * if there is a match. Otherwise it's just a number
11065 | */
11066 | if (val_str) {
11067 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11068 | } else {
11069 | label_fill(label_str, 0, hfinfo, out, value_pos);
11070 | }
11071 | } else {
11072 | if (val_str == NULL((void*)0))
11073 | val_str = "Unknown";
11074 |
11075 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11076 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
11077 | else
11078 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11079 | }
11080 | }
11081 | else {
11082 | out = hfinfo_number_value_format64(hfinfo, buf, value);
11083 |
11084 | label_fill(label_str, 0, hfinfo, out, value_pos);
11085 | }
11086 | }
11087 |
11088 | static size_t
11089 | fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11090 | {
11091 | int display;
11092 | int n;
11093 | double value;
11094 |
11095 | if (label_str_size < 12) {
11096 | /* Not enough room to write an entire floating point value. */
11097 | return 0;
11098 | }
11099 |
11100 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11101 | value = fvalue_get_floating(fi->value);
11102 |
11103 | if (display == BASE_CUSTOM) {
11104 | const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11105 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 11105, "fmtfunc"))));
11106 | fmtfunc(label_str, value);
11107 | return strlen(label_str);
11108 | }
11109 |
11110 | switch (display) {
11111 | case BASE_NONE:
11112 | if (fi->hfinfo->type == FT_FLOAT) {
11113 | n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11114 | } else {
11115 | n = (int)strlen(dtoa_g_fmt(label_str, value));
11116 | }
11117 | break;
11118 | case BASE_DEC:
11119 | n = snprintf(label_str, label_str_size, "%f", value);
11120 | break;
11121 | case BASE_HEX:
11122 | n = snprintf(label_str, label_str_size, "%a", value);
11123 | break;
11124 | case BASE_EXP:
11125 | n = snprintf(label_str, label_str_size, "%e", value);
11126 | break;
11127 | default:
11128 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11128 , __func__, "assertion \"not reached\" failed");
11129 | }
11130 | if (n < 0) {
11131 | return 0; /* error */
11132 | }
11133 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11134 | const char *hf_str_val;
11135 | hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11136 | n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11137 | }
11138 | if (n > label_str_size) {
11139 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11139, __func__, "label length too small"); } } while (0);
11140 | return strlen(label_str);
11141 | }
11142 |
11143 | return n;
11144 | }
11145 |
11146 | void
11147 | fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11148 | {
11149 | char tmp[ITEM_LABEL_LENGTH240];
11150 |
11151 | fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11152 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11153 | }
11154 |
11155 | static size_t
11156 | fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11157 | {
11158 | int display;
11159 | size_t pos = 0;
11160 | double value;
11161 | char* tmp_str;
11162 |
11163 | if (label_str_size < 12) {
11164 | /* Not enough room to write an entire floating point value. */
11165 | return 0;
11166 | }
11167 |
11168 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11169 | tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11170 | pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str, 0);
11171 | wmem_free(NULL((void*)0), tmp_str);
11172 |
11173 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11174 | const char *hf_str_val;
11175 | fvalue_to_double(fi->value, &value);
11176 | hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11177 | 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);
11178 | }
11179 | if ((int)pos > label_str_size) {
11180 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11180, __func__, "label length too small"); } } while (0);
11181 | return strlen(label_str);
11182 | }
11183 |
11184 | return pos;
11185 | }
11186 |
11187 | void
11188 | fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11189 | {
11190 | char tmp[ITEM_LABEL_LENGTH240];
11191 |
11192 | fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11193 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11194 | }
11195 |
11196 | int
11197 | hfinfo_bitshift(const header_field_info *hfinfo)
11198 | {
11199 | return ws_ctz(hfinfo->bitmask);
11200 | }
11201 |
11202 |
11203 | static int
11204 | hfinfo_bitoffset(const header_field_info *hfinfo)
11205 | {
11206 | if (!hfinfo->bitmask) {
11207 | return 0;
11208 | }
11209 |
11210 | /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11211 | * as the first bit */
11212 | return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11213 | }
11214 |
11215 | static int
11216 | hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11217 | {
11218 | if (!hfinfo->bitmask) {
11219 | return 0;
11220 | }
11221 |
11222 | /* ilog2 = first set bit, ctz = last set bit */
11223 | return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11224 | }
11225 |
11226 | static int
11227 | hfinfo_type_bitwidth(enum ftenum type)
11228 | {
11229 | int bitwidth = 0;
11230 |
11231 | switch (type) {
11232 | case FT_CHAR:
11233 | case FT_UINT8:
11234 | case FT_INT8:
11235 | bitwidth = 8;
11236 | break;
11237 | case FT_UINT16:
11238 | case FT_INT16:
11239 | bitwidth = 16;
11240 | break;
11241 | case FT_UINT24:
11242 | case FT_INT24:
11243 | bitwidth = 24;
11244 | break;
11245 | case FT_UINT32:
11246 | case FT_INT32:
11247 | bitwidth = 32;
11248 | break;
11249 | case FT_UINT40:
11250 | case FT_INT40:
11251 | bitwidth = 40;
11252 | break;
11253 | case FT_UINT48:
11254 | case FT_INT48:
11255 | bitwidth = 48;
11256 | break;
11257 | case FT_UINT56:
11258 | case FT_INT56:
11259 | bitwidth = 56;
11260 | break;
11261 | case FT_UINT64:
11262 | case FT_INT64:
11263 | bitwidth = 64;
11264 | break;
11265 | default:
11266 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 11266));
11267 | ;
11268 | }
11269 | return bitwidth;
11270 | }
11271 |
11272 |
11273 | static int
11274 | hfinfo_container_bitwidth(const header_field_info *hfinfo)
11275 | {
11276 | if (!hfinfo->bitmask) {
11277 | return 0;
11278 | }
11279 |
11280 | if (hfinfo->type == FT_BOOLEAN) {
11281 | return hfinfo->display; /* hacky? :) */
11282 | }
11283 |
11284 | return hfinfo_type_bitwidth(hfinfo->type);
11285 | }
11286 |
11287 | static int
11288 | hfinfo_hex_digits(const header_field_info *hfinfo)
11289 | {
11290 | int bitwidth;
11291 |
11292 | /* If we have a bitmask, hfinfo->type is the width of the container, so not
11293 | * appropriate to determine the number of hex digits for the field.
11294 | * So instead, we compute it from the bitmask.
11295 | */
11296 | if (hfinfo->bitmask != 0) {
11297 | bitwidth = hfinfo_mask_bitwidth(hfinfo);
11298 | } else {
11299 | bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11300 | }
11301 |
11302 | /* Divide by 4, rounding up, to get number of hex digits. */
11303 | return (bitwidth + 3) / 4;
11304 | }
11305 |
11306 | const char *
11307 | hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11308 | {
11309 | char *ptr = &buf[6];
11310 | static const char hex_digits[16] =
11311 | { '0', '1', '2', '3', '4', '5', '6', '7',
11312 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11313 |
11314 | *ptr = '\0';
11315 | *(--ptr) = '\'';
11316 | /* Properly format value */
11317 | if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11318 | /*
11319 | * Printable, so just show the character, and, if it needs
11320 | * to be escaped, escape it.
11321 | */
11322 | *(--ptr) = value;
11323 | if (value == '\\' || value == '\'')
11324 | *(--ptr) = '\\';
11325 | } else {
11326 | /*
11327 | * Non-printable; show it as an escape sequence.
11328 | */
11329 | switch (value) {
11330 |
11331 | case '\0':
11332 | /*
11333 | * Show a NUL with only one digit.
11334 | */
11335 | *(--ptr) = '0';
11336 | break;
11337 |
11338 | case '\a':
11339 | case '\b':
11340 | case '\f':
11341 | case '\n':
11342 | case '\r':
11343 | case '\t':
11344 | case '\v':
11345 | *(--ptr) = value - '\a' + 'a';
11346 | break;
11347 |
11348 | default:
11349 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11350 |
11351 | case BASE_OCT:
11352 | *(--ptr) = (value & 0x7) + '0';
11353 | value >>= 3;
11354 | *(--ptr) = (value & 0x7) + '0';
11355 | value >>= 3;
11356 | *(--ptr) = (value & 0x7) + '0';
11357 | break;
11358 |
11359 | case BASE_HEX:
11360 | *(--ptr) = hex_digits[value & 0x0F];
11361 | value >>= 4;
11362 | *(--ptr) = hex_digits[value & 0x0F];
11363 | *(--ptr) = 'x';
11364 | break;
11365 |
11366 | default:
11367 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11368 | }
11369 | }
11370 | *(--ptr) = '\\';
11371 | }
11372 | *(--ptr) = '\'';
11373 | return ptr;
11374 | }
11375 |
11376 | static const char *
11377 | hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11378 | {
11379 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11380 | 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 ));
11381 |
11382 | *ptr = '\0';
11383 | /* Properly format value */
11384 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11385 | case BASE_DEC:
11386 | return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11387 |
11388 | case BASE_DEC_HEX:
11389 | *(--ptr) = ')';
11390 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11391 | *(--ptr) = '(';
11392 | *(--ptr) = ' ';
11393 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11394 | return ptr;
11395 |
11396 | case BASE_OCT:
11397 | return oct_to_str_back(ptr, value);
11398 |
11399 | case BASE_HEX:
11400 | return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11401 |
11402 | case BASE_HEX_DEC:
11403 | *(--ptr) = ')';
11404 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11405 | *(--ptr) = '(';
11406 | *(--ptr) = ' ';
11407 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11408 | return ptr;
11409 |
11410 | case BASE_PT_UDP:
11411 | case BASE_PT_TCP:
11412 | case BASE_PT_DCCP:
11413 | case BASE_PT_SCTP:
11414 | port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11415 | display_to_port_type((field_display_e)display), value);
11416 | return buf;
11417 | case BASE_OUI:
11418 | {
11419 | uint8_t p_oui[3];
11420 | const char *manuf_name;
11421 |
11422 | p_oui[0] = value >> 16 & 0xFF;
11423 | p_oui[1] = value >> 8 & 0xFF;
11424 | p_oui[2] = value & 0xFF;
11425 |
11426 | /* Attempt an OUI lookup. */
11427 | manuf_name = uint_get_manuf_name_if_known(value);
11428 | if (manuf_name == NULL((void*)0)) {
11429 | /* Could not find an OUI. */
11430 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11431 | }
11432 | else {
11433 | /* Found an address string. */
11434 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11435 | }
11436 | return buf;
11437 | }
11438 |
11439 | default:
11440 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11441 | }
11442 | return ptr;
11443 | }
11444 |
11445 | static const char *
11446 | hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11447 | {
11448 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11449 | 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 ));
11450 |
11451 | *ptr = '\0';
11452 | /* Properly format value */
11453 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11454 | case BASE_DEC:
11455 | return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11456 |
11457 | case BASE_DEC_HEX:
11458 | *(--ptr) = ')';
11459 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11460 | *(--ptr) = '(';
11461 | *(--ptr) = ' ';
11462 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11463 | return ptr;
11464 |
11465 | case BASE_OCT:
11466 | return oct64_to_str_back(ptr, value);
11467 |
11468 | case BASE_HEX:
11469 | return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11470 |
11471 | case BASE_HEX_DEC:
11472 | *(--ptr) = ')';
11473 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11474 | *(--ptr) = '(';
11475 | *(--ptr) = ' ';
11476 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11477 | return ptr;
11478 |
11479 | default:
11480 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11481 | }
11482 |
11483 | return ptr;
11484 | }
11485 |
11486 | static const char *
11487 | hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11488 | {
11489 | int display = hfinfo->display;
11490 |
11491 | if (hfinfo->type == FT_FRAMENUM) {
11492 | /*
11493 | * Frame numbers are always displayed in decimal.
11494 | */
11495 | display = BASE_DEC;
11496 | }
11497 |
11498 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11499 | }
11500 |
11501 | static const char *
11502 | hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11503 | {
11504 | int display = hfinfo->display;
11505 |
11506 | if (hfinfo->type == FT_FRAMENUM) {
11507 | /*
11508 | * Frame numbers are always displayed in decimal.
11509 | */
11510 | display = BASE_DEC;
11511 | }
11512 |
11513 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11514 | }
11515 |
11516 | static const char *
11517 | hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11518 | {
11519 | /* Get the underlying BASE_ value */
11520 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11521 |
11522 | return hfinfo_char_value_format_display(display, buf, value);
11523 | }
11524 |
11525 | static const char *
11526 | hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11527 | {
11528 | /* Get the underlying BASE_ value */
11529 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11530 |
11531 | if (hfinfo->type == FT_FRAMENUM) {
11532 | /*
11533 | * Frame numbers are always displayed in decimal.
11534 | */
11535 | display = BASE_DEC;
11536 | }
11537 |
11538 | if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)== BASE_PT_DCCP||(display)==BASE_PT_SCTP))) {
11539 | display = BASE_DEC;
11540 | } else if (display == BASE_OUI) {
11541 | display = BASE_HEX;
11542 | }
11543 |
11544 | switch (display) {
11545 | case BASE_NONE:
11546 | /* case BASE_DEC: */
11547 | case BASE_DEC_HEX:
11548 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11549 | case BASE_CUSTOM:
11550 | display = BASE_DEC;
11551 | break;
11552 |
11553 | /* case BASE_HEX: */
11554 | case BASE_HEX_DEC:
11555 | display = BASE_HEX;
11556 | break;
11557 | }
11558 |
11559 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11560 | }
11561 |
11562 | static const char *
11563 | hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11564 | {
11565 | /* Get the underlying BASE_ value */
11566 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11567 |
11568 | if (hfinfo->type == FT_FRAMENUM) {
11569 | /*
11570 | * Frame numbers are always displayed in decimal.
11571 | */
11572 | display = BASE_DEC;
11573 | }
11574 |
11575 | switch (display) {
11576 | case BASE_NONE:
11577 | /* case BASE_DEC: */
11578 | case BASE_DEC_HEX:
11579 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11580 | case BASE_CUSTOM:
11581 | display = BASE_DEC;
11582 | break;
11583 |
11584 | /* case BASE_HEX: */
11585 | case BASE_HEX_DEC:
11586 | display = BASE_HEX;
11587 | break;
11588 | }
11589 |
11590 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11591 | }
11592 |
11593 | static const char *
11594 | hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11595 | {
11596 | /* Get the underlying BASE_ value */
11597 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11598 |
11599 | return hfinfo_char_value_format_display(display, buf, value);
11600 | }
11601 |
11602 | static const char *
11603 | hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11604 | {
11605 | /* Get the underlying BASE_ value */
11606 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11607 |
11608 | if (display == BASE_NONE)
11609 | return NULL((void*)0);
11610 |
11611 | if (display == BASE_DEC_HEX)
11612 | display = BASE_DEC;
11613 | if (display == BASE_HEX_DEC)
11614 | display = BASE_HEX;
11615 |
11616 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11617 | }
11618 |
11619 | static const char *
11620 | hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11621 | {
11622 | /* Get the underlying BASE_ value */
11623 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11624 |
11625 | if (display == BASE_NONE)
11626 | return NULL((void*)0);
11627 |
11628 | if (display == BASE_DEC_HEX)
11629 | display = BASE_DEC;
11630 | if (display == BASE_HEX_DEC)
11631 | display = BASE_HEX;
11632 |
11633 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11634 | }
11635 |
11636 | const char *
11637 | proto_registrar_get_name(const int n)
11638 | {
11639 | header_field_info *hfinfo;
11640 |
11641 | 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", 11641 , __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", 11641 , "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", 11641, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11642 | return hfinfo->name;
11643 | }
11644 |
11645 | const char *
11646 | proto_registrar_get_abbrev(const int n)
11647 | {
11648 | header_field_info *hfinfo;
11649 |
11650 | 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", 11650 , __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", 11650 , "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", 11650, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11651 | return hfinfo->abbrev;
11652 | }
11653 |
11654 | enum ftenum
11655 | proto_registrar_get_ftype(const int n)
11656 | {
11657 | header_field_info *hfinfo;
11658 |
11659 | 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", 11659 , __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", 11659 , "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", 11659, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11660 | return hfinfo->type;
11661 | }
11662 |
11663 | int
11664 | proto_registrar_get_parent(const int n)
11665 | {
11666 | header_field_info *hfinfo;
11667 |
11668 | 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", 11668 , __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", 11668 , "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", 11668, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11669 | return hfinfo->parent;
11670 | }
11671 |
11672 | bool_Bool
11673 | proto_registrar_is_protocol(const int n)
11674 | {
11675 | header_field_info *hfinfo;
11676 |
11677 | 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", 11677 , __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", 11677 , "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", 11677, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11678 | return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11679 | }
11680 |
11681 | /* Returns length of field in packet (not necessarily the length
11682 | * in our internal representation, as in the case of IPv4).
11683 | * 0 means undeterminable at time of registration
11684 | * -1 means the field is not registered. */
11685 | int
11686 | proto_registrar_get_length(const int n)
11687 | {
11688 | header_field_info *hfinfo;
11689 |
11690 | 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", 11690 , __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", 11690 , "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", 11690, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11691 | return ftype_wire_size(hfinfo->type);
11692 | }
11693 |
11694 | size_t
11695 | proto_registrar_get_count(struct proto_registrar_stats *stats)
11696 | {
11697 | header_field_info *hfinfo;
11698 |
11699 | // Index zero is not used. We have to skip it.
11700 | size_t total_count = gpa_hfinfo.len - 1;
11701 | if (stats == NULL((void*)0)) {
11702 | return total_count;
11703 | }
11704 | for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11705 | if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11706 | stats->deregistered_count++;
11707 | continue; /* This is a deregistered protocol or header field */
11708 | }
11709 |
11710 | 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", 11710 , __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", 11710, "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", 11710, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[id];;
11711 |
11712 | if (proto_registrar_is_protocol(id))
11713 | stats->protocol_count++;
11714 |
11715 | if (hfinfo->same_name_prev_id != -1)
11716 | stats->same_name_count++;
11717 | }
11718 |
11719 | return total_count;
11720 | }
11721 |
11722 | /* Looks for a protocol or a field in a proto_tree. Returns true if
11723 | * it exists anywhere, or false if it exists nowhere. */
11724 | bool_Bool
11725 | proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11726 | {
11727 | GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11728 |
11729 | if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11730 | return true1;
11731 | }
11732 | else {
11733 | return false0;
11734 | }
11735 | }
11736 |
11737 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11738 | * This only works if the hfindex was "primed" before the dissection
11739 | * took place, as we just pass back the already-created GPtrArray*.
11740 | * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11741 | * handles that. */
11742 | GPtrArray *
11743 | proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11744 | {
11745 | if (!tree)
11746 | return NULL((void*)0);
11747 |
11748 | if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11749 | return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11750 | GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11751 | else
11752 | return NULL((void*)0);
11753 | }
11754 |
11755 | bool_Bool
11756 | proto_tracking_interesting_fields(const proto_tree *tree)
11757 | {
11758 | GHashTable *interesting_hfids;
11759 |
11760 | if (!tree)
11761 | return false0;
11762 |
11763 | interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11764 |
11765 | return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11766 | }
11767 |
11768 | /* Helper struct for proto_find_info() and proto_all_finfos() */
11769 | typedef struct {
11770 | GPtrArray *array;
11771 | int id;
11772 | } ffdata_t;
11773 |
11774 | /* Helper function for proto_find_info() */
11775 | static bool_Bool
11776 | find_finfo(proto_node *node, void * data)
11777 | {
11778 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11779 | if (fi && fi->hfinfo) {
11780 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11781 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11782 | }
11783 | }
11784 |
11785 | /* Don't stop traversing. */
11786 | return false0;
11787 | }
11788 |
11789 | /* Helper function for proto_find_first_info() */
11790 | static bool_Bool
11791 | find_first_finfo(proto_node *node, void *data)
11792 | {
11793 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11794 | if (fi && fi->hfinfo) {
11795 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11796 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11797 |
11798 | /* Stop traversing. */
11799 | return true1;
11800 | }
11801 | }
11802 |
11803 | /* Continue traversing. */
11804 | return false0;
11805 | }
11806 |
11807 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11808 | * This works on any proto_tree, primed or unprimed, but actually searches
11809 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11810 | * The caller does need to free the returned GPtrArray with
11811 | * g_ptr_array_free(<array>, true).
11812 | */
11813 | GPtrArray *
11814 | proto_find_finfo(proto_tree *tree, const int id)
11815 | {
11816 | ffdata_t ffdata;
11817 |
11818 | ffdata.array = g_ptr_array_new();
11819 | ffdata.id = id;
11820 |
11821 | proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11822 |
11823 | return ffdata.array;
11824 | }
11825 |
11826 | /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11827 | * This works on any proto_tree, primed or unprimed, but actually searches
11828 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11829 | * The caller does need to free the returned GPtrArray with
11830 | * g_ptr_array_free(<array>, true).
11831 | */
11832 | GPtrArray *
11833 | proto_find_first_finfo(proto_tree *tree, const int id)
11834 | {
11835 | ffdata_t ffdata;
11836 |
11837 | ffdata.array = g_ptr_array_new();
11838 | ffdata.id = id;
11839 |
11840 | proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11841 |
11842 | return ffdata.array;
11843 | }
11844 |
11845 | /* Helper function for proto_all_finfos() */
11846 | static bool_Bool
11847 | every_finfo(proto_node *node, void * data)
11848 | {
11849 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11850 | if (fi && fi->hfinfo) {
11851 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11852 | }
11853 |
11854 | /* Don't stop traversing. */
11855 | return false0;
11856 | }
11857 |
11858 | /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11859 | * The caller does need to free the returned GPtrArray with
11860 | * g_ptr_array_free(<array>, true).
11861 | */
11862 | GPtrArray *
11863 | proto_all_finfos(proto_tree *tree)
11864 | {
11865 | ffdata_t ffdata;
11866 |
11867 | /* Pre allocate enough space to hold all fields in most cases */
11868 | ffdata.array = g_ptr_array_sized_new(512);
11869 | ffdata.id = 0;
11870 |
11871 | proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11872 |
11873 | return ffdata.array;
11874 | }
11875 |
11876 |
11877 | typedef struct {
11878 | unsigned offset;
11879 | field_info *finfo;
11880 | tvbuff_t *tvb;
11881 | } offset_search_t;
11882 |
11883 | static bool_Bool
11884 | check_for_offset(proto_node *node, void * data)
11885 | {
11886 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11887 | offset_search_t *offsearch = (offset_search_t *)data;
11888 |
11889 | /* !fi == the top most container node which holds nothing */
11890 | if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11891 | if (offsearch->offset >= (unsigned) fi->start &&
11892 | offsearch->offset < (unsigned) (fi->start + fi->length)) {
11893 |
11894 | offsearch->finfo = fi;
11895 | return false0; /* keep traversing */
11896 | }
11897 | }
11898 | return false0; /* keep traversing */
11899 | }
11900 |
11901 | /* Search a proto_tree backwards (from leaves to root) looking for the field
11902 | * whose start/length occupies 'offset' */
11903 | /* XXX - I couldn't find an easy way to search backwards, so I search
11904 | * forwards, w/o stopping. Therefore, the last finfo I find will the be
11905 | * the one I want to return to the user. This algorithm is inefficient
11906 | * and could be re-done, but I'd have to handle all the children and
11907 | * siblings of each node myself. When I have more time I'll do that.
11908 | * (yeah right) */
11909 | field_info *
11910 | proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11911 | {
11912 | offset_search_t offsearch;
11913 |
11914 | offsearch.offset = offset;
11915 | offsearch.finfo = NULL((void*)0);
11916 | offsearch.tvb = tvb;
11917 |
11918 | proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11919 |
11920 | return offsearch.finfo;
11921 | }
11922 |
11923 | typedef struct {
11924 | unsigned length;
11925 | char *buf;
11926 | } decoded_data_t;
11927 |
11928 | static bool_Bool
11929 | check_for_undecoded(proto_node *node, void * data)
11930 | {
11931 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11932 | decoded_data_t* decoded = (decoded_data_t*)data;
11933 | unsigned i;
11934 | unsigned byte;
11935 | unsigned bit;
11936 |
11937 | if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11938 | for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11939 | byte = i / 8;
11940 | bit = i % 8;
11941 | decoded->buf[byte] |= (1 << bit);
11942 | }
11943 | }
11944 |
11945 | return false0;
11946 | }
11947 |
11948 | char*
11949 | proto_find_undecoded_data(proto_tree *tree, unsigned length)
11950 | {
11951 | decoded_data_t decoded;
11952 | decoded.length = length;
11953 | decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11954 |
11955 | proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11956 | return decoded.buf;
11957 | }
11958 |
11959 | /* Dumps the protocols in the registration database to stdout. An independent
11960 | * program can take this output and format it into nice tables or HTML or
11961 | * whatever.
11962 | *
11963 | * There is one record per line. The fields are tab-delimited.
11964 | *
11965 | * Field 1 = protocol name
11966 | * Field 2 = protocol short name
11967 | * Field 3 = protocol filter name
11968 | * Field 4 = protocol enabled
11969 | * Field 5 = protocol enabled by default
11970 | * Field 6 = protocol can toggle
11971 | */
11972 | void
11973 | proto_registrar_dump_protocols(void)
11974 | {
11975 | protocol_t *protocol;
11976 | int i;
11977 | void *cookie = NULL((void*)0);
11978 |
11979 |
11980 | i = proto_get_first_protocol(&cookie);
11981 | while (i != -1) {
11982 | protocol = find_protocol_by_id(i);
11983 | printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11984 | protocol->name,
11985 | protocol->short_name,
11986 | protocol->filter_name,
11987 | (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11988 | (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11989 | (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11990 | i = proto_get_next_protocol(&cookie);
11991 | }
11992 | }
11993 |
11994 | /* Dumps the value_strings, extended value string headers, range_strings
11995 | * or true/false strings for fields that have them.
11996 | * There is one record per line. Fields are tab-delimited.
11997 | * There are four types of records: Value String, Extended Value String Header,
11998 | * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11999 | * the type of record.
12000 | *
12001 | * Note that a record will be generated only if the value_string,... is referenced
12002 | * in a registered hfinfo entry.
12003 | *
12004 | *
12005 | * Value Strings
12006 | * -------------
12007 | * Field 1 = 'V'
12008 | * Field 2 = Field abbreviation to which this value string corresponds
12009 | * Field 3 = Integer value
12010 | * Field 4 = String
12011 | *
12012 | * Extended Value String Headers
12013 | * -----------------------------
12014 | * Field 1 = 'E'
12015 | * Field 2 = Field abbreviation to which this extended value string header corresponds
12016 | * Field 3 = Extended Value String "Name"
12017 | * Field 4 = Number of entries in the associated value_string array
12018 | * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
12019 | *
12020 | * Range Strings
12021 | * -------------
12022 | * Field 1 = 'R'
12023 | * Field 2 = Field abbreviation to which this range string corresponds
12024 | * Field 3 = Integer value: lower bound
12025 | * Field 4 = Integer value: upper bound
12026 | * Field 5 = String
12027 | *
12028 | * True/False Strings
12029 | * ------------------
12030 | * Field 1 = 'T'
12031 | * Field 2 = Field abbreviation to which this true/false string corresponds
12032 | * Field 3 = True String
12033 | * Field 4 = False String
12034 | */
12035 | void
12036 | proto_registrar_dump_values(void)
12037 | {
12038 | header_field_info *hfinfo;
12039 | int i, len, vi;
12040 | const value_string *vals;
12041 | const val64_string *vals64;
12042 | const range_string *range;
12043 | const true_false_string *tfs;
12044 | const unit_name_string *units;
12045 |
12046 | len = gpa_hfinfo.len;
12047 | for (i = 1; i < len ; i++) {
12048 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12049 | continue; /* This is a deregistered protocol or field */
12050 |
12051 | 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", 12051 , __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", 12051 , "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", 12051, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12052 |
12053 | if (hfinfo->id == hf_text_only) {
12054 | continue;
12055 | }
12056 |
12057 | /* ignore protocols */
12058 | if (proto_registrar_is_protocol(i)) {
12059 | continue;
12060 | }
12061 | /* process header fields */
12062 | #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12063 | /*
12064 | * If this field isn't at the head of the list of
12065 | * fields with this name, skip this field - all
12066 | * fields with the same name are really just versions
12067 | * of the same field stored in different bits, and
12068 | * should have the same type/radix/value list, and
12069 | * just differ in their bit masks. (If a field isn't
12070 | * a bitfield, but can be, say, 1 or 2 bytes long,
12071 | * it can just be made FT_UINT16, meaning the
12072 | * *maximum* length is 2 bytes, and be used
12073 | * for all lengths.)
12074 | */
12075 | if (hfinfo->same_name_prev_id != -1)
12076 | continue;
12077 | #endif
12078 | vals = NULL((void*)0);
12079 | vals64 = NULL((void*)0);
12080 | range = NULL((void*)0);
12081 | tfs = NULL((void*)0);
12082 | units = NULL((void*)0);
12083 |
12084 | if (hfinfo->strings != NULL((void*)0)) {
12085 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12086 | (hfinfo->type == FT_CHAR ||
12087 | hfinfo->type == FT_UINT8 ||
12088 | hfinfo->type == FT_UINT16 ||
12089 | hfinfo->type == FT_UINT24 ||
12090 | hfinfo->type == FT_UINT32 ||
12091 | hfinfo->type == FT_UINT40 ||
12092 | hfinfo->type == FT_UINT48 ||
12093 | hfinfo->type == FT_UINT56 ||
12094 | hfinfo->type == FT_UINT64 ||
12095 | hfinfo->type == FT_INT8 ||
12096 | hfinfo->type == FT_INT16 ||
12097 | hfinfo->type == FT_INT24 ||
12098 | hfinfo->type == FT_INT32 ||
12099 | hfinfo->type == FT_INT40 ||
12100 | hfinfo->type == FT_INT48 ||
12101 | hfinfo->type == FT_INT56 ||
12102 | hfinfo->type == FT_INT64 ||
12103 | hfinfo->type == FT_FLOAT ||
12104 | hfinfo->type == FT_DOUBLE)) {
12105 |
12106 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12107 | range = (const range_string *)hfinfo->strings;
12108 | } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12109 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12110 | vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12111 | } else {
12112 | vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12113 | }
12114 | } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12115 | vals64 = (const val64_string *)hfinfo->strings;
12116 | } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12117 | units = (const unit_name_string *)hfinfo->strings;
12118 | } else {
12119 | vals = (const value_string *)hfinfo->strings;
12120 | }
12121 | }
12122 | else if (hfinfo->type == FT_BOOLEAN) {
12123 | tfs = (const struct true_false_string *)hfinfo->strings;
12124 | }
12125 | }
12126 |
12127 | /* Print value strings? */
12128 | if (vals) {
12129 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12130 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12131 | val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12132 | if (!val64_string_ext_validate(vse_p)) {
12133 | ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 12133, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
12134 | continue;
12135 | }
12136 | try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12137 | printf("E\t%s\t%u\t%s\t%s\n",
12138 | hfinfo->abbrev,
12139 | VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12140 | VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12141 | val64_string_ext_match_type_str(vse_p));
12142 | } else {
12143 | value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12144 | if (!value_string_ext_validate(vse_p)) {
12145 | ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 12145, __func__, "Invalid value_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
12146 | continue;
12147 | }
12148 | try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12149 | printf("E\t%s\t%u\t%s\t%s\n",
12150 | hfinfo->abbrev,
12151 | VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12152 | VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12153 | value_string_ext_match_type_str(vse_p));
12154 | }
12155 | }
12156 | vi = 0;
12157 | while (vals[vi].strptr) {
12158 | /* Print in the proper base */
12159 | if (hfinfo->type == FT_CHAR) {
12160 | if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT ) != 0)) {
12161 | printf("V\t%s\t'%c'\t%s\n",
12162 | hfinfo->abbrev,
12163 | vals[vi].value,
12164 | vals[vi].strptr);
12165 | } else {
12166 | if (hfinfo->display == BASE_HEX) {
12167 | printf("V\t%s\t'\\x%02x'\t%s\n",
12168 | hfinfo->abbrev,
12169 | vals[vi].value,
12170 | vals[vi].strptr);
12171 | }
12172 | else {
12173 | printf("V\t%s\t'\\%03o'\t%s\n",
12174 | hfinfo->abbrev,
12175 | vals[vi].value,
12176 | vals[vi].strptr);
12177 | }
12178 | }
12179 | } else {
12180 | if (hfinfo->display == BASE_HEX) {
12181 | printf("V\t%s\t0x%x\t%s\n",
12182 | hfinfo->abbrev,
12183 | vals[vi].value,
12184 | vals[vi].strptr);
12185 | }
12186 | else {
12187 | printf("V\t%s\t%u\t%s\n",
12188 | hfinfo->abbrev,
12189 | vals[vi].value,
12190 | vals[vi].strptr);
12191 | }
12192 | }
12193 | vi++;
12194 | }
12195 | }
12196 | else if (vals64) {
12197 | vi = 0;
12198 | while (vals64[vi].strptr) {
12199 | printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12200 | hfinfo->abbrev,
12201 | vals64[vi].value,
12202 | vals64[vi].strptr);
12203 | vi++;
12204 | }
12205 | }
12206 |
12207 | /* print range strings? */
12208 | else if (range) {
12209 | vi = 0;
12210 | while (range[vi].strptr) {
12211 | /* Print in the proper base */
12212 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12213 | printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12214 | hfinfo->abbrev,
12215 | range[vi].value_min,
12216 | range[vi].value_max,
12217 | range[vi].strptr);
12218 | }
12219 | else {
12220 | printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12221 | hfinfo->abbrev,
12222 | range[vi].value_min,
12223 | range[vi].value_max,
12224 | range[vi].strptr);
12225 | }
12226 | vi++;
12227 | }
12228 | }
12229 |
12230 | /* Print true/false strings? */
12231 | else if (tfs) {
12232 | printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12233 | tfs->true_string, tfs->false_string);
12234 | }
12235 | /* Print unit strings? */
12236 | else if (units) {
12237 | printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12238 | units->singular, units->plural ? units->plural : "(no plural)");
12239 | }
12240 | }
12241 | }
12242 |
12243 | /* Prints the number of registered fields.
12244 | * Useful for determining an appropriate value for
12245 | * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12246 | *
12247 | * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12248 | * the number of fields, true otherwise.
12249 | */
12250 | bool_Bool
12251 | proto_registrar_dump_fieldcount(void)
12252 | {
12253 | struct proto_registrar_stats stats = {0, 0, 0};
12254 | size_t total_count = proto_registrar_get_count(&stats);
12255 |
12256 | printf("There are %zu header fields registered, of which:\n"
12257 | "\t%zu are deregistered\n"
12258 | "\t%zu are protocols\n"
12259 | "\t%zu have the same name as another field\n\n",
12260 | total_count, stats.deregistered_count, stats.protocol_count,
12261 | stats.same_name_count);
12262 |
12263 | printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12264 | (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12265 | "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12266 | "\n");
12267 |
12268 | printf("The header field table consumes %u KiB of memory.\n",
12269 | (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12270 | printf("The fields themselves consume %u KiB of memory.\n",
12271 | (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12272 |
12273 | return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12274 | }
12275 |
12276 | static void
12277 | elastic_add_base_mapping(json_dumper *dumper)
12278 | {
12279 | json_dumper_set_member_name(dumper, "index_patterns");
12280 | json_dumper_begin_array(dumper);
12281 | // The index names from write_json_index() in print.c
12282 | json_dumper_value_string(dumper, "packets-*");
12283 | json_dumper_end_array(dumper);
12284 |
12285 | json_dumper_set_member_name(dumper, "settings");
12286 | json_dumper_begin_object(dumper);
12287 | json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12288 | json_dumper_value_anyf(dumper, "%d", 1000000);
12289 | json_dumper_end_object(dumper);
12290 | }
12291 |
12292 | static char*
12293 | ws_type_to_elastic(unsigned type)
12294 | {
12295 | switch(type) {
12296 | case FT_INT8:
12297 | return "byte";
12298 | case FT_UINT8:
12299 | case FT_INT16:
12300 | return "short";
12301 | case FT_UINT16:
12302 | case FT_INT32:
12303 | case FT_UINT24:
12304 | case FT_INT24:
12305 | return "integer";
12306 | case FT_FRAMENUM:
12307 | case FT_UINT32:
12308 | case FT_UINT40:
12309 | case FT_UINT48:
12310 | case FT_UINT56:
12311 | case FT_INT40:
12312 | case FT_INT48:
12313 | case FT_INT56:
12314 | case FT_INT64:
12315 | return "long";
12316 | case FT_UINT64:
12317 | return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12318 | case FT_FLOAT:
12319 | return "float";
12320 | case FT_DOUBLE:
12321 | case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12322 | return "double";
12323 | case FT_IPv6:
12324 | case FT_IPv4:
12325 | return "ip";
12326 | case FT_ABSOLUTE_TIME:
12327 | return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12328 | case FT_BOOLEAN:
12329 | return "boolean";
12330 | default:
12331 | return NULL((void*)0);
12332 | }
12333 | }
12334 |
12335 | static char*
12336 | dot_to_underscore(char* str)
12337 | {
12338 | unsigned i;
12339 | for (i = 0; i < strlen(str); i++) {
12340 | if (str[i] == '.')
12341 | str[i] = '_';
12342 | }
12343 | return str;
12344 | }
12345 |
12346 | /* Dumps a mapping file for ElasticSearch
12347 | * This is the v1 (legacy) _template API.
12348 | * At some point it may need to be updated with the composable templates
12349 | * introduced in Elasticsearch 7.8 (_index_template)
12350 | */
12351 | void
12352 | proto_registrar_dump_elastic(const char* filter)
12353 | {
12354 | header_field_info *hfinfo;
12355 | header_field_info *parent_hfinfo;
12356 | unsigned i;
12357 | bool_Bool open_object = true1;
12358 | const char* prev_proto = NULL((void*)0);
12359 | char* str;
12360 | char** protos = NULL((void*)0);
12361 | char* proto;
12362 | bool_Bool found;
12363 | unsigned j;
12364 | char* type;
12365 | char* prev_item = NULL((void*)0);
12366 |
12367 | /* We have filtering protocols. Extract them. */
12368 | if (filter) {
12369 | protos = g_strsplit(filter, ",", -1);
12370 | }
12371 |
12372 | /*
12373 | * To help tracking down the json tree, objects have been appended with a comment:
12374 | * n.label -> where n is the indentation level and label the name of the object
12375 | */
12376 |
12377 | json_dumper dumper = {
12378 | .output_file = stdoutstdout,
12379 | .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12380 | };
12381 | json_dumper_begin_object(&dumper); // 1.root
12382 | elastic_add_base_mapping(&dumper);
12383 |
12384 | json_dumper_set_member_name(&dumper, "mappings");
12385 | json_dumper_begin_object(&dumper); // 2.mappings
12386 |
12387 | json_dumper_set_member_name(&dumper, "properties");
12388 | json_dumper_begin_object(&dumper); // 3.properties
12389 | json_dumper_set_member_name(&dumper, "timestamp");
12390 | json_dumper_begin_object(&dumper); // 4.timestamp
12391 | json_dumper_set_member_name(&dumper, "type");
12392 | json_dumper_value_string(&dumper, "date");
12393 | json_dumper_end_object(&dumper); // 4.timestamp
12394 |
12395 | json_dumper_set_member_name(&dumper, "layers");
12396 | json_dumper_begin_object(&dumper); // 4.layers
12397 | json_dumper_set_member_name(&dumper, "properties");
12398 | json_dumper_begin_object(&dumper); // 5.properties
12399 |
12400 | for (i = 1; i < gpa_hfinfo.len; i++) {
12401 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12402 | continue; /* This is a deregistered protocol or header field */
12403 |
12404 | 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", 12404 , __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", 12404 , "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", 12404, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12405 |
12406 | /*
12407 | * Skip the pseudo-field for "proto_tree_add_text()" since
12408 | * we don't want it in the list of filterable protocols.
12409 | */
12410 | if (hfinfo->id == hf_text_only)
12411 | continue;
12412 |
12413 | if (!proto_registrar_is_protocol(i)) {
12414 | 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", 12414 , __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", 12414 , "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", 12414 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12415 |
12416 | /*
12417 | * Skip the field if filter protocols have been set and this one's
12418 | * parent is not listed.
12419 | */
12420 | if (protos) {
12421 | found = false0;
12422 | j = 0;
12423 | proto = protos[0];
12424 | while(proto) {
12425 | if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12426 | found = true1;
12427 | break;
12428 | }
12429 | j++;
12430 | proto = protos[j];
12431 | }
12432 | if (!found)
12433 | continue;
12434 | }
12435 |
12436 | if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12437 | json_dumper_end_object(&dumper); // 7.properties
12438 | json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12439 | open_object = true1;
12440 | }
12441 |
12442 | prev_proto = parent_hfinfo->abbrev;
12443 |
12444 | if (open_object) {
12445 | json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12446 | json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12447 | json_dumper_set_member_name(&dumper, "properties");
12448 | json_dumper_begin_object(&dumper); // 7.properties
12449 | open_object = false0;
12450 | }
12451 | /* Skip the fields that would map into string. This is the default in elasticsearch. */
12452 | type = ws_type_to_elastic(hfinfo->type);
12453 | /* when type is NULL, we have the default mapping: string */
12454 | if (type) {
12455 | str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo-> abbrev);
12456 | dot_to_underscore(str);
12457 | if (g_strcmp0(prev_item, str)) {
12458 | json_dumper_set_member_name(&dumper, str);
12459 | json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12460 | json_dumper_set_member_name(&dumper, "type");
12461 | json_dumper_value_string(&dumper, type);
12462 | json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12463 | }
12464 | 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);
12465 | prev_item = str;
12466 | }
12467 | }
12468 | }
12469 | 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);
12470 |
12471 | if (prev_proto) {
12472 | json_dumper_end_object(&dumper); // 7.properties
12473 | json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12474 | }
12475 |
12476 | json_dumper_end_object(&dumper); // 5.properties
12477 | json_dumper_end_object(&dumper); // 4.layers
12478 | json_dumper_end_object(&dumper); // 3.properties
12479 | json_dumper_end_object(&dumper); // 2.mappings
12480 | json_dumper_end_object(&dumper); // 1.root
12481 | bool_Bool ret = json_dumper_finish(&dumper);
12482 | DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12482, "ret"))));
12483 |
12484 | g_strfreev(protos);
12485 | }
12486 |
12487 | /* Dumps the contents of the registration database to stdout. An independent
12488 | * program can take this output and format it into nice tables or HTML or
12489 | * whatever.
12490 | *
12491 | * There is one record per line. Each record is either a protocol or a header
12492 | * field, differentiated by the first field. The fields are tab-delimited.
12493 | *
12494 | * Protocols
12495 | * ---------
12496 | * Field 1 = 'P'
12497 | * Field 2 = descriptive protocol name
12498 | * Field 3 = protocol abbreviation
12499 | *
12500 | * Header Fields
12501 | * -------------
12502 | * Field 1 = 'F'
12503 | * Field 2 = descriptive field name
12504 | * Field 3 = field abbreviation
12505 | * Field 4 = type ( textual representation of the ftenum type )
12506 | * Field 5 = parent protocol abbreviation
12507 | * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12508 | * Field 7 = bitmask: format: hex: 0x....
12509 | * Field 8 = blurb describing field
12510 | */
12511 | void
12512 | proto_registrar_dump_fields(void)
12513 | {
12514 | header_field_info *hfinfo, *parent_hfinfo;
12515 | int i, len;
12516 | const char *enum_name;
12517 | const char *base_name;
12518 | const char *blurb;
12519 | char width[5];
12520 |
12521 | len = gpa_hfinfo.len;
12522 | for (i = 1; i < len ; i++) {
12523 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12524 | continue; /* This is a deregistered protocol or header field */
12525 |
12526 | 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", 12526 , __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", 12526 , "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", 12526, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12527 |
12528 | /*
12529 | * Skip the pseudo-field for "proto_tree_add_text()" since
12530 | * we don't want it in the list of filterable fields.
12531 | */
12532 | if (hfinfo->id == hf_text_only)
12533 | continue;
12534 |
12535 | /* format for protocols */
12536 | if (proto_registrar_is_protocol(i)) {
12537 | printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12538 | }
12539 | /* format for header fields */
12540 | else {
12541 | /*
12542 | * If this field isn't at the head of the list of
12543 | * fields with this name, skip this field - all
12544 | * fields with the same name are really just versions
12545 | * of the same field stored in different bits, and
12546 | * should have the same type/radix/value list, and
12547 | * just differ in their bit masks. (If a field isn't
12548 | * a bitfield, but can be, say, 1 or 2 bytes long,
12549 | * it can just be made FT_UINT16, meaning the
12550 | * *maximum* length is 2 bytes, and be used
12551 | * for all lengths.)
12552 | */
12553 | if (hfinfo->same_name_prev_id != -1)
12554 | continue;
12555 |
12556 | 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", 12556 , __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", 12556 , "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", 12556 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12557 |
12558 | enum_name = ftype_name(hfinfo->type);
12559 | base_name = "";
12560 |
12561 | if (hfinfo->type == FT_CHAR ||
12562 | hfinfo->type == FT_UINT8 ||
12563 | hfinfo->type == FT_UINT16 ||
12564 | hfinfo->type == FT_UINT24 ||
12565 | hfinfo->type == FT_UINT32 ||
12566 | hfinfo->type == FT_UINT40 ||
12567 | hfinfo->type == FT_UINT48 ||
12568 | hfinfo->type == FT_UINT56 ||
12569 | hfinfo->type == FT_UINT64 ||
12570 | hfinfo->type == FT_INT8 ||
12571 | hfinfo->type == FT_INT16 ||
12572 | hfinfo->type == FT_INT24 ||
12573 | hfinfo->type == FT_INT32 ||
12574 | hfinfo->type == FT_INT40 ||
12575 | hfinfo->type == FT_INT48 ||
12576 | hfinfo->type == FT_INT56 ||
12577 | hfinfo->type == FT_INT64) {
12578 |
12579 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12580 | case BASE_NONE:
12581 | case BASE_DEC:
12582 | case BASE_HEX:
12583 | case BASE_OCT:
12584 | case BASE_DEC_HEX:
12585 | case BASE_HEX_DEC:
12586 | case BASE_CUSTOM:
12587 | case BASE_PT_UDP:
12588 | case BASE_PT_TCP:
12589 | case BASE_PT_DCCP:
12590 | case BASE_PT_SCTP:
12591 | case BASE_OUI:
12592 | base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12593 | break;
12594 | default:
12595 | base_name = "????";
12596 | break;
12597 | }
12598 | } else if (hfinfo->type == FT_BOOLEAN) {
12599 | /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12600 | snprintf(width, sizeof(width), "%d", hfinfo->display);
12601 | base_name = width;
12602 | }
12603 |
12604 | blurb = hfinfo->blurb;
12605 | if (blurb == NULL((void*)0))
12606 | blurb = "";
12607 | else if (strlen(blurb) == 0)
12608 | blurb = "\"\"";
12609 |
12610 | printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12611 | hfinfo->name, hfinfo->abbrev, enum_name,
12612 | parent_hfinfo->abbrev, base_name,
12613 | hfinfo->bitmask, blurb);
12614 | }
12615 | }
12616 | }
12617 |
12618 | /* Dumps all abbreviated field and protocol completions of the given string to
12619 | * stdout. An independent program may use this for command-line tab completion
12620 | * of fields.
12621 | */
12622 | bool_Bool
12623 | proto_registrar_dump_field_completions(const char *prefix)
12624 | {
12625 | header_field_info *hfinfo;
12626 | int i, len;
12627 | size_t prefix_len;
12628 | bool_Bool matched = false0;
12629 |
12630 | prefix_len = strlen(prefix);
12631 | len = gpa_hfinfo.len;
12632 | for (i = 1; i < len ; i++) {
12633 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12634 | continue; /* This is a deregistered protocol or header field */
12635 |
12636 | 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", 12636 , __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", 12636 , "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", 12636, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12637 |
12638 | /*
12639 | * Skip the pseudo-field for "proto_tree_add_text()" since
12640 | * we don't want it in the list of filterable fields.
12641 | */
12642 | if (hfinfo->id == hf_text_only)
12643 | continue;
12644 |
12645 | /* format for protocols */
12646 | if (proto_registrar_is_protocol(i)) {
12647 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12648 | matched = true1;
12649 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12650 | }
12651 | }
12652 | /* format for header fields */
12653 | else {
12654 | /*
12655 | * If this field isn't at the head of the list of
12656 | * fields with this name, skip this field - all
12657 | * fields with the same name are really just versions
12658 | * of the same field stored in different bits, and
12659 | * should have the same type/radix/value list, and
12660 | * just differ in their bit masks. (If a field isn't
12661 | * a bitfield, but can be, say, 1 or 2 bytes long,
12662 | * it can just be made FT_UINT16, meaning the
12663 | * *maximum* length is 2 bytes, and be used
12664 | * for all lengths.)
12665 | */
12666 | if (hfinfo->same_name_prev_id != -1)
12667 | continue;
12668 |
12669 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12670 | matched = true1;
12671 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12672 | }
12673 | }
12674 | }
12675 | return matched;
12676 | }
12677 |
12678 | /* Dumps field types and descriptive names to stdout. An independent
12679 | * program can take this output and format it into nice tables or HTML or
12680 | * whatever.
12681 | *
12682 | * There is one record per line. The fields are tab-delimited.
12683 | *
12684 | * Field 1 = field type name, e.g. FT_UINT8
12685 | * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12686 | */
12687 | void
12688 | proto_registrar_dump_ftypes(void)
12689 | {
12690 | int fte;
12691 |
12692 | for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12693 | printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12694 | }
12695 | }
12696 |
12697 | /* This function indicates whether it's possible to construct a
12698 | * "match selected" display filter string for the specified field,
12699 | * returns an indication of whether it's possible, and, if it's
12700 | * possible and "filter" is non-null, constructs the filter and
12701 | * sets "*filter" to point to it.
12702 | * You do not need to [g_]free() this string since it will be automatically
12703 | * freed once the next packet is dissected.
12704 | */
12705 | static bool_Bool
12706 | construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12707 | char **filter)
12708 | {
12709 | const header_field_info *hfinfo;
12710 | int start, length, length_remaining;
12711 |
12712 | if (!finfo)
12713 | return false0;
12714 |
12715 | hfinfo = finfo->hfinfo;
12716 | DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12716, "hfinfo"))));
12717 |
12718 | /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12719 | * then "the numeric value ... is not used when preparing
12720 | * filters for the field in question." If it's any other
12721 | * base, we'll generate the filter normally (which will
12722 | * be numeric, even though the human-readable string does
12723 | * work for filtering.)
12724 | *
12725 | * XXX - It might be nice to use fvalue_to_string_repr() in
12726 | * "proto_item_fill_label()" as well, although, there, you'd
12727 | * have to deal with the base *and* with resolved values for
12728 | * addresses.
12729 | *
12730 | * Perhaps in addition to taking the repr type (DISPLAY
12731 | * or DFILTER) and the display (base), fvalue_to_string_repr()
12732 | * should have the the "strings" values in the header_field_info
12733 | * structure for the field as a parameter, so it can have
12734 | * if the field is Boolean or an enumerated integer type,
12735 | * the tables used to generate human-readable values.
12736 | */
12737 | if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12738 | const char *str = NULL((void*)0);
12739 |
12740 | switch (hfinfo->type) {
12741 |
12742 | case FT_INT8:
12743 | case FT_INT16:
12744 | case FT_INT24:
12745 | case FT_INT32:
12746 | str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12747 | break;
12748 |
12749 | case FT_CHAR:
12750 | case FT_UINT8:
12751 | case FT_UINT16:
12752 | case FT_UINT24:
12753 | case FT_UINT32:
12754 | str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12755 | break;
12756 |
12757 | default:
12758 | break;
12759 | }
12760 |
12761 | if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12762 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12763 | return true1;
12764 | }
12765 | }
12766 |
12767 | switch (hfinfo->type) {
12768 |
12769 | case FT_PROTOCOL:
12770 | if (filter != NULL((void*)0))
12771 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12772 | break;
12773 |
12774 | case FT_NONE:
12775 | /*
12776 | * If the length is 0, just match the name of the
12777 | * field.
12778 | *
12779 | * (Also check for negative values, just in case,
12780 | * as we'll cast it to an unsigned value later.)
12781 | */
12782 | length = finfo->length;
12783 | if (length == 0) {
12784 | if (filter != NULL((void*)0))
12785 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12786 | break;
12787 | }
12788 | if (length < 0)
12789 | return false0;
12790 |
12791 | /*
12792 | * This doesn't have a value, so we'd match
12793 | * on the raw bytes at this address.
12794 | *
12795 | * Should we be allowed to access to the raw bytes?
12796 | * If "edt" is NULL, the answer is "no".
12797 | */
12798 | if (edt == NULL((void*)0))
12799 | return false0;
12800 |
12801 | /*
12802 | * Is this field part of the raw frame tvbuff?
12803 | * If not, we can't use "frame[N:M]" to match
12804 | * it.
12805 | *
12806 | * XXX - should this be frame-relative, or
12807 | * protocol-relative?
12808 | *
12809 | * XXX - does this fallback for non-registered
12810 | * fields even make sense?
12811 | */
12812 | if (finfo->ds_tvb != edt->tvb)
12813 | return false0; /* you lose */
12814 |
12815 | /*
12816 | * Don't go past the end of that tvbuff.
12817 | */
12818 | length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12819 | if (length > length_remaining)
12820 | length = length_remaining;
12821 | if (length <= 0)
12822 | return false0;
12823 |
12824 | if (filter != NULL((void*)0)) {
12825 | start = finfo->start;
12826 | char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12827 | *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12828 | wmem_free(NULL((void*)0), str);
12829 | }
12830 | break;
12831 |
12832 | /* By default, use the fvalue's "to_string_repr" method. */
12833 | default:
12834 | if (filter != NULL((void*)0)) {
12835 | char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12836 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12837 | wmem_free(NULL((void*)0), str);
12838 | }
12839 | break;
12840 | }
12841 |
12842 | return true1;
12843 | }
12844 |
12845 | /*
12846 | * Returns true if we can do a "match selected" on the field, false
12847 | * otherwise.
12848 | */
12849 | bool_Bool
12850 | proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12851 | {
12852 | return construct_match_selected_string(finfo, edt, NULL((void*)0));
12853 | }
12854 |
12855 | /* This function attempts to construct a "match selected" display filter
12856 | * string for the specified field; if it can do so, it returns a pointer
12857 | * to the string, otherwise it returns NULL.
12858 | *
12859 | * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12860 | */
12861 | char *
12862 | proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12863 | {
12864 | char *filter = NULL((void*)0);
12865 |
12866 | if (!construct_match_selected_string(finfo, edt, &filter))
12867 | {
12868 | wmem_free(NULL((void*)0), filter);
12869 | return NULL((void*)0);
12870 | }
12871 | return filter;
12872 | }
12873 |
12874 | /* This function is common code for all proto_tree_add_bitmask... functions.
12875 | */
12876 |
12877 | static bool_Bool
12878 | proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
12879 | const unsigned len, const int ett, int * const *fields,
12880 | const int flags, bool_Bool first,
12881 | bool_Bool use_parent_tree,
12882 | proto_tree* tree, uint64_t value)
12883 | {
12884 | uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12885 | uint64_t bitmask = 0;
12886 | uint64_t tmpval;
12887 | header_field_info *hf;
12888 | uint32_t integer32;
12889 | int bit_offset;
12890 | int no_of_bits;
12891 |
12892 | if (!*fields)
12893 | 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" );
12894 |
12895 | if (len > 8)
12896 | REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12897 | /**
12898 | * packet-frame.c uses len=0 since the value is taken from the packet
12899 | * metadata, not the packet bytes. In that case, assume that all bits
12900 | * in the provided value are valid.
12901 | */
12902 | if (len > 0) {
12903 | available_bits >>= (8 - len)*8;
12904 | }
12905 |
12906 | if (use_parent_tree == false0)
12907 | tree = proto_item_add_subtree(item, ett);
12908 |
12909 | while (*fields) {
12910 | uint64_t present_bits;
12911 | 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", 12911, __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", 12911 , "**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", 12911, "gpa_hfinfo.hfi[**fields] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];;
12912 | 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", 12912 , "hf->bitmask != 0", hf->abbrev))));
12913 |
12914 | bitmask |= hf->bitmask;
12915 |
12916 | /* Skip fields that aren't fully present */
12917 | present_bits = available_bits & hf->bitmask;
12918 | if (present_bits != hf->bitmask) {
12919 | fields++;
12920 | continue;
12921 | }
12922 |
12923 | switch (hf->type) {
12924 | case FT_CHAR:
12925 | case FT_UINT8:
12926 | case FT_UINT16:
12927 | case FT_UINT24:
12928 | case FT_UINT32:
12929 | proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12930 | break;
12931 |
12932 | case FT_INT8:
12933 | case FT_INT16:
12934 | case FT_INT24:
12935 | case FT_INT32:
12936 | proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12937 | break;
12938 |
12939 | case FT_UINT40:
12940 | case FT_UINT48:
12941 | case FT_UINT56:
12942 | case FT_UINT64:
12943 | proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12944 | break;
12945 |
12946 | case FT_INT40:
12947 | case FT_INT48:
12948 | case FT_INT56:
12949 | case FT_INT64:
12950 | proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12951 | break;
12952 |
12953 | case FT_BOOLEAN:
12954 | proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12955 | break;
12956 |
12957 | default:
12958 | 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))
12959 | 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))
12960 | 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))
12961 | 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));
12962 | break;
12963 | }
12964 | if (flags & BMT_NO_APPEND0x01) {
12965 | fields++;
12966 | continue;
12967 | }
12968 | tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12969 |
12970 | /* XXX: README.developer and the comments have always defined
12971 | * BMT_NO_INT as "only boolean flags are added to the title /
12972 | * don't add non-boolean (integral) fields", but the
12973 | * implementation has always added BASE_CUSTOM and fields with
12974 | * value_strings, though not fields with unit_strings.
12975 | * Possibly this is because some dissectors use a FT_UINT8
12976 | * with a value_string for fields that should be a FT_BOOLEAN.
12977 | */
12978 | switch (hf->type) {
12979 | case FT_CHAR:
12980 | if (hf->display == BASE_CUSTOM) {
12981 | char lbl[ITEM_LABEL_LENGTH240];
12982 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12983 |
12984 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12984, "fmtfunc"))));
12985 | fmtfunc(lbl, (uint32_t) tmpval);
12986 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12987 | hf->name, lbl);
12988 | first = false0;
12989 | }
12990 | else if (hf->strings) {
12991 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12992 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12993 | first = false0;
12994 | }
12995 | else if (!(flags & BMT_NO_INT0x02)) {
12996 | char buf[32];
12997 | const char *out;
12998 |
12999 | if (!first) {
13000 | proto_item_append_text(item, ", ");
13001 | }
13002 |
13003 | out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
13004 | proto_item_append_text(item, "%s: %s", hf->name, out);
13005 | first = false0;
13006 | }
13007 |
13008 | break;
13009 |
13010 | case FT_UINT8:
13011 | case FT_UINT16:
13012 | case FT_UINT24:
13013 | case FT_UINT32:
13014 | if (hf->display == BASE_CUSTOM) {
13015 | char lbl[ITEM_LABEL_LENGTH240];
13016 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13017 |
13018 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13018, "fmtfunc"))));
13019 | fmtfunc(lbl, (uint32_t) tmpval);
13020 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13021 | hf->name, lbl);
13022 | first = false0;
13023 | }
13024 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13025 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13026 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
13027 | first = false0;
13028 | }
13029 | else if (!(flags & BMT_NO_INT0x02)) {
13030 | char buf[NUMBER_LABEL_LENGTH80];
13031 | const char *out = NULL((void*)0);
13032 |
13033 | if (!first) {
13034 | proto_item_append_text(item, ", ");
13035 | }
13036 |
13037 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13038 | out = hf_try_val_to_str((uint32_t) tmpval, hf);
13039 | }
13040 | if (out == NULL((void*)0)) {
13041 | out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13042 | }
13043 | proto_item_append_text(item, "%s: %s", hf->name, out);
13044 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13045 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13046 | }
13047 | first = false0;
13048 | }
13049 |
13050 | break;
13051 |
13052 | case FT_INT8:
13053 | case FT_INT16:
13054 | case FT_INT24:
13055 | case FT_INT32:
13056 | integer32 = (uint32_t) tmpval;
13057 | if (hf->bitmask) {
13058 | no_of_bits = ws_count_ones(hf->bitmask);
13059 | integer32 = ws_sign_ext32(integer32, no_of_bits);
13060 | }
13061 | if (hf->display == BASE_CUSTOM) {
13062 | char lbl[ITEM_LABEL_LENGTH240];
13063 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13064 |
13065 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13065, "fmtfunc"))));
13066 | fmtfunc(lbl, (int32_t) integer32);
13067 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13068 | hf->name, lbl);
13069 | first = false0;
13070 | }
13071 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13072 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13073 | hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13074 | first = false0;
13075 | }
13076 | else if (!(flags & BMT_NO_INT0x02)) {
13077 | char buf[NUMBER_LABEL_LENGTH80];
13078 | const char *out = NULL((void*)0);
13079 |
13080 | if (!first) {
13081 | proto_item_append_text(item, ", ");
13082 | }
13083 |
13084 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13085 | out = hf_try_val_to_str((int32_t) integer32, hf);
13086 | }
13087 | if (out == NULL((void*)0)) {
13088 | out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13089 | }
13090 | proto_item_append_text(item, "%s: %s", hf->name, out);
13091 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13092 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13093 | }
13094 | first = false0;
13095 | }
13096 |
13097 | break;
13098 |
13099 | case FT_UINT40:
13100 | case FT_UINT48:
13101 | case FT_UINT56:
13102 | case FT_UINT64:
13103 | if (hf->display == BASE_CUSTOM) {
13104 | char lbl[ITEM_LABEL_LENGTH240];
13105 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13106 |
13107 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13107, "fmtfunc"))));
13108 | fmtfunc(lbl, tmpval);
13109 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13110 | hf->name, lbl);
13111 | first = false0;
13112 | }
13113 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13114 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13115 | hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13116 | first = false0;
13117 | }
13118 | else if (!(flags & BMT_NO_INT0x02)) {
13119 | char buf[NUMBER_LABEL_LENGTH80];
13120 | const char *out = NULL((void*)0);
13121 |
13122 | if (!first) {
13123 | proto_item_append_text(item, ", ");
13124 | }
13125 |
13126 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13127 | out = hf_try_val64_to_str(tmpval, hf);
13128 | }
13129 | if (out == NULL((void*)0)) {
13130 | out = hfinfo_number_value_format64(hf, buf, tmpval);
13131 | }
13132 | proto_item_append_text(item, "%s: %s", hf->name, out);
13133 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13134 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13135 | }
13136 | first = false0;
13137 | }
13138 |
13139 | break;
13140 |
13141 | case FT_INT40:
13142 | case FT_INT48:
13143 | case FT_INT56:
13144 | case FT_INT64:
13145 | if (hf->bitmask) {
13146 | no_of_bits = ws_count_ones(hf->bitmask);
13147 | tmpval = ws_sign_ext64(tmpval, no_of_bits);
13148 | }
13149 | if (hf->display == BASE_CUSTOM) {
13150 | char lbl[ITEM_LABEL_LENGTH240];
13151 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13152 |
13153 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13153, "fmtfunc"))));
13154 | fmtfunc(lbl, (int64_t) tmpval);
13155 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13156 | hf->name, lbl);
13157 | first = false0;
13158 | }
13159 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13160 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13161 | hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13162 | first = false0;
13163 | }
13164 | else if (!(flags & BMT_NO_INT0x02)) {
13165 | char buf[NUMBER_LABEL_LENGTH80];
13166 | const char *out = NULL((void*)0);
13167 |
13168 | if (!first) {
13169 | proto_item_append_text(item, ", ");
13170 | }
13171 |
13172 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13173 | out = hf_try_val64_to_str((int64_t) tmpval, hf);
13174 | }
13175 | if (out == NULL((void*)0)) {
13176 | out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13177 | }
13178 | proto_item_append_text(item, "%s: %s", hf->name, out);
13179 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13180 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13181 | }
13182 | first = false0;
13183 | }
13184 |
13185 | break;
13186 |
13187 | case FT_BOOLEAN:
13188 | if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13189 | /* If we have true/false strings, emit full - otherwise messages
13190 | might look weird */
13191 | const struct true_false_string *tfs =
13192 | (const struct true_false_string *)hf->strings;
13193 |
13194 | if (tmpval) {
13195 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13196 | hf->name, tfs->true_string);
13197 | first = false0;
13198 | } else if (!(flags & BMT_NO_FALSE0x04)) {
13199 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13200 | hf->name, tfs->false_string);
13201 | first = false0;
13202 | }
13203 | } else if (hf->bitmask & value) {
13204 | /* If the flag is set, show the name */
13205 | proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13206 | first = false0;
13207 | }
13208 | break;
13209 | default:
13210 | 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))
13211 | 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))
13212 | 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))
13213 | 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));
13214 | break;
13215 | }
13216 |
13217 | fields++;
13218 | }
13219 |
13220 | /* XXX: We don't pass the hfi into this function. Perhaps we should,
13221 | * but then again most dissectors don't set the bitmask field for
13222 | * the higher level bitmask hfi, so calculate the bitmask from the
13223 | * fields present. */
13224 | if (item) {
13225 | bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13226 | no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13227 | 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);
13228 | 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);
13229 | }
13230 | return first;
13231 | }
13232 |
13233 | /* This function will dissect a sequence of bytes that describe a
13234 | * bitmask and supply the value of that sequence through a pointer.
13235 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13236 | * to be dissected.
13237 | * This field will form an expansion under which the individual fields of the
13238 | * bitmask is dissected and displayed.
13239 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13240 | *
13241 | * fields is an array of pointers to int that lists all the fields of the
13242 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13243 | * or another integer of the same type/size as hf_hdr with a mask specified.
13244 | * This array is terminated by a NULL entry.
13245 | *
13246 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13247 | * FT_integer fields that have a value_string attached will have the
13248 | * matched string displayed on the expansion line.
13249 | */
13250 | proto_item *
13251 | proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13252 | const unsigned offset, const int hf_hdr,
13253 | const int ett, int * const *fields,
13254 | const unsigned encoding, uint64_t *retval)
13255 | {
13256 | 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);
13257 | }
13258 |
13259 | /* This function will dissect a sequence of bytes that describe a
13260 | * bitmask.
13261 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13262 | * to be dissected.
13263 | * This field will form an expansion under which the individual fields of the
13264 | * bitmask is dissected and displayed.
13265 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13266 | *
13267 | * fields is an array of pointers to int that lists all the fields of the
13268 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13269 | * or another integer of the same type/size as hf_hdr with a mask specified.
13270 | * This array is terminated by a NULL entry.
13271 | *
13272 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13273 | * FT_integer fields that have a value_string attached will have the
13274 | * matched string displayed on the expansion line.
13275 | */
13276 | proto_item *
13277 | proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13278 | const unsigned offset, const int hf_hdr,
13279 | const int ett, int * const *fields,
13280 | const unsigned encoding)
13281 | {
13282 | return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13283 | }
13284 |
13285 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13286 | * what data is appended to the header.
13287 | */
13288 | proto_item *
13289 | proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13290 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13291 | uint64_t *retval)
13292 | {
13293 | proto_item *item = NULL((void*)0);
13294 | header_field_info *hf;
13295 | unsigned len;
13296 | uint64_t value;
13297 |
13298 | 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", 13298, __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", 13298 , "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", 13298, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13299 | 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", 13299, (hf)->abbrev)));
13300 | len = ftype_wire_size(hf->type);
13301 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13302 |
13303 | if (parent_tree) {
13304 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13305 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13306 | flags, false0, false0, NULL((void*)0), value);
13307 | }
13308 |
13309 | *retval = value;
13310 | if (hf->bitmask) {
13311 | /* Mask out irrelevant portions */
13312 | *retval &= hf->bitmask;
13313 | /* Shift bits */
13314 | *retval >>= hfinfo_bitshift(hf);
13315 | }
13316 |
13317 | return item;
13318 | }
13319 |
13320 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13321 | * what data is appended to the header.
13322 | */
13323 | proto_item *
13324 | proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13325 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13326 | {
13327 | proto_item *item = NULL((void*)0);
13328 | header_field_info *hf;
13329 | unsigned len;
13330 | uint64_t value;
13331 |
13332 | 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", 13332, __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", 13332 , "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", 13332, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13333 | 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", 13333, (hf)->abbrev)));
13334 |
13335 | if (parent_tree) {
13336 | len = ftype_wire_size(hf->type);
13337 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13338 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13339 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13340 | flags, false0, false0, NULL((void*)0), value);
13341 | }
13342 |
13343 | return item;
13344 | }
13345 |
13346 | /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13347 | can't be retrieved directly from tvb) */
13348 | proto_item *
13349 | proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13350 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13351 | {
13352 | return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13353 | hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13354 | }
13355 |
13356 | /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13357 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13358 | proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13359 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13360 | {
13361 | proto_item *item = NULL((void*)0);
13362 | header_field_info *hf;
13363 | unsigned len;
13364 |
13365 | 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", 13365, __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", 13365 , "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", 13365, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13366 | 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", 13366, (hf)->abbrev)));
13367 | /* the proto_tree_add_uint/_uint64() calls below
13368 | will fail if tvb==NULL and len!=0 */
13369 | len = tvb ? ftype_wire_size(hf->type) : 0;
13370 |
13371 | if (parent_tree) {
13372 | if (len <= 4)
13373 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13374 | else
13375 | item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13376 |
13377 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13378 | flags, false0, false0, NULL((void*)0), value);
13379 | }
13380 |
13381 | return item;
13382 | }
13383 |
13384 | /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13385 | void
13386 | proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13387 | const unsigned len, int * const *fields, const unsigned encoding)
13388 | {
13389 | uint64_t value;
13390 |
13391 | if (tree) {
13392 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13393 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13394 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13395 | }
13396 | }
13397 |
13398 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13399 | proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13400 | const unsigned len, int * const *fields, const unsigned encoding, uint64_t *retval)
13401 | {
13402 | uint64_t value;
13403 |
13404 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13405 | if (tree) {
13406 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13407 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13408 | }
13409 | if (retval) {
13410 | *retval = value;
13411 | }
13412 | }
13413 |
13414 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13415 | proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13416 | const unsigned len, int * const *fields, const uint64_t value)
13417 | {
13418 | if (tree) {
13419 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13420 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13421 | }
13422 | }
13423 |
13424 |
13425 | /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13426 | * This is intended to support bitmask fields whose lengths can vary, perhaps
13427 | * as the underlying standard evolves over time.
13428 | * With this API there is the possibility of being called to display more or
13429 | * less data than the dissector was coded to support.
13430 | * In such cases, it is assumed that bitmasks are extended on the MSb end.
13431 | * Thus when presented with "too much" or "too little" data, MSbits will be
13432 | * ignored or MSfields sacrificed.
13433 | *
13434 | * Only fields for which all defined bits are available are displayed.
13435 | */
13436 | proto_item *
13437 | proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13438 | const unsigned offset, const unsigned len, const int hf_hdr,
13439 | const int ett, int * const *fields, struct expert_field* exp,
13440 | const unsigned encoding)
13441 | {
13442 | proto_item *item = NULL((void*)0);
13443 | header_field_info *hf;
13444 | unsigned decodable_len;
13445 | unsigned decodable_offset;
13446 | uint32_t decodable_value;
13447 | uint64_t value;
13448 |
13449 | 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", 13449, __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", 13449 , "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", 13449, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13450 | 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", 13450, (hf)->abbrev)));
13451 |
13452 | decodable_offset = offset;
13453 | decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len ) : ((unsigned) ftype_wire_size(hf->type)));
13454 |
13455 | /* If we are ftype_wire_size-limited,
13456 | * make sure we decode as many LSBs as possible.
13457 | */
13458 | if (encoding == ENC_BIG_ENDIAN0x00000000) {
13459 | decodable_offset += (len - decodable_len);
13460 | }
13461 |
13462 | if (parent_tree) {
13463 | decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13464 | decodable_len, encoding);
13465 |
13466 | /* The root item covers all the bytes even if we can't decode them all */
13467 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13468 | decodable_value);
13469 | }
13470 |
13471 | if (decodable_len < len) {
13472 | /* Dissector likely requires updating for new protocol revision */
13473 | expert_add_info_format(NULL((void*)0), item, exp,
13474 | "Only least-significant %d of %d bytes decoded",
13475 | decodable_len, len);
13476 | }
13477 |
13478 | if (item) {
13479 | value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13480 | proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13481 | ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13482 | }
13483 |
13484 | return item;
13485 | }
13486 |
13487 | /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13488 | proto_item *
13489 | proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13490 | const unsigned offset, const unsigned len,
13491 | const char *name, const char *fallback,
13492 | const int ett, int * const *fields,
13493 | const unsigned encoding, const int flags)
13494 | {
13495 | proto_item *item = NULL((void*)0);
13496 | uint64_t value;
13497 |
13498 | if (parent_tree) {
13499 | item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13500 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13501 | if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13502 | flags, true1, false0, NULL((void*)0), value) && fallback) {
13503 | /* Still at first item - append 'fallback' text if any */
13504 | proto_item_append_text(item, "%s", fallback);
13505 | }
13506 | }
13507 |
13508 | return item;
13509 | }
13510 |
13511 | proto_item *
13512 | proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13513 | const unsigned bit_offset, const int no_of_bits,
13514 | const unsigned encoding)
13515 | {
13516 | header_field_info *hfinfo;
13517 | int octet_length;
13518 | unsigned octet_offset;
13519 |
13520 | 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", 13520, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13520 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13520, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13521 |
13522 | if (no_of_bits < 0) {
13523 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13524 | }
13525 | octet_length = (no_of_bits + 7) >> 3;
13526 | octet_offset = bit_offset >> 3;
13527 | test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13528 |
13529 | /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13530 | * but only after doing a bunch more work (which we can, in the common
13531 | * case, shortcut here).
13532 | */
13533 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13534 | 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", 13534 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13534, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13534, "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", 13534, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
13535 |
13536 | return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13537 | }
13538 |
13539 | /*
13540 | * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13541 | * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13542 | * Offset should be given in bits from the start of the tvb.
13543 | */
13544 |
13545 | static proto_item *
13546 | _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13547 | const unsigned bit_offset, const int no_of_bits,
13548 | uint64_t *return_value, const unsigned encoding)
13549 | {
13550 | unsigned offset;
13551 | unsigned length;
13552 | uint8_t tot_no_bits;
13553 | char *bf_str;
13554 | char lbl_str[ITEM_LABEL_LENGTH240];
13555 | uint64_t value = 0;
13556 | uint8_t *bytes = NULL((void*)0);
13557 | size_t bytes_length = 0;
13558 |
13559 | proto_item *pi;
13560 | header_field_info *hf_field;
13561 |
13562 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13563 | 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", 13563, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13563 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13563, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;;
13564 |
13565 | if (hf_field->bitmask != 0) {
13566 | 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)
13567 | " 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)
13568 | 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);
13569 | }
13570 |
13571 | if (no_of_bits < 0) {
13572 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13573 | } else if (no_of_bits == 0) {
13574 | 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)
13575 | 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);
13576 | }
13577 |
13578 | /* Byte align offset */
13579 | offset = bit_offset>>3;
13580 |
13581 | /*
13582 | * Calculate the number of octets used to hold the bits
13583 | */
13584 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13585 | length = (tot_no_bits + 7) >> 3;
13586 |
13587 | if (no_of_bits < 65) {
13588 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13589 | } else if (hf_field->type != FT_BYTES) {
13590 | 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)
13591 | 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);
13592 | return NULL((void*)0);
13593 | }
13594 |
13595 | /* Sign extend for signed types */
13596 | switch (hf_field->type) {
13597 | case FT_INT8:
13598 | case FT_INT16:
13599 | case FT_INT24:
13600 | case FT_INT32:
13601 | case FT_INT40:
13602 | case FT_INT48:
13603 | case FT_INT56:
13604 | case FT_INT64:
13605 | value = ws_sign_ext64(value, no_of_bits);
13606 | break;
13607 |
13608 | default:
13609 | break;
13610 | }
13611 |
13612 | if (return_value) {
13613 | *return_value = value;
13614 | }
13615 |
13616 | /* Coast clear. Try and fake it */
13617 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13618 | 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", 13618 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13618, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13618, "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", 13618, __func__, "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); } } };
13619 |
13620 | bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13621 |
13622 | switch (hf_field->type) {
13623 | case FT_BOOLEAN:
13624 | /* Boolean field */
13625 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13626 | "%s = %s: %s",
13627 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13628 | break;
13629 |
13630 | case FT_CHAR:
13631 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13632 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13633 | break;
13634 |
13635 | case FT_UINT8:
13636 | case FT_UINT16:
13637 | case FT_UINT24:
13638 | case FT_UINT32:
13639 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13640 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13641 | break;
13642 |
13643 | case FT_INT8:
13644 | case FT_INT16:
13645 | case FT_INT24:
13646 | case FT_INT32:
13647 | pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13648 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13649 | break;
13650 |
13651 | case FT_UINT40:
13652 | case FT_UINT48:
13653 | case FT_UINT56:
13654 | case FT_UINT64:
13655 | pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13656 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13657 | break;
13658 |
13659 | case FT_INT40:
13660 | case FT_INT48:
13661 | case FT_INT56:
13662 | case FT_INT64:
13663 | pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13664 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13665 | break;
13666 |
13667 | case FT_BYTES:
13668 | bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13669 | pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13670 | proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13671 | proto_item_set_text(pi, "%s", lbl_str);
13672 | return pi;
13673 |
13674 | /* TODO: should handle FT_UINT_BYTES ? */
13675 |
13676 | default:
13677 | 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))
13678 | 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))
13679 | 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))
13680 | 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));
13681 | return NULL((void*)0);
13682 | }
13683 |
13684 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13685 | return pi;
13686 | }
13687 |
13688 | proto_item *
13689 | proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13690 | const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13691 | uint64_t *return_value)
13692 | {
13693 | proto_item *pi;
13694 | int no_of_bits;
13695 | unsigned octet_offset;
13696 | unsigned mask_initial_bit_offset;
13697 | unsigned mask_greatest_bit_offset;
13698 | unsigned octet_length;
13699 | uint8_t i;
13700 | char bf_str[256];
13701 | char lbl_str[ITEM_LABEL_LENGTH240];
13702 | uint64_t value;
13703 | uint64_t composite_bitmask;
13704 | uint64_t composite_bitmap;
13705 |
13706 | header_field_info *hf_field;
13707 |
13708 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13709 | 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", 13709, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13709 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13709, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;;
1 | Assuming 'hfindex' is not equal to 0 | →
2 | ← | Assuming 'hfindex' is <= field 'len' | →
3 | ← | Assuming 'hfindex' is > 0 | →
4 | ← | Assuming 'hfindex' is < field 'len' | →
5 | ← | '?' condition is true | →
6 | ← | Assuming the condition is true | →
7 | ← | '?' condition is true | →
13710 |
13711 | if (hf_field->bitmask != 0) {
8 | ← | Assuming field 'bitmask' is equal to 0 | →
9 | ← | Taking false branch | →
13712 | 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)
13713 | " 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)
13714 | 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);
13715 | }
13716 |
13717 | mask_initial_bit_offset = bit_offset % 8;
13718 |
13719 | no_of_bits = 0;
13720 | value = 0;
13721 | i = 0;
13722 | mask_greatest_bit_offset = 0;
13723 | composite_bitmask = 0;
13724 | composite_bitmap = 0;
13725 |
13726 | while (crumb_spec[i].crumb_bit_length != 0) {
10 | ← | Assuming field 'crumb_bit_length' is not equal to 0 | →
11 | ← | Loop condition is true. Entering loop body | →
13727 | uint64_t crumb_mask, crumb_value;
13728 | uint8_t crumb_end_bit_offset;
13729 |
13730 | crumb_value = tvb_get_bits64(tvb,
13731 | bit_offset + crumb_spec[i].crumb_bit_offset,
13732 | crumb_spec[i].crumb_bit_length,
13733 | ENC_BIG_ENDIAN0x00000000);
13734 | value += crumb_value;
13735 | no_of_bits += crumb_spec[i].crumb_bit_length;
13736 | 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", 13736 , "no_of_bits <= 64", "a value larger than 64 bits cannot be represented" ))));
12 | ← | Assuming 'no_of_bits' is <= 64 | →
13 | ← | '?' condition is true | →
13737 |
13738 | /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13739 | octet containing the initial offset.
13740 | If the mask is beyond 32 bits, then give up on bit map display.
13741 | This could be improved in future, probably showing a table
13742 | of 32 or 64 bits per row */
13743 | if (mask_greatest_bit_offset
13.1 | 'mask_greatest_bit_offset' is < 32
< 32) {
14 | ← | Taking true branch | →
13744 | crumb_end_bit_offset = mask_initial_bit_offset
13745 | + crumb_spec[i].crumb_bit_offset
13746 | + crumb_spec[i].crumb_bit_length;
13747 | crumb_mask = (UINT64_C(1)1UL << crumb_spec[i].crumb_bit_length) - 1;
15 | ← | Assuming right operand of bit shift is less than 64 | →
16 | ← | Value assigned to 'crumb_mask' | →
13748 |
13749 | if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17 | ← | Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset' | →
18 | ← | Taking false branch | →
13750 | mask_greatest_bit_offset = crumb_end_bit_offset;
13751 | }
13752 | /* Currently the bitmap of the crumbs are only shown if
13753 | * smaller than 32 bits. Do not bother calculating the
13754 | * mask if it is larger than that. */
13755 | if (crumb_end_bit_offset
18.1 | 'crumb_end_bit_offset' is <= 32
<= 32) {
19 | ← | Taking true branch | →
13756 | composite_bitmask |= (crumb_mask << (64 - crumb_end_bit_offset));
20 | ← | The result of left shift is undefined because the right operand '64' is not smaller than 64, the capacity of 'uint64_t'
13757 | composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13758 | }
13759 | }
13760 | /* Shift left for the next segment */
13761 | value <<= crumb_spec[++i].crumb_bit_length;
13762 | }
13763 |
13764 | /* Sign extend for signed types */
13765 | switch (hf_field->type) {
13766 | case FT_INT8:
13767 | case FT_INT16:
13768 | case FT_INT24:
13769 | case FT_INT32:
13770 | case FT_INT40:
13771 | case FT_INT48:
13772 | case FT_INT56:
13773 | case FT_INT64:
13774 | value = ws_sign_ext64(value, no_of_bits);
13775 | break;
13776 | default:
13777 | break;
13778 | }
13779 |
13780 | if (return_value) {
13781 | *return_value = value;
13782 | }
13783 |
13784 | /* Coast clear. Try and fake it */
13785 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13786 | 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", 13786 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13786, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13786, "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", 13786, __func__, "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); } } };
13787 |
13788 | /* initialise the format string */
13789 | bf_str[0] = '\0';
13790 |
13791 | octet_offset = bit_offset >> 3;
13792 |
13793 | /* Round up mask length to nearest octet */
13794 | octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13795 | mask_greatest_bit_offset = octet_length << 3;
13796 |
13797 | /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13798 | It would be a useful enhancement to eliminate this restriction. */
13799 | if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13800 | other_decode_bitfield_value(bf_str,
13801 | (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13802 | (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13803 | mask_greatest_bit_offset);
13804 | } else {
13805 | /* If the bitmask is too large, try to describe its contents. */
13806 | snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13807 | }
13808 |
13809 | switch (hf_field->type) {
13810 | case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13811 | /* Boolean field */
13812 | return proto_tree_add_boolean_format(tree, hfindex,
13813 | tvb, octet_offset, octet_length, value,
13814 | "%s = %s: %s",
13815 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13816 | break;
13817 |
13818 | case FT_CHAR:
13819 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13820 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13821 | break;
13822 |
13823 | case FT_UINT8:
13824 | case FT_UINT16:
13825 | case FT_UINT24:
13826 | case FT_UINT32:
13827 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13828 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13829 | break;
13830 |
13831 | case FT_INT8:
13832 | case FT_INT16:
13833 | case FT_INT24:
13834 | case FT_INT32:
13835 | pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13836 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13837 | break;
13838 |
13839 | case FT_UINT40:
13840 | case FT_UINT48:
13841 | case FT_UINT56:
13842 | case FT_UINT64:
13843 | pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13844 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13845 | break;
13846 |
13847 | case FT_INT40:
13848 | case FT_INT48:
13849 | case FT_INT56:
13850 | case FT_INT64:
13851 | pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13852 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13853 | break;
13854 |
13855 | default:
13856 | 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))
13857 | 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))
13858 | 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))
13859 | 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));
13860 | return NULL((void*)0);
13861 | }
13862 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13863 | return pi;
13864 | }
13865 |
13866 | void
13867 | proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13868 | const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13869 | {
13870 | header_field_info *hfinfo;
13871 | unsigned start = bit_offset >> 3;
13872 | unsigned length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13873 |
13874 | /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13875 | * so that we can use the tree's memory scope in calculating the string */
13876 | tvb_ensure_bytes_exist(tvb, start, length);
13877 | if (!tree) return;
13878 |
13879 | 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", 13879, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13879 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13879, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13880 | proto_tree_add_text_internal(tree, tvb, start, length,
13881 | "%s crumb %d of %s (decoded above)",
13882 | decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13883 | tvb_get_bits32(tvb,
13884 | bit_offset,
13885 | crumb_spec[crumb_index].crumb_bit_length,
13886 | ENC_BIG_ENDIAN0x00000000),
13887 | ENC_BIG_ENDIAN0x00000000),
13888 | crumb_index,
13889 | hfinfo->name);
13890 | }
13891 |
13892 | proto_item *
13893 | proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13894 | const unsigned bit_offset, const int no_of_bits,
13895 | uint64_t *return_value, const unsigned encoding)
13896 | {
13897 | proto_item *item;
13898 |
13899 | if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13900 | bit_offset, no_of_bits,
13901 | return_value, encoding))) {
13902 | 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);
13903 | 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);
13904 | }
13905 | return item;
13906 | }
13907 |
13908 | static proto_item *
13909 | _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13910 | tvbuff_t *tvb, const unsigned bit_offset,
13911 | const int no_of_bits, void *value_ptr,
13912 | const unsigned encoding, char *value_str)
13913 | {
13914 | unsigned offset;
13915 | unsigned length;
13916 | uint8_t tot_no_bits;
13917 | char *str;
13918 | uint64_t value = 0;
13919 | header_field_info *hf_field;
13920 |
13921 | /* We do not have to return a value, try to fake it as soon as possible */
13922 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13923 | 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", 13923 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13923, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13923, "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", 13923, __func__, "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); } } };
13924 |
13925 | if (hf_field->bitmask != 0) {
13926 | 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)
13927 | " 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)
13928 | 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);
13929 | }
13930 |
13931 | if (no_of_bits < 0) {
13932 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13933 | } else if (no_of_bits == 0) {
13934 | 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)
13935 | 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);
13936 | }
13937 |
13938 | /* Byte align offset */
13939 | offset = bit_offset>>3;
13940 |
13941 | /*
13942 | * Calculate the number of octets used to hold the bits
13943 | */
13944 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13945 | length = tot_no_bits>>3;
13946 | /* If we are using part of the next octet, increase length by 1 */
13947 | if (tot_no_bits & 0x07)
13948 | length++;
13949 |
13950 | if (no_of_bits < 65) {
13951 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13952 | } else {
13953 | 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)
13954 | 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);
13955 | return NULL((void*)0);
13956 | }
13957 |
13958 | str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13959 |
13960 | (void) g_strlcat(str, " = ", 256+64);
13961 | (void) g_strlcat(str, hf_field->name, 256+64);
13962 |
13963 | /*
13964 | * This function does not receive an actual value but a dimensionless pointer to that value.
13965 | * For this reason, the type of the header field is examined in order to determine
13966 | * what kind of value we should read from this address.
13967 | * The caller of this function must make sure that for the specific header field type the address of
13968 | * a compatible value is provided.
13969 | */
13970 | switch (hf_field->type) {
13971 | case FT_BOOLEAN:
13972 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13973 | "%s: %s", str, value_str);
13974 | break;
13975 |
13976 | case FT_CHAR:
13977 | case FT_UINT8:
13978 | case FT_UINT16:
13979 | case FT_UINT24:
13980 | case FT_UINT32:
13981 | return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13982 | "%s: %s", str, value_str);
13983 | break;
13984 |
13985 | case FT_UINT40:
13986 | case FT_UINT48:
13987 | case FT_UINT56:
13988 | case FT_UINT64:
13989 | return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13990 | "%s: %s", str, value_str);
13991 | break;
13992 |
13993 | case FT_INT8:
13994 | case FT_INT16:
13995 | case FT_INT24:
13996 | case FT_INT32:
13997 | return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13998 | "%s: %s", str, value_str);
13999 | break;
14000 |
14001 | case FT_INT40:
14002 | case FT_INT48:
14003 | case FT_INT56:
14004 | case FT_INT64:
14005 | return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
14006 | "%s: %s", str, value_str);
14007 | break;
14008 |
14009 | case FT_FLOAT:
14010 | return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
14011 | "%s: %s", str, value_str);
14012 | break;
14013 |
14014 | default:
14015 | 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))
14016 | 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))
14017 | 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))
14018 | 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));
14019 | return NULL((void*)0);
14020 | }
14021 | }
14022 |
14023 | static proto_item *
14024 | proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
14025 | tvbuff_t *tvb, const unsigned bit_offset,
14026 | const int no_of_bits, void *value_ptr,
14027 | const unsigned encoding, char *value_str)
14028 | {
14029 | proto_item *item;
14030 |
14031 | if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14032 | tvb, bit_offset, no_of_bits,
14033 | value_ptr, encoding, value_str))) {
14034 | 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);
14035 | 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);
14036 | }
14037 | return item;
14038 | }
14039 |
14040 | #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); \
14041 | va_start(ap, format)__builtin_va_start(ap, format); \
14042 | dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14043 | va_end(ap)__builtin_va_end(ap);
14044 |
14045 | proto_item *
14046 | proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14047 | tvbuff_t *tvb, const unsigned bit_offset,
14048 | const int no_of_bits, uint32_t value,
14049 | const unsigned encoding,
14050 | const char *format, ...)
14051 | {
14052 | va_list ap;
14053 | char *dst;
14054 | header_field_info *hf_field;
14055 |
14056 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14057 |
14058 | 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", 14058 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14058, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14058, "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", 14058, __func__, "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); } } };
14059 |
14060 | switch (hf_field->type) {
14061 | case FT_UINT8:
14062 | case FT_UINT16:
14063 | case FT_UINT24:
14064 | case FT_UINT32:
14065 | break;
14066 |
14067 | default:
14068 | 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)
14069 | 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);
14070 | return NULL((void*)0);
14071 | }
14072 |
14073 | 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);;
14074 |
14075 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14076 | }
14077 |
14078 | proto_item *
14079 | proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14080 | tvbuff_t *tvb, const unsigned bit_offset,
14081 | const int no_of_bits, uint64_t value,
14082 | const unsigned encoding,
14083 | const char *format, ...)
14084 | {
14085 | va_list ap;
14086 | char *dst;
14087 | header_field_info *hf_field;
14088 |
14089 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14090 |
14091 | 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", 14091 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14091, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14091, "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", 14091, __func__, "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); } } };
14092 |
14093 | switch (hf_field->type) {
14094 | case FT_UINT40:
14095 | case FT_UINT48:
14096 | case FT_UINT56:
14097 | case FT_UINT64:
14098 | break;
14099 |
14100 | default:
14101 | 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)
14102 | 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);
14103 | return NULL((void*)0);
14104 | }
14105 |
14106 | 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);;
14107 |
14108 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14109 | }
14110 |
14111 | proto_item *
14112 | proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14113 | tvbuff_t *tvb, const unsigned bit_offset,
14114 | const int no_of_bits, float value,
14115 | const unsigned encoding,
14116 | const char *format, ...)
14117 | {
14118 | va_list ap;
14119 | char *dst;
14120 | header_field_info *hf_field;
14121 |
14122 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14123 |
14124 | 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", 14124 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14124, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14124, "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", 14124, __func__, "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); } } };
14125 |
14126 | 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", 14126, ((hf_field))->abbrev))));
14127 |
14128 | 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);;
14129 |
14130 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14131 | }
14132 |
14133 | proto_item *
14134 | proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14135 | tvbuff_t *tvb, const unsigned bit_offset,
14136 | const int no_of_bits, int32_t value,
14137 | const unsigned encoding,
14138 | const char *format, ...)
14139 | {
14140 | va_list ap;
14141 | char *dst;
14142 | header_field_info *hf_field;
14143 |
14144 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14145 |
14146 | 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", 14146 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14146, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14146, "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", 14146, __func__, "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); } } };
14147 |
14148 | switch (hf_field->type) {
14149 | case FT_INT8:
14150 | case FT_INT16:
14151 | case FT_INT24:
14152 | case FT_INT32:
14153 | break;
14154 |
14155 | default:
14156 | 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)
14157 | 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);
14158 | return NULL((void*)0);
14159 | }
14160 |
14161 | 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);;
14162 |
14163 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14164 | }
14165 |
14166 | proto_item *
14167 | proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14168 | tvbuff_t *tvb, const unsigned bit_offset,
14169 | const int no_of_bits, int64_t value,
14170 | const unsigned encoding,
14171 | const char *format, ...)
14172 | {
14173 | va_list ap;
14174 | char *dst;
14175 | header_field_info *hf_field;
14176 |
14177 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14178 |
14179 | 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", 14179 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14179, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14179, "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", 14179, __func__, "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); } } };
14180 |
14181 | switch (hf_field->type) {
14182 | case FT_INT40:
14183 | case FT_INT48:
14184 | case FT_INT56:
14185 | case FT_INT64:
14186 | break;
14187 |
14188 | default:
14189 | 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)
14190 | 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);
14191 | return NULL((void*)0);
14192 | }
14193 |
14194 | 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);;
14195 |
14196 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14197 | }
14198 |
14199 | proto_item *
14200 | proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14201 | tvbuff_t *tvb, const unsigned bit_offset,
14202 | const int no_of_bits, uint64_t value,
14203 | const unsigned encoding,
14204 | const char *format, ...)
14205 | {
14206 | va_list ap;
14207 | char *dst;
14208 | header_field_info *hf_field;
14209 |
14210 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14211 |
14212 | 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", 14212 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14212, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14212, "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", 14212, __func__, "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); } } };
14213 |
14214 | 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" , 14214, ((hf_field))->abbrev))));
14215 |
14216 | 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);;
14217 |
14218 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14219 | }
14220 |
14221 | proto_item *
14222 | proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14223 | const unsigned bit_offset, const int no_of_chars)
14224 | {
14225 | proto_item *pi;
14226 | header_field_info *hfinfo;
14227 | int byte_length;
14228 | unsigned byte_offset;
14229 | char *string;
14230 |
14231 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14232 |
14233 | 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", 14233 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14233, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14233, "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", 14233, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14234 |
14235 | 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" , 14235, ((hfinfo))->abbrev))));
14236 |
14237 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14238 | byte_offset = bit_offset >> 3;
14239 |
14240 | string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14241 |
14242 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14243 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14243, "byte_length >= 0" ))));
14244 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14245 |
14246 | return pi;
14247 | }
14248 |
14249 | proto_item *
14250 | proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14251 | const unsigned bit_offset, const int no_of_chars)
14252 | {
14253 | proto_item *pi;
14254 | header_field_info *hfinfo;
14255 | int byte_length;
14256 | unsigned byte_offset;
14257 | char *string;
14258 |
14259 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14260 |
14261 | 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", 14261 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14261, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14261, "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", 14261, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14262 |
14263 | 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" , 14263, ((hfinfo))->abbrev))));
14264 |
14265 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14266 | byte_offset = bit_offset >> 3;
14267 |
14268 | string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14269 |
14270 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14271 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14271, "byte_length >= 0" ))));
14272 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14273 |
14274 | return pi;
14275 | }
14276 |
14277 | const value_string proto_checksum_vals[] = {
14278 | { PROTO_CHECKSUM_E_BAD, "Bad" },
14279 | { PROTO_CHECKSUM_E_GOOD, "Good" },
14280 | { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14281 | { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14282 | { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14283 |
14284 | { 0, NULL((void*)0) }
14285 | };
14286 |
14287 | #define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14288 |
14289 | proto_item *
14290 | proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14291 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14292 | packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14293 | {
14294 | header_field_info *hfinfo;
14295 | uint32_t checksum;
14296 | uint32_t len;
14297 | proto_item* ti = NULL((void*)0);
14298 | proto_item* ti2;
14299 | bool_Bool incorrect_checksum = true1;
14300 |
14301 | 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", 14301, __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", 14301 , "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", 14301, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14302 |
14303 | switch (hfinfo->type) {
14304 | case FT_UINT8:
14305 | len = 1;
14306 | break;
14307 | case FT_UINT16:
14308 | len = 2;
14309 | break;
14310 | case FT_UINT24:
14311 | len = 3;
14312 | break;
14313 | case FT_UINT32:
14314 | len = 4;
14315 | break;
14316 | default:
14317 | 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)
14318 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32" , hfinfo->abbrev);
14319 | }
14320 |
14321 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14322 | ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14323 | proto_item_set_generated(ti);
14324 | // Backward compatible with use of -1
14325 | if (hf_checksum_status > 0) {
14326 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14327 | proto_item_set_generated(ti2);
14328 | }
14329 | return ti;
14330 | }
14331 |
14332 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14333 | ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14334 | proto_item_set_generated(ti);
14335 | } else {
14336 | ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14337 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14338 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14339 | if (computed_checksum == 0) {
14340 | proto_item_append_text(ti, " [correct]");
14341 | // Backward compatible with use of -1
14342 | if (hf_checksum_status > 0) {
14343 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14344 | proto_item_set_generated(ti2);
14345 | }
14346 | incorrect_checksum = false0;
14347 | } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14348 | computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14349 | /* XXX - This can't distinguish between "shouldbe"
14350 | * 0x0000 and 0xFFFF unless we know whether there
14351 | * were any nonzero bits (other than the checksum).
14352 | * Protocols should not use this path if they might
14353 | * have an all zero packet.
14354 | * Some implementations put the wrong zero; maybe
14355 | * we should have a special expert info for that?
14356 | */
14357 | }
14358 | } else {
14359 | if (checksum == computed_checksum) {
14360 | proto_item_append_text(ti, " [correct]");
14361 | // Backward compatible with use of -1
14362 | if (hf_checksum_status > 0) {
14363 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14364 | proto_item_set_generated(ti2);
14365 | }
14366 | incorrect_checksum = false0;
14367 | }
14368 | }
14369 |
14370 | if (incorrect_checksum) {
14371 | // Backward compatible with use of -1
14372 | if (hf_checksum_status > 0) {
14373 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14374 | proto_item_set_generated(ti2);
14375 | }
14376 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14377 | proto_item_append_text(ti, " [incorrect]");
14378 | if (bad_checksum_expert != NULL((void*)0))
14379 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14380 | } else {
14381 | proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14382 | if (bad_checksum_expert != NULL((void*)0))
14383 | 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);
14384 | }
14385 | }
14386 | } else {
14387 | // Backward compatible with use of -1
14388 | if (hf_checksum_status > 0) {
14389 | proto_item_append_text(ti, " [unverified]");
14390 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14391 | proto_item_set_generated(ti2);
14392 | }
14393 | }
14394 | }
14395 |
14396 | return ti;
14397 | }
14398 |
14399 | proto_item *
14400 | proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14401 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14402 | packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14403 | {
14404 | header_field_info *hfinfo;
14405 | uint8_t *checksum = NULL((void*)0);
14406 | proto_item* ti = NULL((void*)0);
14407 | proto_item* ti2;
14408 | bool_Bool incorrect_checksum = true1;
14409 |
14410 | 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", 14410, __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", 14410 , "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", 14410, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14411 |
14412 | 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", 14412, ((hfinfo))->abbrev))));
14413 |
14414 | /* Make sure a NULL computed_checksum isn't dereferenced.
14415 | * If checksum_len is 0 it probably won't crash, but in the VERIFY
14416 | * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14417 | * cases the behavior is unexpected and still a programmer error;
14418 | * proto_tree_add_bytes retrieves it from the tvb, thus neither
14419 | * _NOT_PRESENT nor _GENERATED is correct.
14420 | */
14421 | 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", 14421, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)" ))));
14422 |
14423 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14424 | ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14425 | proto_item_set_generated(ti);
14426 | // Backward compatible with use of -1
14427 | if (hf_checksum_status > 0) {
14428 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14429 | proto_item_set_generated(ti2);
14430 | }
14431 | return ti;
14432 | }
14433 |
14434 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14435 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14436 | proto_item_set_generated(ti);
14437 | return ti;
14438 | }
14439 |
14440 | checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14441 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14442 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14443 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14444 | bool_Bool non_zero_flag = false0;
14445 | for (size_t index = 0; index < checksum_len; index++) {
14446 | if (computed_checksum[index]) {
14447 | non_zero_flag = true1;
14448 | break;
14449 | }
14450 | }
14451 | if (!non_zero_flag) {
14452 | proto_item_append_text(ti, " [correct]");
14453 | // Backward compatible with use of -1
14454 | if (hf_checksum_status > 0) {
14455 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14456 | proto_item_set_generated(ti2);
14457 | }
14458 | incorrect_checksum = false0;
14459 | }
14460 | } else {
14461 | if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14462 | proto_item_append_text(ti, " [correct]");
14463 | // Backward compatible with use of -1
14464 | if (hf_checksum_status > 0) {
14465 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14466 | proto_item_set_generated(ti2);
14467 | }
14468 | incorrect_checksum = false0;
14469 | }
14470 | }
14471 |
14472 | if (incorrect_checksum) {
14473 | // Backward compatible with use of -1
14474 | if (hf_checksum_status > 0) {
14475 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14476 | proto_item_set_generated(ti2);
14477 | }
14478 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14479 | proto_item_append_text(ti, " [incorrect]");
14480 | if (bad_checksum_expert != NULL((void*)0))
14481 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14482 | } else {
14483 | char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14484 | proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14485 | if (bad_checksum_expert != NULL((void*)0))
14486 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14487 | }
14488 | }
14489 | } else {
14490 | // Backward compatible with use of -1
14491 | if (hf_checksum_status > 0) {
14492 | proto_item_append_text(ti, " [unverified]");
14493 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14494 | proto_item_set_generated(ti2);
14495 | }
14496 | }
14497 |
14498 | return ti;
14499 | }
14500 |
14501 | unsigned char
14502 | proto_check_field_name(const char *field_name)
14503 | {
14504 | return module_check_valid_name(field_name, false0);
14505 | }
14506 |
14507 | unsigned char
14508 | proto_check_field_name_lower(const char *field_name)
14509 | {
14510 | return module_check_valid_name(field_name, true1);
14511 | }
14512 |
14513 | bool_Bool
14514 | tree_expanded(int tree_type)
14515 | {
14516 | if (tree_type <= 0) {
14517 | return false0;
14518 | }
14519 | 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", 14519, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14520 | return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14521 | }
14522 |
14523 | void
14524 | tree_expanded_set(int tree_type, bool_Bool value)
14525 | {
14526 | 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", 14526, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14527 |
14528 | if (value)
14529 | tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14530 | else
14531 | tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14532 | }
14533 |
14534 | /*
14535 | * Editor modelines - https://www.wireshark.org/tools/modelines.html
14536 | *
14537 | * Local variables:
14538 | * c-basic-offset: 8
14539 | * tab-width: 8
14540 | * indent-tabs-mode: t
14541 | * End:
14542 | *
14543 | * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14544 | * :indentSize=8:tabSize=8:noTabs=false:
14545 | */