### Bug Summary

File: | builds/wireshark/wireshark/epan/proto.c
Warning: | line 13725, 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-06-11-100424-3529-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 lower -1 or equal 0 */
102 | #define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return ( (void*)0); } \
103 | if (length < -1 || 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 lower -1 or equal 0 */
111 | #define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); } \
112 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || 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 | fvalue_free(finfo->value);
913 | finfo->value = NULL((void*)0);
914 | }
915 | }
916 |
917 | void
918 | proto_tree_reset(proto_tree *tree)
919 | {
920 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
921 |
922 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
923 |
924 | /* free tree data */
925 | if (tree_data->interesting_hfids) {
926 | /* Free all the GPtrArray's in the interesting_hfids hash. */
927 | g_hash_table_foreach(tree_data->interesting_hfids,
928 | free_GPtrArray_value, NULL((void*)0));
929 |
930 | /* And then remove all values. */
931 | g_hash_table_remove_all(tree_data->interesting_hfids);
932 | }
933 |
934 | /* Reset track of the number of children */
935 | tree_data->count = 0;
936 |
937 | /* Reset our loop checks */
938 | tree_data->idle_count_ds_tvb = NULL((void*)0);
939 | tree_data->max_start = 0;
940 | tree_data->start_idle_count = 0;
941 |
942 | PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void *)0); tree->next = ((void*)0);;
943 | }
944 |
945 | /* frees the resources that the dissection a proto_tree uses */
946 | void
947 | proto_tree_free(proto_tree *tree)
948 | {
949 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
950 |
951 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
952 |
953 | /* free tree data */
954 | if (tree_data->interesting_hfids) {
955 | /* Free all the GPtrArray's in the interesting_hfids hash. */
956 | g_hash_table_foreach(tree_data->interesting_hfids,
957 | free_GPtrArray_value, NULL((void*)0));
958 |
959 | /* And then destroy the hash. */
960 | g_hash_table_destroy(tree_data->interesting_hfids);
961 | }
962 |
963 | 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);
964 |
965 | g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else (void) ((proto_tree*) 0 == (tree)); } while (0);
966 | }
967 |
968 | /* Is the parsing being done for a visible proto_tree or an invisible one?
969 | * By setting this correctly, the proto_tree creation is sped up by not
970 | * having to call vsnprintf and copy strings around.
971 | */
972 | bool_Bool
973 | proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
974 | {
975 | bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
976 |
977 | PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
978 |
979 | return old_visible;
980 | }
981 |
982 | void
983 | proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
984 | {
985 | if (tree)
986 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
987 | }
988 |
989 | /* Assume dissector set only its protocol fields.
990 | This function is called by dissectors and allows the speeding up of filtering
991 | in wireshark; if this function returns false it is safe to reset tree to NULL
992 | and thus skip calling most of the expensive proto_tree_add_...()
993 | functions.
994 | If the tree is visible we implicitly assume the field is referenced.
995 | */
996 | bool_Bool
997 | proto_field_is_referenced(proto_tree *tree, int proto_id)
998 | {
999 | register header_field_info *hfinfo;
1000 |
1001 |
1002 | if (!tree)
1003 | return false0;
1004 |
1005 | if (PTREE_DATA(tree)((tree)->tree_data)->visible)
1006 | return true1;
1007 |
1008 | 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", 1008, __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", 1008, "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", 1008, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
1009 | if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1010 | return true1;
1011 |
1012 | if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1013 | return true1;
1014 |
1015 | return false0;
1016 | }
1017 |
1018 |
1019 | /* Finds a record in the hfinfo array by id. */
1020 | header_field_info *
1021 | proto_registrar_get_nth(unsigned hfindex)
1022 | {
1023 | register header_field_info *hfinfo;
1024 |
1025 | 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", 1025, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1025, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1025, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
1026 | return hfinfo;
1027 | }
1028 |
1029 |
1030 | /* Prefix initialization
1031 | * this allows for a dissector to register a display filter name prefix
1032 | * so that it can delay the initialization of the hf array as long as
1033 | * possible.
1034 | */
1035 |
1036 | /* compute a hash for the part before the dot of a display filter */
1037 | static unsigned
1038 | prefix_hash (const void *key) {
1039 | /* end the string at the dot and compute its hash */
1040 | char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1041 | char* c = copy;
1042 | unsigned tmp;
1043 |
1044 | for (; *c; c++) {
1045 | if (*c == '.') {
1046 | *c = 0;
1047 | break;
1048 | }
1049 | }
1050 |
1051 | tmp = wmem_str_hash(copy);
1052 | g_free(copy)(__builtin_object_size ((copy), 0) != ((size_t) - 1)) ? g_free_sized (copy, __builtin_object_size ((copy), 0)) : (g_free) (copy);
1053 | return tmp;
1054 | }
1055 |
1056 | /* are both strings equal up to the end or the dot? */
1057 | static gboolean
1058 | prefix_equal (const void *ap, const void *bp) {
1059 | const char* a = (const char *)ap;
1060 | const char* b = (const char *)bp;
1061 |
1062 | do {
1063 | char ac = *a++;
1064 | char bc = *b++;
1065 |
1066 | if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1067 |
1068 | if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1069 | if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1070 |
1071 | if (ac != bc) return FALSE(0);
1072 | } while (1);
1073 |
1074 | return FALSE(0);
1075 | }
1076 |
1077 | /* Register a new prefix for "delayed" initialization of field arrays */
1078 | void
1079 | proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1080 | if (! prefixes ) {
1081 | prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1082 | }
1083 |
1084 | g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1085 | }
1086 |
1087 | /* helper to call all prefix initializers */
1088 | static gboolean
1089 | initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1090 | ((prefix_initializer_t)v)((const char *)k);
1091 | return TRUE(!(0));
1092 | }
1093 |
1094 | /** Initialize every remaining uninitialized prefix. */
1095 | void
1096 | proto_initialize_all_prefixes(void) {
1097 | g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1098 | }
1099 |
1100 | /* Finds a record in the hfinfo array by name.
1101 | * If it fails to find it in the already registered fields,
1102 | * it tries to find and call an initializer in the prefixes
1103 | * table and if so it looks again.
1104 | */
1105 |
1106 | header_field_info *
1107 | proto_registrar_get_byname(const char *field_name)
1108 | {
1109 | header_field_info *hfinfo;
1110 | prefix_initializer_t pi;
1111 |
1112 | if (!field_name)
1113 | return NULL((void*)0);
1114 |
1115 | if (g_strcmp0(field_name, last_field_name) == 0) {
1116 | return last_hfinfo;
1117 | }
1118 |
1119 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1120 |
1121 | if (hfinfo) {
1122 | 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);
1123 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1124 | last_hfinfo = hfinfo;
1125 | return hfinfo;
1126 | }
1127 |
1128 | if (!prefixes)
1129 | return NULL((void*)0);
1130 |
1131 | if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1132 | pi(field_name);
1133 | g_hash_table_remove(prefixes, field_name);
1134 | } else {
1135 | return NULL((void*)0);
1136 | }
1137 |
1138 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1139 |
1140 | if (hfinfo) {
1141 | 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);
1142 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1143 | last_hfinfo = hfinfo;
1144 | }
1145 | return hfinfo;
1146 | }
1147 |
1148 | header_field_info*
1149 | proto_registrar_get_byalias(const char *alias_name)
1150 | {
1151 | if (!alias_name) {
1152 | return NULL((void*)0);
1153 | }
1154 |
1155 | /* Find our aliased protocol. */
1156 | char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1157 | char *dot = strchr(an_copy, '.');
1158 | if (dot) {
1159 | *dot = '\0';
1160 | }
1161 | const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1162 | if (!proto_pfx) {
1163 | 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);
1164 | return NULL((void*)0);
1165 | }
1166 |
1167 | /* Construct our aliased field and look it up. */
1168 | GString *filter_name = g_string_new(proto_pfx);
1169 | if (dot) {
1170 | g_string_append_printf(filter_name, ".%s", dot+1);
1171 | }
1172 | header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1173 | 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);
1174 | 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)))));
1175 |
1176 | return hfinfo;
1177 | }
1178 |
1179 | int
1180 | proto_registrar_get_id_byname(const char *field_name)
1181 | {
1182 | header_field_info *hfinfo;
1183 |
1184 | hfinfo = proto_registrar_get_byname(field_name);
1185 |
1186 | if (!hfinfo)
1187 | return -1;
1188 |
1189 | return hfinfo->id;
1190 | }
1191 |
1192 | static int
1193 | label_strcat_flags(const header_field_info *hfinfo)
1194 | {
1195 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1196 | return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1197 |
1198 | return 0;
1199 | }
1200 |
1201 | static char *
1202 | format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1203 | const uint8_t *bytes, unsigned length, size_t max_str_len)
1204 | {
1205 | char *str = NULL((void*)0);
1206 | const uint8_t *p;
1207 | bool_Bool is_printable;
1208 |
1209 | if (bytes) {
1210 | if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1211 | /*
1212 | * If all bytes are valid and printable UTF-8, show the
1213 | * bytes as a string - in quotes to indicate that it's
1214 | * a string.
1215 | */
1216 | if (isprint_utf8_string((const char*)bytes, length)) {
1217 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1218 | (int)length, bytes);
1219 | return str;
1220 | }
1221 | } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1222 | /*
1223 | * Check whether all bytes are printable.
1224 | */
1225 | is_printable = true1;
1226 | for (p = bytes; p < bytes+length; p++) {
1227 | if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1228 | /* Not printable. */
1229 | is_printable = false0;
1230 | break;
1231 | }
1232 | }
1233 |
1234 | /*
1235 | * If all bytes are printable ASCII, show the bytes
1236 | * as a string - in quotes to indicate that it's
1237 | * a string.
1238 | */
1239 | if (is_printable) {
1240 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1241 | (int)length, bytes);
1242 | return str;
1243 | }
1244 | }
1245 |
1246 | /*
1247 | * Either it's not printable ASCII, or we don't care whether
1248 | * it's printable ASCII; show it as hex bytes.
1249 | */
1250 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1251 | case SEP_DOT:
1252 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1253 | break;
1254 | case SEP_DASH:
1255 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1256 | break;
1257 | case SEP_COLON:
1258 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1259 | break;
1260 | case SEP_SPACE:
1261 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1262 | break;
1263 | case BASE_NONE:
1264 | default:
1265 | if (prefs.display_byte_fields_with_spaces) {
1266 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1267 | } else {
1268 | str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1269 | }
1270 | break;
1271 | }
1272 | }
1273 | else {
1274 | if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1275 | str = wmem_strdup(scope, "<none>");
1276 | } else {
1277 | str = wmem_strdup(scope, "<MISSING>");
1278 | }
1279 | }
1280 | return str;
1281 | }
1282 |
1283 | static char *
1284 | format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1285 | const uint8_t *bytes, unsigned length)
1286 | {
1287 | return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1288 | }
1289 |
1290 | static void
1291 | ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1292 | {
1293 | subtree_lvl *pushed_tree;
1294 |
1295 | 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" , 1295, "ptvc->pushed_tree_max <= 256-8"))));
1296 | ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1297 |
1298 | pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1299 | DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1299, "pushed_tree != ((void*)0)" ))));
1300 | ptvc->pushed_tree = pushed_tree;
1301 | }
1302 |
1303 | static void
1304 | ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1305 | {
1306 | ptvc->pushed_tree = NULL((void*)0);
1307 | ptvc->pushed_tree_max = 0;
1308 | 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", 1308, "ptvc->pushed_tree_index == 0" ))));
1309 | ptvc->pushed_tree_index = 0;
1310 | }
1311 |
1312 | /* Allocates an initializes a ptvcursor_t with 3 variables:
1313 | * proto_tree, tvbuff, and offset. */
1314 | ptvcursor_t *
1315 | ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, unsigned offset)
1316 | {
1317 | ptvcursor_t *ptvc;
1318 |
1319 | ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1320 | ptvc->scope = scope;
1321 | ptvc->tree = tree;
1322 | ptvc->tvb = tvb;
1323 | ptvc->offset = offset;
1324 | ptvc->pushed_tree = NULL((void*)0);
1325 | ptvc->pushed_tree_max = 0;
1326 | ptvc->pushed_tree_index = 0;
1327 | return ptvc;
1328 | }
1329 |
1330 |
1331 | /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1332 | void
1333 | ptvcursor_free(ptvcursor_t *ptvc)
1334 | {
1335 | ptvcursor_free_subtree_levels(ptvc);
1336 | wmem_free(ptvc->scope, ptvc);
1337 | }
1338 |
1339 | /* Returns tvbuff. */
1340 | tvbuff_t *
1341 | ptvcursor_tvbuff(ptvcursor_t *ptvc)
1342 | {
1343 | return ptvc->tvb;
1344 | }
1345 |
1346 | /* Returns current offset. */
1347 | unsigned
1348 | ptvcursor_current_offset(ptvcursor_t *ptvc)
1349 | {
1350 | return ptvc->offset;
1351 | }
1352 |
1353 | proto_tree *
1354 | ptvcursor_tree(ptvcursor_t *ptvc)
1355 | {
1356 | if (!ptvc)
1357 | return NULL((void*)0);
1358 |
1359 | return ptvc->tree;
1360 | }
1361 |
1362 | void
1363 | ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1364 | {
1365 | ptvc->tree = tree;
1366 | }
1367 |
1368 | /* creates a subtree, sets it as the working tree and pushes the old working tree */
1369 | proto_tree *
1370 | ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1371 | {
1372 | subtree_lvl *subtree;
1373 | if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1374 | ptvcursor_new_subtree_levels(ptvc);
1375 |
1376 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1377 | subtree->tree = ptvc->tree;
1378 | subtree->it= NULL((void*)0);
1379 | ptvc->pushed_tree_index++;
1380 | return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1381 | }
1382 |
1383 | /* pops a subtree */
1384 | void
1385 | ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1386 | {
1387 | subtree_lvl *subtree;
1388 |
1389 | if (ptvc->pushed_tree_index <= 0)
1390 | return;
1391 |
1392 | ptvc->pushed_tree_index--;
1393 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1394 | if (subtree->it != NULL((void*)0))
1395 | proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1396 |
1397 | ptvc->tree = subtree->tree;
1398 | }
1399 |
1400 | /* saves the current tvb offset and the item in the current subtree level */
1401 | static void
1402 | ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1403 | {
1404 | subtree_lvl *subtree;
1405 |
1406 | 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", 1406, "ptvc->pushed_tree_index > 0" ))));
1407 |
1408 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1409 | subtree->it = it;
1410 | subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1411 | }
1412 |
1413 | /* Creates a subtree and adds it to the cursor as the working tree but does not
1414 | * save the old working tree */
1415 | proto_tree *
1416 | ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1417 | {
1418 | ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1419 | return ptvc->tree;
1420 | }
1421 |
1422 | static proto_tree *
1423 | ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1424 | {
1425 | ptvcursor_push_subtree(ptvc, it, ett_subtree);
1426 | if (length == SUBTREE_UNDEFINED_LENGTH-1)
1427 | ptvcursor_subtree_set_item(ptvc, it);
1428 | return ptvcursor_tree(ptvc);
1429 | }
1430 |
1431 | /* Add an item to the tree and create a subtree
1432 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1433 | * In this case, when the subtree will be closed, the parent item length will
1434 | * be equal to the advancement of the cursor since the creation of the subtree.
1435 | */
1436 | proto_tree *
1437 | ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1438 | const unsigned encoding, int ett_subtree)
1439 | {
1440 | proto_item *it;
1441 |
1442 | it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1443 | return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1444 | }
1445 |
1446 | static proto_item *
1447 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length);
1448 |
1449 | /* Add a text node to the tree and create a subtree
1450 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1451 | * In this case, when the subtree will be closed, the item length will be equal
1452 | * to the advancement of the cursor since the creation of the subtree.
1453 | */
1454 | proto_tree *
1455 | ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1456 | int ett_subtree, const char *format, ...)
1457 | {
1458 | proto_item *pi;
1459 | va_list ap;
1460 | header_field_info *hfinfo;
1461 | proto_tree *tree;
1462 |
1463 | tree = ptvcursor_tree(ptvc);
1464 |
1465 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1466 |
1467 | 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", 1467 , __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", 1467, "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", 1467, "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", 1467, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1468 |
1469 | pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1470 | ptvcursor_current_offset(ptvc), length);
1471 |
1472 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1472, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1473 |
1474 | va_start(ap, format)__builtin_va_start(ap, format);
1475 | proto_tree_set_representation(pi, format, ap);
1476 | va_end(ap)__builtin_va_end(ap);
1477 |
1478 | return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1479 | }
1480 |
1481 | /* Add a text-only node, leaving it to our caller to fill the text in */
1482 | static proto_item *
1483 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1484 | {
1485 | proto_item *pi;
1486 |
1487 | if (tree == NULL((void*)0))
1488 | return NULL((void*)0);
1489 |
1490 | pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1491 |
1492 | return pi;
1493 | }
1494 |
1495 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1496 | proto_item *
1497 | proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length,
1498 | const char *format, ...)
1499 | {
1500 | proto_item *pi;
1501 | va_list ap;
1502 | header_field_info *hfinfo;
1503 |
1504 | if (length == -1) {
1505 | length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1506 | } else {
1507 | tvb_ensure_bytes_exist(tvb, start, length);
1508 | }
1509 |
1510 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1511 |
1512 | 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", 1512 , __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", 1512, "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", 1512, "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", 1512, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1513 |
1514 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1515 |
1516 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1516, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1517 |
1518 | va_start(ap, format)__builtin_va_start(ap, format);
1519 | proto_tree_set_representation(pi, format, ap);
1520 | va_end(ap)__builtin_va_end(ap);
1521 |
1522 | return pi;
1523 | }
1524 |
1525 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1526 | proto_item *
1527 | proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, unsigned start,
1528 | int length, const char *format, va_list ap)
1529 | {
1530 | proto_item *pi;
1531 | header_field_info *hfinfo;
1532 |
1533 | /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1534 | * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1535 | * the length to be what's in the tvbuff if length is -1, and the
1536 | * minimum of length and what's in the tvbuff if not.
1537 | */
1538 |
1539 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1540 |
1541 | 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", 1541 , __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", 1541, "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", 1541, "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", 1541, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1542 |
1543 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1544 |
1545 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1545, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1546 |
1547 | proto_tree_set_representation(pi, format, ap);
1548 |
1549 | return pi;
1550 | }
1551 |
1552 | /* Add a text-only node that creates a subtree underneath.
1553 | */
1554 | proto_tree *
1555 | proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *text)
1556 | {
1557 | return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1558 | }
1559 |
1560 | /* Add a text-only node that creates a subtree underneath.
1561 | */
1562 | proto_tree *
1563 | proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length, int idx, proto_item **tree_item, const char *format, ...)
1564 | {
1565 | proto_tree *pt;
1566 | proto_item *pi;
1567 | va_list ap;
1568 |
1569 | va_start(ap, format)__builtin_va_start(ap, format);
1570 | pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1571 | va_end(ap)__builtin_va_end(ap);
1572 |
1573 | if (tree_item != NULL((void*)0))
1574 | *tree_item = pi;
1575 |
1576 | pt = proto_item_add_subtree(pi, idx);
1577 |
1578 | return pt;
1579 | }
1580 |
1581 | /* Add a text-only node for debugging purposes. The caller doesn't need
1582 | * to worry about tvbuff, start, or length. Debug message gets sent to
1583 | * STDOUT, too */
1584 | proto_item *
1585 | proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1586 | {
1587 | proto_item *pi;
1588 | va_list ap;
1589 |
1590 | pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1591 |
1592 | if (pi) {
1593 | va_start(ap, format)__builtin_va_start(ap, format);
1594 | proto_tree_set_representation(pi, format, ap);
1595 | va_end(ap)__builtin_va_end(ap);
1596 | }
1597 | va_start(ap, format)__builtin_va_start(ap, format);
1598 | vprintf(format, ap);
1599 | va_end(ap)__builtin_va_end(ap);
1600 | printf("\n");
1601 |
1602 | return pi;
1603 | }
1604 |
1605 | proto_item *
1606 | proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1607 | {
1608 | proto_item *pi;
1609 | header_field_info *hfinfo;
1610 |
1611 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1612 |
1613 | 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", 1613 , __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", 1613, "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", 1613, "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", 1613, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1614 |
1615 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1616 |
1617 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1617, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1618 |
1619 | proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1620 |
1621 | return pi;
1622 | }
1623 |
1624 | proto_item *
1625 | proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, unsigned start, int length)
1626 | {
1627 | proto_item *pi;
1628 | header_field_info *hfinfo;
1629 | char *str;
1630 |
1631 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1632 |
1633 | 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", 1633 , __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", 1633, "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", 1633, "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", 1633, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1634 |
1635 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1636 |
1637 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1637, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1638 |
1639 | str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1640 | proto_item_set_text(pi, "%s", str);
1641 | wmem_free(NULL((void*)0), str);
1642 |
1643 | return pi;
1644 | }
1645 |
1646 | void proto_report_dissector_bug(const char *format, ...)
1647 | {
1648 | va_list args;
1649 |
1650 | if (wireshark_abort_on_dissector_bug) {
1651 | /*
1652 | * Try to have the error message show up in the crash
1653 | * information.
1654 | */
1655 | va_start(args, format)__builtin_va_start(args, format);
1656 | ws_vadd_crash_info(format, args);
1657 | va_end(args)__builtin_va_end(args);
1658 |
1659 | /*
1660 | * Print the error message.
1661 | */
1662 | va_start(args, format)__builtin_va_start(args, format);
1663 | vfprintf(stderrstderr, format, args);
1664 | va_end(args)__builtin_va_end(args);
1665 | putc('\n', stderrstderr);
1666 |
1667 | /*
1668 | * And crash.
1669 | */
1670 | abort();
1671 | } else {
1672 | va_start(args, format)__builtin_va_start(args, format);
1673 | VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1674 | va_end(args)__builtin_va_end(args);
1675 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1675 , __func__, "assertion \"not reached\" failed"); /* GCC 12 with ASAN needs this. */
1676 | }
1677 | }
1678 |
1679 | /* We could probably get away with changing is_error to a minimum length value. */
1680 | static void
1681 | report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1682 | {
1683 | if (is_error) {
1684 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1685 | } else {
1686 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1687 | }
1688 |
1689 | if (is_error) {
1690 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1691 | }
1692 | }
1693 |
1694 | static uint32_t
1695 | get_uint_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1696 | {
1697 | uint32_t value;
1698 | bool_Bool length_error;
1699 |
1700 | switch (length) {
1701 |
1702 | case 1:
1703 | value = tvb_get_uint8(tvb, offset);
1704 | if (encoding & ENC_ZIGBEE0x40000000) {
1705 | if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1706 | value = 0;
1707 | }
1708 | }
1709 | break;
1710 |
1711 | case 2:
1712 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1713 | : tvb_get_ntohs(tvb, offset);
1714 | if (encoding & ENC_ZIGBEE0x40000000) {
1715 | if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1716 | value = 0;
1717 | }
1718 | }
1719 | break;
1720 |
1721 | case 3:
1722 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1723 | : tvb_get_ntoh24(tvb, offset);
1724 | break;
1725 |
1726 | case 4:
1727 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1728 | : tvb_get_ntohl(tvb, offset);
1729 | break;
1730 |
1731 | default:
1732 | if (length < 1) {
1733 | length_error = true1;
1734 | value = 0;
1735 | } else {
1736 | length_error = false0;
1737 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1738 | : tvb_get_ntohl(tvb, offset);
1739 | }
1740 | report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1741 | break;
1742 | }
1743 | return value;
1744 | }
1745 |
1746 | static inline uint64_t
1747 | get_uint64_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, unsigned length, const unsigned encoding)
1748 | {
1749 | uint64_t value;
1750 |
1751 | value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1752 |
1753 | if (length < 1 || length > 8) {
1754 | report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1755 | }
1756 |
1757 | return value;
1758 | }
1759 |
1760 | static int32_t
1761 | get_int_value(proto_tree *tree, tvbuff_t *tvb, unsigned offset, int length, const unsigned encoding)
1762 | {
1763 | int32_t value;
1764 | bool_Bool length_error;
1765 |
1766 | switch (length) {
1767 |
1768 | case 1:
1769 | value = tvb_get_int8(tvb, offset);
1770 | break;
1771 |
1772 | case 2:
1773 | value = encoding ? tvb_get_letohis(tvb, offset)
1774 | : tvb_get_ntohis(tvb, offset);
1775 | break;
1776 |
1777 | case 3:
1778 | value = encoding ? tvb_get_letohi24(tvb, offset)
1779 | : tvb_get_ntohi24(tvb, offset);
1780 | break;
1781 |
1782 | case 4:
1783 | value = encoding ? tvb_get_letohil(tvb, offset)
1784 | : tvb_get_ntohil(tvb, offset);
1785 | break;
1786 |
1787 | default:
1788 | if (length < 1) {
1789 | length_error = true1;
1790 | value = 0;
1791 | } else {
1792 | length_error = false0;
1793 | value = encoding ? tvb_get_letohil(tvb, offset)
1794 | : tvb_get_ntohil(tvb, offset);
1795 | }
1796 | report_type_length_mismatch(tree, "a signed integer", length, length_error);
1797 | break;
1798 | }
1799 | return value;
1800 | }
1801 |
1802 | /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1803 | * be cast-able as a int64_t. This is weird, but what the code has always done.
1804 | */
1805 | static inline uint64_t
1806 | get_int64_value(proto_tree *tree, tvbuff_t *tvb, unsigned start, unsigned length, const unsigned encoding)
1807 | {
1808 | uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1809 |
1810 | switch (length) {
1811 | case 7:
1812 | value = ws_sign_ext64(value, 56);
1813 | break;
1814 | case 6:
1815 | value = ws_sign_ext64(value, 48);
1816 | break;
1817 | case 5:
1818 | value = ws_sign_ext64(value, 40);
1819 | break;
1820 | case 4:
1821 | value = ws_sign_ext64(value, 32);
1822 | break;
1823 | case 3:
1824 | value = ws_sign_ext64(value, 24);
1825 | break;
1826 | case 2:
1827 | value = ws_sign_ext64(value, 16);
1828 | break;
1829 | case 1:
1830 | value = ws_sign_ext64(value, 8);
1831 | break;
1832 | }
1833 |
1834 | return value;
1835 | }
1836 |
1837 | /* For FT_STRING */
1838 | static inline const uint8_t *
1839 | get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1840 | int length, int *ret_length, const unsigned encoding)
1841 | {
1842 | if (length == -1) {
1843 | length = tvb_ensure_captured_length_remaining(tvb, start);
1844 | }
1845 | *ret_length = length;
1846 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1847 | }
1848 |
1849 | /* For FT_STRINGZ */
1850 | static inline const uint8_t *
1851 | get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1852 | unsigned start, int length, int *ret_length, const unsigned encoding)
1853 | {
1854 | const uint8_t *value;
1855 |
1856 | if (length < -1) {
1857 | report_type_length_mismatch(tree, "a string", length, true1);
1858 | }
1859 |
1860 | /* XXX - Ideally, every "null-terminated string which fits into a
1861 | * known length" should be either FT_STRINGZPAD or FT_STRINGZTRUNC
1862 | * as appropriate, not a FT_STRINGZ. If so, then we could always call
1863 | * tvb_get_stringz_enc here. Failing that, we could treat length 0
1864 | * as unknown length as well (since there is a trailing '\0', the real
1865 | * length is never zero), allowing switching to unsigned lengths.
1866 | */
1867 | if (length == -1) {
1868 | /* This can throw an exception */
1869 | value = tvb_get_stringz_enc(scope, tvb, start, (unsigned*)&length, encoding);
1870 | } else {
1871 | /* In this case, length signifies the length of the string.
1872 | *
1873 | * This could either be a null-padded string, which doesn't
1874 | * necessarily have a '\0' at the end, or a null-terminated
1875 | * string, with a trailing '\0'. (Yes, there are cases
1876 | * where you have a string that's both counted and null-
1877 | * terminated.)
1878 | *
1879 | * In the first case, we must allocate a buffer of length
1880 | * "length+1", to make room for a trailing '\0'.
1881 | *
1882 | * In the second case, we don't assume that there is a
1883 | * trailing '\0' there, as the packet might be malformed.
1884 | * (XXX - should we throw an exception if there's no
1885 | * trailing '\0'?) Therefore, we allocate a buffer of
1886 | * length "length+1", and put in a trailing '\0', just to
1887 | * be safe.
1888 | *
1889 | * (XXX - this would change if we made string values counted
1890 | * rather than null-terminated.)
1891 | */
1892 | value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1893 | }
1894 | *ret_length = length;
1895 | return value;
1896 | }
1897 |
1898 | /* For FT_UINT_STRING */
1899 | static inline const uint8_t *
1900 | get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1901 | tvbuff_t *tvb, unsigned start, int length, int *ret_length,
1902 | const unsigned encoding)
1903 | {
1904 | uint32_t n;
1905 | const uint8_t *value;
1906 |
1907 | /* I believe it's ok if this is called with a NULL tree */
1908 | n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1909 | value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1910 | length += n;
1911 | *ret_length = length;
1912 | return value;
1913 | }
1914 |
1915 | /* For FT_STRINGZPAD */
1916 | static inline const uint8_t *
1917 | get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1918 | int length, int *ret_length, const unsigned encoding)
1919 | {
1920 | /*
1921 | * XXX - currently, string values are null-
1922 | * terminated, so a "zero-padded" string
1923 | * isn't special. If we represent string
1924 | * values as something that includes a counted
1925 | * array of bytes, we'll need to strip the
1926 | * trailing NULs.
1927 | */
1928 | if (length == -1) {
1929 | length = tvb_ensure_captured_length_remaining(tvb, start);
1930 | }
1931 | *ret_length = length;
1932 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1933 | }
1934 |
1935 | /* For FT_STRINGZTRUNC */
1936 | static inline const uint8_t *
1937 | get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, unsigned start,
1938 | int length, int *ret_length, const unsigned encoding)
1939 | {
1940 | /*
1941 | * XXX - currently, string values are null-
1942 | * terminated, so a "zero-truncated" string
1943 | * isn't special. If we represent string
1944 | * values as something that includes a counted
1945 | * array of bytes, we'll need to strip everything
1946 | * starting with the terminating NUL.
1947 | */
1948 | if (length == -1) {
1949 | length = tvb_ensure_captured_length_remaining(tvb, start);
1950 | }
1951 | *ret_length = length;
1952 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1953 | }
1954 |
1955 | /*
1956 | * Deltas between the epochs for various non-UN*X time stamp formats and
1957 | * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1958 | * stamp format.
1959 | */
1960 |
1961 | /*
1962 | * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1963 | * XXX - if it's OK if this is unsigned, can we just use
1964 | * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1965 | */
1966 | #define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1967 |
1968 | /*
1969 | * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1970 | */
1971 | #define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1972 |
1973 | /* this can be called when there is no tree, so tree may be null */
1974 | static void
1975 | get_time_value(proto_tree *tree, tvbuff_t *tvb, const unsigned start,
1976 | const int length, const unsigned encoding, nstime_t *time_stamp,
1977 | const bool_Bool is_relative)
1978 | {
1979 | uint32_t tmpsecs;
1980 | uint64_t tmp64secs;
1981 | uint64_t todusecs;
1982 |
1983 | switch (encoding) {
1984 |
1985 | case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1986 | /*
1987 | * If the length is 16, 8-byte seconds, followed
1988 | * by 8-byte fractional time in nanoseconds,
1989 | * both big-endian.
1990 | *
1991 | * If the length is 12, 8-byte seconds, followed
1992 | * by 4-byte fractional time in nanoseconds,
1993 | * both big-endian.
1994 | *
1995 | * If the length is 8, 4-byte seconds, followed
1996 | * by 4-byte fractional time in nanoseconds,
1997 | * both big-endian.
1998 | *
1999 | * For absolute times, the seconds are seconds
2000 | * since the UN*X epoch.
2001 | */
2002 | if (length == 16) {
2003 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2004 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
2005 | } else if (length == 12) {
2006 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2007 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
2008 | } else if (length == 8) {
2009 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2010 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
2011 | } else if (length == 4) {
2012 | /*
2013 | * Backwards compatibility.
2014 | * ENC_TIME_SECS_NSECS is 0; using
2015 | * ENC_BIG_ENDIAN by itself with a 4-byte
2016 | * time-in-seconds value was done in the
2017 | * past.
2018 | */
2019 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2020 | time_stamp->nsecs = 0;
2021 | } else {
2022 | time_stamp->secs = 0;
2023 | time_stamp->nsecs = 0;
2024 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2025 | }
2026 | break;
2027 |
2028 | case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2029 | /*
2030 | * If the length is 16, 8-byte seconds, followed
2031 | * by 8-byte fractional time in nanoseconds,
2032 | * both little-endian.
2033 | *
2034 | * If the length is 12, 8-byte seconds, followed
2035 | * by 4-byte fractional time in nanoseconds,
2036 | * both little-endian.
2037 | *
2038 | * If the length is 8, 4-byte seconds, followed
2039 | * by 4-byte fractional time in nanoseconds,
2040 | * both little-endian.
2041 | *
2042 | * For absolute times, the seconds are seconds
2043 | * since the UN*X epoch.
2044 | */
2045 | if (length == 16) {
2046 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2047 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2048 | } else if (length == 12) {
2049 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2050 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2051 | } else if (length == 8) {
2052 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2053 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2054 | } else if (length == 4) {
2055 | /*
2056 | * Backwards compatibility.
2057 | * ENC_TIME_SECS_NSECS is 0; using
2058 | * ENC_LITTLE_ENDIAN by itself with a 4-byte
2059 | * time-in-seconds value was done in the
2060 | * past.
2061 | */
2062 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2063 | time_stamp->nsecs = 0;
2064 | } else {
2065 | time_stamp->secs = 0;
2066 | time_stamp->nsecs = 0;
2067 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2068 | }
2069 | break;
2070 |
2071 | case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2072 | /*
2073 | * NTP time stamp, big-endian.
2074 | * Only supported for absolute times.
2075 | */
2076 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2076, "!is_relative" ))));
2077 |
2078 | /* We need a temporary variable here so the unsigned math
2079 | * works correctly (for years > 2036 according to RFC 2030
2080 | * chapter 3).
2081 | *
2082 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2083 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2084 | * If bit 0 is not set, the time is in the range 2036-2104 and
2085 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2086 | */
2087 | tmpsecs = tvb_get_ntohl(tvb, start);
2088 | if ((tmpsecs & 0x80000000) != 0)
2089 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2090 | else
2091 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2092 |
2093 | if (length == 8) {
2094 | tmp64secs = tvb_get_ntoh64(tvb, start);
2095 | if (tmp64secs == 0) {
2096 | //This is "NULL" time
2097 | time_stamp->secs = 0;
2098 | time_stamp->nsecs = 0;
2099 | } else {
2100 | /*
2101 | * Convert 1/2^32s of a second to
2102 | * nanoseconds.
2103 | */
2104 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2105 | }
2106 | } else if (length == 4) {
2107 | /*
2108 | * Backwards compatibility.
2109 | */
2110 | if (tmpsecs == 0) {
2111 | //This is "NULL" time
2112 | time_stamp->secs = 0;
2113 | }
2114 | time_stamp->nsecs = 0;
2115 | } else {
2116 | time_stamp->secs = 0;
2117 | time_stamp->nsecs = 0;
2118 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2119 | }
2120 | break;
2121 |
2122 | case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2123 | /*
2124 | * NTP time stamp, little-endian.
2125 | * Only supported for absolute times.
2126 | *
2127 | * NTP doesn't use this, because it's an Internet format
2128 | * and hence big-endian. Any implementation must decide
2129 | * whether the NTP timestamp is a 64-bit unsigned fixed
2130 | * point number (RFC 1305, RFC 4330) or a 64-bit struct
2131 | * with a 32-bit unsigned seconds field followed by a
2132 | * 32-bit fraction field (cf. RFC 5905, which obsoletes
2133 | * the previous two).
2134 | *
2135 | * XXX: We do the latter, but no dissector uses this format.
2136 | * OTOH, ERF timestamps do the former, so perhaps we
2137 | * should switch the interpretation so that packet-erf.c
2138 | * could use this directly?
2139 | */
2140 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2140, "!is_relative" ))));
2141 |
2142 | /* We need a temporary variable here so the unsigned math
2143 | * works correctly (for years > 2036 according to RFC 2030
2144 | * chapter 3).
2145 | *
2146 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2147 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2148 | * If bit 0 is not set, the time is in the range 2036-2104 and
2149 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2150 | */
2151 | tmpsecs = tvb_get_letohl(tvb, start);
2152 | if ((tmpsecs & 0x80000000) != 0)
2153 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2154 | else
2155 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2156 |
2157 | if (length == 8) {
2158 | tmp64secs = tvb_get_letoh64(tvb, start);
2159 | if (tmp64secs == 0) {
2160 | //This is "NULL" time
2161 | time_stamp->secs = 0;
2162 | time_stamp->nsecs = 0;
2163 | } else {
2164 | /*
2165 | * Convert 1/2^32s of a second to
2166 | * nanoseconds.
2167 | */
2168 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2169 | }
2170 | } else if (length == 4) {
2171 | /*
2172 | * Backwards compatibility.
2173 | */
2174 | if (tmpsecs == 0) {
2175 | //This is "NULL" time
2176 | time_stamp->secs = 0;
2177 | }
2178 | time_stamp->nsecs = 0;
2179 | } else {
2180 | time_stamp->secs = 0;
2181 | time_stamp->nsecs = 0;
2182 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2183 | }
2184 | break;
2185 |
2186 | case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2187 | /*
2188 | * S/3x0 and z/Architecture TOD clock time stamp,
2189 | * big-endian. The epoch is January 1, 1900,
2190 | * 00:00:00 (proleptic?) UTC.
2191 | *
2192 | * Only supported for absolute times.
2193 | */
2194 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2194, "!is_relative" ))));
2195 | DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2195, "length == 8" ))));
2196 |
2197 | if (length == 8) {
2198 | todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2199 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2200 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2201 | } else {
2202 | time_stamp->secs = 0;
2203 | time_stamp->nsecs = 0;
2204 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2205 | }
2206 | break;
2207 |
2208 | case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2209 | /*
2210 | * S/3x0 and z/Architecture TOD clock time stamp,
2211 | * little-endian. The epoch is January 1, 1900,
2212 | * 00:00:00 (proleptic?) UTC.
2213 | *
2214 | * Only supported for absolute times.
2215 | */
2216 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2216, "!is_relative" ))));
2217 |
2218 | if (length == 8) {
2219 | todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2220 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2221 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2222 | } else {
2223 | time_stamp->secs = 0;
2224 | time_stamp->nsecs = 0;
2225 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2226 | }
2227 | break;
2228 |
2229 | case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2230 | /*
2231 | * Time stamp using the same seconds/fraction format
2232 | * as NTP, but with the origin of the time stamp being
2233 | * the UNIX epoch rather than the NTP epoch; big-
2234 | * endian.
2235 | *
2236 | * Only supported for absolute times.
2237 | */
2238 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2238, "!is_relative" ))));
2239 |
2240 | if (length == 8) {
2241 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2242 | /*
2243 | * Convert 1/2^32s of a second to nanoseconds.
2244 | */
2245 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2246 | } else {
2247 | time_stamp->secs = 0;
2248 | time_stamp->nsecs = 0;
2249 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2250 | }
2251 | break;
2252 |
2253 | case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2254 | /*
2255 | * Time stamp using the same seconds/fraction format
2256 | * as NTP, but with the origin of the time stamp being
2257 | * the UNIX epoch rather than the NTP epoch; little-
2258 | * endian.
2259 | *
2260 | * Only supported for absolute times.
2261 | *
2262 | * The RTPS specification explicitly supports Little
2263 | * Endian encoding. In one place, it states that its
2264 | * Time_t representation "is the one defined by ...
2265 | * RFC 1305", but in another explicitly defines it as
2266 | * a struct consisting of an 32 bit unsigned seconds
2267 | * field and a 32 bit unsigned fraction field, not a 64
2268 | * bit fixed point, so we do that here.
2269 | * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2270 | */
2271 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2271, "!is_relative" ))));
2272 |
2273 | if (length == 8) {
2274 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2275 | /*
2276 | * Convert 1/2^32s of a second to nanoseconds.
2277 | */
2278 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2279 | } else {
2280 | time_stamp->secs = 0;
2281 | time_stamp->nsecs = 0;
2282 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2283 | }
2284 | break;
2285 |
2286 | case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2287 | /*
2288 | * MIP6 time stamp, big-endian.
2289 | * A 64-bit unsigned integer field containing a timestamp. The
2290 | * value indicates the number of seconds since January 1, 1970,
2291 | * 00:00 UTC, by using a fixed point format. In this format, the
2292 | * integer number of seconds is contained in the first 48 bits of
2293 | * the field, and the remaining 16 bits indicate the number of
2294 | * 1/65536 fractions of a second.
2295 |
2296 | * Only supported for absolute times.
2297 | */
2298 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2298, "!is_relative" ))));
2299 |
2300 | if (length == 8) {
2301 | /* We need a temporary variable here so the casting and fractions
2302 | * of a second work correctly.
2303 | */
2304 | tmp64secs = tvb_get_ntoh48(tvb, start);
2305 | tmpsecs = tvb_get_ntohs(tvb, start + 6);
2306 | tmpsecs <<= 16;
2307 |
2308 | if ((tmp64secs == 0) && (tmpsecs == 0)) {
2309 | //This is "NULL" time
2310 | time_stamp->secs = 0;
2311 | time_stamp->nsecs = 0;
2312 | } else {
2313 | time_stamp->secs = (time_t)tmp64secs;
2314 | time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2315 | }
2316 | } else {
2317 | time_stamp->secs = 0;
2318 | time_stamp->nsecs = 0;
2319 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2320 | }
2321 | break;
2322 |
2323 | case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2324 | /*
2325 | * If the length is 16, 8-byte seconds, followed
2326 | * by 8-byte fractional time in microseconds,
2327 | * both big-endian.
2328 | *
2329 | * If the length is 12, 8-byte seconds, followed
2330 | * by 4-byte fractional time in microseconds,
2331 | * both big-endian.
2332 | *
2333 | * If the length is 8, 4-byte seconds, followed
2334 | * by 4-byte fractional time in microseconds,
2335 | * both big-endian.
2336 | *
2337 | * For absolute times, the seconds are seconds
2338 | * since the UN*X epoch.
2339 | */
2340 | if (length == 16) {
2341 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2342 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2343 | } else if (length == 12) {
2344 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2345 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2346 | } else if (length == 8) {
2347 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2348 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2349 | } else {
2350 | time_stamp->secs = 0;
2351 | time_stamp->nsecs = 0;
2352 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2353 | }
2354 | break;
2355 |
2356 | case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2357 | /*
2358 | * If the length is 16, 8-byte seconds, followed
2359 | * by 8-byte fractional time in microseconds,
2360 | * both little-endian.
2361 | *
2362 | * If the length is 12, 8-byte seconds, followed
2363 | * by 4-byte fractional time in microseconds,
2364 | * both little-endian.
2365 | *
2366 | * If the length is 8, 4-byte seconds, followed
2367 | * by 4-byte fractional time in microseconds,
2368 | * both little-endian.
2369 | *
2370 | * For absolute times, the seconds are seconds
2371 | * since the UN*X epoch.
2372 | */
2373 | if (length == 16) {
2374 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2375 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2376 | } else if (length == 12) {
2377 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2378 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2379 | } else if (length == 8) {
2380 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2381 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2382 | } else {
2383 | time_stamp->secs = 0;
2384 | time_stamp->nsecs = 0;
2385 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2386 | }
2387 | break;
2388 |
2389 | case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2390 | case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2391 | /*
2392 | * Seconds, 1 to 8 bytes.
2393 | * For absolute times, it's seconds since the
2394 | * UN*X epoch.
2395 | */
2396 | if (length >= 1 && length <= 8) {
2397 | time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2398 | time_stamp->nsecs = 0;
2399 | } else {
2400 | time_stamp->secs = 0;
2401 | time_stamp->nsecs = 0;
2402 | report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2403 | }
2404 | break;
2405 |
2406 | case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2407 | case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2408 | /*
2409 | * Milliseconds, 1 to 8 bytes.
2410 | * For absolute times, it's milliseconds since the
2411 | * UN*X epoch.
2412 | */
2413 | if (length >= 1 && length <= 8) {
2414 | uint64_t msecs;
2415 |
2416 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2417 | time_stamp->secs = (time_t)(msecs / 1000);
2418 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2419 | } else {
2420 | time_stamp->secs = 0;
2421 | time_stamp->nsecs = 0;
2422 | report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2423 | }
2424 | break;
2425 |
2426 | case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2427 | case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2428 | /*
2429 | * Microseconds, 1 to 8 bytes.
2430 | * For absolute times, it's microseconds since the
2431 | * UN*X epoch.
2432 | */
2433 | if (length >= 1 && length <= 8) {
2434 | uint64_t usecs;
2435 |
2436 | usecs = get_uint64_value(tree, tvb, start, length, encoding);
2437 | time_stamp->secs = (time_t)(usecs / 1000000);
2438 | time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2439 | } else {
2440 | time_stamp->secs = 0;
2441 | time_stamp->nsecs = 0;
2442 | report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2443 | }
2444 | break;
2445 |
2446 | case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2447 | case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2448 | /*
2449 | * nanoseconds, 1 to 8 bytes.
2450 | * For absolute times, it's nanoseconds since the
2451 | * UN*X epoch.
2452 | */
2453 |
2454 | if (length >= 1 && length <= 8) {
2455 | uint64_t nsecs;
2456 |
2457 | nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2458 | time_stamp->secs = (time_t)(nsecs / 1000000000);
2459 | time_stamp->nsecs = (int)(nsecs % 1000000000);
2460 | } else {
2461 | time_stamp->secs = 0;
2462 | time_stamp->nsecs = 0;
2463 | report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2464 | }
2465 | break;
2466 |
2467 | case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2468 | /*
2469 | * 1/64ths of a second since the UN*X epoch,
2470 | * big-endian.
2471 | *
2472 | * Only supported for absolute times.
2473 | */
2474 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2474, "!is_relative" ))));
2475 |
2476 | if (length == 8) {
2477 | /*
2478 | * The upper 48 bits are seconds since the
2479 | * UN*X epoch.
2480 | */
2481 | time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2482 | /*
2483 | * The lower 16 bits are 1/2^16s of a second;
2484 | * convert them to nanoseconds.
2485 | *
2486 | * XXX - this may give the impression of higher
2487 | * precision than you actually get.
2488 | */
2489 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2490 | } else {
2491 | time_stamp->secs = 0;
2492 | time_stamp->nsecs = 0;
2493 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2494 | }
2495 | break;
2496 |
2497 | case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2498 | /*
2499 | * 1/64ths of a second since the UN*X epoch,
2500 | * little-endian.
2501 | *
2502 | * Only supported for absolute times.
2503 | */
2504 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2504, "!is_relative" ))));
2505 |
2506 | if (length == 8) {
2507 | /*
2508 | * XXX - this is assuming that, if anybody
2509 | * were ever to use this format - RFC 3971
2510 | * doesn't, because that's an Internet
2511 | * protocol, and those use network byte
2512 | * order, i.e. big-endian - they'd treat it
2513 | * as a 64-bit count of 1/2^16s of a second,
2514 | * putting the upper 48 bits at the end.
2515 | *
2516 | * The lower 48 bits are seconds since the
2517 | * UN*X epoch.
2518 | */
2519 | time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2520 | /*
2521 | * The upper 16 bits are 1/2^16s of a second;
2522 | * convert them to nanoseconds.
2523 | *
2524 | * XXX - this may give the impression of higher
2525 | * precision than you actually get.
2526 | */
2527 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2528 | } else {
2529 | time_stamp->secs = 0;
2530 | time_stamp->nsecs = 0;
2531 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2532 | }
2533 | break;
2534 |
2535 | case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2536 | /*
2537 | * NTP time stamp, with 1-second resolution (i.e.,
2538 | * seconds since the NTP epoch), big-endian.
2539 | * Only supported for absolute times.
2540 | */
2541 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2541, "!is_relative" ))));
2542 |
2543 | if (length == 4) {
2544 | /*
2545 | * We need a temporary variable here so the unsigned math
2546 | * works correctly (for years > 2036 according to RFC 2030
2547 | * chapter 3).
2548 | *
2549 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2550 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2551 | * If bit 0 is not set, the time is in the range 2036-2104 and
2552 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2553 | */
2554 | tmpsecs = tvb_get_ntohl(tvb, start);
2555 | if ((tmpsecs & 0x80000000) != 0)
2556 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2557 | else
2558 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2559 | time_stamp->nsecs = 0;
2560 | } else {
2561 | time_stamp->secs = 0;
2562 | time_stamp->nsecs = 0;
2563 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2564 | }
2565 | break;
2566 |
2567 | case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2568 | /*
2569 | * NTP time stamp, with 1-second resolution (i.e.,
2570 | * seconds since the NTP epoch), little-endian.
2571 | * Only supported for absolute times.
2572 | */
2573 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2573, "!is_relative" ))));
2574 |
2575 | /*
2576 | * We need a temporary variable here so the unsigned math
2577 | * works correctly (for years > 2036 according to RFC 2030
2578 | * chapter 3).
2579 | *
2580 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2581 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2582 | * If bit 0 is not set, the time is in the range 2036-2104 and
2583 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2584 | */
2585 | if (length == 4) {
2586 | tmpsecs = tvb_get_letohl(tvb, start);
2587 | if ((tmpsecs & 0x80000000) != 0)
2588 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2589 | else
2590 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2591 | time_stamp->nsecs = 0;
2592 | } else {
2593 | time_stamp->secs = 0;
2594 | time_stamp->nsecs = 0;
2595 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2596 | }
2597 | break;
2598 |
2599 | case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2600 | /*
2601 | * Milliseconds, 6 to 8 bytes.
2602 | * For absolute times, it's milliseconds since the
2603 | * NTP epoch.
2604 | *
2605 | * ETSI TS 129.274 8.119 defines this as:
2606 | * "a 48 bit unsigned integer in network order format
2607 | * ...encoded as the number of milliseconds since
2608 | * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2609 | * rounded value of 1000 x the value of the 64-bit
2610 | * timestamp (Seconds + (Fraction / (1<<32))) defined
2611 | * in clause 6 of IETF RFC 5905."
2612 | *
2613 | * Taken literally, the part after "i.e." would
2614 | * mean that the value rolls over before reaching
2615 | * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2616 | * when the 64 bit timestamp rolls over, and we have
2617 | * to pick an NTP Era equivalence class to support
2618 | * (such as 1968-01-20 to 2104-02-06).
2619 | *
2620 | * OTOH, the extra room might be used to store Era
2621 | * information instead, in which case times until
2622 | * 10819-08-03 can be represented with 6 bytes without
2623 | * ambiguity. We handle both implementations, and assume
2624 | * that times before 1968-01-20 are not represented.
2625 | *
2626 | * Only 6 bytes or more makes sense as an absolute
2627 | * time. 5 bytes or fewer could express a span of
2628 | * less than 35 years, either 1900-1934 or 2036-2070.
2629 | */
2630 | if (length >= 6 && length <= 8) {
2631 | uint64_t msecs;
2632 |
2633 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2634 | tmp64secs = (msecs / 1000);
2635 | /*
2636 | * Assume that times in the first half of NTP
2637 | * Era 0 really represent times in the NTP
2638 | * Era 1.
2639 | */
2640 | if (tmp64secs >= 0x80000000)
2641 | time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2642 | else
2643 | time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2644 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2645 | }
2646 | else {
2647 | time_stamp->secs = 0;
2648 | time_stamp->nsecs = 0;
2649 | report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2650 | }
2651 | break;
2652 |
2653 | case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2654 | /*
2655 | * MP4 file time stamps, big-endian.
2656 | * Only supported for absolute times.
2657 | */
2658 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2658, "!is_relative" ))));
2659 |
2660 | if (length == 8) {
2661 | tmp64secs = tvb_get_ntoh64(tvb, start);
2662 | time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2663 | time_stamp->nsecs = 0;
2664 | } else if (length == 4) {
2665 | tmpsecs = tvb_get_ntohl(tvb, start);
2666 | time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2667 | time_stamp->nsecs = 0;
2668 | } else {
2669 | time_stamp->secs = 0;
2670 | time_stamp->nsecs = 0;
2671 | report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2672 | }
2673 | break;
2674 |
2675 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2676 | /*
2677 | * Zigbee ZCL time stamps, big-endian.
2678 | * Only supported for absolute times.
2679 | */
2680 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2680, "!is_relative" ))));
2681 |
2682 | if (length == 8) {
2683 | tmp64secs = tvb_get_ntoh64(tvb, start);
2684 | time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2685 | time_stamp->nsecs = 0;
2686 | } else if (length == 4) {
2687 | tmpsecs = tvb_get_ntohl(tvb, start);
2688 | time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2689 | time_stamp->nsecs = 0;
2690 | } else {
2691 | time_stamp->secs = 0;
2692 | time_stamp->nsecs = 0;
2693 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2694 | }
2695 | break;
2696 |
2697 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2698 | /*
2699 | * Zigbee ZCL time stamps, little-endian.
2700 | * Only supported for absolute times.
2701 | */
2702 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2702, "!is_relative" ))));
2703 |
2704 | if (length == 8) {
2705 | tmp64secs = tvb_get_letoh64(tvb, start);
2706 | time_stamp->secs = (time_t)(int64_t)(tmp64secs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2707 | time_stamp->nsecs = 0;
2708 | } else if (length == 4) {
2709 | tmpsecs = tvb_get_letohl(tvb, start);
2710 | time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2711 | time_stamp->nsecs = 0;
2712 | } else {
2713 | time_stamp->secs = 0;
2714 | time_stamp->nsecs = 0;
2715 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2716 | }
2717 | break;
2718 |
2719 | default:
2720 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 2720));
2721 | break;
2722 | }
2723 | }
2724 |
2725 | static void
2726 | tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2727 | {
2728 | const header_field_info *hfinfo = fi->hfinfo;
2729 |
2730 | if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2731 | GPtrArray *ptrs = NULL((void*)0);
2732 |
2733 | if (tree_data->interesting_hfids == NULL((void*)0)) {
2734 | /* Initialize the hash because we now know that it is needed */
2735 | tree_data->interesting_hfids =
2736 | g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2737 | } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2738 | ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2739 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2740 | }
2741 |
2742 | if (!ptrs) {
2743 | /* First element triggers the creation of pointer array */
2744 | ptrs = g_ptr_array_new();
2745 | g_hash_table_insert(tree_data->interesting_hfids,
2746 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2747 | }
2748 |
2749 | g_ptr_array_add(ptrs, fi);
2750 | }
2751 | }
2752 |
2753 |
2754 | /*
2755 | * Validates that field length bytes are available starting from
2756 | * start (pos/neg). Throws an exception if they aren't.
2757 | */
2758 | static void
2759 | test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2760 | unsigned start, int length, const unsigned encoding)
2761 | {
2762 | int size = length;
2763 |
2764 | if (!tvb)
2765 | return;
2766 |
2767 | if ((hfinfo->type == FT_STRINGZ) ||
2768 | ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2769 | (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 ))))) {
2770 | /* If we're fetching until the end of the TVB, only validate
2771 | * that the offset is within range.
2772 | */
2773 | if (length == -1)
2774 | size = 0;
2775 | }
2776 |
2777 | tvb_ensure_bytes_exist(tvb, start, size);
2778 | }
2779 |
2780 | static void
2781 | detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2782 | {
2783 | bool_Bool found_stray_character = false0;
2784 |
2785 | if (!string)
2786 | return;
2787 |
2788 | switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2789 | case ENC_ASCII0x00000000:
2790 | case ENC_UTF_80x00000002:
2791 | for (int i = (int)strlen(string); i < length; i++) {
2792 | if (string[i] != '\0') {
2793 | found_stray_character = true1;
2794 | break;
2795 | }
2796 | }
2797 | break;
2798 |
2799 | default:
2800 | break;
2801 | }
2802 |
2803 | if (found_stray_character) {
2804 | expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2805 | }
2806 | }
2807 |
2808 | static void
2809 | free_fvalue_cb(void *data)
2810 | {
2811 | fvalue_t *fv = (fvalue_t*)data;
2812 | fvalue_free(fv);
2813 | }
2814 |
2815 | /* Add an item to a proto_tree, using the text label registered to that item;
2816 | the item is extracted from the tvbuff handed to it. */
2817 | static proto_item *
2818 | proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2819 | tvbuff_t *tvb, unsigned start, int length,
2820 | unsigned encoding)
2821 | {
2822 | proto_item *pi;
2823 | uint32_t value, n;
2824 | uint64_t value64;
2825 | ws_in4_addr ipv4_value;
2826 | float floatval;
2827 | double doubleval;
2828 | const char *stringval = NULL((void*)0);
2829 | nstime_t time_stamp;
2830 | bool_Bool length_error;
2831 |
2832 | /* Ensure that the newly created fvalue_t is freed if we throw an
2833 | * exception before adding it to the tree. (gcc creates clobbering
2834 | * when it optimizes the equivalent TRY..EXCEPT implementation.)
2835 | * XXX: Move the new_field_info() call inside here?
2836 | */
2837 | CLEANUP_PUSH(free_fvalue_cb, new_fi->value){ struct except_stacknode except_sn; struct except_cleanup except_cl ; except_setup_clean(&except_sn, &except_cl, (free_fvalue_cb ), (new_fi->value));
2838 |
2839 | switch (new_fi->hfinfo->type) {
2840 | case FT_NONE:
2841 | /* no value to set for FT_NONE */
2842 | break;
2843 |
2844 | case FT_PROTOCOL:
2845 | /* Set the protocol_tvb via the start offset, but include
2846 | * rest of the ds_tvb so that if finfo_set_len is called
2847 | * later it can be lengthened as much as possible. */
2848 | 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);
2849 | break;
2850 |
2851 | case FT_BYTES:
2852 | proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2853 | break;
2854 |
2855 | case FT_UINT_BYTES:
2856 | n = get_uint_value(tree, tvb, start, length, encoding);
2857 | proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2858 |
2859 | /* Instead of calling proto_item_set_len(), since we don't yet
2860 | * have a proto_item, we set the field_info's length ourselves. */
2861 | new_fi->length = n + length;
2862 | break;
2863 |
2864 | case FT_BOOLEAN:
2865 | /*
2866 | * Map all non-zero values to little-endian for
2867 | * backwards compatibility.
2868 | */
2869 | if (encoding)
2870 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2871 | proto_tree_set_boolean(new_fi,
2872 | get_uint64_value(tree, tvb, start, length, encoding));
2873 | break;
2874 |
2875 | case FT_CHAR:
2876 | /* XXX - make these just FT_UINT? */
2877 | case FT_UINT8:
2878 | case FT_UINT16:
2879 | case FT_UINT24:
2880 | case FT_UINT32:
2881 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2882 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2883 | value = (uint32_t)value64;
2884 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2885 | new_fi->flags |= FI_VARINT0x00040000;
2886 | }
2887 | }
2888 | else {
2889 | /*
2890 | * Map all non-zero values to little-endian for
2891 | * backwards compatibility.
2892 | */
2893 | if (encoding)
2894 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2895 |
2896 | value = get_uint_value(tree, tvb, start, length, encoding);
2897 | }
2898 | proto_tree_set_uint(new_fi, value);
2899 | break;
2900 |
2901 | case FT_UINT40:
2902 | case FT_UINT48:
2903 | case FT_UINT56:
2904 | case FT_UINT64:
2905 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2906 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2907 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2908 | new_fi->flags |= FI_VARINT0x00040000;
2909 | }
2910 | }
2911 | else {
2912 | /*
2913 | * Map all other non-zero values to little-endian for
2914 | * backwards compatibility.
2915 | */
2916 | if (encoding)
2917 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2918 |
2919 | value64 = get_uint64_value(tree, tvb, start, length, encoding);
2920 | }
2921 | proto_tree_set_uint64(new_fi, value64);
2922 | break;
2923 |
2924 | /* XXX - make these just FT_INT? */
2925 | case FT_INT8:
2926 | case FT_INT16:
2927 | case FT_INT24:
2928 | case FT_INT32:
2929 | /*
2930 | * Map all non-zero values to little-endian for
2931 | * backwards compatibility.
2932 | */
2933 | if (encoding)
2934 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2935 | proto_tree_set_int(new_fi,
2936 | get_int_value(tree, tvb, start, length, encoding));
2937 | break;
2938 |
2939 | case FT_INT40:
2940 | case FT_INT48:
2941 | case FT_INT56:
2942 | case FT_INT64:
2943 | /*
2944 | * Map all non-zero values to little-endian for
2945 | * backwards compatibility.
2946 | */
2947 | if (encoding)
2948 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2949 | proto_tree_set_int64(new_fi,
2950 | get_int64_value(tree, tvb, start, length, encoding));
2951 | break;
2952 |
2953 | case FT_IPv4:
2954 | /*
2955 | * Map all non-zero values to little-endian for
2956 | * backwards compatibility.
2957 | */
2958 | if (encoding)
2959 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2960 | if (length != FT_IPv4_LEN4) {
2961 | length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2962 | report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2963 | }
2964 | ipv4_value = tvb_get_ipv4(tvb, start);
2965 | /*
2966 | * NOTE: to support code written when
2967 | * proto_tree_add_item() took a bool as its
2968 | * last argument, with false meaning "big-endian"
2969 | * and true meaning "little-endian", we treat any
2970 | * non-zero value of "encoding" as meaning
2971 | * "little-endian".
2972 | */
2973 | 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);
2974 | break;
2975 |
2976 | case FT_IPXNET:
2977 | if (length != FT_IPXNET_LEN4) {
2978 | length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2979 | report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2980 | }
2981 | proto_tree_set_ipxnet(new_fi,
2982 | get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2983 | break;
2984 |
2985 | case FT_IPv6:
2986 | if (length != FT_IPv6_LEN16) {
2987 | length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2988 | report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2989 | }
2990 | proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2991 | break;
2992 |
2993 | case FT_FCWWN:
2994 | if (length != FT_FCWWN_LEN8) {
2995 | length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2996 | report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2997 | }
2998 | proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2999 | break;
3000 |
3001 | case FT_AX25:
3002 | if (length != 7) {
3003 | length_error = length < 7 ? true1 : false0;
3004 | report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
3005 | }
3006 | proto_tree_set_ax25_tvb(new_fi, tvb, start);
3007 | break;
3008 |
3009 | case FT_VINES:
3010 | if (length != VINES_ADDR_LEN6) {
3011 | length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
3012 | report_type_length_mismatch(tree, "a Vines address", length, length_error);
3013 | }
3014 | proto_tree_set_vines_tvb(new_fi, tvb, start);
3015 | break;
3016 |
3017 | case FT_ETHER:
3018 | if (length != FT_ETHER_LEN6) {
3019 | length_error = length < FT_ETHER_LEN6 ? true1 : false0;
3020 | report_type_length_mismatch(tree, "a MAC address", length, length_error);
3021 | }
3022 | proto_tree_set_ether_tvb(new_fi, tvb, start);
3023 | break;
3024 |
3025 | case FT_EUI64:
3026 | /*
3027 | * Map all non-zero values to little-endian for
3028 | * backwards compatibility.
3029 | */
3030 | if (encoding)
3031 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3032 | if (length != FT_EUI64_LEN8) {
3033 | length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3034 | report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3035 | }
3036 | proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3037 | break;
3038 | case FT_GUID:
3039 | /*
3040 | * Map all non-zero values to little-endian for
3041 | * backwards compatibility.
3042 | */
3043 | if (encoding)
3044 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3045 | if (length != FT_GUID_LEN16) {
3046 | length_error = length < FT_GUID_LEN16 ? true1 : false0;
3047 | report_type_length_mismatch(tree, "a GUID", length, length_error);
3048 | }
3049 | proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3050 | break;
3051 |
3052 | case FT_OID:
3053 | case FT_REL_OID:
3054 | proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3055 | break;
3056 |
3057 | case FT_SYSTEM_ID:
3058 | proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3059 | break;
3060 |
3061 | case FT_FLOAT:
3062 | /*
3063 | * NOTE: to support code written when
3064 | * proto_tree_add_item() took a bool as its
3065 | * last argument, with false meaning "big-endian"
3066 | * and true meaning "little-endian", we treat any
3067 | * non-zero value of "encoding" as meaning
3068 | * "little-endian".
3069 | *
3070 | * At some point in the future, we might
3071 | * support non-IEEE-binary floating-point
3072 | * formats in the encoding as well
3073 | * (IEEE decimal, System/3x0, VAX).
3074 | */
3075 | if (encoding)
3076 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3077 | if (length != 4) {
3078 | length_error = length < 4 ? true1 : false0;
3079 | report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3080 | }
3081 | if (encoding)
3082 | floatval = tvb_get_letohieee_float(tvb, start);
3083 | else
3084 | floatval = tvb_get_ntohieee_float(tvb, start);
3085 | proto_tree_set_float(new_fi, floatval);
3086 | break;
3087 |
3088 | case FT_DOUBLE:
3089 | /*
3090 | * NOTE: to support code written when
3091 | * proto_tree_add_item() took a bool as its
3092 | * last argument, with false meaning "big-endian"
3093 | * and true meaning "little-endian", we treat any
3094 | * non-zero value of "encoding" as meaning
3095 | * "little-endian".
3096 | *
3097 | * At some point in the future, we might
3098 | * support non-IEEE-binary floating-point
3099 | * formats in the encoding as well
3100 | * (IEEE decimal, System/3x0, VAX).
3101 | */
3102 | if (encoding == true1)
3103 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3104 | if (length != 8) {
3105 | length_error = length < 8 ? true1 : false0;
3106 | report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3107 | }
3108 | if (encoding)
3109 | doubleval = tvb_get_letohieee_double(tvb, start);
3110 | else
3111 | doubleval = tvb_get_ntohieee_double(tvb, start);
3112 | proto_tree_set_double(new_fi, doubleval);
3113 | break;
3114 |
3115 | case FT_STRING:
3116 | stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3117 | tvb, start, length, &length, encoding);
3118 | proto_tree_set_string(new_fi, stringval);
3119 |
3120 | /* Instead of calling proto_item_set_len(), since we
3121 | * don't yet have a proto_item, we set the
3122 | * field_info's length ourselves.
3123 | *
3124 | * XXX - our caller can't use that length to
3125 | * advance an offset unless they arrange that
3126 | * there always be a protocol tree into which
3127 | * we're putting this item.
3128 | */
3129 | new_fi->length = length;
3130 | break;
3131 |
3132 | case FT_STRINGZ:
3133 | stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3134 | tree, tvb, start, length, &length, encoding);
3135 | proto_tree_set_string(new_fi, stringval);
3136 |
3137 | /* Instead of calling proto_item_set_len(),
3138 | * since we don't yet have a proto_item, we
3139 | * set the field_info's length ourselves.
3140 | *
3141 | * XXX - our caller can't use that length to
3142 | * advance an offset unless they arrange that
3143 | * there always be a protocol tree into which
3144 | * we're putting this item.
3145 | */
3146 | new_fi->length = length;
3147 | break;
3148 |
3149 | case FT_UINT_STRING:
3150 | /*
3151 | * NOTE: to support code written when
3152 | * proto_tree_add_item() took a bool as its
3153 | * last argument, with false meaning "big-endian"
3154 | * and true meaning "little-endian", if the
3155 | * encoding value is true, treat that as
3156 | * ASCII with a little-endian length.
3157 | *
3158 | * This won't work for code that passes
3159 | * arbitrary non-zero values; that code
3160 | * will need to be fixed.
3161 | */
3162 | if (encoding == true1)
3163 | encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3164 | stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3165 | tree, tvb, start, length, &length, encoding);
3166 | proto_tree_set_string(new_fi, stringval);
3167 |
3168 | /* Instead of calling proto_item_set_len(), since we
3169 | * don't yet have a proto_item, we set the
3170 | * field_info's length ourselves.
3171 | *
3172 | * XXX - our caller can't use that length to
3173 | * advance an offset unless they arrange that
3174 | * there always be a protocol tree into which
3175 | * we're putting this item.
3176 | */
3177 | new_fi->length = length;
3178 | break;
3179 |
3180 | case FT_STRINGZPAD:
3181 | stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3182 | tvb, start, length, &length, encoding);
3183 | proto_tree_set_string(new_fi, stringval);
3184 |
3185 | /* Instead of calling proto_item_set_len(), since we
3186 | * don't yet have a proto_item, we set the
3187 | * field_info's length ourselves.
3188 | *
3189 | * XXX - our caller can't use that length to
3190 | * advance an offset unless they arrange that
3191 | * there always be a protocol tree into which
3192 | * we're putting this item.
3193 | */
3194 | new_fi->length = length;
3195 | break;
3196 |
3197 | case FT_STRINGZTRUNC:
3198 | stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3199 | tvb, start, length, &length, encoding);
3200 | proto_tree_set_string(new_fi, stringval);
3201 |
3202 | /* Instead of calling proto_item_set_len(), since we
3203 | * don't yet have a proto_item, we set the
3204 | * field_info's length ourselves.
3205 | *
3206 | * XXX - our caller can't use that length to
3207 | * advance an offset unless they arrange that
3208 | * there always be a protocol tree into which
3209 | * we're putting this item.
3210 | */
3211 | new_fi->length = length;
3212 | break;
3213 |
3214 | case FT_ABSOLUTE_TIME:
3215 | /*
3216 | * Absolute times can be in any of a number of
3217 | * formats, and they can be big-endian or
3218 | * little-endian.
3219 | *
3220 | * Historically FT_TIMEs were only timespecs;
3221 | * the only question was whether they were stored
3222 | * in big- or little-endian format.
3223 | *
3224 | * For backwards compatibility, we interpret an
3225 | * encoding of 1 as meaning "little-endian timespec",
3226 | * so that passing true is interpreted as that.
3227 | */
3228 | if (encoding == true1)
3229 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3230 |
3231 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3232 |
3233 | proto_tree_set_time(new_fi, &time_stamp);
3234 | break;
3235 |
3236 | case FT_RELATIVE_TIME:
3237 | /*
3238 | * Relative times can be in any of a number of
3239 | * formats, and they can be big-endian or
3240 | * little-endian.
3241 | *
3242 | * Historically FT_TIMEs were only timespecs;
3243 | * the only question was whether they were stored
3244 | * in big- or little-endian format.
3245 | *
3246 | * For backwards compatibility, we interpret an
3247 | * encoding of 1 as meaning "little-endian timespec",
3248 | * so that passing true is interpreted as that.
3249 | */
3250 | if (encoding == true1)
3251 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3252 |
3253 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3254 |
3255 | proto_tree_set_time(new_fi, &time_stamp);
3256 | break;
3257 | case FT_IEEE_11073_SFLOAT:
3258 | if (encoding)
3259 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3260 | if (length != 2) {
3261 | length_error = length < 2 ? true1 : false0;
3262 | report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3263 | }
3264 |
3265 | fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3266 |
3267 | break;
3268 | case FT_IEEE_11073_FLOAT:
3269 | if (encoding)
3270 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3271 | if (length != 4) {
3272 | length_error = length < 4 ? true1 : false0;
3273 | report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3274 | }
3275 | fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3276 |
3277 | break;
3278 | default:
3279 | 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))
3280 | 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))
3281 | 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))
3282 | 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));
3283 | break;
3284 | }
3285 | 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);
3286 |
3287 | /* Don't add new node to proto_tree until now so that any exceptions
3288 | * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3289 | /* XXX. wouldn't be better to add this item to tree, with some special
3290 | * flag (FI_EXCEPTION?) to know which item caused exception? For
3291 | * strings and bytes, we would have to set new_fi->value to something
3292 | * non-NULL, or otherwise ensure that proto_item_fill_display_label
3293 | * could handle NULL values. */
3294 | CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context ); }
3295 | pi = proto_tree_add_node(tree, new_fi);
3296 |
3297 | switch (new_fi->hfinfo->type) {
3298 |
3299 | case FT_STRING:
3300 | /* XXX: trailing stray character detection should be done
3301 | * _before_ conversion to UTF-8, because conversion can change
3302 | * the length, or else get_string_length should return a value
3303 | * for the "length in bytes of the string after conversion
3304 | * including internal nulls." (Noting that we do, for other
3305 | * reasons, still need the "length in bytes in the field",
3306 | * especially for FT_STRINGZ.)
3307 | *
3308 | * This is true even for ASCII and UTF-8, because
3309 | * substituting REPLACEMENT CHARACTERS for illegal characters
3310 | * can also do so (and for UTF-8 possibly even make the
3311 | * string _shorter_).
3312 | */
3313 | detect_trailing_stray_characters(encoding, stringval, length, pi);
3314 | break;
3315 |
3316 | default:
3317 | break;
3318 | }
3319 |
3320 | return pi;
3321 | }
3322 |
3323 | proto_item *
3324 | proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3325 | const unsigned start, int length,
3326 | const unsigned encoding, int32_t *retval)
3327 | {
3328 | header_field_info *hfinfo;
3329 | field_info *new_fi;
3330 | int32_t value;
3331 |
3332 | 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", 3332, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3332, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3332, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3333 |
3334 | switch (hfinfo->type) {
3335 | case FT_INT8:
3336 | case FT_INT16:
3337 | case FT_INT24:
3338 | case FT_INT32:
3339 | break;
3340 | case FT_INT64:
3341 | 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)
3342 | hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3343 | default:
3344 | 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)
3345 | hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3346 | }
3347 |
3348 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3349 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3350 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3351 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3352 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3353 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3354 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3355 |
3356 | if (encoding & ENC_STRING0x07000000) {
3357 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3358 | }
3359 | /* I believe it's ok if this is called with a NULL tree */
3360 | value = get_int_value(tree, tvb, start, length, encoding);
3361 |
3362 | if (retval) {
3363 | int no_of_bits;
3364 | *retval = value;
3365 | if (hfinfo->bitmask) {
3366 | /* Mask out irrelevant portions */
3367 | *retval &= (uint32_t)(hfinfo->bitmask);
3368 | /* Shift bits */
3369 | *retval >>= hfinfo_bitshift(hfinfo);
3370 | }
3371 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3372 | *retval = ws_sign_ext32(*retval, no_of_bits);
3373 | }
3374 |
3375 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3376 |
3377 | 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", 3377 , __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", 3377, "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", 3377, "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", 3377, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3378 |
3379 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3380 |
3381 | proto_tree_set_int(new_fi, value);
3382 |
3383 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3384 |
3385 | return proto_tree_add_node(tree, new_fi);
3386 | }
3387 |
3388 | proto_item *
3389 | proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3390 | const unsigned start, int length,
3391 | const unsigned encoding, uint32_t *retval)
3392 | {
3393 | header_field_info *hfinfo;
3394 | field_info *new_fi;
3395 | uint32_t value;
3396 |
3397 | 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", 3397, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3397, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3397, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3398 |
3399 | switch (hfinfo->type) {
3400 | case FT_CHAR:
3401 | case FT_UINT8:
3402 | case FT_UINT16:
3403 | case FT_UINT24:
3404 | case FT_UINT32:
3405 | break;
3406 | default:
3407 | 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)
3408 | 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);
3409 | }
3410 |
3411 | if (length == 0) {
3412 | if (retval) {
3413 | *retval = 0;
3414 | }
3415 | return NULL((void*)0);
3416 | }
3417 |
3418 | if (encoding & ENC_STRING0x07000000) {
3419 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3420 | }
3421 | /* I believe it's ok if this is called with a NULL tree */
3422 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3423 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3424 | uint64_t temp64;
3425 | tvb_get_varint(tvb, start, length, &temp64, encoding);
3426 | value = (uint32_t)temp64;
3427 | } else {
3428 | value = get_uint_value(tree, tvb, start, length, encoding);
3429 | }
3430 |
3431 | if (retval) {
3432 | *retval = value;
3433 | if (hfinfo->bitmask) {
3434 | /* Mask out irrelevant portions */
3435 | *retval &= (uint32_t)(hfinfo->bitmask);
3436 | /* Shift bits */
3437 | *retval >>= hfinfo_bitshift(hfinfo);
3438 | }
3439 | }
3440 |
3441 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3442 |
3443 | 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", 3443 , __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", 3443, "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", 3443, "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", 3443, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3444 |
3445 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3446 |
3447 | proto_tree_set_uint(new_fi, value);
3448 |
3449 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3450 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3451 | new_fi->flags |= FI_VARINT0x00040000;
3452 | }
3453 | return proto_tree_add_node(tree, new_fi);
3454 | }
3455 |
3456 | proto_item *
3457 | proto_tree_add_item_ret_uint32(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3458 | const unsigned start, int length,
3459 | const unsigned encoding, uint32_t *retval)
3460 | {
3461 | return proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, retval);
3462 | }
3463 |
3464 | proto_item *
3465 | proto_tree_add_item_ret_uint8(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3466 | const unsigned start, int length,
3467 | const unsigned encoding, uint8_t *retval)
3468 | {
3469 | /* TODO: further restrict by hfinfo->type ? */
3470 | uint32_t val32;
3471 | proto_item *item = proto_tree_add_item_ret_uint(tree, hfindex, tvb, start, length, encoding, &val32);
3472 | *retval = (uint8_t)val32;
3473 | return item;
3474 | }
3475 |
3476 | proto_item *
3477 | proto_tree_add_item_ret_uint16(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3478 | const unsigned start, int length,
3479 | const unsigned encoding, uint16_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 = (uint16_t)(val32 & 0xFFFF); /* Bitwise AND is a classic 'Reset' for taint */
3485 | return item;
3486 | }
3487 |
3488 |
3489 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3490 | * and returns proto_item* and uint value retrieved*/
3491 | proto_item *
3492 | ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, unsigned length,
3493 | const unsigned encoding, uint32_t *retval)
3494 | {
3495 | field_info *new_fi;
3496 | header_field_info *hfinfo;
3497 | unsigned item_length;
3498 | unsigned offset;
3499 | uint32_t value;
3500 |
3501 | offset = ptvc->offset;
3502 | 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", 3502, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3502, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3502, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3503 |
3504 | switch (hfinfo->type) {
3505 | case FT_CHAR:
3506 | case FT_UINT8:
3507 | case FT_UINT16:
3508 | case FT_UINT24:
3509 | case FT_UINT32:
3510 | break;
3511 | default:
3512 | 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)
3513 | 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);
3514 | }
3515 |
3516 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3517 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3518 |
3519 | /* I believe it's ok if this is called with a NULL tree */
3520 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3521 | value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3522 |
3523 | if (retval) {
3524 | *retval = value;
3525 | if (hfinfo->bitmask) {
3526 | /* Mask out irrelevant portions */
3527 | *retval &= (uint32_t)(hfinfo->bitmask);
3528 | /* Shift bits */
3529 | *retval >>= hfinfo_bitshift(hfinfo);
3530 | }
3531 | }
3532 |
3533 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3534 |
3535 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3536 |
3537 | /* Coast clear. Try and fake it */
3538 | 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", 3538 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3538, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3538, "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", 3538, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree )->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc ->tree)->tree_data)->visible)) { if (proto_item_is_hidden ((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT ) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data )->fake_protocols)) { ((void)0); return proto_tree_add_fake_node (ptvc->tree, hfinfo); } } };
3539 |
3540 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3541 |
3542 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3543 | offset, length, encoding);
3544 | }
3545 |
3546 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3547 | * and returns proto_item* and int value retrieved*/
3548 | proto_item *
3549 | ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, unsigned length,
3550 | const unsigned encoding, int32_t *retval)
3551 | {
3552 | field_info *new_fi;
3553 | header_field_info *hfinfo;
3554 | unsigned item_length;
3555 | unsigned offset;
3556 | uint32_t value;
3557 |
3558 | offset = ptvc->offset;
3559 | 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", 3559, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3559, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3559, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3560 |
3561 | switch (hfinfo->type) {
3562 | case FT_INT8:
3563 | case FT_INT16:
3564 | case FT_INT24:
3565 | case FT_INT32:
3566 | break;
3567 | default:
3568 | 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)
3569 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
3570 | }
3571 |
3572 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3573 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3574 |
3575 | /* I believe it's ok if this is called with a NULL tree */
3576 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3577 | value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3578 |
3579 | if (retval) {
3580 | int no_of_bits;
3581 | *retval = value;
3582 | if (hfinfo->bitmask) {
3583 | /* Mask out irrelevant portions */
3584 | *retval &= (uint32_t)(hfinfo->bitmask);
3585 | /* Shift bits */
3586 | *retval >>= hfinfo_bitshift(hfinfo);
3587 | }
3588 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3589 | *retval = ws_sign_ext32(*retval, no_of_bits);
3590 | }
3591 |
3592 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3593 |
3594 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3595 |
3596 | /* Coast clear. Try and fake it */
3597 | 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", 3597 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3597, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3597, "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", 3597, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((ptvc->tree )->tree_data)->count = 0; except_throw(1, (6), (wmem_strdup_printf (((ptvc->tree)->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((ptvc ->tree)->tree_data)->visible)) { if (proto_item_is_hidden ((ptvc->tree))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT ) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo->type != FT_PROTOCOL || ((ptvc->tree)->tree_data )->fake_protocols)) { ((void)0); return proto_tree_add_fake_node (ptvc->tree, hfinfo); } } };
3598 |
3599 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3600 |
3601 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3602 | offset, length, encoding);
3603 | }
3604 |
3605 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3606 | * and returns proto_item* and string value retrieved */
3607 | proto_item*
3608 | ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3609 | {
3610 | header_field_info *hfinfo;
3611 | field_info *new_fi;
3612 | const uint8_t *value;
3613 | unsigned item_length;
3614 | unsigned offset;
3615 |
3616 | offset = ptvc->offset;
3617 |
3618 | 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", 3618 , __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", 3618, "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", 3618, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hf];;
3619 |
3620 | switch (hfinfo->type) {
3621 | case FT_STRING:
3622 | value = get_string_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3623 | break;
3624 | case FT_STRINGZ:
3625 | value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3626 | break;
3627 | case FT_UINT_STRING:
3628 | value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3629 | break;
3630 | case FT_STRINGZPAD:
3631 | value = get_stringzpad_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3632 | break;
3633 | case FT_STRINGZTRUNC:
3634 | value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, (int*)&item_length, encoding);
3635 | break;
3636 | default:
3637 | 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)
3638 | 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);
3639 | }
3640 |
3641 | if (retval)
3642 | *retval = value;
3643 |
3644 | ptvcursor_advance(ptvc, item_length);
3645 |
3646 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3647 |
3648 | 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", 3648, __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", 3648, "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", 3648, "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", 3648 , __func__, "Adding %s would put more than %d 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); } } };
3649 |
3650 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3651 |
3652 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3653 | offset, length, encoding);
3654 | }
3655 |
3656 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3657 | * and returns proto_item* and boolean value retrieved */
3658 | proto_item*
3659 | ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, unsigned length, const unsigned encoding, bool_Bool *retval)
3660 | {
3661 | header_field_info *hfinfo;
3662 | field_info *new_fi;
3663 | unsigned item_length;
3664 | unsigned offset;
3665 | uint64_t value, bitval;
3666 |
3667 | offset = ptvc->offset;
3668 | 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", 3668, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3668, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3668, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3669 |
3670 | if (hfinfo->type != FT_BOOLEAN) {
3671 | 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)
3672 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3673 | }
3674 |
3675 | if (length == 0) {
3676 | if (retval) {
3677 | *retval = 0;
3678 | }
3679 | return NULL((void*)0);
3680 | }
3681 | if (encoding & ENC_STRING0x07000000) {
3682 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3683 | }
3684 |
3685 | get_hfi_length_unsigned(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3686 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3687 |
3688 | /* I believe it's ok if this is called with a NULL tree */
3689 | value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3690 |
3691 | if (retval) {
3692 | bitval = value;
3693 | if (hfinfo->bitmask) {
3694 | /* Mask out irrelevant portions */
3695 | bitval &= hfinfo->bitmask;
3696 | }
3697 | *retval = (bitval != 0);
3698 | }
3699 |
3700 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3701 |
3702 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3703 |
3704 | 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", 3704, __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", 3704, "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", 3704, "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", 3704 , __func__, "Adding %s would put more than %d 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); } } };
3705 |
3706 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3707 |
3708 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3709 | offset, length, encoding);
3710 | }
3711 |
3712 | proto_item *
3713 | proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3714 | const unsigned start, int length, const unsigned encoding, uint64_t *retval)
3715 | {
3716 | header_field_info *hfinfo;
3717 | field_info *new_fi;
3718 | uint64_t value;
3719 |
3720 | 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", 3720, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3720, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3720, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3721 |
3722 | switch (hfinfo->type) {
3723 | case FT_UINT40:
3724 | case FT_UINT48:
3725 | case FT_UINT56:
3726 | case FT_UINT64:
3727 | break;
3728 | default:
3729 | 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)
3730 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64" , hfinfo->abbrev);
3731 | }
3732 |
3733 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3734 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3735 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3736 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3737 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3738 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3739 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3740 |
3741 | if (encoding & ENC_STRING0x07000000) {
3742 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3743 | }
3744 | /* I believe it's ok if this is called with a NULL tree */
3745 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3746 | tvb_get_varint(tvb, start, length, &value, encoding);
3747 | } else {
3748 | value = get_uint64_value(tree, tvb, start, length, encoding);
3749 | }
3750 |
3751 | if (retval) {
3752 | *retval = value;
3753 | if (hfinfo->bitmask) {
3754 | /* Mask out irrelevant portions */
3755 | *retval &= hfinfo->bitmask;
3756 | /* Shift bits */
3757 | *retval >>= hfinfo_bitshift(hfinfo);
3758 | }
3759 | }
3760 |
3761 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3762 |
3763 | 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", 3763 , __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", 3763, "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", 3763, "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", 3763, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3764 |
3765 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3766 |
3767 | proto_tree_set_uint64(new_fi, value);
3768 |
3769 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3770 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3771 | new_fi->flags |= FI_VARINT0x00040000;
3772 | }
3773 |
3774 | return proto_tree_add_node(tree, new_fi);
3775 | }
3776 |
3777 | proto_item *
3778 | proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3779 | const unsigned start, int length, const unsigned encoding, int64_t *retval)
3780 | {
3781 | header_field_info *hfinfo;
3782 | field_info *new_fi;
3783 | int64_t value;
3784 |
3785 | 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", 3785, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3785, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3785, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3786 |
3787 | switch (hfinfo->type) {
3788 | case FT_INT40:
3789 | case FT_INT48:
3790 | case FT_INT56:
3791 | case FT_INT64:
3792 | break;
3793 | default:
3794 | 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)
3795 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
3796 | }
3797 |
3798 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3799 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3800 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3801 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3802 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3803 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3804 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3805 |
3806 | if (encoding & ENC_STRING0x07000000) {
3807 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3808 | }
3809 | /* I believe it's ok if this is called with a NULL tree */
3810 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3811 | tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3812 | }
3813 | else {
3814 | value = get_int64_value(tree, tvb, start, length, encoding);
3815 | }
3816 |
3817 | if (retval) {
3818 | *retval = value;
3819 | }
3820 |
3821 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3822 |
3823 | 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", 3823 , __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", 3823, "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", 3823, "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", 3823, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3824 |
3825 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3826 |
3827 | proto_tree_set_int64(new_fi, value);
3828 |
3829 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3830 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3831 | new_fi->flags |= FI_VARINT0x00040000;
3832 | }
3833 |
3834 | return proto_tree_add_node(tree, new_fi);
3835 | }
3836 |
3837 | proto_item *
3838 | proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3839 | const unsigned start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3840 | {
3841 | header_field_info *hfinfo;
3842 | field_info *new_fi;
3843 | uint64_t value;
3844 |
3845 | 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", 3845, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3845, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3845, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3846 |
3847 | 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 )))) {
3848 | 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)
3849 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT" , hfinfo->abbrev);
3850 | }
3851 |
3852 | /* length validation for native number encoding caught by get_uint64_value() */
3853 | /* length has to be -1 or > 0 regardless of encoding */
3854 | if (length == 0)
3855 | REPORT_DISSECTOR_BUG("Invalid length %d passed to proto_tree_add_item_ret_varint",proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint" , length)
3856 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint" , length);
3857 |
3858 | if (encoding & ENC_STRING0x07000000) {
3859 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3860 | }
3861 |
3862 | length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3863 |
3864 | if (retval) {
3865 | *retval = value;
3866 | if (hfinfo->bitmask) {
3867 | /* Mask out irrelevant portions */
3868 | *retval &= hfinfo->bitmask;
3869 | /* Shift bits */
3870 | *retval >>= hfinfo_bitshift(hfinfo);
3871 | }
3872 | }
3873 |
3874 | if (lenretval) {
3875 | *lenretval = length;
3876 | }
3877 |
3878 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3879 |
3880 | 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", 3880 , __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", 3880, "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", 3880, "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", 3880, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3881 |
3882 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3883 |
3884 | proto_tree_set_uint64(new_fi, value);
3885 |
3886 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3887 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3888 | new_fi->flags |= FI_VARINT0x00040000;
3889 | }
3890 |
3891 | return proto_tree_add_node(tree, new_fi);
3892 |
3893 | }
3894 |
3895 | proto_item *
3896 | proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3897 | const unsigned start, int length,
3898 | const unsigned encoding, bool_Bool *retval)
3899 | {
3900 | header_field_info *hfinfo;
3901 | field_info *new_fi;
3902 | uint64_t value, bitval;
3903 |
3904 | 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", 3904, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3904, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3904, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3905 |
3906 | if (hfinfo->type != FT_BOOLEAN) {
3907 | 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)
3908 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3909 | }
3910 |
3911 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3912 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3913 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3914 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3915 | *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3916 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3917 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3918 |
3919 | if (encoding & ENC_STRING0x07000000) {
3920 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3921 | }
3922 | /* I believe it's ok if this is called with a NULL tree */
3923 | value = get_uint64_value(tree, tvb, start, length, encoding);
3924 |
3925 | if (retval) {
3926 | bitval = value;
3927 | if (hfinfo->bitmask) {
3928 | /* Mask out irrelevant portions */
3929 | bitval &= hfinfo->bitmask;
3930 | }
3931 | *retval = (bitval != 0);
3932 | }
3933 |
3934 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3935 |
3936 | 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", 3936 , __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", 3936, "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", 3936, "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", 3936, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3937 |
3938 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3939 |
3940 | proto_tree_set_boolean(new_fi, value);
3941 |
3942 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3943 |
3944 | return proto_tree_add_node(tree, new_fi);
3945 | }
3946 |
3947 | proto_item *
3948 | proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3949 | const unsigned start, int length,
3950 | const unsigned encoding, float *retval)
3951 | {
3952 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3953 | field_info *new_fi;
3954 | float value;
3955 |
3956 | 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", 3956, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3957 |
3958 | if (hfinfo->type != FT_FLOAT) {
3959 | 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);
3960 | }
3961 |
3962 | if (length != 4) {
3963 | report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3964 | }
3965 |
3966 | /* treat any nonzero encoding as little endian for backwards compatibility */
3967 | value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3968 | if (retval) {
3969 | *retval = value;
3970 | }
3971 |
3972 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3973 |
3974 | 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", 3974 , __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", 3974, "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", 3974, "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", 3974, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3975 |
3976 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3977 | if (encoding) {
3978 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3979 | }
3980 |
3981 | proto_tree_set_float(new_fi, value);
3982 |
3983 | return proto_tree_add_node(tree, new_fi);
3984 | }
3985 |
3986 | proto_item *
3987 | proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3988 | const unsigned start, int length,
3989 | const unsigned encoding, double *retval)
3990 | {
3991 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3992 | field_info *new_fi;
3993 | double value;
3994 |
3995 | 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", 3995, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3996 |
3997 | if (hfinfo->type != FT_DOUBLE) {
3998 | 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);
3999 | }
4000 |
4001 | if (length != 8) {
4002 | report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
4003 | }
4004 |
4005 | /* treat any nonzero encoding as little endian for backwards compatibility */
4006 | value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
4007 | if (retval) {
4008 | *retval = value;
4009 | }
4010 |
4011 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4012 |
4013 | 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", 4013 , __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", 4013, "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", 4013, "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", 4013, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4014 |
4015 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4016 | if (encoding) {
4017 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
4018 | }
4019 |
4020 | proto_tree_set_double(new_fi, value);
4021 |
4022 | return proto_tree_add_node(tree, new_fi);
4023 | }
4024 |
4025 | proto_item *
4026 | proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4027 | const unsigned start, int length,
4028 | const unsigned encoding, ws_in4_addr *retval)
4029 | {
4030 | header_field_info *hfinfo;
4031 | field_info *new_fi;
4032 | ws_in4_addr value;
4033 |
4034 | 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", 4034, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4034, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4034, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4035 |
4036 | switch (hfinfo->type) {
4037 | case FT_IPv4:
4038 | break;
4039 | default:
4040 | 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)
4041 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4", hfinfo->abbrev);
4042 | }
4043 |
4044 | if (length != FT_IPv4_LEN4)
4045 | 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)
4046 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4" , length);
4047 |
4048 | if (encoding & (ENC_STRING0x07000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
4049 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
4050 | }
4051 |
4052 | /*
4053 | * NOTE: to support code written when proto_tree_add_item() took
4054 | * a bool as its last argument, with false meaning "big-endian"
4055 | * and true meaning "little-endian", we treat any non-zero value
4056 | * of "encoding" as meaning "little-endian".
4057 | */
4058 | value = tvb_get_ipv4(tvb, start);
4059 | if (encoding)
4060 | 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))));
4061 |
4062 | if (retval) {
4063 | *retval = value;
4064 | }
4065 |
4066 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4067 |
4068 | 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", 4068 , __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", 4068, "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", 4068, "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", 4068, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4069 |
4070 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4071 |
4072 | proto_tree_set_ipv4(new_fi, value);
4073 |
4074 | new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4075 | return proto_tree_add_node(tree, new_fi);
4076 | }
4077 |
4078 | proto_item *
4079 | proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4080 | const unsigned start, int length,
4081 | const unsigned encoding, ws_in6_addr *addr)
4082 | {
4083 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4084 | field_info *new_fi;
4085 |
4086 | 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", 4086, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4087 |
4088 | switch (hfinfo->type) {
4089 | case FT_IPv6:
4090 | break;
4091 | default:
4092 | 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)
4093 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6", hfinfo->abbrev);
4094 | }
4095 |
4096 | if (length != FT_IPv6_LEN16)
4097 | 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)
4098 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6" , length);
4099 |
4100 | if (encoding) {
4101 | 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" );
4102 | }
4103 |
4104 | tvb_get_ipv6(tvb, start, addr);
4105 |
4106 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4107 |
4108 | 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", 4108 , __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", 4108, "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", 4108, "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", 4108, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4109 |
4110 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4111 |
4112 | proto_tree_set_ipv6(new_fi, addr);
4113 |
4114 | return proto_tree_add_node(tree, new_fi);
4115 | }
4116 |
4117 | proto_item *
4118 | proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4119 | const unsigned start, int length, const unsigned encoding, uint8_t *retval) {
4120 |
4121 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4122 | field_info *new_fi;
4123 |
4124 | 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", 4124, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4125 |
4126 | switch (hfinfo->type) {
4127 | case FT_ETHER:
4128 | break;
4129 | default:
4130 | 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)
4131 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER" , hfinfo->abbrev);
4132 | }
4133 |
4134 | if (length != FT_ETHER_LEN6)
4135 | 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)
4136 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether" , length);
4137 |
4138 | if (encoding) {
4139 | 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" );
4140 | }
4141 |
4142 | tvb_memcpy(tvb, retval, start, length);
4143 |
4144 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4145 |
4146 | 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", 4146 , __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", 4146, "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", 4146, "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", 4146, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4147 |
4148 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4149 |
4150 | proto_tree_set_ether(new_fi, retval);
4151 |
4152 | return proto_tree_add_node(tree, new_fi);
4153 | }
4154 |
4155 |
4156 | proto_item *
4157 | proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4158 | tvbuff_t *tvb,
4159 | const unsigned start, int length,
4160 | const unsigned encoding,
4161 | wmem_allocator_t *scope,
4162 | const uint8_t **retval,
4163 | int *lenretval)
4164 | {
4165 | proto_item *pi;
4166 | header_field_info *hfinfo;
4167 | field_info *new_fi;
4168 | const uint8_t *value;
4169 |
4170 | 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", 4170, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4170, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4170, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4171 |
4172 | switch (hfinfo->type) {
4173 | case FT_STRING:
4174 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4175 | break;
4176 | case FT_STRINGZ:
4177 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4178 | break;
4179 | case FT_UINT_STRING:
4180 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4181 | break;
4182 | case FT_STRINGZPAD:
4183 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4184 | break;
4185 | case FT_STRINGZTRUNC:
4186 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4187 | break;
4188 | default:
4189 | 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)
4190 | 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);
4191 | }
4192 |
4193 | if (retval)
4194 | *retval = value;
4195 |
4196 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4197 |
4198 | 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", 4198 , __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", 4198, "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", 4198, "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", 4198, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4199 |
4200 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4201 |
4202 | proto_tree_set_string(new_fi, (const char*)value);
4203 |
4204 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4205 |
4206 | pi = proto_tree_add_node(tree, new_fi);
4207 |
4208 | switch (hfinfo->type) {
4209 |
4210 | case FT_STRINGZ:
4211 | case FT_STRINGZPAD:
4212 | case FT_STRINGZTRUNC:
4213 | case FT_UINT_STRING:
4214 | break;
4215 |
4216 | case FT_STRING:
4217 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4218 | break;
4219 |
4220 | default:
4221 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4221 , __func__, "assertion \"not reached\" failed");
4222 | }
4223 |
4224 | return pi;
4225 | }
4226 |
4227 | proto_item *
4228 | proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4229 | const unsigned start, int length,
4230 | const unsigned encoding, wmem_allocator_t *scope,
4231 | const uint8_t **retval)
4232 | {
4233 | return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4234 | tvb, start, length, encoding, scope, retval, &length);
4235 | }
4236 |
4237 | proto_item *
4238 | proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4239 | tvbuff_t *tvb,
4240 | const unsigned start, int length,
4241 | const unsigned encoding,
4242 | wmem_allocator_t *scope,
4243 | char **retval,
4244 | int *lenretval)
4245 | {
4246 | proto_item *pi;
4247 | header_field_info *hfinfo;
4248 | field_info *new_fi;
4249 | const uint8_t *value;
4250 | uint32_t n = 0;
4251 |
4252 | 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", 4252, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4252, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4252, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4253 |
4254 | switch (hfinfo->type) {
4255 | case FT_STRING:
4256 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4257 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4258 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4259 | break;
4260 | case FT_STRINGZ:
4261 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4262 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4263 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4264 | break;
4265 | case FT_UINT_STRING:
4266 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4267 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4268 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4269 | break;
4270 | case FT_STRINGZPAD:
4271 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4272 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4273 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4274 | break;
4275 | case FT_STRINGZTRUNC:
4276 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4277 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4278 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4279 | break;
4280 | case FT_BYTES:
4281 | tvb_ensure_bytes_exist(tvb, start, length);
4282 | value = tvb_get_ptr(tvb, start, length);
4283 | *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4284 | *lenretval = length;
4285 | break;
4286 | case FT_UINT_BYTES:
4287 | n = get_uint_value(tree, tvb, start, length, encoding);
4288 | tvb_ensure_bytes_exist(tvb, start + length, n);
4289 | value = tvb_get_ptr(tvb, start + length, n);
4290 | *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4291 | *lenretval = length + n;
4292 | break;
4293 | default:
4294 | 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)
4295 | 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);
4296 | }
4297 |
4298 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4299 |
4300 | 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", 4300 , __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", 4300, "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", 4300, "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", 4300, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4301 |
4302 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4303 |
4304 | switch (hfinfo->type) {
4305 |
4306 | case FT_STRING:
4307 | case FT_STRINGZ:
4308 | case FT_UINT_STRING:
4309 | case FT_STRINGZPAD:
4310 | case FT_STRINGZTRUNC:
4311 | proto_tree_set_string(new_fi, (const char*)value);
4312 | break;
4313 |
4314 | case FT_BYTES:
4315 | proto_tree_set_bytes(new_fi, value, length);
4316 | break;
4317 |
4318 | case FT_UINT_BYTES:
4319 | proto_tree_set_bytes(new_fi, value, n);
4320 | break;
4321 |
4322 | default:
4323 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4323 , __func__, "assertion \"not reached\" failed");
4324 | }
4325 |
4326 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4327 |
4328 | pi = proto_tree_add_node(tree, new_fi);
4329 |
4330 | switch (hfinfo->type) {
4331 |
4332 | case FT_STRINGZ:
4333 | case FT_STRINGZPAD:
4334 | case FT_STRINGZTRUNC:
4335 | case FT_UINT_STRING:
4336 | break;
4337 |
4338 | case FT_STRING:
4339 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4340 | break;
4341 |
4342 | case FT_BYTES:
4343 | case FT_UINT_BYTES:
4344 | break;
4345 |
4346 | default:
4347 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4347 , __func__, "assertion \"not reached\" failed");
4348 | }
4349 |
4350 | return pi;
4351 | }
4352 |
4353 | proto_item *
4354 | proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4355 | tvbuff_t *tvb,
4356 | const unsigned start, int length,
4357 | const unsigned encoding,
4358 | wmem_allocator_t *scope,
4359 | char **retval)
4360 | {
4361 | return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4362 | tvb, start, length, encoding, scope, retval, &length);
4363 | }
4364 |
4365 | proto_item *
4366 | proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4367 | tvbuff_t *tvb,
4368 | const unsigned start, int length, const unsigned encoding,
4369 | wmem_allocator_t *scope, char **retval)
4370 | {
4371 | header_field_info *hfinfo;
4372 | field_info *new_fi;
4373 | nstime_t time_stamp;
4374 | int flags;
4375 |
4376 | 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", 4376, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4376, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4376, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4377 |
4378 | switch (hfinfo->type) {
4379 | case FT_ABSOLUTE_TIME:
4380 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4381 | flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4382 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4383 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4384 | }
4385 | *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4386 | break;
4387 | case FT_RELATIVE_TIME:
4388 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4389 | *retval = rel_time_to_secs_str(scope, &time_stamp);
4390 | break;
4391 | default:
4392 | 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)
4393 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME" , hfinfo->abbrev);
4394 | }
4395 |
4396 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4397 |
4398 | 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", 4398 , __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", 4398, "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", 4398, "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", 4398, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4399 |
4400 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4401 |
4402 | switch (hfinfo->type) {
4403 |
4404 | case FT_ABSOLUTE_TIME:
4405 | case FT_RELATIVE_TIME:
4406 | proto_tree_set_time(new_fi, &time_stamp);
4407 | break;
4408 | default:
4409 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4409 , __func__, "assertion \"not reached\" failed");
4410 | }
4411 |
4412 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4413 |
4414 | return proto_tree_add_node(tree, new_fi);
4415 | }
4416 |
4417 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
4418 | and returns proto_item* */
4419 | proto_item *
4420 | ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4421 | const unsigned encoding)
4422 | {
4423 | field_info *new_fi;
4424 | header_field_info *hfinfo;
4425 | int item_length;
4426 | unsigned offset;
4427 |
4428 | offset = ptvc->offset;
4429 | 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", 4429, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4429, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4429, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4430 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4431 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4432 |
4433 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4434 |
4435 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4436 |
4437 | /* Coast clear. Try and fake it */
4438 | 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", 4438 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4438, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4438, "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", 4438, __func__, "Adding %s would put more than %d 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); } } };
4439 |
4440 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4441 |
4442 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4443 | offset, length, encoding);
4444 | }
4445 |
4446 | /* Add an item to a proto_tree, using the text label registered to that item;
4447 | the item is extracted from the tvbuff handed to it. */
4448 | proto_item *
4449 | proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4450 | const unsigned start, int length, const unsigned encoding)
4451 | {
4452 | field_info *new_fi;
4453 | int item_length;
4454 |
4455 | 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", 4455, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4456 |
4457 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4458 | test_length(hfinfo, tvb, start, item_length, encoding);
4459 |
4460 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4461 |
4462 | 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", 4462 , __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", 4462, "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", 4462, "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", 4462, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4463 |
4464 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4465 |
4466 | return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4467 | }
4468 |
4469 | proto_item *
4470 | proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4471 | const unsigned start, int length, const unsigned encoding)
4472 | {
4473 | register header_field_info *hfinfo;
4474 |
4475 | 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", 4475, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4475, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4475, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4476 | return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4477 | }
4478 |
4479 | /* Add an item to a proto_tree, using the text label registered to that item;
4480 | the item is extracted from the tvbuff handed to it.
4481 |
4482 | Return the length of the item through the pointer. */
4483 | proto_item *
4484 | proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4485 | tvbuff_t *tvb, const unsigned start,
4486 | int length, const unsigned encoding,
4487 | int *lenretval)
4488 | {
4489 | field_info *new_fi;
4490 | int item_length;
4491 | proto_item *item;
4492 |
4493 | 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", 4493, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4494 |
4495 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4496 | test_length(hfinfo, tvb, start, item_length, encoding);
4497 |
4498 | if (!tree) {
4499 | /*
4500 | * We need to get the correct item length here.
4501 | * That's normally done by proto_tree_new_item(),
4502 | * but we won't be calling it.
4503 | */
4504 | *lenretval = get_full_length(hfinfo, tvb, start, length,
4505 | item_length, encoding);
4506 | return NULL((void*)0);
4507 | }
4508 |
4509 | 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", 4516 , __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", 4516, "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", 4516, "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", 4516 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4510 | /*((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", 4516 , __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", 4516, "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", 4516, "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", 4516 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4511 | * 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", 4516 , __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", 4516, "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", 4516, "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", 4516 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4512 | * 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", 4516 , __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", 4516, "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", 4516, "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", 4516 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4513 | */((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", 4516 , __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", 4516, "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", 4516, "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", 4516 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4514 | *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", 4516 , __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", 4516, "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", 4516, "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", 4516 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4515 | 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", 4516 , __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", 4516, "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", 4516, "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", 4516 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4516 | })((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", 4516 , __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", 4516, "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", 4516, "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", 4516 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } };
4517 |
4518 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4519 |
4520 | item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4521 | *lenretval = new_fi->length;
4522 | return item;
4523 | }
4524 |
4525 | proto_item *
4526 | proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4527 | const unsigned start, int length,
4528 | const unsigned encoding, int *lenretval)
4529 | {
4530 | register header_field_info *hfinfo;
4531 |
4532 | 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", 4532, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4532, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4532, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4533 | return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4534 | }
4535 |
4536 | /* which FT_ types can use proto_tree_add_bytes_item() */
4537 | static inline bool_Bool
4538 | validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4539 | {
4540 | return (type == FT_BYTES ||
4541 | type == FT_UINT_BYTES ||
4542 | type == FT_OID ||
4543 | type == FT_REL_OID ||
4544 | type == FT_SYSTEM_ID );
4545 | }
4546 |
4547 | /* Note: this does no validation that the byte array of an FT_OID or
4548 | FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4549 | so I think it's ok to continue not validating it?
4550 | */
4551 | proto_item *
4552 | proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4553 | const unsigned start, unsigned length,
4554 | const unsigned encoding,
4555 | GByteArray *retval, unsigned *endoff, int *err)
4556 | {
4557 | field_info *new_fi;
4558 | GByteArray *bytes = retval;
4559 | GByteArray *created_bytes = NULL((void*)0);
4560 | bool_Bool failed = false0;
4561 | uint32_t n = 0;
4562 | header_field_info *hfinfo;
4563 | bool_Bool generate = (bytes || tree) ? true1 : false0;
4564 |
4565 | 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", 4565, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4565, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4565, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4566 |
4567 | 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", 4567, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4568 |
4569 | 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", 4570, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))))
4570 | "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", 4570, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))));
4571 |
4572 | if (length == 0) {
4573 | return NULL((void*)0);
4574 | }
4575 |
4576 | if (encoding & ENC_STR_NUM0x01000000) {
4577 | 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" );
4578 | }
4579 |
4580 | if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4581 | if (hfinfo->type == FT_UINT_BYTES) {
4582 | /* can't decode FT_UINT_BYTES from strings */
4583 | 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")
4584 | "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");
4585 | }
4586 |
4587 | unsigned hex_encoding = encoding;
4588 | if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4589 | /* If none of the separator values are used,
4590 | * assume no separator (the common case). */
4591 | hex_encoding |= ENC_SEP_NONE0x00010000;
4592 | #if 0
4593 | 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")
4594 | "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");
4595 | #endif
4596 | }
4597 |
4598 | if (!bytes) {
4599 | /* caller doesn't care about return value, but we need it to
4600 | call tvb_get_string_bytes() and set the tree later */
4601 | bytes = created_bytes = g_byte_array_new();
4602 | }
4603 |
4604 | /*
4605 | * bytes might be NULL after this, but can't add expert
4606 | * error until later; if it's NULL, just note that
4607 | * it failed.
4608 | */
4609 | bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4610 | if (bytes == NULL((void*)0))
4611 | failed = true1;
4612 | }
4613 | else if (generate) {
4614 | tvb_ensure_bytes_exist(tvb, start, length);
4615 |
4616 | if (hfinfo->type == FT_UINT_BYTES) {
4617 | n = length; /* n is now the "header" length */
4618 | length = get_uint_value(tree, tvb, start, n, encoding);
4619 | /* length is now the value's length; only store the value in the array */
4620 | tvb_ensure_bytes_exist(tvb, start + n, length);
4621 | if (!bytes) {
4622 | /* caller doesn't care about return value, but
4623 | * we may need it to set the tree later */
4624 | bytes = created_bytes = g_byte_array_new();
4625 | }
4626 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4627 | }
4628 | else if (length > 0) {
4629 | if (!bytes) {
4630 | /* caller doesn't care about return value, but
4631 | * we may need it to set the tree later */
4632 | bytes = created_bytes = g_byte_array_new();
4633 | }
4634 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4635 | }
4636 |
4637 | if (endoff)
4638 | *endoff = start + n + length;
4639 | }
4640 |
4641 | if (err)
4642 | *err = failed ? EINVAL22 : 0;
4643 |
4644 | 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); }
4645 | {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4646 | 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); }
4647 | 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); }
4648 | 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); }
4649 | bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4650 | } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); };
4651 |
4652 | 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", 4658 , __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", 4658, "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", 4658, "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", 4658 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4653 | {((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", 4658 , __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", 4658, "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", 4658, "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", 4658 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4654 | 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", 4658 , __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", 4658, "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", 4658, "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", 4658 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4655 | 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", 4658 , __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", 4658, "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", 4658, "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", 4658 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4656 | 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", 4658 , __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", 4658, "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", 4658, "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", 4658 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4657 | 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", 4658 , __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", 4658, "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", 4658, "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", 4658 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4658 | } )((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", 4658 , __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", 4658, "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", 4658, "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", 4658 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } };
4659 |
4660 | /* n will be zero except when it's a FT_UINT_BYTES */
4661 | new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4662 |
4663 | if (encoding & ENC_STRING0x07000000) {
4664 | if (failed)
4665 | expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4666 |
4667 | if (bytes)
4668 | proto_tree_set_bytes_gbytearray(new_fi, bytes);
4669 | else
4670 | proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4671 |
4672 | if (created_bytes)
4673 | g_byte_array_free(created_bytes, true1);
4674 | }
4675 | else {
4676 | /* n will be zero except when it's a FT_UINT_BYTES */
4677 | proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4678 |
4679 | /* XXX: If we have a non-NULL tree but NULL retval, we don't
4680 | * use the byte array created above in this case.
4681 | */
4682 | if (created_bytes)
4683 | g_byte_array_free(created_bytes, true1);
4684 |
4685 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4686 | (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);
4687 | }
4688 |
4689 | return proto_tree_add_node(tree, new_fi);
4690 | }
4691 |
4692 |
4693 | proto_item *
4694 | proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4695 | const unsigned start, const unsigned length,
4696 | const unsigned encoding,
4697 | nstime_t *retval, unsigned *endoff, int *err)
4698 | {
4699 | field_info *new_fi;
4700 | nstime_t time_stamp;
4701 | int saved_err = 0;
4702 | header_field_info *hfinfo;
4703 |
4704 | 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", 4704, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4704, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4704, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4705 |
4706 | 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", 4706, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4707 |
4708 | if (length == 0) {
4709 | if(retval) {
4710 | nstime_set_zero(retval);
4711 | }
4712 | return NULL((void*)0);
4713 | }
4714 |
4715 | nstime_set_zero(&time_stamp);
4716 |
4717 | if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4718 | 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", 4718, ((hfinfo))->abbrev))));
4719 | /* The only string format that could be a relative time is
4720 | * ENC_ISO_8601_TIME, and that is treated as an absolute time
4721 | * relative to "now" currently.
4722 | */
4723 | if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4724 | saved_err = EINVAL22;
4725 | }
4726 | else {
4727 | 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", 4727, ((hfinfo))->abbrev))));
4728 | const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4729 |
4730 | tvb_ensure_bytes_exist(tvb, start, length);
4731 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4732 | if (endoff) *endoff = start + length;
4733 | }
4734 |
4735 | if (err) *err = saved_err;
4736 |
4737 | if (retval) {
4738 | retval->secs = time_stamp.secs;
4739 | retval->nsecs = time_stamp.nsecs;
4740 | }
4741 |
4742 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4743 |
4744 | 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", 4744 , __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", 4744, "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", 4744, "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", 4744, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4745 |
4746 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4747 |
4748 | proto_tree_set_time(new_fi, &time_stamp);
4749 |
4750 | if (encoding & ENC_STRING0x07000000) {
4751 | if (saved_err)
4752 | expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4753 | }
4754 | else {
4755 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4756 | (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);
4757 | }
4758 |
4759 | return proto_tree_add_node(tree, new_fi);
4760 | }
4761 |
4762 | /* Add a FT_NONE to a proto_tree */
4763 | proto_item *
4764 | proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4765 | const unsigned start, int length, const char *format,
4766 | ...)
4767 | {
4768 | proto_item *pi;
4769 | va_list ap;
4770 | header_field_info *hfinfo;
4771 |
4772 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4773 |
4774 | 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", 4774 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4774, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4774, "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", 4774, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4775 |
4776 | 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", 4776 , ((hfinfo))->abbrev))));
4777 |
4778 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4779 |
4780 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4780, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4781 |
4782 | va_start(ap, format)__builtin_va_start(ap, format);
4783 | proto_tree_set_representation(pi, format, ap);
4784 | va_end(ap)__builtin_va_end(ap);
4785 |
4786 | /* no value to set for FT_NONE */
4787 | return pi;
4788 | }
4789 |
4790 | /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4791 | * offset, and returns proto_item* */
4792 | proto_item *
4793 | ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4794 | const unsigned encoding)
4795 | {
4796 | proto_item *item;
4797 |
4798 | item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4799 | length, encoding);
4800 |
4801 | return item;
4802 | }
4803 |
4804 | /* Advance the ptvcursor's offset within its tvbuff without
4805 | * adding anything to the proto_tree. */
4806 | void
4807 | ptvcursor_advance(ptvcursor_t* ptvc, unsigned length)
4808 | {
4809 | if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc ->offset))) {
4810 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4811 | }
4812 | }
4813 |
4814 |
4815 | static void
4816 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4817 | {
4818 | ws_assert(length >= 0)do { if ((1) && !(length >= 0)) ws_log_fatal_full( "Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4818, __func__, "assertion failed: %s" , "length >= 0"); } while (0);
4819 | fvalue_set_protocol(fi->value, tvb, field_data, (unsigned)length);
4820 | }
4821 |
4822 | /* Add a FT_PROTOCOL to a proto_tree */
4823 | proto_item *
4824 | proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4825 | unsigned start, int length, const char *format, ...)
4826 | {
4827 | proto_item *pi;
4828 | field_info *new_fi;
4829 | tvbuff_t *protocol_tvb;
4830 | va_list ap;
4831 | header_field_info *hfinfo;
4832 | char* protocol_rep;
4833 |
4834 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4835 |
4836 | 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", 4836 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4836, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4836, "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", 4836, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4837 |
4838 | 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" , 4838, ((hfinfo))->abbrev))));
4839 |
4840 | /*
4841 | * This can throw an exception when it calls get_hfi_length before
4842 | * it allocates anything, if length is nonzero and start is past
4843 | * the end of the tvb. Afterwards it can't throw an exception,
4844 | * as length is clamped to the captured length remaining.
4845 | */
4846 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4847 | new_fi = PNODE_FINFO(pi)((pi)->finfo);
4848 | /* Start the protocol_tvb at the correct start offset, but allow it
4849 | * to be lengthened later via finfo_set_len. */
4850 | protocol_tvb = new_fi->ds_tvb ? tvb_new_subset_remaining(new_fi->ds_tvb, new_fi->start) : NULL((void*)0);
4851 |
4852 | va_start(ap, format)__builtin_va_start(ap, format);
4853 | protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4854 | proto_tree_set_protocol_tvb(new_fi, protocol_tvb, protocol_rep, length);
4855 | 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);
4856 | va_end(ap)__builtin_va_end(ap);
4857 |
4858 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4858, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4859 |
4860 | va_start(ap, format)__builtin_va_start(ap, format);
4861 | proto_tree_set_representation(pi, format, ap);
4862 | va_end(ap)__builtin_va_end(ap);
4863 |
4864 | return pi;
4865 | }
4866 |
4867 | /* Add a FT_BYTES to a proto_tree */
4868 | proto_item *
4869 | proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4870 | int length, const uint8_t *start_ptr)
4871 | {
4872 | proto_item *pi;
4873 | header_field_info *hfinfo;
4874 | int item_length;
4875 |
4876 | 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", 4876, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4876, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4876, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4877 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4878 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4879 |
4880 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4881 |
4882 | 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", 4882 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4882, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4882, "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", 4882, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4883 |
4884 | 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", 4884, ((hfinfo))->abbrev))));
4885 |
4886 | if (start_ptr == NULL((void*)0) && tvb != NULL((void*)0))
4887 | start_ptr = tvb_get_ptr(tvb, start, length);
4888 |
4889 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4890 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4891 |
4892 | return pi;
4893 | }
4894 |
4895 | /* Add a FT_BYTES to a proto_tree */
4896 | proto_item *
4897 | proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4898 | int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4899 | {
4900 | proto_item *pi;
4901 | header_field_info *hfinfo;
4902 | int item_length;
4903 |
4904 | 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", 4904, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4904, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4904, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4905 | get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4906 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4907 |
4908 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4909 |
4910 | TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4910 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4910, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4910, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4910, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4911 |
4912 | 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", 4912, ((hfinfo))->abbrev))));
4913 |
4914 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4915 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4916 |
4917 | return pi;
4918 | }
4919 |
4920 | proto_item *
4921 | proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4922 | unsigned start, int length,
4923 | const uint8_t *start_ptr,
4924 | const char *format, ...)
4925 | {
4926 | proto_item *pi;
4927 | va_list ap;
4928 |
4929 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4930 |
4931 | 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; };
4932 |
4933 | va_start(ap, format)__builtin_va_start(ap, format);
4934 | proto_tree_set_representation_value(pi, format, ap);
4935 | va_end(ap)__builtin_va_end(ap);
4936 |
4937 | return pi;
4938 | }
4939 |
4940 | proto_item *
4941 | proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4942 | unsigned start, int length, const uint8_t *start_ptr,
4943 | const char *format, ...)
4944 | {
4945 | proto_item *pi;
4946 | va_list ap;
4947 |
4948 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4949 |
4950 | 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; };
4951 |
4952 | va_start(ap, format)__builtin_va_start(ap, format);
4953 | proto_tree_set_representation(pi, format, ap);
4954 | va_end(ap)__builtin_va_end(ap);
4955 |
4956 | return pi;
4957 | }
4958 |
4959 | static void
4960 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4961 | {
4962 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4962, "length >= 0" ))));
4963 | 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", 4963, "start_ptr != ((void*)0) || length == 0" ))));
4964 |
4965 | fvalue_set_bytes_data(fi->value, start_ptr, length);
4966 | }
4967 |
4968 |
4969 | static void
4970 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, unsigned offset, int length)
4971 | {
4972 | tvb_ensure_bytes_exist(tvb, offset, length);
4973 | proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4974 | }
4975 |
4976 | static void
4977 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4978 | {
4979 | GByteArray *bytes;
4980 |
4981 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4981, "value != ((void*)0)" ))));
4982 |
4983 | bytes = byte_array_dup(value);
4984 |
4985 | fvalue_set_byte_array(fi->value, bytes);
4986 | }
4987 |
4988 | /* Add a FT_*TIME to a proto_tree */
4989 | proto_item *
4990 | proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
4991 | unsigned length, const nstime_t *value_ptr)
4992 | {
4993 | proto_item *pi;
4994 | header_field_info *hfinfo;
4995 |
4996 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4997 |
4998 | 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", 4998 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4998, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4998, "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", 4998, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4999 |
5000 | 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", 5000, ((hfinfo))->abbrev))));
5001 |
5002 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5003 | proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5004 |
5005 | return pi;
5006 | }
5007 |
5008 | proto_item *
5009 | proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5010 | unsigned start, unsigned length, nstime_t *value_ptr,
5011 | const char *format, ...)
5012 | {
5013 | proto_item *pi;
5014 | va_list ap;
5015 |
5016 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5017 | if (pi != tree) {
5018 | va_start(ap, format)__builtin_va_start(ap, format);
5019 | proto_tree_set_representation_value(pi, format, ap);
5020 | va_end(ap)__builtin_va_end(ap);
5021 | }
5022 |
5023 | return pi;
5024 | }
5025 |
5026 | proto_item *
5027 | proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5028 | unsigned start, unsigned length, nstime_t *value_ptr,
5029 | const char *format, ...)
5030 | {
5031 | proto_item *pi;
5032 | va_list ap;
5033 |
5034 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
5035 | if (pi != tree) {
5036 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5036, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5037 |
5038 | va_start(ap, format)__builtin_va_start(ap, format);
5039 | proto_tree_set_representation(pi, format, ap);
5040 | va_end(ap)__builtin_va_end(ap);
5041 | }
5042 |
5043 | return pi;
5044 | }
5045 |
5046 | /* Set the FT_*TIME value */
5047 | static void
5048 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
5049 | {
5050 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5050, "value_ptr != ((void*)0)" ))));
5051 |
5052 | fvalue_set_time(fi->value, value_ptr);
5053 | }
5054 |
5055 | /* Add a FT_IPXNET to a proto_tree */
5056 | proto_item *
5057 | proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5058 | unsigned length, uint32_t value)
5059 | {
5060 | proto_item *pi;
5061 | header_field_info *hfinfo;
5062 |
5063 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5064 |
5065 | 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", 5065 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5065, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5065, "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", 5065, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5066 |
5067 | 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" , 5067, ((hfinfo))->abbrev))));
5068 |
5069 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5070 | proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5071 |
5072 | return pi;
5073 | }
5074 |
5075 | proto_item *
5076 | proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5077 | unsigned start, unsigned length, uint32_t value,
5078 | const char *format, ...)
5079 | {
5080 | proto_item *pi;
5081 | va_list ap;
5082 |
5083 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5084 | if (pi != tree) {
5085 | va_start(ap, format)__builtin_va_start(ap, format);
5086 | proto_tree_set_representation_value(pi, format, ap);
5087 | va_end(ap)__builtin_va_end(ap);
5088 | }
5089 |
5090 | return pi;
5091 | }
5092 |
5093 | proto_item *
5094 | proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5095 | unsigned start, unsigned length, uint32_t value,
5096 | const char *format, ...)
5097 | {
5098 | proto_item *pi;
5099 | va_list ap;
5100 |
5101 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5102 | if (pi != tree) {
5103 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5103, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5104 |
5105 | va_start(ap, format)__builtin_va_start(ap, format);
5106 | proto_tree_set_representation(pi, format, ap);
5107 | va_end(ap)__builtin_va_end(ap);
5108 | }
5109 |
5110 | return pi;
5111 | }
5112 |
5113 | /* Set the FT_IPXNET value */
5114 | static void
5115 | proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5116 | {
5117 | fvalue_set_uinteger(fi->value, value);
5118 | }
5119 |
5120 | /* Add a FT_IPv4 to a proto_tree */
5121 | proto_item *
5122 | proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5123 | unsigned length, ws_in4_addr value)
5124 | {
5125 | proto_item *pi;
5126 | header_field_info *hfinfo;
5127 |
5128 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5129 |
5130 | 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", 5130 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5130, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5130, "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", 5130, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5131 |
5132 | 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", 5132 , ((hfinfo))->abbrev))));
5133 |
5134 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5135 | proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5136 |
5137 | return pi;
5138 | }
5139 |
5140 | proto_item *
5141 | proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5142 | unsigned start, unsigned length, ws_in4_addr value,
5143 | const char *format, ...)
5144 | {
5145 | proto_item *pi;
5146 | va_list ap;
5147 |
5148 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5149 | if (pi != tree) {
5150 | va_start(ap, format)__builtin_va_start(ap, format);
5151 | proto_tree_set_representation_value(pi, format, ap);
5152 | va_end(ap)__builtin_va_end(ap);
5153 | }
5154 |
5155 | return pi;
5156 | }
5157 |
5158 | proto_item *
5159 | proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5160 | unsigned start, unsigned length, ws_in4_addr value,
5161 | const char *format, ...)
5162 | {
5163 | proto_item *pi;
5164 | va_list ap;
5165 |
5166 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5167 | if (pi != tree) {
5168 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5168, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5169 |
5170 | va_start(ap, format)__builtin_va_start(ap, format);
5171 | proto_tree_set_representation(pi, format, ap);
5172 | va_end(ap)__builtin_va_end(ap);
5173 | }
5174 |
5175 | return pi;
5176 | }
5177 |
5178 | /* Set the FT_IPv4 value */
5179 | static void
5180 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5181 | {
5182 | ipv4_addr_and_mask ipv4;
5183 | ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5184 | fvalue_set_ipv4(fi->value, &ipv4);
5185 | }
5186 |
5187 | /* Add a FT_IPv6 to a proto_tree */
5188 | proto_item *
5189 | proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5190 | unsigned length, const ws_in6_addr *value)
5191 | {
5192 | proto_item *pi;
5193 | header_field_info *hfinfo;
5194 |
5195 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5196 |
5197 | 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", 5197 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5197, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5197, "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", 5197, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5198 |
5199 | 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", 5199 , ((hfinfo))->abbrev))));
5200 |
5201 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5202 | proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5203 |
5204 | return pi;
5205 | }
5206 |
5207 | proto_item *
5208 | proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5209 | unsigned start, unsigned length,
5210 | const ws_in6_addr *value_ptr,
5211 | const char *format, ...)
5212 | {
5213 | proto_item *pi;
5214 | va_list ap;
5215 |
5216 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5217 | if (pi != tree) {
5218 | va_start(ap, format)__builtin_va_start(ap, format);
5219 | proto_tree_set_representation_value(pi, format, ap);
5220 | va_end(ap)__builtin_va_end(ap);
5221 | }
5222 |
5223 | return pi;
5224 | }
5225 |
5226 | proto_item *
5227 | proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5228 | unsigned start, unsigned length,
5229 | const ws_in6_addr *value_ptr,
5230 | const char *format, ...)
5231 | {
5232 | proto_item *pi;
5233 | va_list ap;
5234 |
5235 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5236 | if (pi != tree) {
5237 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5237, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5238 |
5239 | va_start(ap, format)__builtin_va_start(ap, format);
5240 | proto_tree_set_representation(pi, format, ap);
5241 | va_end(ap)__builtin_va_end(ap);
5242 | }
5243 |
5244 | return pi;
5245 | }
5246 |
5247 | /* Set the FT_IPv6 value */
5248 | static void
5249 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5250 | {
5251 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5251, "value != ((void*)0)" ))));
5252 | ipv6_addr_and_prefix ipv6;
5253 | ipv6.addr = *value;
5254 | ipv6.prefix = 128;
5255 | fvalue_set_ipv6(fi->value, &ipv6);
5256 | }
5257 |
5258 | static void
5259 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5260 | {
5261 | proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5262 | }
5263 |
5264 | /* Set the FT_FCWWN value */
5265 | static void
5266 | proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5267 | {
5268 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5268, "value_ptr != ((void*)0)" ))));
5269 | fvalue_set_fcwwn(fi->value, value_ptr);
5270 | }
5271 |
5272 | static void
5273 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5274 | {
5275 | proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5276 | }
5277 |
5278 | /* Add a FT_GUID to a proto_tree */
5279 | proto_item *
5280 | proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5281 | unsigned length, const e_guid_t *value_ptr)
5282 | {
5283 | proto_item *pi;
5284 | header_field_info *hfinfo;
5285 |
5286 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5287 |
5288 | 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", 5288 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5288, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5288, "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", 5288, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5289 |
5290 | 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", 5290 , ((hfinfo))->abbrev))));
5291 |
5292 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5293 | proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5294 |
5295 | return pi;
5296 | }
5297 |
5298 | proto_item *
5299 | proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5300 | unsigned start, unsigned length,
5301 | const e_guid_t *value_ptr,
5302 | const char *format, ...)
5303 | {
5304 | proto_item *pi;
5305 | va_list ap;
5306 |
5307 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5308 | if (pi != tree) {
5309 | va_start(ap, format)__builtin_va_start(ap, format);
5310 | proto_tree_set_representation_value(pi, format, ap);
5311 | va_end(ap)__builtin_va_end(ap);
5312 | }
5313 |
5314 | return pi;
5315 | }
5316 |
5317 | proto_item *
5318 | proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5319 | unsigned start, unsigned length, const e_guid_t *value_ptr,
5320 | const char *format, ...)
5321 | {
5322 | proto_item *pi;
5323 | va_list ap;
5324 |
5325 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5326 | if (pi != tree) {
5327 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5327, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5328 |
5329 | va_start(ap, format)__builtin_va_start(ap, format);
5330 | proto_tree_set_representation(pi, format, ap);
5331 | va_end(ap)__builtin_va_end(ap);
5332 | }
5333 |
5334 | return pi;
5335 | }
5336 |
5337 | /* Set the FT_GUID value */
5338 | static void
5339 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5340 | {
5341 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5341, "value_ptr != ((void*)0)" ))));
5342 | fvalue_set_guid(fi->value, value_ptr);
5343 | }
5344 |
5345 | static void
5346 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start,
5347 | const unsigned encoding)
5348 | {
5349 | e_guid_t guid;
5350 |
5351 | tvb_get_guid(tvb, start, &guid, encoding);
5352 | proto_tree_set_guid(fi, &guid);
5353 | }
5354 |
5355 | /* Add a FT_OID to a proto_tree */
5356 | proto_item *
5357 | proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5358 | unsigned length, const uint8_t* value_ptr)
5359 | {
5360 | proto_item *pi;
5361 | header_field_info *hfinfo;
5362 |
5363 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5364 |
5365 | TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5365 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5365, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5365, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5365, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5366 |
5367 | DISSECTOR_ASSERT_FIELD_TYPE(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", 5367 , ((hfinfo))->abbrev))));
5368 |
5369 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5370 | proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5371 |
5372 | return pi;
5373 | }
5374 |
5375 | proto_item *
5376 | proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5377 | unsigned start, unsigned length,
5378 | const uint8_t* value_ptr,
5379 | const char *format, ...)
5380 | {
5381 | proto_item *pi;
5382 | va_list ap;
5383 |
5384 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5385 | if (pi != tree) {
5386 | va_start(ap, format)__builtin_va_start(ap, format);
5387 | proto_tree_set_representation_value(pi, format, ap);
5388 | va_end(ap)__builtin_va_end(ap);
5389 | }
5390 |
5391 | return pi;
5392 | }
5393 |
5394 | proto_item *
5395 | proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5396 | unsigned start, unsigned length, const uint8_t* value_ptr,
5397 | const char *format, ...)
5398 | {
5399 | proto_item *pi;
5400 | va_list ap;
5401 |
5402 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5403 | if (pi != tree) {
5404 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5404, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5405 |
5406 | va_start(ap, format)__builtin_va_start(ap, format);
5407 | proto_tree_set_representation(pi, format, ap);
5408 | va_end(ap)__builtin_va_end(ap);
5409 | }
5410 |
5411 | return pi;
5412 | }
5413 |
5414 | /* Set the FT_OID value */
5415 | static void
5416 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, unsigned length)
5417 | {
5418 | GByteArray *bytes;
5419 |
5420 | 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", 5420, "value_ptr != ((void*)0) || length == 0" ))));
5421 |
5422 | bytes = g_byte_array_new();
5423 | if (length > 0) {
5424 | g_byte_array_append(bytes, value_ptr, length);
5425 | }
5426 | fvalue_set_byte_array(fi->value, bytes);
5427 | }
5428 |
5429 | static void
5430 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5431 | {
5432 | proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5433 | }
5434 |
5435 | /* Set the FT_SYSTEM_ID value */
5436 | static void
5437 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, unsigned length)
5438 | {
5439 | GByteArray *bytes;
5440 |
5441 | 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", 5441, "value_ptr != ((void*)0) || length == 0" ))));
5442 |
5443 | bytes = g_byte_array_new();
5444 | if (length > 0) {
5445 | g_byte_array_append(bytes, value_ptr, length);
5446 | }
5447 | fvalue_set_byte_array(fi->value, bytes);
5448 | }
5449 |
5450 | static void
5451 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, unsigned length)
5452 | {
5453 | proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5454 | }
5455 |
5456 | /* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5457 | * proto_tree. Creates own copy of string, and frees it when the proto_tree
5458 | * is destroyed. */
5459 | proto_item *
5460 | proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5461 | int length, const char* value)
5462 | {
5463 | proto_item *pi;
5464 | header_field_info *hfinfo;
5465 | int item_length;
5466 |
5467 | 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", 5467, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5467, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5467, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
5468 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5469 | /*
5470 | * Special case - if the length is 0, skip the test, so that
5471 | * we can have an empty string right after the end of the
5472 | * packet. (This handles URL-encoded forms where the last field
5473 | * has no value so the form ends right after the =.)
5474 | *
5475 | * XXX - length zero makes sense for FT_STRING, and more or less
5476 | * for FT_STRINGZTRUNC, and FT_STRINGZPAD, but doesn't make sense
5477 | * for FT_STRINGZ (except that a number of fields that should be
5478 | * one of the others are actually registered as FT_STRINGZ.)
5479 | */
5480 | if (item_length != 0)
5481 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5482 |
5483 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5484 |
5485 | 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", 5485 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5485, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5485, "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", 5485, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5486 |
5487 | 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", 5487, ((hfinfo))->abbrev))));
5488 |
5489 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5490 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5490, "length >= 0" ))));
5491 |
5492 | 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", 5492, __func__, value, -1, __uni_endptr); } } while (0); } } while (0);
5493 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5494 |
5495 | return pi;
5496 | }
5497 |
5498 | proto_item *
5499 | proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5500 | unsigned start, int length, const char* value,
5501 | const char *format,
5502 | ...)
5503 | {
5504 | proto_item *pi;
5505 | va_list ap;
5506 |
5507 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5508 | if (pi != tree) {
5509 | va_start(ap, format)__builtin_va_start(ap, format);
5510 | proto_tree_set_representation_value(pi, format, ap);
5511 | va_end(ap)__builtin_va_end(ap);
5512 | }
5513 |
5514 | return pi;
5515 | }
5516 |
5517 | proto_item *
5518 | proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5519 | unsigned start, int length, const char* value,
5520 | const char *format, ...)
5521 | {
5522 | proto_item *pi;
5523 | va_list ap;
5524 |
5525 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5526 | if (pi != tree) {
5527 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5527, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5528 |
5529 | va_start(ap, format)__builtin_va_start(ap, format);
5530 | proto_tree_set_representation(pi, format, ap);
5531 | va_end(ap)__builtin_va_end(ap);
5532 | }
5533 |
5534 | return pi;
5535 | }
5536 |
5537 | /* Set the FT_STRING value */
5538 | static void
5539 | proto_tree_set_string(field_info *fi, const char* value)
5540 | {
5541 | if (value) {
5542 | fvalue_set_string(fi->value, value);
5543 | } else {
5544 | /*
5545 | * XXX - why is a null value for a string field
5546 | * considered valid?
5547 | */
5548 | fvalue_set_string(fi->value, "[ Null ]");
5549 | }
5550 | }
5551 |
5552 | /* Set the FT_AX25 value */
5553 | static void
5554 | proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5555 | {
5556 | fvalue_set_ax25(fi->value, value);
5557 | }
5558 |
5559 | static void
5560 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5561 | {
5562 | proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5563 | }
5564 |
5565 | /* Set the FT_VINES value */
5566 | static void
5567 | proto_tree_set_vines(field_info *fi, const uint8_t* value)
5568 | {
5569 | fvalue_set_vines(fi->value, value);
5570 | }
5571 |
5572 | static void
5573 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5574 | {
5575 | proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5576 | }
5577 |
5578 | /* Add a FT_ETHER to a proto_tree */
5579 | proto_item *
5580 | proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5581 | unsigned length, const uint8_t* value)
5582 | {
5583 | proto_item *pi;
5584 | header_field_info *hfinfo;
5585 |
5586 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5587 |
5588 | 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", 5588 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5588, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5588, "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", 5588, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5589 |
5590 | 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", 5590, ((hfinfo))->abbrev))));
5591 |
5592 | pi = proto_tree_add_pi_unsigned(tree, hfinfo, tvb, start, &length);
5593 | proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5594 |
5595 | return pi;
5596 | }
5597 |
5598 | proto_item *
5599 | proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5600 | unsigned start, unsigned length, const uint8_t* value,
5601 | const char *format, ...)
5602 | {
5603 | proto_item *pi;
5604 | va_list ap;
5605 |
5606 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5607 | if (pi != tree) {
5608 | va_start(ap, format)__builtin_va_start(ap, format);
5609 | proto_tree_set_representation_value(pi, format, ap);
5610 | va_end(ap)__builtin_va_end(ap);
5611 | }
5612 |
5613 | return pi;
5614 | }
5615 |
5616 | proto_item *
5617 | proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5618 | unsigned start, unsigned length, const uint8_t* value,
5619 | const char *format, ...)
5620 | {
5621 | proto_item *pi;
5622 | va_list ap;
5623 |
5624 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5625 | if (pi != tree) {
5626 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5626, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5627 |
5628 | va_start(ap, format)__builtin_va_start(ap, format);
5629 | proto_tree_set_representation(pi, format, ap);
5630 | va_end(ap)__builtin_va_end(ap);
5631 | }
5632 |
5633 | return pi;
5634 | }
5635 |
5636 | /* Set the FT_ETHER value */
5637 | static void
5638 | proto_tree_set_ether(field_info *fi, const uint8_t* value)
5639 | {
5640 | fvalue_set_ether(fi->value, value);
5641 | }
5642 |
5643 | static void
5644 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, unsigned start)
5645 | {
5646 | proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5647 | }
5648 |
5649 | /* Add a FT_BOOLEAN to a proto_tree */
5650 | proto_item *
5651 | proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5652 | int length, uint64_t value)
5653 | {
5654 | proto_item *pi;
5655 | header_field_info *hfinfo;
5656 |
5657 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5658 |
5659 | 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", 5659 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5659, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5659, "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", 5659, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5660 |
5661 | 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" , 5661, ((hfinfo))->abbrev))));
5662 |
5663 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5664 | proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5665 |
5666 | return pi;
5667 | }
5668 |
5669 | proto_item *
5670 | proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5671 | tvbuff_t *tvb, unsigned start, int length,
5672 | uint64_t value, const char *format, ...)
5673 | {
5674 | proto_item *pi;
5675 | va_list ap;
5676 |
5677 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5678 | if (pi != tree) {
5679 | va_start(ap, format)__builtin_va_start(ap, format);
5680 | proto_tree_set_representation_value(pi, format, ap);
5681 | va_end(ap)__builtin_va_end(ap);
5682 | }
5683 |
5684 | return pi;
5685 | }
5686 |
5687 | proto_item *
5688 | proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5689 | unsigned start, int length, uint64_t value,
5690 | const char *format, ...)
5691 | {
5692 | proto_item *pi;
5693 | va_list ap;
5694 |
5695 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5696 | if (pi != tree) {
5697 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5697, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5698 |
5699 | va_start(ap, format)__builtin_va_start(ap, format);
5700 | proto_tree_set_representation(pi, format, ap);
5701 | va_end(ap)__builtin_va_end(ap);
5702 | }
5703 |
5704 | return pi;
5705 | }
5706 |
5707 | /* Set the FT_BOOLEAN value */
5708 | static void
5709 | proto_tree_set_boolean(field_info *fi, uint64_t value)
5710 | {
5711 | proto_tree_set_uint64(fi, value);
5712 | }
5713 |
5714 | /* Generate, into "buf", a string showing the bits of a bitfield.
5715 | Return a pointer to the character after that string. */
5716 | static char *
5717 | other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5718 | {
5719 | int i = 0;
5720 | uint64_t bit;
5721 | char *p;
5722 |
5723 | p = buf;
5724 |
5725 | /* This is a devel error. It is safer to stop here. */
5726 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5726, "width >= 1" ))));
5727 |
5728 | bit = UINT64_C(1)1UL << (width - 1);
5729 | for (;;) {
5730 | if (mask & bit) {
5731 | /* This bit is part of the field. Show its value. */
5732 | if (val & bit)
5733 | *p++ = '1';
5734 | else
5735 | *p++ = '0';
5736 | } else {
5737 | /* This bit is not part of the field. */
5738 | *p++ = '.';
5739 | }
5740 | bit >>= 1;
5741 | i++;
5742 | if (i >= width)
5743 | break;
5744 | if (i % 4 == 0)
5745 | *p++ = ' ';
5746 | }
5747 | *p = '\0';
5748 | return p;
5749 | }
5750 |
5751 | static char *
5752 | decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5753 | {
5754 | char *p;
5755 |
5756 | p = other_decode_bitfield_value(buf, val, mask, width);
5757 | p = g_stpcpy(p, " = ");
5758 |
5759 | return p;
5760 | }
5761 |
5762 | static char *
5763 | other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5764 | {
5765 | int i = 0;
5766 | uint64_t bit;
5767 | char *p;
5768 |
5769 | p = buf;
5770 |
5771 | /* This is a devel error. It is safer to stop here. */
5772 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5772, "width >= 1" ))));
5773 |
5774 | bit = UINT64_C(1)1UL << (width - 1);
5775 | for (;;) {
5776 | if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5777 | (mask & bit)) {
5778 | /* This bit is part of the field. Show its value. */
5779 | if (val & bit)
5780 | *p++ = '1';
5781 | else
5782 | *p++ = '0';
5783 | } else {
5784 | /* This bit is not part of the field. */
5785 | *p++ = '.';
5786 | }
5787 | bit >>= 1;
5788 | i++;
5789 | if (i >= width)
5790 | break;
5791 | if (i % 4 == 0)
5792 | *p++ = ' ';
5793 | }
5794 |
5795 | *p = '\0';
5796 | return p;
5797 | }
5798 |
5799 | static char *
5800 | decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5801 | {
5802 | char *p;
5803 |
5804 | p = other_decode_bitfield_varint_value(buf, val, mask, width);
5805 | p = g_stpcpy(p, " = ");
5806 |
5807 | return p;
5808 | }
5809 |
5810 | /* Add a FT_FLOAT to a proto_tree */
5811 | proto_item *
5812 | proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5813 | int length, float value)
5814 | {
5815 | proto_item *pi;
5816 | header_field_info *hfinfo;
5817 |
5818 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5819 |
5820 | 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", 5820 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5820, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5820, "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", 5820, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5821 |
5822 | 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", 5822, ((hfinfo))->abbrev))));
5823 |
5824 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5825 | proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5826 |
5827 | return pi;
5828 | }
5829 |
5830 | proto_item *
5831 | proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5832 | unsigned start, int length, float value,
5833 | const char *format, ...)
5834 | {
5835 | proto_item *pi;
5836 | va_list ap;
5837 |
5838 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5839 | if (pi != tree) {
5840 | va_start(ap, format)__builtin_va_start(ap, format);
5841 | proto_tree_set_representation_value(pi, format, ap);
5842 | va_end(ap)__builtin_va_end(ap);
5843 | }
5844 |
5845 | return pi;
5846 | }
5847 |
5848 | proto_item *
5849 | proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5850 | unsigned start, int length, float value,
5851 | const char *format, ...)
5852 | {
5853 | proto_item *pi;
5854 | va_list ap;
5855 |
5856 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5857 | if (pi != tree) {
5858 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5858, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5859 |
5860 | va_start(ap, format)__builtin_va_start(ap, format);
5861 | proto_tree_set_representation(pi, format, ap);
5862 | va_end(ap)__builtin_va_end(ap);
5863 | }
5864 |
5865 | return pi;
5866 | }
5867 |
5868 | /* Set the FT_FLOAT value */
5869 | static void
5870 | proto_tree_set_float(field_info *fi, float value)
5871 | {
5872 | fvalue_set_floating(fi->value, value);
5873 | }
5874 |
5875 | /* Add a FT_DOUBLE to a proto_tree */
5876 | proto_item *
5877 | proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5878 | int length, double value)
5879 | {
5880 | proto_item *pi;
5881 | header_field_info *hfinfo;
5882 |
5883 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5884 |
5885 | 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", 5885 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5885, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5885, "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", 5885, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5886 |
5887 | 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" , 5887, ((hfinfo))->abbrev))));
5888 |
5889 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5890 | proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5891 |
5892 | return pi;
5893 | }
5894 |
5895 | proto_item *
5896 | proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5897 | unsigned start, int length, double value,
5898 | const char *format, ...)
5899 | {
5900 | proto_item *pi;
5901 | va_list ap;
5902 |
5903 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5904 | if (pi != tree) {
5905 | va_start(ap, format)__builtin_va_start(ap, format);
5906 | proto_tree_set_representation_value(pi, format, ap);
5907 | va_end(ap)__builtin_va_end(ap);
5908 | }
5909 |
5910 | return pi;
5911 | }
5912 |
5913 | proto_item *
5914 | proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5915 | unsigned start, int length, double value,
5916 | const char *format, ...)
5917 | {
5918 | proto_item *pi;
5919 | va_list ap;
5920 |
5921 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5922 | if (pi != tree) {
5923 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5923, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5924 |
5925 | va_start(ap, format)__builtin_va_start(ap, format);
5926 | proto_tree_set_representation(pi, format, ap);
5927 | va_end(ap)__builtin_va_end(ap);
5928 | }
5929 |
5930 | return pi;
5931 | }
5932 |
5933 | /* Set the FT_DOUBLE value */
5934 | static void
5935 | proto_tree_set_double(field_info *fi, double value)
5936 | {
5937 | fvalue_set_floating(fi->value, value);
5938 | }
5939 |
5940 | /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5941 | proto_item *
5942 | proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
5943 | int length, uint32_t value)
5944 | {
5945 | proto_item *pi = NULL((void*)0);
5946 | header_field_info *hfinfo;
5947 |
5948 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5949 |
5950 | TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5950 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5950, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5950, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5950, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5951 |
5952 | switch (hfinfo->type) {
5953 | case FT_CHAR:
5954 | case FT_UINT8:
5955 | case FT_UINT16:
5956 | case FT_UINT24:
5957 | case FT_UINT32:
5958 | case FT_FRAMENUM:
5959 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5960 | proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5961 | break;
5962 |
5963 | default:
5964 | 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)
5965 | 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);
5966 | }
5967 |
5968 | return pi;
5969 | }
5970 |
5971 | proto_item *
5972 | proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5973 | unsigned start, int length, uint32_t value,
5974 | const char *format, ...)
5975 | {
5976 | proto_item *pi;
5977 | va_list ap;
5978 |
5979 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5980 | if (pi != tree) {
5981 | va_start(ap, format)__builtin_va_start(ap, format);
5982 | proto_tree_set_representation_value(pi, format, ap);
5983 | va_end(ap)__builtin_va_end(ap);
5984 | }
5985 |
5986 | return pi;
5987 | }
5988 |
5989 | proto_item *
5990 | proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5991 | unsigned start, int length, uint32_t value,
5992 | const char *format, ...)
5993 | {
5994 | proto_item *pi;
5995 | va_list ap;
5996 |
5997 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5998 | if (pi != tree) {
5999 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5999, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6000 |
6001 | va_start(ap, format)__builtin_va_start(ap, format);
6002 | proto_tree_set_representation(pi, format, ap);
6003 | va_end(ap)__builtin_va_end(ap);
6004 | }
6005 |
6006 | return pi;
6007 | }
6008 |
6009 | /* Set the FT_UINT{8,16,24,32} value */
6010 | static void
6011 | proto_tree_set_uint(field_info *fi, uint32_t value)
6012 | {
6013 | const header_field_info *hfinfo;
6014 | uint32_t integer;
6015 |
6016 | hfinfo = fi->hfinfo;
6017 | integer = value;
6018 |
6019 | if (hfinfo->bitmask) {
6020 | /* Mask out irrelevant portions */
6021 | integer &= (uint32_t)(hfinfo->bitmask);
6022 |
6023 | /* Shift bits */
6024 | integer >>= hfinfo_bitshift(hfinfo);
6025 |
6026 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6027 | 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);
6028 | }
6029 |
6030 | fvalue_set_uinteger(fi->value, integer);
6031 | }
6032 |
6033 | /* Add FT_UINT{40,48,56,64} to a proto_tree */
6034 | proto_item *
6035 | proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6036 | int length, uint64_t value)
6037 | {
6038 | proto_item *pi = NULL((void*)0);
6039 | header_field_info *hfinfo;
6040 |
6041 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6042 |
6043 | 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", 6043 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6043, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6043, "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", 6043, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6044 |
6045 | switch (hfinfo->type) {
6046 | case FT_UINT40:
6047 | case FT_UINT48:
6048 | case FT_UINT56:
6049 | case FT_UINT64:
6050 | case FT_FRAMENUM:
6051 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6052 | proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
6053 | break;
6054 |
6055 | default:
6056 | 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)
6057 | 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);
6058 | }
6059 |
6060 | return pi;
6061 | }
6062 |
6063 | proto_item *
6064 | proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6065 | unsigned start, int length, uint64_t value,
6066 | const char *format, ...)
6067 | {
6068 | proto_item *pi;
6069 | va_list ap;
6070 |
6071 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6072 | if (pi != tree) {
6073 | va_start(ap, format)__builtin_va_start(ap, format);
6074 | proto_tree_set_representation_value(pi, format, ap);
6075 | va_end(ap)__builtin_va_end(ap);
6076 | }
6077 |
6078 | return pi;
6079 | }
6080 |
6081 | proto_item *
6082 | proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6083 | unsigned start, int length, uint64_t value,
6084 | const char *format, ...)
6085 | {
6086 | proto_item *pi;
6087 | va_list ap;
6088 |
6089 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6090 | if (pi != tree) {
6091 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6091, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6092 |
6093 | va_start(ap, format)__builtin_va_start(ap, format);
6094 | proto_tree_set_representation(pi, format, ap);
6095 | va_end(ap)__builtin_va_end(ap);
6096 | }
6097 |
6098 | return pi;
6099 | }
6100 |
6101 | /* Set the FT_UINT{40,48,56,64} value */
6102 | static void
6103 | proto_tree_set_uint64(field_info *fi, uint64_t value)
6104 | {
6105 | const header_field_info *hfinfo;
6106 | uint64_t integer;
6107 |
6108 | hfinfo = fi->hfinfo;
6109 | integer = value;
6110 |
6111 | if (hfinfo->bitmask) {
6112 | /* Mask out irrelevant portions */
6113 | integer &= hfinfo->bitmask;
6114 |
6115 | /* Shift bits */
6116 | integer >>= hfinfo_bitshift(hfinfo);
6117 |
6118 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6119 | 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);
6120 | }
6121 |
6122 | fvalue_set_uinteger64(fi->value, integer);
6123 | }
6124 |
6125 | /* Add FT_INT{8,16,24,32} to a proto_tree */
6126 | proto_item *
6127 | proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6128 | int length, int32_t value)
6129 | {
6130 | proto_item *pi = NULL((void*)0);
6131 | header_field_info *hfinfo;
6132 |
6133 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6134 |
6135 | 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", 6135 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6135, "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", 6135, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6136 |
6137 | switch (hfinfo->type) {
6138 | case FT_INT8:
6139 | case FT_INT16:
6140 | case FT_INT24:
6141 | case FT_INT32:
6142 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6143 | proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6144 | break;
6145 |
6146 | default:
6147 | 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)
6148 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
6149 | }
6150 |
6151 | return pi;
6152 | }
6153 |
6154 | proto_item *
6155 | proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6156 | unsigned start, int length, int32_t value,
6157 | const char *format, ...)
6158 | {
6159 | proto_item *pi;
6160 | va_list ap;
6161 |
6162 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6163 | if (pi != tree) {
6164 | va_start(ap, format)__builtin_va_start(ap, format);
6165 | proto_tree_set_representation_value(pi, format, ap);
6166 | va_end(ap)__builtin_va_end(ap);
6167 | }
6168 |
6169 | return pi;
6170 | }
6171 |
6172 | proto_item *
6173 | proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6174 | unsigned start, int length, int32_t value,
6175 | const char *format, ...)
6176 | {
6177 | proto_item *pi;
6178 | va_list ap;
6179 |
6180 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6181 | if (pi != tree) {
6182 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6182, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6183 |
6184 | va_start(ap, format)__builtin_va_start(ap, format);
6185 | proto_tree_set_representation(pi, format, ap);
6186 | va_end(ap)__builtin_va_end(ap);
6187 | }
6188 |
6189 | return pi;
6190 | }
6191 |
6192 | /* Set the FT_INT{8,16,24,32} value */
6193 | static void
6194 | proto_tree_set_int(field_info *fi, int32_t value)
6195 | {
6196 | const header_field_info *hfinfo;
6197 | uint32_t integer;
6198 | int no_of_bits;
6199 |
6200 | hfinfo = fi->hfinfo;
6201 | integer = (uint32_t) value;
6202 |
6203 | if (hfinfo->bitmask) {
6204 | /* Mask out irrelevant portions */
6205 | integer &= (uint32_t)(hfinfo->bitmask);
6206 |
6207 | /* Shift bits */
6208 | integer >>= hfinfo_bitshift(hfinfo);
6209 |
6210 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6211 | integer = ws_sign_ext32(integer, no_of_bits);
6212 |
6213 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6214 | 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);
6215 | }
6216 |
6217 | fvalue_set_sinteger(fi->value, integer);
6218 | }
6219 |
6220 | /* Add FT_INT{40,48,56,64} to a proto_tree */
6221 | proto_item *
6222 | proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6223 | int length, int64_t value)
6224 | {
6225 | proto_item *pi = NULL((void*)0);
6226 | header_field_info *hfinfo;
6227 |
6228 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6229 |
6230 | 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", 6230 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6230, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6230, "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", 6230, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6231 |
6232 | switch (hfinfo->type) {
6233 | case FT_INT40:
6234 | case FT_INT48:
6235 | case FT_INT56:
6236 | case FT_INT64:
6237 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6238 | proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6239 | break;
6240 |
6241 | default:
6242 | 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)
6243 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
6244 | }
6245 |
6246 | return pi;
6247 | }
6248 |
6249 | proto_item *
6250 | proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6251 | unsigned start, int length, int64_t value,
6252 | const char *format, ...)
6253 | {
6254 | proto_item *pi;
6255 | va_list ap;
6256 |
6257 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6258 | if (pi != tree) {
6259 | va_start(ap, format)__builtin_va_start(ap, format);
6260 | proto_tree_set_representation_value(pi, format, ap);
6261 | va_end(ap)__builtin_va_end(ap);
6262 | }
6263 |
6264 | return pi;
6265 | }
6266 |
6267 | /* Set the FT_INT{40,48,56,64} value */
6268 | static void
6269 | proto_tree_set_int64(field_info *fi, int64_t value)
6270 | {
6271 | const header_field_info *hfinfo;
6272 | uint64_t integer;
6273 | int no_of_bits;
6274 |
6275 | hfinfo = fi->hfinfo;
6276 | integer = value;
6277 |
6278 | if (hfinfo->bitmask) {
6279 | /* Mask out irrelevant portions */
6280 | integer &= hfinfo->bitmask;
6281 |
6282 | /* Shift bits */
6283 | integer >>= hfinfo_bitshift(hfinfo);
6284 |
6285 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6286 | integer = ws_sign_ext64(integer, no_of_bits);
6287 |
6288 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6289 | 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);
6290 | }
6291 |
6292 | fvalue_set_sinteger64(fi->value, integer);
6293 | }
6294 |
6295 | proto_item *
6296 | proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6297 | unsigned start, int length, int64_t value,
6298 | const char *format, ...)
6299 | {
6300 | proto_item *pi;
6301 | va_list ap;
6302 |
6303 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6304 | if (pi != tree) {
6305 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6305, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6306 |
6307 | va_start(ap, format)__builtin_va_start(ap, format);
6308 | proto_tree_set_representation(pi, format, ap);
6309 | va_end(ap)__builtin_va_end(ap);
6310 | }
6311 |
6312 | return pi;
6313 | }
6314 |
6315 | /* Add a FT_EUI64 to a proto_tree */
6316 | proto_item *
6317 | proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, unsigned start,
6318 | int length, const uint64_t value)
6319 | {
6320 | proto_item *pi;
6321 | header_field_info *hfinfo;
6322 |
6323 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6324 |
6325 | 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", 6325 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6325, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6325, "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", 6325, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6326 |
6327 | 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", 6327, ((hfinfo))->abbrev))));
6328 |
6329 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6330 | proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6331 |
6332 | return pi;
6333 | }
6334 |
6335 | proto_item *
6336 | proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6337 | unsigned start, int length, const uint64_t value,
6338 | const char *format, ...)
6339 | {
6340 | proto_item *pi;
6341 | va_list ap;
6342 |
6343 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6344 | if (pi != tree) {
6345 | va_start(ap, format)__builtin_va_start(ap, format);
6346 | proto_tree_set_representation_value(pi, format, ap);
6347 | va_end(ap)__builtin_va_end(ap);
6348 | }
6349 |
6350 | return pi;
6351 | }
6352 |
6353 | proto_item *
6354 | proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6355 | unsigned start, int length, const uint64_t value,
6356 | const char *format, ...)
6357 | {
6358 | proto_item *pi;
6359 | va_list ap;
6360 |
6361 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6362 | if (pi != tree) {
6363 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6363, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6364 |
6365 | va_start(ap, format)__builtin_va_start(ap, format);
6366 | proto_tree_set_representation(pi, format, ap);
6367 | va_end(ap)__builtin_va_end(ap);
6368 | }
6369 |
6370 | return pi;
6371 | }
6372 |
6373 | /* Set the FT_EUI64 value */
6374 | static void
6375 | proto_tree_set_eui64(field_info *fi, const uint64_t value)
6376 | {
6377 | uint8_t v[FT_EUI64_LEN8];
6378 | phtonu64(v, value);
6379 | fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6380 | }
6381 |
6382 | static void
6383 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, unsigned start, const unsigned encoding)
6384 | {
6385 | if (encoding)
6386 | {
6387 | proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6388 | } else {
6389 | proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6390 | }
6391 | }
6392 |
6393 | proto_item *
6394 | proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6395 | const mac_hf_list_t *list_generic,
6396 | int idx, tvbuff_t *tvb,
6397 | proto_tree *tree, unsigned offset)
6398 | {
6399 | uint8_t addr[6];
6400 | const char *addr_name = NULL((void*)0);
6401 | const char *oui_name = NULL((void*)0);
6402 | proto_item *addr_item = NULL((void*)0);
6403 | proto_tree *addr_tree = NULL((void*)0);
6404 | proto_item *ret_val = NULL((void*)0);
6405 |
6406 | if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6407 | return NULL((void*)0);
6408 | }
6409 |
6410 | /* Resolve what we can of the address */
6411 | tvb_memcpy(tvb, addr, offset, sizeof addr);
6412 | if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6413 | addr_name = get_ether_name(addr);
6414 | }
6415 | if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6416 | oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6417 | }
6418 |
6419 | /* Add the item for the specific address type */
6420 | ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6421 | if (idx >= 0) {
6422 | addr_tree = proto_item_add_subtree(ret_val, idx);
6423 | }
6424 | else {
6425 | addr_tree = tree;
6426 | }
6427 |
6428 | if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6429 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6430 | tvb, offset, 6, addr_name);
6431 | proto_item_set_generated(addr_item);
6432 | proto_item_set_hidden(addr_item);
6433 | }
6434 |
6435 | if (list_specific->hf_oui != NULL((void*)0)) {
6436 | addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6437 | proto_item_set_generated(addr_item);
6438 | proto_item_set_hidden(addr_item);
6439 |
6440 | if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6441 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6442 | proto_item_set_generated(addr_item);
6443 | proto_item_set_hidden(addr_item);
6444 | }
6445 | }
6446 |
6447 | if (list_specific->hf_lg != NULL((void*)0)) {
6448 | proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6449 | }
6450 | if (list_specific->hf_ig != NULL((void*)0)) {
6451 | proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6452 | }
6453 |
6454 | /* Were we given a list for generic address fields? If not, stop here */
6455 | if (list_generic == NULL((void*)0)) {
6456 | return ret_val;
6457 | }
6458 |
6459 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6460 | proto_item_set_hidden(addr_item);
6461 |
6462 | if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6463 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6464 | tvb, offset, 6, addr_name);
6465 | proto_item_set_generated(addr_item);
6466 | proto_item_set_hidden(addr_item);
6467 | }
6468 |
6469 | if (list_generic->hf_oui != NULL((void*)0)) {
6470 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6471 | proto_item_set_generated(addr_item);
6472 | proto_item_set_hidden(addr_item);
6473 |
6474 | if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6475 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6476 | proto_item_set_generated(addr_item);
6477 | proto_item_set_hidden(addr_item);
6478 | }
6479 | }
6480 |
6481 | if (list_generic->hf_lg != NULL((void*)0)) {
6482 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6483 | proto_item_set_hidden(addr_item);
6484 | }
6485 | if (list_generic->hf_ig != NULL((void*)0)) {
6486 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6487 | proto_item_set_hidden(addr_item);
6488 | }
6489 | return ret_val;
6490 | }
6491 |
6492 | static proto_item *
6493 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6494 | {
6495 | proto_node *pnode, *tnode, *sibling;
6496 | field_info *tfi;
6497 | unsigned depth = 1;
6498 |
6499 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6499, __func__, "assertion failed: %s", "tree" ); } while (0);
6500 |
6501 | /*
6502 | * Restrict our depth. proto_tree_traverse_pre_order and
6503 | * proto_tree_traverse_post_order (and possibly others) are recursive
6504 | * so we need to be mindful of our stack size.
6505 | */
6506 | if (tree->first_child == NULL((void*)0)) {
6507 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6508 | depth++;
6509 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6510 | 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__)), 6513)))
6511 | "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__)), 6513)))
6512 | 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__)), 6513)))
6513 | 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__)), 6513)));
6514 | }
6515 | }
6516 | }
6517 |
6518 | /*
6519 | * Make sure "tree" is ready to have subtrees under it, by
6520 | * checking whether it's been given an ett_ value.
6521 | *
6522 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6523 | * node of the protocol tree. That node is not displayed,
6524 | * so it doesn't need an ett_ value to remember whether it
6525 | * was expanded.
6526 | */
6527 | tnode = tree;
6528 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6529 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6530 | 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" , 6531)
6531 | 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" , 6531);
6532 | /* XXX - is it safe to continue here? */
6533 | }
6534 |
6535 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6536 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6537 | pnode->parent = tnode;
6538 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6539 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6540 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6541 |
6542 | if (tnode->last_child != NULL((void*)0)) {
6543 | sibling = tnode->last_child;
6544 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6544, "sibling->next == ((void*)0)" ))));
6545 | sibling->next = pnode;
6546 | } else
6547 | tnode->first_child = pnode;
6548 | tnode->last_child = pnode;
6549 |
6550 | /* We should not be adding a fake node for an interesting field */
6551 | 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", 6551, __func__, "assertion failed: %s" , "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT" ); } while (0);
6552 |
6553 | /* XXX - Should the proto_item have a header_field_info member, at least
6554 | * for faked items, to know what hfi was faked? (Some dissectors look at
6555 | * the tree items directly.)
6556 | */
6557 | return (proto_item *)pnode;
6558 | }
6559 |
6560 | /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6561 | static proto_item *
6562 | proto_tree_add_node(proto_tree *tree, field_info *fi)
6563 | {
6564 | proto_node *pnode, *tnode, *sibling;
6565 | field_info *tfi;
6566 | unsigned depth = 1;
6567 |
6568 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6568, __func__, "assertion failed: %s", "tree" ); } while (0);
6569 |
6570 | /*
6571 | * Restrict our depth. proto_tree_traverse_pre_order and
6572 | * proto_tree_traverse_post_order (and possibly others) are recursive
6573 | * so we need to be mindful of our stack size.
6574 | */
6575 | if (tree->first_child == NULL((void*)0)) {
6576 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6577 | depth++;
6578 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6579 | fvalue_free(fi->value);
6580 | fi->value = NULL((void*)0);
6581 | 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__)), 6584)))
6582 | "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__)), 6584)))
6583 | 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__)), 6584)))
6584 | 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__)), 6584)));
6585 | }
6586 | }
6587 | }
6588 |
6589 | /*
6590 | * Make sure "tree" is ready to have subtrees under it, by
6591 | * checking whether it's been given an ett_ value.
6592 | *
6593 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6594 | * node of the protocol tree. That node is not displayed,
6595 | * so it doesn't need an ett_ value to remember whether it
6596 | * was expanded.
6597 | */
6598 | tnode = tree;
6599 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6600 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6601 | /* Since we are not adding fi to a node, its fvalue won't get
6602 | * freed by proto_tree_free_node(), so free it now.
6603 | */
6604 | fvalue_free(fi->value);
6605 | fi->value = NULL((void*)0);
6606 | 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", 6607)
6607 | 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", 6607);
6608 | /* XXX - is it safe to continue here? */
6609 | }
6610 |
6611 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6612 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6613 | pnode->parent = tnode;
6614 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6615 | PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6616 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6617 |
6618 | if (tnode->last_child != NULL((void*)0)) {
6619 | sibling = tnode->last_child;
6620 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6620, "sibling->next == ((void*)0)" ))));
6621 | sibling->next = pnode;
6622 | } else
6623 | tnode->first_child = pnode;
6624 | tnode->last_child = pnode;
6625 |
6626 | tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6627 |
6628 | return (proto_item *)pnode;
6629 | }
6630 |
6631 |
6632 | /* Generic way to allocate field_info and add to proto_tree.
6633 | * Sets *pfi to address of newly-allocated field_info struct */
6634 | static proto_item *
6635 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6636 | int *length)
6637 | {
6638 | proto_item *pi;
6639 | field_info *fi;
6640 | int item_length;
6641 |
6642 | get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6643 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6644 | pi = proto_tree_add_node(tree, fi);
6645 |
6646 | return pi;
6647 | }
6648 |
6649 | /* Generic way to allocate field_info and add to proto_tree with unsigned length.
6650 | * Eventually this should replace the other function.
6651 | * Sets *pfi to address of newly-allocated field_info struct */
6652 | static proto_item *
6653 | proto_tree_add_pi_unsigned(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, unsigned start,
6654 | unsigned *length)
6655 | {
6656 | proto_item *pi;
6657 | field_info *fi;
6658 | unsigned item_length;
6659 |
6660 | get_hfi_length_unsigned(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6661 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6662 | pi = proto_tree_add_node(tree, fi);
6663 |
6664 | return pi;
6665 | }
6666 |
6667 | static void
6668 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start, int *length,
6669 | int *item_length, const unsigned encoding)
6670 | {
6671 | int length_remaining;
6672 |
6673 | /*
6674 | * We only allow a null tvbuff if the item has a zero length,
6675 | * i.e. if there's no data backing it.
6676 | */
6677 | 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", 6677, "tvb != ((void*)0) || *length == 0" ))));
6678 |
6679 | /*
6680 | * XXX - in some protocols, there are 32-bit unsigned length
6681 | * fields, so lengths in protocol tree and tvbuff routines
6682 | * should really be unsigned. We should have, for those
6683 | * field types for which "to the end of the tvbuff" makes sense,
6684 | * additional routines that take no length argument and
6685 | * add fields that run to the end of the tvbuff.
6686 | */
6687 | if (*length == -1) {
6688 | /*
6689 | * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6690 | * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6691 | * of -1 means "set the length to what remains in the
6692 | * tvbuff".
6693 | *
6694 | * The assumption is either that
6695 | *
6696 | * 1) the length of the item can only be determined
6697 | * by dissection (typically true of items with
6698 | * subitems, which are probably FT_NONE or
6699 | * FT_PROTOCOL)
6700 | *
6701 | * or
6702 | *
6703 | * 2) if the tvbuff is "short" (either due to a short
6704 | * snapshot length or due to lack of reassembly of
6705 | * fragments/segments/whatever), we want to display
6706 | * what's available in the field (probably FT_BYTES
6707 | * or FT_STRING) and then throw an exception later
6708 | *
6709 | * or
6710 | *
6711 | * 3) the field is defined to be "what's left in the
6712 | * packet"
6713 | *
6714 | * so we set the length to what remains in the tvbuff so
6715 | * that, if we throw an exception while dissecting, it
6716 | * has what is probably the right value.
6717 | *
6718 | * For FT_STRINGZ, it means "the string is null-terminated,
6719 | * not null-padded; set the length to the actual length
6720 | * of the string", and if the tvbuff if short, we just
6721 | * throw an exception.
6722 | *
6723 | * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6724 | * it means "find the end of the string",
6725 | * and if the tvbuff if short, we just throw an exception.
6726 | *
6727 | * It's not valid for any other type of field. For those
6728 | * fields, we treat -1 the same way we treat other
6729 | * negative values - we assume the length is a Really
6730 | * Big Positive Number, and throw a ReportedBoundsError
6731 | * exception, under the assumption that the Really Big
6732 | * Length would run past the end of the packet.
6733 | */
6734 | 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 )))) {
6735 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6736 | /*
6737 | * Leave the length as -1, so our caller knows
6738 | * it was -1.
6739 | */
6740 | *item_length = *length;
6741 | return;
6742 | } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6743 | switch (tvb_get_uint8(tvb, start) >> 6)
6744 | {
6745 | case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6746 | *item_length = 1;
6747 | break;
6748 | case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6749 | *item_length = 2;
6750 | break;
6751 | case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6752 | *item_length = 4;
6753 | break;
6754 | case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6755 | *item_length = 8;
6756 | break;
6757 | }
6758 | }
6759 | }
6760 |
6761 | switch (hfinfo->type) {
6762 |
6763 | case FT_PROTOCOL:
6764 | case FT_NONE:
6765 | case FT_BYTES:
6766 | case FT_STRING:
6767 | case FT_STRINGZPAD:
6768 | case FT_STRINGZTRUNC:
6769 | /*
6770 | * We allow FT_PROTOCOLs to be zero-length -
6771 | * for example, an ONC RPC NULL procedure has
6772 | * neither arguments nor reply, so the
6773 | * payload for that protocol is empty.
6774 | *
6775 | * We also allow the others to be zero-length -
6776 | * because that's the way the code has been for a
6777 | * long, long time.
6778 | *
6779 | * However, we want to ensure that the start
6780 | * offset is not *past* the byte past the end
6781 | * of the tvbuff: we throw an exception in that
6782 | * case.
6783 | */
6784 | *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6785 | DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6785, "*length >= 0" ))));
6786 | break;
6787 |
6788 | case FT_STRINGZ:
6789 | /*
6790 | * Leave the length as -1, so our caller knows
6791 | * it was -1.
6792 | */
6793 | break;
6794 |
6795 | default:
6796 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6797 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 6797));
6798 | }
6799 | *item_length = *length;
6800 | } else {
6801 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6802 | /*
6803 | * These types are for interior nodes of the
6804 | * tree, and don't have data associated with
6805 | * them; if the length is negative (XXX - see
6806 | * above) or goes past the end of the tvbuff,
6807 | * cut it short at the end of the tvbuff.
6808 | * That way, if this field is selected in
6809 | * Wireshark, we don't highlight stuff past
6810 | * the end of the data.
6811 | *
6812 | * If we don't have a tvb, then length must be zero,
6813 | * per the DISSECTOR_ASSERT() above.
6814 | *
6815 | * If we do have a tvb, and the length requested is
6816 | * nonzero, we want to ensure that the start offset
6817 | * is not *past* the byte past the end of the tvbuff
6818 | * data: we throw an exception in that case as above.
6819 | */
6820 | if (tvb && *length) {
6821 | length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6822 | if (*length < 0 ||
6823 | (*length > 0 &&
6824 | (length_remaining < *length)))
6825 | *length = length_remaining;
6826 | }
6827 | }
6828 | *item_length = *length;
6829 | if (*item_length < 0) {
6830 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6831 | }
6832 | }
6833 | }
6834 |
6835 | static void
6836 | get_hfi_length_unsigned(header_field_info* hfinfo, tvbuff_t* tvb, const unsigned start, unsigned* length,
6837 | unsigned* item_length, const unsigned encoding _U___attribute__((unused)))
6838 | {
6839 | unsigned length_remaining;
6840 |
6841 | /*
6842 | * We only allow a null tvbuff if the item has a zero length,
6843 | * i.e. if there's no data backing it.
6844 | */
6845 | 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", 6845, "tvb != ((void*)0) || *length == 0" ))));
6846 |
6847 |
6848 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6849 | /*
6850 | * These types are for interior nodes of the
6851 | * tree, and don't have data associated with
6852 | * them; if the length is negative (XXX - see
6853 | * above) or goes past the end of the tvbuff,
6854 | * cut it short at the end of the tvbuff.
6855 | * That way, if this field is selected in
6856 | * Wireshark, we don't highlight stuff past
6857 | * the end of the data.
6858 | *
6859 | * If we don't have a tvb, then length must be zero,
6860 | * per the DISSECTOR_ASSERT() above.
6861 | *
6862 | * If we do have a tvb, and the length requested is
6863 | * nonzero, we want to ensure that the start offset
6864 | * is not *past* the byte past the end of the tvbuff
6865 | * data: we throw an exception in that case as above.
6866 | * (If the length requested is zero, then it's quite
6867 | * likely that the start offset is the byte past the
6868 | * end, but that's ok.)
6869 | */
6870 | if (tvb && *length) {
6871 | length_remaining = tvb_ensure_captured_length_remaining(tvb, start);
6872 | if (length_remaining < *length) {
6873 | *length = length_remaining;
6874 | }
6875 | }
6876 | }
6877 | *item_length = *length;
6878 | }
6879 |
6880 | static int
6881 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const unsigned start,
6882 | int length, unsigned item_length, const int encoding)
6883 | {
6884 | uint32_t n;
6885 |
6886 | /*
6887 | * We need to get the correct item length here.
6888 | * That's normally done by proto_tree_new_item(),
6889 | * but we won't be calling it.
6890 | */
6891 | switch (hfinfo->type) {
6892 |
6893 | case FT_NONE:
6894 | case FT_PROTOCOL:
6895 | case FT_BYTES:
6896 | /*
6897 | * The length is the specified length.
6898 | */
6899 | break;
6900 |
6901 | case FT_UINT_BYTES:
6902 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6903 | item_length += n;
6904 | if ((int)item_length < length) {
6905 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6906 | }
6907 | break;
6908 |
6909 | /* XXX - make these just FT_UINT? */
6910 | case FT_UINT8:
6911 | case FT_UINT16:
6912 | case FT_UINT24:
6913 | case FT_UINT32:
6914 | case FT_UINT40:
6915 | case FT_UINT48:
6916 | case FT_UINT56:
6917 | case FT_UINT64:
6918 | /* XXX - make these just FT_INT? */
6919 | case FT_INT8:
6920 | case FT_INT16:
6921 | case FT_INT24:
6922 | case FT_INT32:
6923 | case FT_INT40:
6924 | case FT_INT48:
6925 | case FT_INT56:
6926 | case FT_INT64:
6927 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6928 | if (length < -1) {
6929 | report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6930 | }
6931 | if (length == -1) {
6932 | uint64_t dummy;
6933 | /* This can throw an exception */
6934 | /* XXX - do this without fetching the varint? */
6935 | length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6936 | if (length == 0) {
6937 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6938 | }
6939 | }
6940 | item_length = length;
6941 | break;
6942 | }
6943 |
6944 | /*
6945 | * The length is the specified length.
6946 | */
6947 | break;
6948 |
6949 | case FT_BOOLEAN:
6950 | case FT_CHAR:
6951 | case FT_IPv4:
6952 | case FT_IPXNET:
6953 | case FT_IPv6:
6954 | case FT_FCWWN:
6955 | case FT_AX25:
6956 | case FT_VINES:
6957 | case FT_ETHER:
6958 | case FT_EUI64:
6959 | case FT_GUID:
6960 | case FT_OID:
6961 | case FT_REL_OID:
6962 | case FT_SYSTEM_ID:
6963 | case FT_FLOAT:
6964 | case FT_DOUBLE:
6965 | case FT_STRING:
6966 | /*
6967 | * The length is the specified length.
6968 | */
6969 | break;
6970 |
6971 | case FT_STRINGZ:
6972 | if (length < -1) {
6973 | report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6974 | }
6975 | if (length == -1) {
6976 | /* This can throw an exception */
6977 | item_length = tvb_strsize_enc(tvb, start, encoding);
6978 | }
6979 | break;
6980 |
6981 | case FT_UINT_STRING:
6982 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6983 | item_length += n;
6984 | if ((int)item_length < length) {
6985 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6986 | }
6987 | break;
6988 |
6989 | case FT_STRINGZPAD:
6990 | case FT_STRINGZTRUNC:
6991 | case FT_ABSOLUTE_TIME:
6992 | case FT_RELATIVE_TIME:
6993 | case FT_IEEE_11073_SFLOAT:
6994 | case FT_IEEE_11073_FLOAT:
6995 | /*
6996 | * The length is the specified length.
6997 | */
6998 | break;
6999 |
7000 | default:
7001 | 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 ))
7002 | 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 ))
7003 | 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 ))
7004 | 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 ));
7005 | break;
7006 | }
7007 | return item_length;
7008 | }
7009 |
7010 | // This was arbitrarily chosen, but if you're adding 50K items to the tree
7011 | // without advancing the offset you should probably take a long, hard look
7012 | // at what you're doing.
7013 | // We *could* make this a configurable option, but I (Gerald) would like to
7014 | // avoid adding yet another nerd knob.
7015 | # define PROTO_TREE_MAX_IDLE50000 50000
7016 | static field_info *
7017 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
7018 | const unsigned start, const int item_length)
7019 | {
7020 | field_info *fi;
7021 |
7022 | FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo ->pool)), sizeof(field_info)));
7023 |
7024 | fi->hfinfo = hfinfo;
7025 | fi->start = start;
7026 | fi->start += (tvb)?tvb_raw_offset(tvb):0;
7027 | /* add the data source tvbuff */
7028 | fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
7029 |
7030 | // If our start offset hasn't advanced after adding many items it probably
7031 | // means we're in a large or infinite loop.
7032 | if (fi->start > 0) {
7033 | if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
7034 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
7035 | if (PTREE_DATA(tree)((tree)->tree_data)->start_idle_count > PROTO_TREE_MAX_IDLE50000) {
7036 | if (wireshark_abort_on_too_many_items) {
7037 | 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", 7038 , __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000)
7038 | hfinfo->abbrev, PROTO_TREE_MAX_IDLE)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7038 , __func__, "Adding %s would be the %dth consecutive item that doesn't advance the maximum start offset - possible infinite loop" , hfinfo->abbrev, 50000);
7039 | }
7040 | /* PROTO_TREE_MAX_IDLE should be < pref.gui_max_tree_items,
7041 | * but if not, we should hit the max item error earlier,
7042 | * so we shouldn't need to reset the tree count to
7043 | * ensure that the exception handler can add the item. */
7044 | 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)))
7045 | 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)))
7046 | "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)))
7047 | 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)));
7048 | }
7049 | } else {
7050 | PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
7051 | PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
7052 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
7053 | }
7054 | }
7055 | fi->length = item_length;
7056 | fi->tree_type = -1;
7057 | fi->flags = 0;
7058 | if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
7059 | /* If the tree is not visible, set the item hidden, unless we
7060 | * need the representation or length and can't fake them.
7061 | */
7062 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
7063 | FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); } while(0);
7064 | }
7065 | }
7066 | fi->value = fvalue_new(fi->hfinfo->type);
7067 | fi->rep = NULL((void*)0);
7068 |
7069 | fi->appendix_start = 0;
7070 | fi->appendix_length = 0;
7071 |
7072 | fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
7073 | fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
7074 |
7075 | return fi;
7076 | }
7077 |
7078 | static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
7079 | {
7080 | if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
7081 | return 0;
7082 | }
7083 |
7084 | /* Search for field name */
7085 | char *ptr = strstr(representation, hfinfo->name);
7086 | if (!ptr) {
7087 | return 0;
7088 | }
7089 |
7090 | /* Check if field name ends with the ": " delimiter */
7091 | ptr += strlen(hfinfo->name);
7092 | if (strncmp(ptr, ": ", 2) == 0) {
7093 | ptr += 2;
7094 | }
7095 |
7096 | /* Return offset to after field name */
7097 | return ptr - representation;
7098 | }
7099 |
7100 | static size_t label_find_name_pos(const item_label_t *rep)
7101 | {
7102 | size_t name_pos = 0;
7103 |
7104 | /* If the value_pos is too small or too large, we can't find the expected format */
7105 | if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
7106 | return 0;
7107 | }
7108 |
7109 | /* Check if the format looks like "label: value", then set name_pos before ':'. */
7110 | if (rep->representation[rep->value_pos-2] == ':') {
7111 | name_pos = rep->value_pos - 2;
7112 | }
7113 |
7114 | return name_pos;
7115 | }
7116 |
7117 | /* If the protocol tree is to be visible, set the representation of a
7118 | proto_tree entry with the name of the field for the item and with
7119 | the value formatted with the supplied printf-style format and
7120 | argument list. */
7121 | static void
7122 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
7123 | {
7124 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 7124, __func__, "assertion failed: %s", "pi" ); } while (0);
7125 |
7126 | /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
7127 | * items string representation */
7128 | if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
7129 | size_t name_pos, ret = 0;
7130 | char *str;
7131 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7132 | const header_field_info *hf;
7133 |
7134 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7134, "fi"))));
7135 |
7136 | hf = fi->hfinfo;
7137 |
7138 | 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;;
7139 | 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)))) {
7140 | uint64_t val;
7141 | char *p;
7142 |
7143 | 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))
7144 | val = fvalue_get_uinteger(fi->value);
7145 | else
7146 | val = fvalue_get_uinteger64(fi->value);
7147 |
7148 | val <<= hfinfo_bitshift(hf);
7149 |
7150 | p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7151 | ret = (p - fi->rep->representation);
7152 | }
7153 |
7154 | /* put in the hf name */
7155 | 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);
7156 |
7157 | ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const uint8_t*)": ", 0);
7158 | /* If possible, Put in the value of the string */
7159 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7160 | 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" , 7160, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7161 | fi->rep->value_pos = ret;
7162 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7163 | if (ret >= ITEM_LABEL_LENGTH240) {
7164 | /* Uh oh, we don't have enough room. Tell the user
7165 | * that the field is truncated.
7166 | */
7167 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7168 | }
7169 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7170 | }
7171 | }
7172 |
7173 | /* If the protocol tree is to be visible, set the representation of a
7174 | proto_tree entry with the representation formatted with the supplied
7175 | printf-style format and argument list. */
7176 | static void
7177 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7178 | {
7179 | size_t ret; /*tmp return value */
7180 | char *str;
7181 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7182 |
7183 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7183, "fi"))));
7184 |
7185 | if (!proto_item_is_hidden(pi)) {
7186 | 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;;
7187 |
7188 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7189 | 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" , 7189, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7190 | fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7191 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7192 | if (ret >= ITEM_LABEL_LENGTH240) {
7193 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7194 | size_t name_pos = label_find_name_pos(fi->rep);
7195 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7196 | }
7197 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7198 | }
7199 | }
7200 |
7201 | static int
7202 | proto_strlcpy(char *dest, const char *src, size_t dest_size)
7203 | {
7204 | if (dest_size == 0) return 0;
7205 |
7206 | size_t res = g_strlcpy(dest, src, dest_size);
7207 |
7208 | /* At most dest_size - 1 characters will be copied
7209 | * (unless dest_size is 0). */
7210 | if (res >= dest_size)
7211 | res = dest_size - 1;
7212 | return (int) res;
7213 | }
7214 |
7215 | static header_field_info *
7216 | hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7217 | {
7218 | header_field_info *dup_hfinfo;
7219 |
7220 | if (hfinfo->same_name_prev_id == -1)
7221 | return NULL((void*)0);
7222 | 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", 7222 , __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", 7222, "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", 7222, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo ->same_name_prev_id];;
7223 | return dup_hfinfo;
7224 | }
7225 |
7226 | static void
7227 | hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7228 | {
7229 | 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);
7230 | last_field_name = NULL((void*)0);
7231 |
7232 | if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7233 | /* No hfinfo with the same name */
7234 | wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7235 | return;
7236 | }
7237 |
7238 | if (hfinfo->same_name_next) {
7239 | hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7240 | }
7241 |
7242 | if (hfinfo->same_name_prev_id != -1) {
7243 | header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7244 | same_name_prev->same_name_next = hfinfo->same_name_next;
7245 | if (!hfinfo->same_name_next) {
7246 | /* It's always the latest added hfinfo which is stored in gpa_name_map */
7247 | wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7248 | }
7249 | }
7250 | }
7251 |
7252 | int
7253 | proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7254 | {
7255 | const header_field_info *hfinfo = finfo->hfinfo;
7256 | int label_len = 0;
7257 | char *tmp_str;
7258 | const char *str;
7259 | const uint8_t *bytes;
7260 | uint32_t number;
7261 | uint64_t number64;
7262 | const char *hf_str_val;
7263 | char number_buf[NUMBER_LABEL_LENGTH80];
7264 | const char *number_out;
7265 | address addr;
7266 | const ipv4_addr_and_mask *ipv4;
7267 | const ipv6_addr_and_prefix *ipv6;
7268 |
7269 | switch (hfinfo->type) {
7270 |
7271 | case FT_NONE:
7272 | case FT_PROTOCOL:
7273 | return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7274 |
7275 | case FT_UINT_BYTES:
7276 | case FT_BYTES:
7277 | tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7278 | hfinfo,
7279 | fvalue_get_bytes_data(finfo->value),
7280 | (unsigned)fvalue_length2(finfo->value),
7281 | label_str_size);
7282 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7283 | wmem_free(NULL((void*)0), tmp_str);
7284 | break;
7285 |
7286 | case FT_ABSOLUTE_TIME:
7287 | {
7288 | const nstime_t *value = fvalue_get_time(finfo->value);
7289 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7290 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7291 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7292 | }
7293 | if (hfinfo->strings) {
7294 | const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7295 | if (time_string != NULL((void*)0)) {
7296 | label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7297 | break;
7298 | }
7299 | }
7300 | tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7301 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7302 | wmem_free(NULL((void*)0), tmp_str);
7303 | break;
7304 | }
7305 |
7306 | case FT_RELATIVE_TIME:
7307 | tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7308 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7309 | wmem_free(NULL((void*)0), tmp_str);
7310 | break;
7311 |
7312 | case FT_BOOLEAN:
7313 | number64 = fvalue_get_uinteger64(finfo->value);
7314 | label_len = proto_strlcpy(display_label_str,
7315 | tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7316 | break;
7317 |
7318 | case FT_CHAR:
7319 | number = fvalue_get_uinteger(finfo->value);
7320 |
7321 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7322 | char tmp[ITEM_LABEL_LENGTH240];
7323 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7324 |
7325 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7325, "fmtfunc"))));
7326 | fmtfunc(tmp, number);
7327 |
7328 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7329 |
7330 | } else if (hfinfo->strings) {
7331 | number_out = hf_try_val_to_str(number, hfinfo);
7332 |
7333 | if (!number_out) {
7334 | number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7335 | }
7336 |
7337 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7338 |
7339 | } else {
7340 | number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7341 |
7342 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7343 | }
7344 |
7345 | break;
7346 |
7347 | /* XXX - make these just FT_NUMBER? */
7348 | case FT_INT8:
7349 | case FT_INT16:
7350 | case FT_INT24:
7351 | case FT_INT32:
7352 | case FT_UINT8:
7353 | case FT_UINT16:
7354 | case FT_UINT24:
7355 | case FT_UINT32:
7356 | case FT_FRAMENUM:
7357 | hf_str_val = NULL((void*)0);
7358 | 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 )) ?
7359 | (uint32_t) fvalue_get_sinteger(finfo->value) :
7360 | fvalue_get_uinteger(finfo->value);
7361 |
7362 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7363 | char tmp[ITEM_LABEL_LENGTH240];
7364 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7365 |
7366 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7366, "fmtfunc"))));
7367 | fmtfunc(tmp, number);
7368 |
7369 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7370 |
7371 | } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7372 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7373 | number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7374 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7375 | hf_str_val = hf_try_val_to_str(number, hfinfo);
7376 | if (hf_str_val)
7377 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7378 | } else {
7379 | number_out = hf_try_val_to_str(number, hfinfo);
7380 |
7381 | if (!number_out) {
7382 | number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7383 | }
7384 |
7385 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7386 | }
7387 | } else {
7388 | number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7389 |
7390 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7391 | }
7392 |
7393 | break;
7394 |
7395 | case FT_INT40:
7396 | case FT_INT48:
7397 | case FT_INT56:
7398 | case FT_INT64:
7399 | case FT_UINT40:
7400 | case FT_UINT48:
7401 | case FT_UINT56:
7402 | case FT_UINT64:
7403 | hf_str_val = NULL((void*)0);
7404 | 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 )) ?
7405 | (uint64_t) fvalue_get_sinteger64(finfo->value) :
7406 | fvalue_get_uinteger64(finfo->value);
7407 |
7408 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7409 | char tmp[ITEM_LABEL_LENGTH240];
7410 | custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7411 |
7412 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 7412, "fmtfunc64" ))));
7413 | fmtfunc64(tmp, number64);
7414 |
7415 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7416 | } else if (hfinfo->strings) {
7417 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7418 | number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7419 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7420 | hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7421 | if (hf_str_val)
7422 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7423 | } else {
7424 | number_out = hf_try_val64_to_str(number64, hfinfo);
7425 |
7426 | if (!number_out)
7427 | number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7428 |
7429 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7430 | }
7431 | } else {
7432 | number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7433 |
7434 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7435 | }
7436 |
7437 | break;
7438 |
7439 | case FT_EUI64:
7440 | set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7441 | tmp_str = address_to_display(NULL((void*)0), &addr);
7442 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7443 | wmem_free(NULL((void*)0), tmp_str);
7444 | break;
7445 |
7446 | case FT_IPv4:
7447 | ipv4 = fvalue_get_ipv4(finfo->value);
7448 | //XXX: Should we ignore the mask?
7449 | set_address_ipv4(&addr, ipv4);
7450 | tmp_str = address_to_display(NULL((void*)0), &addr);
7451 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7452 | wmem_free(NULL((void*)0), tmp_str);
7453 | free_address(&addr);
7454 | break;
7455 |
7456 | case FT_IPv6:
7457 | ipv6 = fvalue_get_ipv6(finfo->value);
7458 | set_address_ipv6(&addr, ipv6);
7459 | tmp_str = address_to_display(NULL((void*)0), &addr);
7460 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7461 | wmem_free(NULL((void*)0), tmp_str);
7462 | free_address(&addr);
7463 | break;
7464 |
7465 | case FT_FCWWN:
7466 | set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7467 | tmp_str = address_to_display(NULL((void*)0), &addr);
7468 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7469 | wmem_free(NULL((void*)0), tmp_str);
7470 | break;
7471 |
7472 | case FT_ETHER:
7473 | set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7474 | tmp_str = address_to_display(NULL((void*)0), &addr);
7475 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7476 | wmem_free(NULL((void*)0), tmp_str);
7477 | break;
7478 |
7479 | case FT_GUID:
7480 | tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7481 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7482 | wmem_free(NULL((void*)0), tmp_str);
7483 | break;
7484 |
7485 | case FT_REL_OID:
7486 | bytes = fvalue_get_bytes_data(finfo->value);
7487 | tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7488 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7489 | wmem_free(NULL((void*)0), tmp_str);
7490 | break;
7491 |
7492 | case FT_OID:
7493 | bytes = fvalue_get_bytes_data(finfo->value);
7494 | tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7495 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7496 | wmem_free(NULL((void*)0), tmp_str);
7497 | break;
7498 |
7499 | case FT_SYSTEM_ID:
7500 | bytes = fvalue_get_bytes_data(finfo->value);
7501 | tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7502 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7503 | wmem_free(NULL((void*)0), tmp_str);
7504 | break;
7505 |
7506 | case FT_FLOAT:
7507 | case FT_DOUBLE:
7508 | label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7509 | break;
7510 |
7511 | case FT_IEEE_11073_SFLOAT:
7512 | case FT_IEEE_11073_FLOAT:
7513 | label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7514 | break;
7515 |
7516 | case FT_STRING:
7517 | case FT_STRINGZ:
7518 | case FT_UINT_STRING:
7519 | case FT_STRINGZPAD:
7520 | case FT_STRINGZTRUNC:
7521 | str = fvalue_get_string(finfo->value);
7522 | label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7523 | if (label_len >= label_str_size) {
7524 | /* Truncation occurred. Get the real length
7525 | * copied (not including '\0') */
7526 | label_len = label_str_size ? label_str_size - 1 : 0;
7527 | }
7528 | break;
7529 |
7530 | default:
7531 | /* First try ftype string representation */
7532 | tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7533 | if (!tmp_str) {
7534 | /* Default to show as bytes */
7535 | bytes = fvalue_get_bytes_data(finfo->value);
7536 | tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo-> value), 36);
7537 | }
7538 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7539 | wmem_free(NULL((void*)0), tmp_str);
7540 | break;
7541 | }
7542 | return label_len;
7543 | }
7544 |
7545 | const char *
7546 | proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7547 | char *result, char *expr, const int size)
7548 | {
7549 | int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7550 | GPtrArray *finfos;
7551 | field_info *finfo = NULL((void*)0);
7552 | header_field_info* hfinfo;
7553 | const char *abbrev = NULL((void*)0);
7554 |
7555 | char *str;
7556 | col_custom_t *field_idx;
7557 | int field_id;
7558 | int ii = 0;
7559 |
7560 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7560, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7561 | while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7562 | field_id = field_idx->field_id;
7563 | if (field_id == 0) {
7564 | GPtrArray *fvals = NULL((void*)0);
7565 | bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7566 | if (fvals != NULL((void*)0)) {
7567 |
7568 | // XXX - Handling occurrences is unusual when more
7569 | // than one field is involved, e.g. there's four
7570 | // results for tcp.port + tcp.port. We may really
7571 | // want to apply it to the operands, not the output.
7572 | // Note that occurrences are not quite the same as
7573 | // the layer operator (should the grammar support
7574 | // both?)
7575 | /* Calculate single index or set outer boundaries */
7576 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7577 | if (occurrence < 0) {
7578 | i = occurrence + len;
7579 | last = i;
7580 | } else if (occurrence > 0) {
7581 | i = occurrence - 1;
7582 | last = i;
7583 | } else {
7584 | i = 0;
7585 | last = len - 1;
7586 | }
7587 | if (i < 0 || i >= len) {
7588 | g_ptr_array_unref(fvals);
7589 | continue;
7590 | }
7591 | for (; i <= last; i++) {
7592 | /* XXX - We could have a "resolved" result
7593 | * for types where the value depends only
7594 | * on the type, e.g. FT_IPv4, and not on
7595 | * hfinfo->strings. Supporting the latter
7596 | * requires knowing which hfinfo matched
7597 | * if there are multiple with the same
7598 | * abbreviation. In any case, we need to
7599 | * know the expected return type of the
7600 | * field expression.
7601 | */
7602 | str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7603 | if (offset_r && (offset_r < (size - 1)))
7604 | result[offset_r++] = ',';
7605 | if (offset_e && (offset_e < (size - 1)))
7606 | expr[offset_e++] = ',';
7607 | offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7608 | // col_{add,append,set}_* calls ws_label_strcpy
7609 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7610 |
7611 | g_free(str)(__builtin_object_size ((str), 0) != ((size_t) - 1)) ? g_free_sized (str, __builtin_object_size ((str), 0)) : (g_free) (str);
7612 | }
7613 | g_ptr_array_unref(fvals);
7614 | } else if (passed) {
7615 | // XXX - Occurrence doesn't make sense for a test
7616 | // output, it should be applied to the operands.
7617 | if (offset_r && (offset_r < (size - 1)))
7618 | result[offset_r++] = ',';
7619 | if (offset_e && (offset_e < (size - 1)))
7620 | expr[offset_e++] = ',';
7621 | /* Prevent multiple check marks */
7622 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7623 | offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7624 | } else {
7625 | result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7626 | }
7627 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7628 | offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7629 | } else {
7630 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7631 | }
7632 | }
7633 | continue;
7634 | }
7635 | 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", 7635 , __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", 7635, "(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", 7635, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7636 |
7637 | /* do we need to rewind ? */
7638 | if (!hfinfo)
7639 | return "";
7640 |
7641 | if (occurrence < 0) {
7642 | /* Search other direction */
7643 | while (hfinfo->same_name_prev_id != -1) {
7644 | 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", 7644 , __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", 7644, "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", 7644, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7645 | }
7646 | }
7647 |
7648 | prev_len = 0; /* Reset handled occurrences */
7649 |
7650 | while (hfinfo) {
7651 | finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7652 |
7653 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7654 | if (occurrence < 0) {
7655 | hfinfo = hfinfo->same_name_next;
7656 | } else {
7657 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7658 | }
7659 | continue;
7660 | }
7661 |
7662 | /* Are there enough occurrences of the field? */
7663 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7664 | if (occurrence < 0) {
7665 | hfinfo = hfinfo->same_name_next;
7666 | } else {
7667 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7668 | }
7669 | prev_len += len;
7670 | continue;
7671 | }
7672 |
7673 | /* Calculate single index or set outer boundaries */
7674 | if (occurrence < 0) {
7675 | i = occurrence + len + prev_len;
7676 | last = i;
7677 | } else if (occurrence > 0) {
7678 | i = occurrence - 1 - prev_len;
7679 | last = i;
7680 | } else {
7681 | i = 0;
7682 | last = len - 1;
7683 | }
7684 |
7685 | prev_len += len; /* Count handled occurrences */
7686 |
7687 | while (i <= last) {
7688 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7689 |
7690 | if (offset_r && (offset_r < (size - 1)))
7691 | result[offset_r++] = ',';
7692 |
7693 | if (display_details) {
7694 | char representation[ITEM_LABEL_LENGTH240];
7695 | size_t offset = 0;
7696 |
7697 | if (finfo->rep && finfo->rep->value_len) {
7698 | (void) g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7699 | MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo-> rep->value_len + 1) : (240)));
7700 | } else {
7701 | proto_item_fill_label(finfo, representation, &offset);
7702 | }
7703 | offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7704 | } else {
7705 | switch (hfinfo->type) {
7706 |
7707 | case FT_NONE:
7708 | case FT_PROTOCOL:
7709 | /* Prevent multiple check marks */
7710 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7711 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7712 | } else {
7713 | result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7714 | }
7715 | break;
7716 |
7717 | default:
7718 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7719 | break;
7720 | }
7721 | }
7722 |
7723 | if (offset_e && (offset_e < (size - 1)))
7724 | expr[offset_e++] = ',';
7725 |
7726 | 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 )))) {
7727 | const char *hf_str_val;
7728 | /* Integer types with BASE_NONE never get the numeric value. */
7729 | if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16 || (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32 )) {
7730 | hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7731 | } 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 )) {
7732 | hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7733 | } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48 || (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64 )) {
7734 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7735 | } else { // if (FT_IS_UINT64(hfinfo->type)) {
7736 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7737 | }
7738 | snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7739 | offset_e = (int)strlen(expr);
7740 | } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7741 | /* Prevent multiple check marks */
7742 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7743 | offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7744 | } else {
7745 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7746 | }
7747 | } else {
7748 | str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7749 | // col_{add,append,set}_* calls ws_label_strcpy
7750 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7751 | wmem_free(NULL((void*)0), str);
7752 | }
7753 | i++;
7754 | }
7755 |
7756 | /* XXX: Why is only the first abbreviation returned for a multifield
7757 | * custom column? */
7758 | if (!abbrev) {
7759 | /* Store abbrev for return value */
7760 | abbrev = hfinfo->abbrev;
7761 | }
7762 |
7763 | if (occurrence == 0) {
7764 | /* Fetch next hfinfo with same name (abbrev) */
7765 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7766 | } else {
7767 | hfinfo = NULL((void*)0);
7768 | }
7769 | }
7770 | }
7771 |
7772 | if (offset_r >= (size - 1)) {
7773 | mark_truncated(result, 0, size, NULL((void*)0));
7774 | }
7775 | if (offset_e >= (size - 1)) {
7776 | mark_truncated(expr, 0, size, NULL((void*)0));
7777 | }
7778 | return abbrev ? abbrev : "";
7779 | }
7780 |
7781 | char *
7782 | proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7783 | {
7784 | int len, prev_len, last, i;
7785 | GPtrArray *finfos;
7786 | field_info *finfo = NULL((void*)0);
7787 | header_field_info* hfinfo;
7788 |
7789 | char *filter = NULL((void*)0);
7790 | GPtrArray *filter_array;
7791 |
7792 | col_custom_t *col_custom;
7793 | int field_id;
7794 |
7795 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7795, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7796 | filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7797 | for (GSList *iter = field_ids; iter; iter = iter->next) {
7798 | col_custom = (col_custom_t*)iter->data;
7799 | field_id = col_custom->field_id;
7800 | if (field_id == 0) {
7801 | GPtrArray *fvals = NULL((void*)0);
7802 | bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7803 | if (fvals != NULL((void*)0)) {
7804 | // XXX - Handling occurrences is unusual when more
7805 | // than one field is involved, e.g. there's four
7806 | // results for tcp.port + tcp.port. We really
7807 | // want to apply it to the operands, not the output.
7808 | /* Calculate single index or set outer boundaries */
7809 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7810 | if (occurrence < 0) {
7811 | i = occurrence + len;
7812 | last = i;
7813 | } else if (occurrence > 0) {
7814 | i = occurrence - 1;
7815 | last = i;
7816 | } else {
7817 | i = 0;
7818 | last = len - 1;
7819 | }
7820 | if (i < 0 || i >= len) {
7821 | g_ptr_array_unref(fvals);
7822 | continue;
7823 | }
7824 | for (; i <= last; i++) {
7825 | /* XXX - Should multiple values for one
7826 | * field use set membership to reduce
7827 | * verbosity, here and below? */
7828 | char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7829 | filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7830 | wmem_free(NULL((void*)0), str);
7831 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7832 | g_ptr_array_add(filter_array, filter);
7833 | }
7834 | }
7835 | g_ptr_array_unref(fvals);
7836 | } else if (passed) {
7837 | filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7838 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7839 | g_ptr_array_add(filter_array, filter);
7840 | }
7841 | } else {
7842 | filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7843 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7844 | g_ptr_array_add(filter_array, filter);
7845 | }
7846 | }
7847 | continue;
7848 | }
7849 |
7850 | 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", 7850 , __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", 7850, "(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", 7850, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7851 |
7852 | /* do we need to rewind ? */
7853 | if (!hfinfo)
7854 | return NULL((void*)0);
7855 |
7856 | if (occurrence < 0) {
7857 | /* Search other direction */
7858 | while (hfinfo->same_name_prev_id != -1) {
7859 | 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", 7859 , __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", 7859, "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", 7859, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7860 | }
7861 | }
7862 |
7863 | prev_len = 0; /* Reset handled occurrences */
7864 |
7865 | while (hfinfo) {
7866 | finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7867 |
7868 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7869 | if (occurrence < 0) {
7870 | hfinfo = hfinfo->same_name_next;
7871 | } else {
7872 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7873 | }
7874 | continue;
7875 | }
7876 |
7877 | /* Are there enough occurrences of the field? */
7878 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7879 | if (occurrence < 0) {
7880 | hfinfo = hfinfo->same_name_next;
7881 | } else {
7882 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7883 | }
7884 | prev_len += len;
7885 | continue;
7886 | }
7887 |
7888 | /* Calculate single index or set outer boundaries */
7889 | if (occurrence < 0) {
7890 | i = occurrence + len + prev_len;
7891 | last = i;
7892 | } else if (occurrence > 0) {
7893 | i = occurrence - 1 - prev_len;
7894 | last = i;
7895 | } else {
7896 | i = 0;
7897 | last = len - 1;
7898 | }
7899 |
7900 | prev_len += len; /* Count handled occurrences */
7901 |
7902 | while (i <= last) {
7903 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7904 |
7905 | filter = proto_construct_match_selected_string(finfo, edt);
7906 | if (filter) {
7907 | /* Only add the same expression once (especially for FT_PROTOCOL).
7908 | * The ptr array doesn't have NULL entries so g_str_equal is fine.
7909 | */
7910 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7911 | g_ptr_array_add(filter_array, filter);
7912 | }
7913 | }
7914 | i++;
7915 | }
7916 |
7917 | if (occurrence == 0) {
7918 | /* Fetch next hfinfo with same name (abbrev) */
7919 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7920 | } else {
7921 | hfinfo = NULL((void*)0);
7922 | }
7923 | }
7924 | }
7925 |
7926 | g_ptr_array_add(filter_array, NULL((void*)0));
7927 |
7928 | /* XXX: Should this be || or && ? */
7929 | char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7930 |
7931 | g_ptr_array_free(filter_array, true1);
7932 |
7933 | return output;
7934 | }
7935 |
7936 | /* Set text of proto_item after having already been created. */
7937 | void
7938 | proto_item_set_text(proto_item *pi, const char *format, ...)
7939 | {
7940 | field_info *fi = NULL((void*)0);
7941 | va_list ap;
7942 |
7943 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7944 |
7945 | fi = PITEM_FINFO(pi)((pi)->finfo);
7946 | if (fi == NULL((void*)0))
7947 | return;
7948 |
7949 | if (fi->rep) {
7950 | ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep );;
7951 | fi->rep = NULL((void*)0);
7952 | }
7953 |
7954 | va_start(ap, format)__builtin_va_start(ap, format);
7955 | proto_tree_set_representation(pi, format, ap);
7956 | va_end(ap)__builtin_va_end(ap);
7957 | }
7958 |
7959 | /* Append to text of proto_item after having already been created. */
7960 | void
7961 | proto_item_append_text(proto_item *pi, const char *format, ...)
7962 | {
7963 | field_info *fi = NULL((void*)0);
7964 | size_t curlen;
7965 | char *str;
7966 | va_list ap;
7967 |
7968 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7969 |
7970 | fi = PITEM_FINFO(pi)((pi)->finfo);
7971 | if (fi == NULL((void*)0)) {
7972 | return;
7973 | }
7974 |
7975 | if (!proto_item_is_hidden(pi)) {
7976 | /*
7977 | * If we don't already have a representation,
7978 | * generate the default representation.
7979 | */
7980 | if (fi->rep == NULL((void*)0)) {
7981 | 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;;
7982 | proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7983 | /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7984 | if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7985 | (strncmp(format, ": ", 2) == 0)) {
7986 | fi->rep->value_pos += 2;
7987 | }
7988 | }
7989 | if (fi->rep) {
7990 | curlen = strlen(fi->rep->representation);
7991 | /* curlen doesn't include the \0 byte.
7992 | * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7993 | * the representation has already been truncated (of an up
7994 | * to 4 byte UTF-8 character) or is just at the maximum length
7995 | * unless we search for " [truncated]" (which may not be
7996 | * at the start.)
7997 | * It's safer to do nothing.
7998 | */
7999 | if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
8000 | va_start(ap, format)__builtin_va_start(ap, format);
8001 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8002 | va_end(ap)__builtin_va_end(ap);
8003 | 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" , 8003, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
8004 | /* Keep fi->rep->value_pos */
8005 | curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
8006 | if (curlen >= ITEM_LABEL_LENGTH240) {
8007 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8008 | size_t name_pos = label_find_name_pos(fi->rep);
8009 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8010 | }
8011 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8012 | }
8013 | }
8014 | }
8015 | }
8016 |
8017 | /* Prepend to text of proto_item after having already been created. */
8018 | void
8019 | proto_item_prepend_text(proto_item *pi, const char *format, ...)
8020 | {
8021 | field_info *fi = NULL((void*)0);
8022 | size_t pos;
8023 | char representation[ITEM_LABEL_LENGTH240];
8024 | char *str;
8025 | va_list ap;
8026 |
8027 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
8028 |
8029 | fi = PITEM_FINFO(pi)((pi)->finfo);
8030 | if (fi == NULL((void*)0)) {
8031 | return;
8032 | }
8033 |
8034 | if (!proto_item_is_hidden(pi)) {
8035 | /*
8036 | * If we don't already have a representation,
8037 | * generate the default representation.
8038 | */
8039 | if (fi->rep == NULL((void*)0)) {
8040 | 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;;
8041 | proto_item_fill_label(fi, representation, &fi->rep->value_pos);
8042 | } else
8043 | (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
8044 |
8045 | va_start(ap, format)__builtin_va_start(ap, format);
8046 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
8047 | va_end(ap)__builtin_va_end(ap);
8048 | 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" , 8048, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
8049 | fi->rep->value_pos += strlen(str);
8050 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
8051 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
8052 | /* XXX: As above, if the old representation is close to the label
8053 | * length, it might already be marked as truncated. */
8054 | if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
8055 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
8056 | size_t name_pos = label_find_name_pos(fi->rep);
8057 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
8058 | }
8059 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
8060 | }
8061 | }
8062 |
8063 | static void
8064 | finfo_set_len(field_info *fi, const unsigned length)
8065 | {
8066 | unsigned length_remaining;
8067 |
8068 | length_remaining = G_LIKELY(fi->ds_tvb)(fi->ds_tvb) ? tvb_captured_length_remaining(fi->ds_tvb, fi->start) : 0;
8069 | if (length > length_remaining)
8070 | fi->length = length_remaining;
8071 | else
8072 | fi->length = length;
8073 |
8074 | /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
8075 | if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
8076 | fvalue_set_protocol_length(fi->value, fi->length);
8077 | }
8078 |
8079 | /*
8080 | * You cannot just make the "len" field of a GByteArray
8081 | * larger, if there's no data to back that length;
8082 | * you can only make it smaller.
8083 | */
8084 | if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
8085 | GBytes *bytes = fvalue_get_bytes(fi->value);
8086 | size_t size;
8087 | const void *data = g_bytes_get_data(bytes, &size);
8088 | if ((size_t)fi->length <= size) {
8089 | fvalue_set_bytes_data(fi->value, data, fi->length);
8090 | }
8091 | g_bytes_unref(bytes);
8092 | }
8093 | }
8094 |
8095 | void
8096 | proto_item_set_len(proto_item *pi, const unsigned length)
8097 | {
8098 | field_info *fi;
8099 |
8100 | if (pi == NULL((void*)0))
8101 | return;
8102 |
8103 | fi = PITEM_FINFO(pi)((pi)->finfo);
8104 | if (fi == NULL((void*)0))
8105 | return;
8106 |
8107 | finfo_set_len(fi, length);
8108 | }
8109 |
8110 | /*
8111 | * Sets the length of the item based on its start and on the specified
8112 | * offset, which is the offset past the end of the item; as the start
8113 | * in the item is relative to the beginning of the data source tvbuff,
8114 | * we need to pass in a tvbuff - the end offset is relative to the beginning
8115 | * of that tvbuff.
8116 | */
8117 | void
8118 | proto_item_set_end(proto_item *pi, tvbuff_t *tvb, unsigned end)
8119 | {
8120 | field_info *fi;
8121 | unsigned length;
8122 |
8123 | if (pi == NULL((void*)0))
8124 | return;
8125 |
8126 | fi = PITEM_FINFO(pi)((pi)->finfo);
8127 | if (fi == NULL((void*)0))
8128 | return;
8129 |
8130 | if (G_LIKELY(tvb)(tvb)) {
8131 | 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" , 8131, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))));
8132 | end += tvb_raw_offset(tvb);
8133 | } else {
8134 | 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", 8134, "((void*)0) == fi->ds_tvb" ))));
8135 | }
8136 | DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8136, "end >= fi->start" ))));
8137 | length = end - fi->start;
8138 |
8139 | finfo_set_len(fi, length);
8140 | }
8141 |
8142 | unsigned
8143 | proto_item_get_len(const proto_item *pi)
8144 | {
8145 | /* XXX - The only use case where this is really guaranteed to work is
8146 | * increasing the length of an item (which has no effect if the item
8147 | * is faked, so it doesn't matter that this returns 0 in that case), e.g.
8148 | *
8149 | * proto_item_set_len(pi, proto_item_get_len(pi) + delta);
8150 | *
8151 | * Should there be a macro or function to do that, and possibly this
8152 | * be deprecated? As a bonus, we could handle overflow.
8153 | */
8154 | field_info *fi;
8155 |
8156 | if (!pi)
8157 | return 0;
8158 | fi = PITEM_FINFO(pi)((pi)->finfo);
8159 | if (fi) {
8160 | return fi->length;
8161 | }
8162 | return 0;
8163 | }
8164 |
8165 | void
8166 | proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8167 | if (!ti) {
8168 | return;
8169 | }
8170 | 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);
8171 | 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);
8172 | }
8173 |
8174 | char *
8175 | proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8176 | {
8177 | field_info *fi;
8178 |
8179 | if (!pi)
8180 | return wmem_strdup(scope, "");
8181 | fi = PITEM_FINFO(pi)((pi)->finfo);
8182 | if (!fi)
8183 | return wmem_strdup(scope, "");
8184 | DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8184, "fi->hfinfo != ((void*)0)" ))));
8185 | return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8186 | }
8187 |
8188 | proto_tree *
8189 | proto_tree_create_root(packet_info *pinfo)
8190 | {
8191 | proto_node *pnode;
8192 |
8193 | /* Initialize the proto_node */
8194 | pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc ((sizeof (proto_tree) > 0 ? sizeof (proto_tree) : 1)));
8195 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
8196 | pnode->parent = NULL((void*)0);
8197 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8198 | 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)));
8199 |
8200 | /* Make sure we can access pinfo everywhere */
8201 | pnode->tree_data->pinfo = pinfo;
8202 |
8203 | /* Don't initialize the tree_data_t. Wait until we know we need it */
8204 | pnode->tree_data->interesting_hfids = NULL((void*)0);
8205 |
8206 | /* Set the default to false so it's easier to
8207 | * find errors; if we expect to see the protocol tree
8208 | * but for some reason the default 'visible' is not
8209 | * changed, then we'll find out very quickly. */
8210 | pnode->tree_data->visible = false0;
8211 |
8212 | /* Make sure that we fake protocols (if possible) */
8213 | pnode->tree_data->fake_protocols = true1;
8214 |
8215 | /* Keep track of the number of children */
8216 | pnode->tree_data->count = 0;
8217 |
8218 | /* Initialize our loop checks */
8219 | pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8220 | pnode->tree_data->max_start = 0;
8221 | pnode->tree_data->start_idle_count = 0;
8222 |
8223 | return (proto_tree *)pnode;
8224 | }
8225 |
8226 |
8227 | /* "prime" a proto_tree with a single hfid that a dfilter
8228 | * is interested in. */
8229 | void
8230 | proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8231 | {
8232 | header_field_info *hfinfo;
8233 |
8234 | 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", 8234, __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", 8234, "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", 8234, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8235 | /* this field is referenced by a filter so increase the refcount.
8236 | also increase the refcount for the parent, i.e the protocol.
8237 | Don't increase the refcount if we're already printing the
8238 | type, as that is a superset of direct reference.
8239 | */
8240 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8241 | hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8242 | }
8243 | /* only increase the refcount if there is a parent.
8244 | if this is a protocol and not a field then parent will be -1
8245 | and there is no parent to add any refcounting for.
8246 | */
8247 | if (hfinfo->parent != -1) {
8248 | header_field_info *parent_hfinfo;
8249 | 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", 8249 , __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", 8249, "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", 8249, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8250 |
8251 | /* Mark parent as indirectly referenced unless it is already directly
8252 | * referenced, i.e. the user has specified the parent in a filter.
8253 | */
8254 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8255 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8256 | }
8257 | }
8258 |
8259 | /* "prime" a proto_tree with a single hfid that a dfilter
8260 | * is interested in. */
8261 | void
8262 | proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8263 | {
8264 | header_field_info *hfinfo;
8265 |
8266 | 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", 8266, __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", 8266, "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", 8266, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8267 | /* this field is referenced by an (output) filter so increase the refcount.
8268 | also increase the refcount for the parent, i.e the protocol.
8269 | */
8270 | hfinfo->ref_type = HF_REF_TYPE_PRINT;
8271 | /* only increase the refcount if there is a parent.
8272 | if this is a protocol and not a field then parent will be -1
8273 | and there is no parent to add any refcounting for.
8274 | */
8275 | if (hfinfo->parent != -1) {
8276 | header_field_info *parent_hfinfo;
8277 | 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", 8277 , __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", 8277, "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", 8277, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8278 |
8279 | /* Mark parent as indirectly referenced unless it is already directly
8280 | * referenced, i.e. the user has specified the parent in a filter.
8281 | */
8282 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8283 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8284 | }
8285 | }
8286 |
8287 | proto_tree *
8288 | proto_item_add_subtree(proto_item *pi, const int idx) {
8289 | field_info *fi;
8290 |
8291 | if (!pi)
8292 | return NULL((void*)0);
8293 |
8294 | 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", 8294, "idx >= 0 && idx < num_tree_types" ))));
8295 |
8296 | fi = PITEM_FINFO(pi)((pi)->finfo);
8297 | if (!fi)
8298 | return (proto_tree *)pi;
8299 |
8300 | fi->tree_type = idx;
8301 |
8302 | return (proto_tree *)pi;
8303 | }
8304 |
8305 | proto_tree *
8306 | proto_item_get_subtree(proto_item *pi) {
8307 | field_info *fi;
8308 |
8309 | if (!pi)
8310 | return NULL((void*)0);
8311 | fi = PITEM_FINFO(pi)((pi)->finfo);
8312 | if ( (fi) && (fi->tree_type == -1) )
8313 | return NULL((void*)0);
8314 | return (proto_tree *)pi;
8315 | }
8316 |
8317 | proto_item *
8318 | proto_item_get_parent(const proto_item *ti) {
8319 | if (!ti)
8320 | return NULL((void*)0);
8321 | return ti->parent;
8322 | }
8323 |
8324 | proto_item *
8325 | proto_item_get_parent_nth(proto_item *ti, int gen) {
8326 | if (!ti)
8327 | return NULL((void*)0);
8328 | while (gen--) {
8329 | ti = ti->parent;
8330 | if (!ti)
8331 | return NULL((void*)0);
8332 | }
8333 | return ti;
8334 | }
8335 |
8336 |
8337 | proto_item *
8338 | proto_tree_get_parent(proto_tree *tree) {
8339 | if (!tree)
8340 | return NULL((void*)0);
8341 | return (proto_item *)tree;
8342 | }
8343 |
8344 | proto_tree *
8345 | proto_tree_get_parent_tree(proto_tree *tree) {
8346 | if (!tree)
8347 | return NULL((void*)0);
8348 |
8349 | /* we're the root tree, there's no parent
8350 | return ourselves so the caller has at least a tree to attach to */
8351 | if (!tree->parent)
8352 | return tree;
8353 |
8354 | return (proto_tree *)tree->parent;
8355 | }
8356 |
8357 | proto_tree *
8358 | proto_tree_get_root(proto_tree *tree) {
8359 | if (!tree)
8360 | return NULL((void*)0);
8361 | while (tree->parent) {
8362 | tree = tree->parent;
8363 | }
8364 | return tree;
8365 | }
8366 |
8367 | void
8368 | proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8369 | proto_item *item_to_move)
8370 | {
8371 | /* This function doesn't generate any values. It only reorganizes the protocol tree
8372 | * so we can bail out immediately if it isn't visible. */
8373 | if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8374 | return;
8375 |
8376 | 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", 8376, "item_to_move->parent == tree" ))));
8377 | 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", 8377, "fixed_item->parent == tree" ))));
8378 |
8379 | /*** cut item_to_move out ***/
8380 |
8381 | /* is item_to_move the first? */
8382 | if (tree->first_child == item_to_move) {
8383 | /* simply change first child to next */
8384 | tree->first_child = item_to_move->next;
8385 |
8386 | 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", 8386, "tree->last_child != item_to_move" ))));
8387 | } else {
8388 | proto_item *curr_item;
8389 | /* find previous and change it's next */
8390 | for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8391 | if (curr_item->next == item_to_move) {
8392 | break;
8393 | }
8394 | }
8395 |
8396 | DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 8396, "curr_item" ))));
8397 |
8398 | curr_item->next = item_to_move->next;
8399 |
8400 | /* fix last_child if required */
8401 | if (tree->last_child == item_to_move) {
8402 | tree->last_child = curr_item;
8403 | }
8404 | }
8405 |
8406 | /*** insert to_move after fixed ***/
8407 | item_to_move->next = fixed_item->next;
8408 | fixed_item->next = item_to_move;
8409 | if (tree->last_child == fixed_item) {
8410 | tree->last_child = item_to_move;
8411 | }
8412 | }
8413 |
8414 | void
8415 | proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, unsigned start,
8416 | const unsigned length)
8417 | {
8418 | field_info *fi;
8419 |
8420 | if (tree == NULL((void*)0))
8421 | return;
8422 |
8423 | fi = PTREE_FINFO(tree)((tree)->finfo);
8424 | if (fi == NULL((void*)0))
8425 | return;
8426 |
8427 | /* We don't store a separate data source tvb for the appendix, so
8428 | * it must be from the same data source. (XXX - Are there any
8429 | * situations where it makes sense to have an appendix from a
8430 | * different data source?) */
8431 | if (G_LIKELY(tvb)(tvb)) {
8432 | 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" , 8432, "tvb_get_ds_tvb(tvb) == fi->ds_tvb"))));
8433 | start += tvb_raw_offset(tvb);
8434 | } else {
8435 | 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", 8435, "((void*)0) == fi->ds_tvb" ))));
8436 | }
8437 |
8438 | /* XXX - DISSECTOR_ASSERT that the appendix doesn't overlap the
8439 | * main body? */
8440 |
8441 | fi->appendix_start = start;
8442 | fi->appendix_length = length;
8443 | }
8444 |
8445 | static void
8446 | check_protocol_filter_name_or_fail(const char *filter_name)
8447 | {
8448 | /* Require at least two characters. */
8449 | if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8450 | 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);
8451 | }
8452 |
8453 | if (proto_check_field_name(filter_name) != '\0') {
8454 | 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)
8455 | " 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)
8456 | " 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);
8457 | }
8458 |
8459 | /* Check that it doesn't match some very common numeric forms. */
8460 | if (filter_name[0] == '0' &&
8461 | (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8462 | filter_name[1] == 'b' || filter_name[1] == 'B')) {
8463 | 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])
8464 | 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]);
8465 | }
8466 |
8467 | /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8468 |
8469 | /* Check that it contains at least one letter. */
8470 | bool_Bool have_letter = false0;
8471 | for (const char *s = filter_name; *s != '\0'; s++) {
8472 | if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8473 | have_letter = true1;
8474 | break;
8475 | }
8476 | }
8477 | if (!have_letter) {
8478 | 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)
8479 | filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z." , filter_name);
8480 | }
8481 |
8482 | /* Check for reserved keywords. */
8483 | if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8484 | 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)
8485 | " 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);
8486 | }
8487 | }
8488 |
8489 | int
8490 | proto_register_protocol(const char *name, const char *short_name,
8491 | const char *filter_name)
8492 | {
8493 | protocol_t *protocol;
8494 | header_field_info *hfinfo;
8495 |
8496 | check_protocol_filter_name_or_fail(filter_name);
8497 |
8498 | /*
8499 | * Add this protocol to the list of known protocols;
8500 | * the list is sorted by protocol short name.
8501 | */
8502 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8503 | protocol->name = name;
8504 | protocol->short_name = short_name;
8505 | protocol->filter_name = filter_name;
8506 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8507 | protocol->is_enabled = true1; /* protocol is enabled by default */
8508 | protocol->enabled_by_default = true1; /* see previous comment */
8509 | protocol->can_toggle = true1;
8510 | protocol->parent_proto_id = -1;
8511 | protocol->heur_list = NULL((void*)0);
8512 |
8513 | /* List will be sorted later by name, when all protocols completed registering */
8514 | protocols = g_list_prepend(protocols, protocol);
8515 | /*
8516 | * Make sure there's not already a protocol with any of those
8517 | * names. Crash if there is, as that's an error in the code
8518 | * or an inappropriate plugin.
8519 | * This situation has to be fixed to not register more than one
8520 | * protocol with the same name.
8521 | */
8522 | if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8523 | /* ws_error will terminate the program */
8524 | 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)
8525 | " 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);
8526 | }
8527 | if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8528 | 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)
8529 | " 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);
8530 | }
8531 | if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8532 | 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)
8533 | " 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);
8534 | }
8535 |
8536 | /* Here we allocate a new header_field_info struct */
8537 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info ) > 0 ? sizeof (header_field_info) : 1)));
8538 | hfinfo->name = name;
8539 | hfinfo->abbrev = filter_name;
8540 | hfinfo->type = FT_PROTOCOL;
8541 | hfinfo->display = BASE_NONE;
8542 | hfinfo->strings = protocol;
8543 | hfinfo->bitmask = 0;
8544 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8545 | hfinfo->blurb = NULL((void*)0);
8546 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8547 |
8548 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8549 | return protocol->proto_id;
8550 | }
8551 |
8552 | int
8553 | proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8554 | {
8555 | protocol_t *protocol;
8556 | header_field_info *hfinfo;
8557 |
8558 | /*
8559 | * Helper protocols don't need the strict rules as a "regular" protocol
8560 | * Just register it in a list and make a hf_ field from it
8561 | */
8562 | if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8563 | 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);
8564 | }
8565 |
8566 | if (parent_proto <= 0) {
8567 | 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)
8568 | " 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);
8569 | }
8570 |
8571 | check_protocol_filter_name_or_fail(filter_name);
8572 |
8573 | /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8574 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8575 | protocol->name = name;
8576 | protocol->short_name = short_name;
8577 | protocol->filter_name = filter_name;
8578 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8579 |
8580 | /* Enabling and toggling is really determined by parent protocol,
8581 | but provide default values here */
8582 | protocol->is_enabled = true1;
8583 | protocol->enabled_by_default = true1;
8584 | protocol->can_toggle = true1;
8585 |
8586 | protocol->parent_proto_id = parent_proto;
8587 | protocol->heur_list = NULL((void*)0);
8588 |
8589 | /* List will be sorted later by name, when all protocols completed registering */
8590 | protocols = g_list_prepend(protocols, protocol);
8591 |
8592 | /* Here we allocate a new header_field_info struct */
8593 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc ((sizeof (header_field_info ) > 0 ? sizeof (header_field_info) : 1)));
8594 | hfinfo->name = name;
8595 | hfinfo->abbrev = filter_name;
8596 | hfinfo->type = field_type;
8597 | hfinfo->display = BASE_NONE;
8598 | if (field_type == FT_BYTES) {
8599 | hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8600 | }
8601 | hfinfo->strings = protocol;
8602 | hfinfo->bitmask = 0;
8603 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8604 | hfinfo->blurb = NULL((void*)0);
8605 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8606 |
8607 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8608 | return protocol->proto_id;
8609 | }
8610 |
8611 | bool_Bool
8612 | proto_deregister_protocol(const char *short_name)
8613 | {
8614 | protocol_t *protocol;
8615 | header_field_info *hfinfo;
8616 | int proto_id;
8617 | unsigned i;
8618 |
8619 | proto_id = proto_get_id_by_short_name(short_name);
8620 | protocol = find_protocol_by_id(proto_id);
8621 | if (protocol == NULL((void*)0))
8622 | return false0;
8623 |
8624 | g_hash_table_remove(proto_names, protocol->name);
8625 | g_hash_table_remove(proto_short_names, (void *)short_name);
8626 | g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8627 |
8628 | if (protocol->fields) {
8629 | for (i = 0; i < protocol->fields->len; i++) {
8630 | hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8631 | hfinfo_remove_from_gpa_name_map(hfinfo);
8632 | expert_deregister_expertinfo(hfinfo->abbrev);
8633 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8634 | }
8635 | g_ptr_array_free(protocol->fields, true1);
8636 | protocol->fields = NULL((void*)0);
8637 | }
8638 |
8639 | g_list_free(protocol->heur_list);
8640 |
8641 | /* Remove this protocol from the list of known protocols */
8642 | protocols = g_list_remove(protocols, protocol);
8643 |
8644 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8645 | wmem_map_remove(gpa_name_map, protocol->filter_name);
8646 |
8647 | 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);
8648 | last_field_name = NULL((void*)0);
8649 |
8650 | return true1;
8651 | }
8652 |
8653 | void
8654 | proto_register_alias(const int proto_id, const char *alias_name)
8655 | {
8656 | protocol_t *protocol;
8657 |
8658 | protocol = find_protocol_by_id(proto_id);
8659 | if (alias_name && protocol) {
8660 | g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8661 | }
8662 | }
8663 |
8664 | /*
8665 | * Routines to use to iterate over the protocols.
8666 | * The argument passed to the iterator routines is an opaque cookie to
8667 | * their callers; it's the GList pointer for the current element in
8668 | * the list.
8669 | * The ID of the protocol is returned, or -1 if there is no protocol.
8670 | */
8671 | int
8672 | proto_get_first_protocol(void **cookie)
8673 | {
8674 | protocol_t *protocol;
8675 |
8676 | if (protocols == NULL((void*)0))
8677 | return -1;
8678 | *cookie = protocols;
8679 | protocol = (protocol_t *)protocols->data;
8680 | return protocol->proto_id;
8681 | }
8682 |
8683 | int
8684 | proto_get_data_protocol(void *cookie)
8685 | {
8686 | GList *list_item = (GList *)cookie;
8687 |
8688 | protocol_t *protocol = (protocol_t *)list_item->data;
8689 | return protocol->proto_id;
8690 | }
8691 |
8692 | int
8693 | proto_get_next_protocol(void **cookie)
8694 | {
8695 | GList *list_item = (GList *)*cookie;
8696 | protocol_t *protocol;
8697 |
8698 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8699 | if (list_item == NULL((void*)0))
8700 | return -1;
8701 | *cookie = list_item;
8702 | protocol = (protocol_t *)list_item->data;
8703 | return protocol->proto_id;
8704 | }
8705 |
8706 | header_field_info *
8707 | proto_get_first_protocol_field(const int proto_id, void **cookie)
8708 | {
8709 | protocol_t *protocol = find_protocol_by_id(proto_id);
8710 |
8711 | if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8712 | return NULL((void*)0);
8713 |
8714 | *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8715 | return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8716 | }
8717 |
8718 | header_field_info *
8719 | proto_get_next_protocol_field(const int proto_id, void **cookie)
8720 | {
8721 | protocol_t *protocol = find_protocol_by_id(proto_id);
8722 | unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8723 |
8724 | i++;
8725 |
8726 | if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8727 | return NULL((void*)0);
8728 |
8729 | *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8730 | return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8731 | }
8732 |
8733 | protocol_t *
8734 | find_protocol_by_id(const int proto_id)
8735 | {
8736 | header_field_info *hfinfo;
8737 |
8738 | if (proto_id <= 0)
8739 | return NULL((void*)0);
8740 |
8741 | 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", 8741, __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", 8741, "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", 8741, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
8742 | if (hfinfo->type != FT_PROTOCOL) {
8743 | 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", 8743, "hfinfo->display & 0x00004000" ))));
8744 | }
8745 | return (protocol_t *)hfinfo->strings;
8746 | }
8747 |
8748 | int
8749 | proto_get_id(const protocol_t *protocol)
8750 | {
8751 | return protocol->proto_id;
8752 | }
8753 |
8754 | bool_Bool
8755 | proto_name_already_registered(const char *name)
8756 | {
8757 | DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 8757, "name", "No name present"))));
8758 |
8759 | if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8760 | return true1;
8761 | return false0;
8762 | }
8763 |
8764 | int
8765 | proto_get_id_by_filter_name(const char *filter_name)
8766 | {
8767 | const protocol_t *protocol = NULL((void*)0);
8768 |
8769 | 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", 8769, "filter_name", "No filter name present"))));
8770 |
8771 | protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8772 |
8773 | if (protocol == NULL((void*)0))
8774 | return -1;
8775 | return protocol->proto_id;
8776 | }
8777 |
8778 | int
8779 | proto_get_id_by_short_name(const char *short_name)
8780 | {
8781 | const protocol_t *protocol = NULL((void*)0);
8782 |
8783 | 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", 8783, "short_name", "No short name present"))));
8784 |
8785 | protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8786 |
8787 | if (protocol == NULL((void*)0))
8788 | return -1;
8789 | return protocol->proto_id;
8790 | }
8791 |
8792 | const char *
8793 | proto_get_protocol_name(const int proto_id)
8794 | {
8795 | protocol_t *protocol;
8796 |
8797 | protocol = find_protocol_by_id(proto_id);
8798 |
8799 | if (protocol == NULL((void*)0))
8800 | return NULL((void*)0);
8801 | return protocol->name;
8802 | }
8803 |
8804 | const char *
8805 | proto_get_protocol_short_name(const protocol_t *protocol)
8806 | {
8807 | if (protocol == NULL((void*)0))
8808 | return "(none)";
8809 | return protocol->short_name;
8810 | }
8811 |
8812 | const char *
8813 | proto_get_protocol_long_name(const protocol_t *protocol)
8814 | {
8815 | if (protocol == NULL((void*)0))
8816 | return "(none)";
8817 | return protocol->name;
8818 | }
8819 |
8820 | const char *
8821 | proto_get_protocol_filter_name(const int proto_id)
8822 | {
8823 | protocol_t *protocol;
8824 |
8825 | protocol = find_protocol_by_id(proto_id);
8826 | if (protocol == NULL((void*)0))
8827 | return "(none)";
8828 | return protocol->filter_name;
8829 | }
8830 |
8831 | void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8832 | {
8833 | heur_dtbl_entry_t* heuristic_dissector;
8834 |
8835 | if (protocol == NULL((void*)0))
8836 | return;
8837 |
8838 | heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8839 | if (heuristic_dissector != NULL((void*)0))
8840 | {
8841 | protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8842 | }
8843 | }
8844 |
8845 | void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8846 | {
8847 | if (protocol == NULL((void*)0))
8848 | return;
8849 |
8850 | g_list_foreach(protocol->heur_list, func, user_data);
8851 | }
8852 |
8853 | void
8854 | proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8855 | bool_Bool *is_tcp, bool_Bool *is_udp,
8856 | bool_Bool *is_sctp, bool_Bool *is_tls,
8857 | bool_Bool *is_rtp,
8858 | bool_Bool *is_lte_rlc)
8859 | {
8860 | wmem_list_frame_t *protos = wmem_list_head(layers);
8861 | int proto_id;
8862 | const char *proto_name;
8863 |
8864 | /* Walk the list of a available protocols in the packet and
8865 | attempt to find "major" ones. */
8866 | /* It might make more sense to assemble and return a bitfield. */
8867 | while (protos != NULL((void*)0))
8868 | {
8869 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8870 | proto_name = proto_get_protocol_filter_name(proto_id);
8871 |
8872 | if (is_ip && ((!strcmp(proto_name, "ip")) ||
8873 | (!strcmp(proto_name, "ipv6")))) {
8874 | *is_ip = true1;
8875 | } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8876 | *is_tcp = true1;
8877 | } else if (is_udp && !strcmp(proto_name, "udp")) {
8878 | *is_udp = true1;
8879 | } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8880 | *is_sctp = true1;
8881 | } else if (is_tls && !strcmp(proto_name, "tls")) {
8882 | *is_tls = true1;
8883 | } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8884 | *is_rtp = true1;
8885 | } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8886 | *is_lte_rlc = true1;
8887 | }
8888 |
8889 | protos = wmem_list_frame_next(protos);
8890 | }
8891 | }
8892 |
8893 | bool_Bool
8894 | proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8895 | {
8896 | wmem_list_frame_t *protos = wmem_list_head(layers);
8897 | int proto_id;
8898 | const char *name;
8899 |
8900 | /* Walk the list of a available protocols in the packet and
8901 | attempt to find the specified protocol. */
8902 | while (protos != NULL((void*)0))
8903 | {
8904 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8905 | name = proto_get_protocol_filter_name(proto_id);
8906 |
8907 | if (!strcmp(name, proto_name))
8908 | {
8909 | return true1;
8910 | }
8911 |
8912 | protos = wmem_list_frame_next(protos);
8913 | }
8914 |
8915 | return false0;
8916 | }
8917 |
8918 | char *
8919 | proto_list_layers(const packet_info *pinfo)
8920 | {
8921 | wmem_strbuf_t *buf;
8922 | wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8923 |
8924 | buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8925 |
8926 | /* Walk the list of layers in the packet and
8927 | return a string of all entries. */
8928 | while (layers != NULL((void*)0))
8929 | {
8930 | wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8931 |
8932 | layers = wmem_list_frame_next(layers);
8933 | if (layers != NULL((void*)0)) {
8934 | wmem_strbuf_append_c(buf, ':');
8935 | }
8936 | }
8937 |
8938 | return wmem_strbuf_finalize(buf);
8939 | }
8940 |
8941 | uint8_t
8942 | proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8943 | {
8944 | int *proto_layer_num_ptr;
8945 |
8946 | proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8947 | if (proto_layer_num_ptr == NULL((void*)0)) {
8948 | return 0;
8949 | }
8950 |
8951 | return (uint8_t)*proto_layer_num_ptr;
8952 | }
8953 |
8954 | bool_Bool
8955 | proto_is_pino(const protocol_t *protocol)
8956 | {
8957 | return (protocol->parent_proto_id != -1);
8958 | }
8959 |
8960 | bool_Bool
8961 | // NOLINTNEXTLINE(misc-no-recursion)
8962 | proto_is_protocol_enabled(const protocol_t *protocol)
8963 | {
8964 | if (protocol == NULL((void*)0))
8965 | return false0;
8966 |
8967 | //parent protocol determines enable/disable for helper dissectors
8968 | if (proto_is_pino(protocol))
8969 | return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8970 |
8971 | return protocol->is_enabled;
8972 | }
8973 |
8974 | bool_Bool
8975 | // NOLINTNEXTLINE(misc-no-recursion)
8976 | proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8977 | {
8978 | //parent protocol determines enable/disable for helper dissectors
8979 | if (proto_is_pino(protocol))
8980 | return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8981 |
8982 | return protocol->enabled_by_default;
8983 | }
8984 |
8985 | bool_Bool
8986 | // NOLINTNEXTLINE(misc-no-recursion)
8987 | proto_can_toggle_protocol(const int proto_id)
8988 | {
8989 | protocol_t *protocol;
8990 |
8991 | protocol = find_protocol_by_id(proto_id);
8992 | //parent protocol determines toggling for helper dissectors
8993 | if (proto_is_pino(protocol))
8994 | return proto_can_toggle_protocol(protocol->parent_proto_id);
8995 |
8996 | return protocol->can_toggle;
8997 | }
8998 |
8999 | void
9000 | proto_disable_by_default(const int proto_id)
9001 | {
9002 | protocol_t *protocol;
9003 |
9004 | protocol = find_protocol_by_id(proto_id);
9005 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9005, "protocol->can_toggle" ))));
9006 | 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", 9006, "proto_is_pino(protocol) == 0" ))));
9007 | protocol->is_enabled = false0;
9008 | protocol->enabled_by_default = false0;
9009 | }
9010 |
9011 | void
9012 | proto_set_decoding(const int proto_id, const bool_Bool enabled)
9013 | {
9014 | protocol_t *protocol;
9015 |
9016 | protocol = find_protocol_by_id(proto_id);
9017 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 9017, "protocol->can_toggle" ))));
9018 | 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", 9018, "proto_is_pino(protocol) == 0" ))));
9019 | protocol->is_enabled = enabled;
9020 | }
9021 |
9022 | void
9023 | proto_disable_all(void)
9024 | {
9025 | /* This doesn't explicitly disable heuristic protocols,
9026 | * but the heuristic doesn't get called if the parent
9027 | * protocol isn't enabled.
9028 | */
9029 | protocol_t *protocol;
9030 | GList *list_item = protocols;
9031 |
9032 | if (protocols == NULL((void*)0))
9033 | return;
9034 |
9035 | while (list_item) {
9036 | protocol = (protocol_t *)list_item->data;
9037 | if (protocol->can_toggle) {
9038 | protocol->is_enabled = false0;
9039 | }
9040 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
9041 | }
9042 | }
9043 |
9044 | static void
9045 | heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
9046 | {
9047 | heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
9048 |
9049 | heur->enabled = heur->enabled_by_default;
9050 | }
9051 |
9052 | void
9053 | proto_reenable_all(void)
9054 | {
9055 | protocol_t *protocol;
9056 | GList *list_item = protocols;
9057 |
9058 | if (protocols == NULL((void*)0))
9059 | return;
9060 |
9061 | while (list_item) {
9062 | protocol = (protocol_t *)list_item->data;
9063 | if (protocol->can_toggle)
9064 | protocol->is_enabled = protocol->enabled_by_default;
9065 | proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
9066 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
9067 | }
9068 | }
9069 |
9070 | void
9071 | proto_set_cant_toggle(const int proto_id)
9072 | {
9073 | protocol_t *protocol;
9074 |
9075 | protocol = find_protocol_by_id(proto_id);
9076 | protocol->can_toggle = false0;
9077 | }
9078 |
9079 | static int
9080 | proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
9081 | {
9082 | g_ptr_array_add(proto->fields, hfi);
9083 |
9084 | return proto_register_field_init(hfi, parent);
9085 | }
9086 |
9087 | /* for use with static arrays only, since we don't allocate our own copies
9088 | of the header_field_info struct contained within the hf_register_info struct */
9089 | void
9090 | proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
9091 | {
9092 | hf_register_info *ptr = hf;
9093 | protocol_t *proto;
9094 | int i;
9095 |
9096 | proto = find_protocol_by_id(parent);
9097 |
9098 | /* if (proto == NULL) - error or return? */
9099 |
9100 | if (proto->fields == NULL((void*)0)) {
9101 | /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
9102 | * GLib introduced g_ptr_array_new_from_array, which might have
9103 | * given a reason to actually use it. (#17774)
9104 | */
9105 | proto->fields = g_ptr_array_sized_new(num_records);
9106 | }
9107 |
9108 | for (i = 0; i < num_records; i++, ptr++) {
9109 | /*
9110 | * Make sure we haven't registered this yet.
9111 | * Most fields have variables associated with them that
9112 | * are initialized to 0; some are initialized to -1 (which
9113 | * was the standard before 4.4).
9114 | *
9115 | * XXX - Since this is called almost 300000 times at startup,
9116 | * it might be nice to compare to only 0 and require
9117 | * dissectors to pass in zero for unregistered fields.
9118 | */
9119 | if (*ptr->p_id != -1 && *ptr->p_id != 0) {
9120 | REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev)
9121 | "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)
9122 | ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev);
9123 | return;
9124 | }
9125 |
9126 | *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
9127 | }
9128 | }
9129 |
9130 | /* deregister already registered fields */
9131 | void
9132 | proto_deregister_field (const int parent, int hf_id)
9133 | {
9134 | header_field_info *hfi;
9135 | protocol_t *proto;
9136 | unsigned i;
9137 |
9138 | 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);
9139 | last_field_name = NULL((void*)0);
9140 |
9141 | if (hf_id == -1 || hf_id == 0)
9142 | return;
9143 |
9144 | proto = find_protocol_by_id (parent);
9145 | if (!proto || proto->fields == NULL((void*)0)) {
9146 | return;
9147 | }
9148 |
9149 | for (i = 0; i < proto->fields->len; i++) {
9150 | hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9151 | if (hfi->id == hf_id) {
9152 | /* Found the hf_id in this protocol */
9153 | wmem_map_remove(gpa_name_map, hfi->abbrev);
9154 | g_ptr_array_remove_index_fast(proto->fields, i);
9155 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
9156 | return;
9157 | }
9158 | }
9159 | }
9160 |
9161 | /* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
9162 | void
9163 | proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
9164 | {
9165 | header_field_info *hfinfo;
9166 | protocol_t *proto;
9167 |
9168 | 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);
9169 | last_field_name = NULL((void*)0);
9170 |
9171 | proto = find_protocol_by_id(parent);
9172 | if (proto && proto->fields && proto->fields->len > 0) {
9173 | unsigned i = proto->fields->len;
9174 | do {
9175 | i--;
9176 |
9177 | hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9178 | 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) )) {
9179 | hfinfo_remove_from_gpa_name_map(hfinfo);
9180 | expert_deregister_expertinfo(hfinfo->abbrev);
9181 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9182 | g_ptr_array_remove_index_fast(proto->fields, i);
9183 | }
9184 | } while (i > 0);
9185 | }
9186 | }
9187 |
9188 | void
9189 | proto_add_deregistered_data (void *data)
9190 | {
9191 | g_ptr_array_add(deregistered_data, data);
9192 | }
9193 |
9194 | void
9195 | proto_add_deregistered_slice (size_t block_size, void *mem_block)
9196 | {
9197 | 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)));
9198 |
9199 | slice_data->block_size = block_size;
9200 | slice_data->mem_block = mem_block;
9201 |
9202 | g_ptr_array_add(deregistered_slice, slice_data);
9203 | }
9204 |
9205 | void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9206 | {
9207 | if (field_strings == NULL((void*)0)) {
9208 | return;
9209 | }
9210 |
9211 | switch (field_type) {
9212 | case FT_FRAMENUM:
9213 | /* This is just an integer represented as a pointer */
9214 | break;
9215 | case FT_PROTOCOL: {
9216 | protocol_t *protocol = (protocol_t *)field_strings;
9217 | 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);
9218 | break;
9219 | }
9220 | case FT_BOOLEAN: {
9221 | true_false_string *tf = (true_false_string *)field_strings;
9222 | 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);
9223 | 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);
9224 | break;
9225 | }
9226 | case FT_UINT40:
9227 | case FT_INT40:
9228 | case FT_UINT48:
9229 | case FT_INT48:
9230 | case FT_UINT56:
9231 | case FT_INT56:
9232 | case FT_UINT64:
9233 | case FT_INT64: {
9234 | if (field_display & BASE_UNIT_STRING0x00001000) {
9235 | unit_name_string *unit = (unit_name_string *)field_strings;
9236 | 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);
9237 | 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);
9238 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9239 | range_string *rs = (range_string *)field_strings;
9240 | while (rs->strptr) {
9241 | 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 );
9242 | rs++;
9243 | }
9244 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9245 | val64_string_ext *vse = (val64_string_ext *)field_strings;
9246 | val64_string *vs = (val64_string *)vse->_vs_p;
9247 | while (vs->strptr) {
9248 | 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 );
9249 | vs++;
9250 | }
9251 | val64_string_ext_free(vse);
9252 | field_strings = NULL((void*)0);
9253 | } else if (field_display == BASE_CUSTOM) {
9254 | /* this will be a pointer to a function, don't free that */
9255 | field_strings = NULL((void*)0);
9256 | } else {
9257 | val64_string *vs64 = (val64_string *)field_strings;
9258 | while (vs64->strptr) {
9259 | 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);
9260 | vs64++;
9261 | }
9262 | }
9263 | break;
9264 | }
9265 | case FT_CHAR:
9266 | case FT_UINT8:
9267 | case FT_INT8:
9268 | case FT_UINT16:
9269 | case FT_INT16:
9270 | case FT_UINT24:
9271 | case FT_INT24:
9272 | case FT_UINT32:
9273 | case FT_INT32:
9274 | case FT_FLOAT:
9275 | case FT_DOUBLE: {
9276 | if (field_display & BASE_UNIT_STRING0x00001000) {
9277 | unit_name_string *unit = (unit_name_string *)field_strings;
9278 | 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);
9279 | 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);
9280 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9281 | range_string *rs = (range_string *)field_strings;
9282 | while (rs->strptr) {
9283 | 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 );
9284 | rs++;
9285 | }
9286 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9287 | value_string_ext *vse = (value_string_ext *)field_strings;
9288 | value_string *vs = (value_string *)vse->_vs_p;
9289 | while (vs->strptr) {
9290 | 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 );
9291 | vs++;
9292 | }
9293 | value_string_ext_free(vse);
9294 | field_strings = NULL((void*)0);
9295 | } else if (field_display == BASE_CUSTOM) {
9296 | /* this will be a pointer to a function, don't free that */
9297 | field_strings = NULL((void*)0);
9298 | } else {
9299 | value_string *vs = (value_string *)field_strings;
9300 | while (vs->strptr) {
9301 | 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 );
9302 | vs++;
9303 | }
9304 | }
9305 | break;
9306 | default:
9307 | break;
9308 | }
9309 | }
9310 |
9311 | if (field_type != FT_FRAMENUM) {
9312 | 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 );
9313 | }
9314 | }
9315 |
9316 | static void
9317 | free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9318 | {
9319 | header_field_info *hfi = (header_field_info *) data;
9320 | int hf_id = hfi->id;
9321 |
9322 | 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 );
9323 | 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 );
9324 | 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 );
9325 |
9326 | proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9327 |
9328 | if (hfi->parent == -1)
9329 | 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);
9330 |
9331 | gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9332 | }
9333 |
9334 | static void
9335 | free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9336 | {
9337 | g_free (data)(__builtin_object_size ((data), 0) != ((size_t) - 1)) ? g_free_sized (data, __builtin_object_size ((data), 0)) : (g_free) (data);
9338 | }
9339 |
9340 | static void
9341 | free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9342 | {
9343 | struct g_slice_data *slice_data = (struct g_slice_data *)data;
9344 |
9345 | g_slice_free1(slice_data->block_size, slice_data->mem_block);
9346 | 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);
9347 | }
9348 |
9349 | /* free deregistered fields and data */
9350 | void
9351 | proto_free_deregistered_fields (void)
9352 | {
9353 | expert_free_deregistered_expertinfos();
9354 |
9355 | g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9356 | g_ptr_array_free(deregistered_fields, true1);
9357 | deregistered_fields = g_ptr_array_new();
9358 |
9359 | g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9360 | g_ptr_array_free(deregistered_data, true1);
9361 | deregistered_data = g_ptr_array_new();
9362 |
9363 | g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9364 | g_ptr_array_free(deregistered_slice, true1);
9365 | deregistered_slice = g_ptr_array_new();
9366 | }
9367 |
9368 | static const value_string hf_display[] = {
9369 | { BASE_NONE, "BASE_NONE" },
9370 | { BASE_DEC, "BASE_DEC" },
9371 | { BASE_HEX, "BASE_HEX" },
9372 | { BASE_OCT, "BASE_OCT" },
9373 | { BASE_DEC_HEX, "BASE_DEC_HEX" },
9374 | { BASE_HEX_DEC, "BASE_HEX_DEC" },
9375 | { BASE_CUSTOM, "BASE_CUSTOM" },
9376 | { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9377 | { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9378 | { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9379 | { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9380 | { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9381 | { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9382 | { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9383 | { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9384 | { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9385 | { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9386 | { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9387 | { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9388 | { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9389 | { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9390 | { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9391 | { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9392 | { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9393 | { BASE_PT_UDP, "BASE_PT_UDP" },
9394 | { BASE_PT_TCP, "BASE_PT_TCP" },
9395 | { BASE_PT_DCCP, "BASE_PT_DCCP" },
9396 | { BASE_PT_SCTP, "BASE_PT_SCTP" },
9397 | { BASE_OUI, "BASE_OUI" },
9398 | { 0, NULL((void*)0) } };
9399 |
9400 | const char* proto_field_display_to_string(int field_display)
9401 | {
9402 | return val_to_str_const(field_display, hf_display, "Unknown");
9403 | }
9404 |
9405 | static inline port_type
9406 | display_to_port_type(field_display_e e)
9407 | {
9408 | switch (e) {
9409 | case BASE_PT_UDP:
9410 | return PT_UDP;
9411 | case BASE_PT_TCP:
9412 | return PT_TCP;
9413 | case BASE_PT_DCCP:
9414 | return PT_DCCP;
9415 | case BASE_PT_SCTP:
9416 | return PT_SCTP;
9417 | default:
9418 | break;
9419 | }
9420 | return PT_NONE;
9421 | }
9422 |
9423 | /* temporary function containing assert part for easier profiling */
9424 | static void
9425 | tmp_fld_check_assert(header_field_info *hfinfo)
9426 | {
9427 | char* tmp_str;
9428 |
9429 | /* The field must have a name (with length > 0) */
9430 | if (!hfinfo->name || !hfinfo->name[0]) {
9431 | if (hfinfo->abbrev)
9432 | /* Try to identify the field */
9433 | 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)
9434 | hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name" , hfinfo->abbrev);
9435 | else
9436 | /* Hum, no luck */
9437 | 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)" );
9438 | }
9439 |
9440 | /* fields with an empty string for an abbreviation aren't filterable */
9441 | if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9442 | 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);
9443 |
9444 | /* TODO: This check is a significant percentage of startup time (~10%),
9445 | although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9446 | It might be nice to have a way to disable this check when, e.g.,
9447 | running TShark many times with the same configuration. */
9448 | /* Check that the filter name (abbreviation) is legal;
9449 | * it must contain only alphanumerics, '-', "_", and ".". */
9450 | unsigned char c;
9451 | c = module_check_valid_name(hfinfo->abbrev, false0);
9452 | if (c) {
9453 | if (c == '.') {
9454 | 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);
9455 | } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9456 | 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);
9457 | } else {
9458 | 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);
9459 | }
9460 | }
9461 |
9462 | /* These types of fields are allowed to have value_strings,
9463 | * true_false_strings or a protocol_t struct
9464 | */
9465 | if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9466 | switch (hfinfo->type) {
9467 |
9468 | /*
9469 | * These types are allowed to support display value_strings,
9470 | * value64_strings, the extended versions of the previous
9471 | * two, range strings, or unit strings.
9472 | */
9473 | case FT_CHAR:
9474 | case FT_UINT8:
9475 | case FT_UINT16:
9476 | case FT_UINT24:
9477 | case FT_UINT32:
9478 | case FT_UINT40:
9479 | case FT_UINT48:
9480 | case FT_UINT56:
9481 | case FT_UINT64:
9482 | case FT_INT8:
9483 | case FT_INT16:
9484 | case FT_INT24:
9485 | case FT_INT32:
9486 | case FT_INT40:
9487 | case FT_INT48:
9488 | case FT_INT56:
9489 | case FT_INT64:
9490 | case FT_BOOLEAN:
9491 | case FT_PROTOCOL:
9492 | break;
9493 |
9494 | /*
9495 | * This is allowed to have a value of type
9496 | * enum ft_framenum_type to indicate what relationship
9497 | * the frame in question has to the frame in which
9498 | * the field is put.
9499 | */
9500 | case FT_FRAMENUM:
9501 | break;
9502 |
9503 | /*
9504 | * These types are allowed to support only unit strings.
9505 | */
9506 | case FT_FLOAT:
9507 | case FT_DOUBLE:
9508 | case FT_IEEE_11073_SFLOAT:
9509 | case FT_IEEE_11073_FLOAT:
9510 | if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9511 | 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))
9512 | " (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))
9513 | 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));
9514 | }
9515 | break;
9516 |
9517 | /*
9518 | * These types are allowed to support display
9519 | * time_value_strings.
9520 | */
9521 | case FT_ABSOLUTE_TIME:
9522 | if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9523 | hfinfo->display & BASE_EXT_STRING0x00000200 ||
9524 | hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9525 | hfinfo->display & BASE_UNIT_STRING0x00001000) {
9526 | 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))
9527 | " (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))
9528 | 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));
9529 | }
9530 | break;
9531 |
9532 | /*
9533 | * This type is only allowed to support a string if it's
9534 | * a protocol (for pinos).
9535 | */
9536 | case FT_BYTES:
9537 | if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9538 | 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))
9539 | " (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))
9540 | 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));
9541 | }
9542 | break;
9543 |
9544 | default:
9545 | 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))
9546 | " (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))
9547 | 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));
9548 | }
9549 | }
9550 |
9551 | /* TODO: This check may slow down startup, and output quite a few warnings.
9552 | It would be good to be able to enable this (and possibly other checks?)
9553 | in non-release builds. */
9554 | #ifdef ENABLE_CHECK_FILTER
9555 | /* Check for duplicate value_string values.
9556 | There are lots that have the same value *and* string, so for now only
9557 | report those that have same value but different string. */
9558 | if ((hfinfo->strings != NULL((void*)0)) &&
9559 | !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9560 | !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9561 | !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9562 | (
9563 | (hfinfo->type == FT_CHAR) ||
9564 | (hfinfo->type == FT_UINT8) ||
9565 | (hfinfo->type == FT_UINT16) ||
9566 | (hfinfo->type == FT_UINT24) ||
9567 | (hfinfo->type == FT_UINT32) ||
9568 | (hfinfo->type == FT_INT8) ||
9569 | (hfinfo->type == FT_INT16) ||
9570 | (hfinfo->type == FT_INT24) ||
9571 | (hfinfo->type == FT_INT32) )) {
9572 |
9573 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9574 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9575 | const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9576 | CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9577 | } else {
9578 | const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9579 | CHECK_HF_VALUE(value_string, "u", start_values);
9580 | }
9581 | } else {
9582 | const value_string *start_values = (const value_string*)hfinfo->strings;
9583 | CHECK_HF_VALUE(value_string, "u", start_values);
9584 | }
9585 | }
9586 |
9587 | if (hfinfo->type == FT_BOOLEAN) {
9588 | const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9589 | if (tfs) {
9590 | if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9591 | ws_error("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9593 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string)
9592 | hfinfo->name, hfinfo->abbrev,ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9593 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string)
9593 | tfs->false_string, tfs->true_string)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 9593 , __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string);
9594 | }
9595 | }
9596 | }
9597 |
9598 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9599 | const range_string *rs = (const range_string*)(hfinfo->strings);
9600 | if (rs) {
9601 | const range_string *this_it = rs;
9602 |
9603 | do {
9604 | if (this_it->value_max < this_it->value_min) {
9605 | 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" , 9609, __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)
9606 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9609, __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)
9607 | this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9609, __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)
9608 | this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9609, __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)
9609 | this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9609, __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);
9610 | ++this_it;
9611 | continue;
9612 | }
9613 |
9614 | for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9615 | /* Not OK if this one is completely hidden by an earlier one! */
9616 | if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9617 | 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" , 9623, __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)
9618 | "(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" , 9623, __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)
9619 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9623, __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)
9620 | prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9623, __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)
9621 | prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9623, __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)
9622 | this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9623, __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)
9623 | this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9623, __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);
9624 | }
9625 | }
9626 | ++this_it;
9627 | } while (this_it->strptr);
9628 | }
9629 | }
9630 | #endif
9631 |
9632 | switch (hfinfo->type) {
9633 |
9634 | case FT_CHAR:
9635 | /* Require the char type to have BASE_HEX, BASE_OCT,
9636 | * BASE_CUSTOM, or BASE_NONE as its base.
9637 | *
9638 | * If the display value is BASE_NONE and there is a
9639 | * strings conversion then the dissector writer is
9640 | * telling us that the field's numerical value is
9641 | * meaningless; we'll avoid showing the value to the
9642 | * user.
9643 | */
9644 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9645 | case BASE_HEX:
9646 | case BASE_OCT:
9647 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9648 | break;
9649 | case BASE_NONE:
9650 | if (hfinfo->strings == NULL((void*)0))
9651 | 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 ))
9652 | " 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 ))
9653 | " 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 ))
9654 | 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 ))
9655 | 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 ));
9656 | break;
9657 | default:
9658 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9659 | 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)
9660 | " 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)
9661 | 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)
9662 | 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);
9663 | //wmem_free(NULL, tmp_str);
9664 | }
9665 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9666 | 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 ))
9667 | 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 ))
9668 | 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 ));
9669 | }
9670 | break;
9671 | case FT_INT8:
9672 | case FT_INT16:
9673 | case FT_INT24:
9674 | case FT_INT32:
9675 | case FT_INT40:
9676 | case FT_INT48:
9677 | case FT_INT56:
9678 | case FT_INT64:
9679 | /* Hexadecimal and octal are, in printf() and everywhere
9680 | * else, unsigned so don't allow dissectors to register a
9681 | * signed field to be displayed unsigned. (Else how would
9682 | * we display negative values?)
9683 | */
9684 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9685 | case BASE_HEX:
9686 | case BASE_OCT:
9687 | case BASE_DEC_HEX:
9688 | case BASE_HEX_DEC:
9689 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9690 | 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)
9691 | 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)
9692 | 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);
9693 | //wmem_free(NULL, tmp_str);
9694 | }
9695 | /* FALL THROUGH */
9696 | case FT_UINT8:
9697 | case FT_UINT16:
9698 | case FT_UINT24:
9699 | case FT_UINT32:
9700 | case FT_UINT40:
9701 | case FT_UINT48:
9702 | case FT_UINT56:
9703 | case FT_UINT64:
9704 | 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 ))) {
9705 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9706 | if (hfinfo->type != FT_UINT16) {
9707 | 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))
9708 | 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))
9709 | 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));
9710 | }
9711 | if (hfinfo->strings != NULL((void*)0)) {
9712 | 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)
9713 | 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)
9714 | 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);
9715 | }
9716 | if (hfinfo->bitmask != 0) {
9717 | 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)
9718 | 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)
9719 | 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);
9720 | }
9721 | wmem_free(NULL((void*)0), tmp_str);
9722 | break;
9723 | }
9724 |
9725 | if (hfinfo->display == BASE_OUI) {
9726 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9727 | 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) {
9728 | 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))
9729 | 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))
9730 | 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));
9731 | }
9732 | if (hfinfo->strings != NULL((void*)0)) {
9733 | 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)
9734 | 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)
9735 | 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);
9736 | }
9737 | /* It can be a FT_UINT24 with a 0 bitmask, or
9738 | * larger with a bitmask with 24 bits set. */
9739 | if ((hfinfo->type != FT_UINT24 || hfinfo->bitmask != 0) && ws_count_ones(hfinfo->bitmask) != 24) {
9740 | 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)
9741 | 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)
9742 | 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);
9743 | }
9744 | wmem_free(NULL((void*)0), tmp_str);
9745 | break;
9746 | }
9747 |
9748 | /* Require integral types (other than frame number,
9749 | * which is always displayed in decimal) to have a
9750 | * number base.
9751 | *
9752 | * If the display value is BASE_NONE and there is a
9753 | * strings conversion then the dissector writer is
9754 | * telling us that the field's numerical value is
9755 | * meaningless; we'll avoid showing the value to the
9756 | * user.
9757 | */
9758 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9759 | case BASE_DEC:
9760 | case BASE_HEX:
9761 | case BASE_OCT:
9762 | case BASE_DEC_HEX:
9763 | case BASE_HEX_DEC:
9764 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9765 | break;
9766 | case BASE_NONE:
9767 | if (hfinfo->strings == NULL((void*)0)) {
9768 | 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 ))
9769 | " 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 ))
9770 | " 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 ))
9771 | 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 ))
9772 | 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 ));
9773 | }
9774 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9775 | 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 ))
9776 | " 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 ))
9777 | " 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 ))
9778 | 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 ))
9779 | 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 ));
9780 | }
9781 | break;
9782 |
9783 | default:
9784 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9785 | 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)
9786 | " 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)
9787 | 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)
9788 | 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);
9789 | //wmem_free(NULL, tmp_str);
9790 | }
9791 | break;
9792 | case FT_BYTES:
9793 | case FT_UINT_BYTES:
9794 | /* Require bytes to have a "display type" that could
9795 | * add a character between displayed bytes.
9796 | */
9797 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9798 | case BASE_NONE:
9799 | case SEP_DOT:
9800 | case SEP_DASH:
9801 | case SEP_COLON:
9802 | case SEP_SPACE:
9803 | break;
9804 | default:
9805 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9806 | 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)
9807 | 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);
9808 | //wmem_free(NULL, tmp_str);
9809 | }
9810 | if (hfinfo->bitmask != 0)
9811 | 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 ))
9812 | 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 ))
9813 | 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 ));
9814 | //allowed to support string if its a protocol (for pinos)
9815 | if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9816 | 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 ))
9817 | 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 ))
9818 | 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 ));
9819 | break;
9820 |
9821 | case FT_PROTOCOL:
9822 | case FT_FRAMENUM:
9823 | if (hfinfo->display != BASE_NONE) {
9824 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9825 | 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)
9826 | 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)
9827 | 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);
9828 | //wmem_free(NULL, tmp_str);
9829 | }
9830 | if (hfinfo->bitmask != 0)
9831 | 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 ))
9832 | 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 ))
9833 | 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 ));
9834 | break;
9835 |
9836 | case FT_BOOLEAN:
9837 | break;
9838 |
9839 | case FT_ABSOLUTE_TIME:
9840 | if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL && ((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)) {
9841 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9842 | 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)
9843 | 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);
9844 | //wmem_free(NULL, tmp_str);
9845 | }
9846 | if (hfinfo->bitmask != 0)
9847 | 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 ))
9848 | 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 ))
9849 | 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 ));
9850 | break;
9851 |
9852 | case FT_STRING:
9853 | case FT_STRINGZ:
9854 | case FT_UINT_STRING:
9855 | case FT_STRINGZPAD:
9856 | case FT_STRINGZTRUNC:
9857 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9858 | case BASE_NONE:
9859 | case BASE_STR_WSP:
9860 | break;
9861 |
9862 | default:
9863 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9864 | 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)
9865 | " 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)
9866 | 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)
9867 | 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);
9868 | //wmem_free(NULL, tmp_str);
9869 | }
9870 |
9871 | if (hfinfo->bitmask != 0)
9872 | 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 ))
9873 | 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 ))
9874 | 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 ));
9875 | if (hfinfo->strings != NULL((void*)0))
9876 | 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 ))
9877 | 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 ))
9878 | 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 ));
9879 | break;
9880 |
9881 | case FT_IPv4:
9882 | switch (hfinfo->display) {
9883 | case BASE_NONE:
9884 | case BASE_NETMASK:
9885 | break;
9886 |
9887 | default:
9888 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9889 | 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)
9890 | " 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)
9891 | 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)
9892 | 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);
9893 | //wmem_free(NULL, tmp_str);
9894 | break;
9895 | }
9896 | break;
9897 | case FT_FLOAT:
9898 | case FT_DOUBLE:
9899 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9900 | case BASE_NONE:
9901 | case BASE_DEC:
9902 | case BASE_HEX:
9903 | case BASE_EXP:
9904 | case BASE_CUSTOM:
9905 | break;
9906 | default:
9907 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9908 | 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)
9909 | " 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)
9910 | 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)
9911 | 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);
9912 | //wmem_free(NULL, tmp_str);
9913 | }
9914 | if (hfinfo->bitmask != 0)
9915 | 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 ))
9916 | 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 ))
9917 | 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 ));
9918 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9919 | 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 ))
9920 | 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 ))
9921 | 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 ));
9922 | break;
9923 | case FT_IEEE_11073_SFLOAT:
9924 | case FT_IEEE_11073_FLOAT:
9925 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9926 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9927 | 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)
9928 | 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)
9929 | 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)
9930 | 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);
9931 | //wmem_free(NULL, tmp_str);
9932 | }
9933 | if (hfinfo->bitmask != 0)
9934 | 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 ))
9935 | 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 ))
9936 | 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 ));
9937 | if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9938 | 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 ))
9939 | 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 ))
9940 | 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 ));
9941 | break;
9942 | default:
9943 | if (hfinfo->display != BASE_NONE) {
9944 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9945 | 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)
9946 | 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)
9947 | 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)
9948 | 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);
9949 | //wmem_free(NULL, tmp_str);
9950 | }
9951 | if (hfinfo->bitmask != 0)
9952 | 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 ))
9953 | 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 ))
9954 | 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 ));
9955 | if (hfinfo->strings != NULL((void*)0))
9956 | 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 ))
9957 | 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 ))
9958 | 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 ));
9959 | break;
9960 | }
9961 | }
9962 |
9963 | static void
9964 | register_type_length_mismatch(void)
9965 | {
9966 | static ei_register_info ei[] = {
9967 | { &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)}} }},
9968 | { &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)}} }},
9969 | };
9970 |
9971 | expert_module_t* expert_type_length_mismatch;
9972 |
9973 | proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9974 |
9975 | expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9976 | expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9977 |
9978 | /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9979 | disabling them makes no sense. */
9980 | proto_set_cant_toggle(proto_type_length_mismatch);
9981 | }
9982 |
9983 | static void
9984 | register_byte_array_string_decodinws_error(void)
9985 | {
9986 | static ei_register_info ei[] = {
9987 | { &ei_byte_array_string_decoding_failed_error,
9988 | { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9989 | "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)}}
9990 | }
9991 | },
9992 | };
9993 |
9994 | expert_module_t* expert_byte_array_string_decoding_error;
9995 |
9996 | proto_byte_array_string_decoding_error =
9997 | proto_register_protocol("Byte Array-String Decoding Error",
9998 | "Byte Array-string decoding error",
9999 | "_ws.byte_array_string.decoding_error");
10000 |
10001 | expert_byte_array_string_decoding_error =
10002 | expert_register_protocol(proto_byte_array_string_decoding_error);
10003 | expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10004 |
10005 | /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
10006 | disabling them makes no sense. */
10007 | proto_set_cant_toggle(proto_byte_array_string_decoding_error);
10008 | }
10009 |
10010 | static void
10011 | register_date_time_string_decodinws_error(void)
10012 | {
10013 | static ei_register_info ei[] = {
10014 | { &ei_date_time_string_decoding_failed_error,
10015 | { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
10016 | "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)}}
10017 | }
10018 | },
10019 | };
10020 |
10021 | expert_module_t* expert_date_time_string_decoding_error;
10022 |
10023 | proto_date_time_string_decoding_error =
10024 | proto_register_protocol("Date and Time-String Decoding Error",
10025 | "Date and Time-string decoding error",
10026 | "_ws.date_time_string.decoding_error");
10027 |
10028 | expert_date_time_string_decoding_error =
10029 | expert_register_protocol(proto_date_time_string_decoding_error);
10030 | expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10031 |
10032 | /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
10033 | disabling them makes no sense. */
10034 | proto_set_cant_toggle(proto_date_time_string_decoding_error);
10035 | }
10036 |
10037 | static void
10038 | register_string_errors(void)
10039 | {
10040 | static ei_register_info ei[] = {
10041 | { &ei_string_trailing_characters,
10042 | { "_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)}} }
10043 | },
10044 | };
10045 |
10046 | expert_module_t* expert_string_errors;
10047 |
10048 | proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
10049 |
10050 | expert_string_errors = expert_register_protocol(proto_string_errors);
10051 | expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
10052 |
10053 | /* "String Errors" isn't really a protocol, it's an error indication;
10054 | disabling them makes no sense. */
10055 | proto_set_cant_toggle(proto_string_errors);
10056 | }
10057 |
10058 | static int
10059 | proto_register_field_init(header_field_info *hfinfo, const int parent)
10060 | {
10061 |
10062 | tmp_fld_check_assert(hfinfo);
10063 |
10064 | hfinfo->parent = parent;
10065 | hfinfo->same_name_next = NULL((void*)0);
10066 | hfinfo->same_name_prev_id = -1;
10067 |
10068 | /* if we always add and never delete, then id == len - 1 is correct */
10069 | if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
10070 | if (!gpa_hfinfo.hfi) {
10071 | gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
10072 | gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
10073 | /* The entry with index 0 is not used. */
10074 | gpa_hfinfo.hfi[0] = NULL((void*)0);
10075 | gpa_hfinfo.len = 1;
10076 | } else {
10077 | gpa_hfinfo.allocated_len += 1000;
10078 | gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
10079 | sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
10080 | /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
10081 | }
10082 | }
10083 | gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
10084 | gpa_hfinfo.len++;
10085 | hfinfo->id = gpa_hfinfo.len - 1;
10086 |
10087 | /* if we have real names, enter this field in the name tree */
10088 | /* Already checked in tmp_fld_check_assert */
10089 | /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
10090 | {
10091 |
10092 | header_field_info *same_name_next_hfinfo;
10093 |
10094 | /* We allow multiple hfinfo's to be registered under the same
10095 | * abbreviation. This was done for X.25, as, depending
10096 | * on whether it's modulo-8 or modulo-128 operation,
10097 | * some bitfield fields may be in different bits of
10098 | * a byte, and we want to be able to refer to that field
10099 | * with one name regardless of whether the packets
10100 | * are modulo-8 or modulo-128 packets. */
10101 |
10102 | /* wmem_map_insert - if key is already present the previous
10103 | * hfinfo with the same key/name is returned, otherwise NULL */
10104 | same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
10105 | if (same_name_hfinfo) {
10106 | /* There's already a field with this name.
10107 | * Put the current field *before* that field
10108 | * in the list of fields with this name, Thus,
10109 | * we end up with an effectively
10110 | * doubly-linked-list of same-named hfinfo's,
10111 | * with the head of the list (stored in the
10112 | * hash) being the last seen hfinfo.
10113 | */
10114 | same_name_next_hfinfo =
10115 | same_name_hfinfo->same_name_next;
10116 |
10117 | hfinfo->same_name_next = same_name_next_hfinfo;
10118 | if (same_name_next_hfinfo)
10119 | same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
10120 |
10121 | same_name_hfinfo->same_name_next = hfinfo;
10122 | hfinfo->same_name_prev_id = same_name_hfinfo->id;
10123 | #ifdef ENABLE_CHECK_FILTER
10124 | while (same_name_hfinfo) {
10125 | if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
10126 | 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", 10126 , __func__, "'%s' exists multiple times with incompatible types: %s and %s" , hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name( same_name_hfinfo->type));
10127 | same_name_hfinfo = same_name_hfinfo->same_name_next;
10128 | }
10129 | #endif
10130 | }
10131 | }
10132 |
10133 | return hfinfo->id;
10134 | }
10135 |
10136 | void
10137 | proto_register_subtree_array(int * const *indices, const int num_indices)
10138 | {
10139 | int i;
10140 | int *const *ptr = indices;
10141 |
10142 | /*
10143 | * If we've already allocated the array of tree types, expand
10144 | * it; this lets plugins such as mate add tree types after
10145 | * the initial startup. (If we haven't already allocated it,
10146 | * we don't allocate it; on the first pass, we just assign
10147 | * ett values and keep track of how many we've assigned, and
10148 | * when we're finished registering all dissectors we allocate
10149 | * the array, so that we do only one allocation rather than
10150 | * wasting CPU time and memory by growing the array for each
10151 | * dissector that registers ett values.)
10152 | */
10153 | if (tree_is_expanded != NULL((void*)0)) {
10154 | tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
10155 |
10156 | /* set new items to 0 */
10157 | /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
10158 | for (i = num_tree_types; i < num_tree_types + num_indices; i++)
10159 | tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
10160 | }
10161 |
10162 | /*
10163 | * Assign "num_indices" subtree numbers starting at "num_tree_types",
10164 | * returning the indices through the pointers in the array whose
10165 | * first element is pointed to by "indices", and update
10166 | * "num_tree_types" appropriately.
10167 | */
10168 | for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
10169 | if (**ptr != -1 && **ptr != 0) {
10170 | 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.")
10171 | " 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.")
10172 | " 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.")
10173 | " 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.");
10174 | }
10175 | **ptr = num_tree_types;
10176 | }
10177 | }
10178 |
10179 | static void
10180 | mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10181 | {
10182 | static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10183 | const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10184 | char *last_char;
10185 |
10186 | /* ..... field_name: dataaaaaaaaaaaaa
10187 | * |
10188 | * ^^^^^ name_pos
10189 | *
10190 | * ..... field_name […]: dataaaaaaaaaaaaa
10191 | *
10192 | * name_pos==0 means that we have only data or only a field_name
10193 | */
10194 |
10195 | ws_abort_if_fail(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10195, __func__, "assertion failed: %s" , "size > trunc_len"); } while (0);
10196 |
10197 | if (name_pos >= size - trunc_len) {
10198 | /* No room for trunc_str after the field_name, put it first. */
10199 | name_pos = 0;
10200 | }
10201 |
10202 | memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10203 | if (name_pos == 0) {
10204 | /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10205 | memcpy(label_str, trunc_str + 1, trunc_len);
10206 | } else {
10207 | memcpy(label_str + name_pos, trunc_str, trunc_len);
10208 | }
10209 | /* in general, label_str is UTF-8
10210 | we can truncate it only at the beginning of a new character
10211 | we go backwards from the byte right after our buffer and
10212 | find the next starting byte of a UTF-8 character, this is
10213 | where we cut
10214 | there's no need to use g_utf8_find_prev_char(), the search
10215 | will always succeed since we copied trunc_str into the
10216 | buffer */
10217 | /* g_utf8_prev_char does not deference the memory address
10218 | * passed in (until after decrementing it, so it is perfectly
10219 | * legal to pass in a pointer one past the last element.
10220 | */
10221 | last_char = g_utf8_prev_char(label_str + size);
10222 | *last_char = '\0';
10223 | /* This is unnecessary (above always terminates), but try to
10224 | * convince Coverity to avoid dozens of false positives. */
10225 | label_str[size - 1] = '\0';
10226 |
10227 | if (value_pos && *value_pos > 0) {
10228 | if (name_pos == 0) {
10229 | *value_pos += trunc_len;
10230 | } else {
10231 | /* Move one back to include trunc_str in the value. */
10232 | *value_pos -= 1;
10233 | }
10234 | }
10235 |
10236 | /* Check if value_pos is past label_str. */
10237 | if (value_pos && *value_pos >= size) {
10238 | *value_pos = size - 1;
10239 | }
10240 | }
10241 |
10242 | static void
10243 | label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10244 | {
10245 | mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10246 | }
10247 |
10248 | static size_t
10249 | label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10250 | {
10251 | size_t name_pos;
10252 |
10253 | /* "%s: %s", hfinfo->name, text */
10254 | 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);
10255 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10256 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10257 | if (value_pos) {
10258 | *value_pos = pos;
10259 | }
10260 | pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10261 | }
10262 |
10263 | if (pos >= ITEM_LABEL_LENGTH240) {
10264 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10265 | label_mark_truncated(label_str, name_pos, value_pos);
10266 | }
10267 |
10268 | return pos;
10269 | }
10270 |
10271 | static size_t
10272 | label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10273 | {
10274 | size_t name_pos;
10275 |
10276 | /* "%s: %s (%s)", hfinfo->name, text, descr */
10277 | 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);
10278 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10279 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10280 | if (value_pos) {
10281 | *value_pos = pos;
10282 | }
10283 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10284 | 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);
10285 | 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);
10286 | } else {
10287 | 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);
10288 | pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10289 | 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);
10290 | pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10291 | }
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 | void
10303 | proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10304 | {
10305 | const header_field_info *hfinfo;
10306 | const char *str;
10307 | const uint8_t *bytes;
10308 | uint32_t integer;
10309 | const ipv4_addr_and_mask *ipv4;
10310 | const ipv6_addr_and_prefix *ipv6;
10311 | const e_guid_t *guid;
10312 | char *name;
10313 | address addr;
10314 | char *addr_str;
10315 | char *tmp;
10316 |
10317 | if (!label_str) {
10318 | ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10318, __func__, "NULL label_str passed to proto_item_fill_label." ); } } while (0);
10319 | return;
10320 | }
10321 |
10322 | label_str[0]= '\0';
10323 |
10324 | if (!fi) {
10325 | return;
10326 | }
10327 |
10328 | hfinfo = fi->hfinfo;
10329 |
10330 | switch (hfinfo->type) {
10331 | case FT_NONE:
10332 | case FT_PROTOCOL:
10333 | (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10334 | if (value_pos) {
10335 | *value_pos = strlen(hfinfo->name);
10336 | }
10337 | break;
10338 |
10339 | case FT_BOOLEAN:
10340 | fill_label_boolean(fi, label_str, value_pos);
10341 | break;
10342 |
10343 | case FT_BYTES:
10344 | case FT_UINT_BYTES:
10345 | tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10346 | fvalue_get_bytes_data(fi->value),
10347 | (unsigned)fvalue_length2(fi->value));
10348 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10349 | wmem_free(NULL((void*)0), tmp);
10350 | break;
10351 |
10352 | case FT_CHAR:
10353 | if (hfinfo->bitmask) {
10354 | fill_label_bitfield_char(fi, label_str, value_pos);
10355 | } else {
10356 | fill_label_char(fi, label_str, value_pos);
10357 | }
10358 | break;
10359 |
10360 | /* Four types of integers to take care of:
10361 | * Bitfield, with val_string
10362 | * Bitfield, w/o val_string
10363 | * Non-bitfield, with val_string
10364 | * Non-bitfield, w/o val_string
10365 | */
10366 | case FT_UINT8:
10367 | case FT_UINT16:
10368 | case FT_UINT24:
10369 | case FT_UINT32:
10370 | if (hfinfo->bitmask) {
10371 | fill_label_bitfield(fi, label_str, value_pos, false0);
10372 | } else {
10373 | fill_label_number(fi, label_str, value_pos, false0);
10374 | }
10375 | break;
10376 |
10377 | case FT_FRAMENUM:
10378 | fill_label_number(fi, label_str, value_pos, false0);
10379 | break;
10380 |
10381 | case FT_UINT40:
10382 | case FT_UINT48:
10383 | case FT_UINT56:
10384 | case FT_UINT64:
10385 | if (hfinfo->bitmask) {
10386 | fill_label_bitfield64(fi, label_str, value_pos, false0);
10387 | } else {
10388 | fill_label_number64(fi, label_str, value_pos, false0);
10389 | }
10390 | break;
10391 |
10392 | case FT_INT8:
10393 | case FT_INT16:
10394 | case FT_INT24:
10395 | case FT_INT32:
10396 | if (hfinfo->bitmask) {
10397 | fill_label_bitfield(fi, label_str, value_pos, true1);
10398 | } else {
10399 | fill_label_number(fi, label_str, value_pos, true1);
10400 | }
10401 | break;
10402 |
10403 | case FT_INT40:
10404 | case FT_INT48:
10405 | case FT_INT56:
10406 | case FT_INT64:
10407 | if (hfinfo->bitmask) {
10408 | fill_label_bitfield64(fi, label_str, value_pos, true1);
10409 | } else {
10410 | fill_label_number64(fi, label_str, value_pos, true1);
10411 | }
10412 | break;
10413 |
10414 | case FT_FLOAT:
10415 | case FT_DOUBLE:
10416 | fill_label_float(fi, label_str, value_pos);
10417 | break;
10418 |
10419 | case FT_ABSOLUTE_TIME:
10420 | {
10421 | const nstime_t *value = fvalue_get_time(fi->value);
10422 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10423 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10424 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10425 | }
10426 | if (hfinfo->strings) {
10427 | /*
10428 | * Table of time valus to be displayed
10429 | * specially.
10430 | */
10431 | const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10432 | if (time_string != NULL((void*)0)) {
10433 | label_fill(label_str, 0, hfinfo, time_string, value_pos);
10434 | break;
10435 | }
10436 | }
10437 | tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10438 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10439 | wmem_free(NULL((void*)0), tmp);
10440 | break;
10441 | }
10442 | case FT_RELATIVE_TIME:
10443 | tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10444 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10445 | wmem_free(NULL((void*)0), tmp);
10446 | break;
10447 |
10448 | case FT_IPXNET:
10449 | integer = fvalue_get_uinteger(fi->value);
10450 | tmp = get_ipxnet_name(NULL((void*)0), integer);
10451 | addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10452 | label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10453 | wmem_free(NULL((void*)0), tmp);
10454 | wmem_free(NULL((void*)0), addr_str);
10455 | break;
10456 |
10457 | case FT_VINES:
10458 | addr.type = AT_VINES;
10459 | addr.len = VINES_ADDR_LEN6;
10460 | addr.data = fvalue_get_bytes_data(fi->value);
10461 |
10462 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10463 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10464 | wmem_free(NULL((void*)0), addr_str);
10465 | break;
10466 |
10467 | case FT_ETHER:
10468 | bytes = fvalue_get_bytes_data(fi->value);
10469 |
10470 | addr.type = AT_ETHER;
10471 | addr.len = 6;
10472 | addr.data = bytes;
10473 |
10474 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10475 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10476 | wmem_free(NULL((void*)0), addr_str);
10477 | break;
10478 |
10479 | case FT_IPv4:
10480 | ipv4 = fvalue_get_ipv4(fi->value);
10481 | set_address_ipv4(&addr, ipv4);
10482 |
10483 | if (hfinfo->display == BASE_NETMASK) {
10484 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10485 | } else {
10486 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10487 | }
10488 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10489 | wmem_free(NULL((void*)0), addr_str);
10490 | free_address(&addr);
10491 | break;
10492 |
10493 | case FT_IPv6:
10494 | ipv6 = fvalue_get_ipv6(fi->value);
10495 | set_address_ipv6(&addr, ipv6);
10496 |
10497 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10498 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10499 | wmem_free(NULL((void*)0), addr_str);
10500 | free_address(&addr);
10501 | break;
10502 |
10503 | case FT_FCWWN:
10504 | bytes = fvalue_get_bytes_data(fi->value);
10505 | addr.type = AT_FCWWN;
10506 | addr.len = FCWWN_ADDR_LEN8;
10507 | addr.data = bytes;
10508 |
10509 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10510 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10511 | wmem_free(NULL((void*)0), addr_str);
10512 | break;
10513 |
10514 | case FT_GUID:
10515 | guid = fvalue_get_guid(fi->value);
10516 | tmp = guid_to_str(NULL((void*)0), guid);
10517 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10518 | wmem_free(NULL((void*)0), tmp);
10519 | break;
10520 |
10521 | case FT_OID:
10522 | bytes = fvalue_get_bytes_data(fi->value);
10523 | name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10524 | tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10525 | if (name) {
10526 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10527 | wmem_free(NULL((void*)0), name);
10528 | } else {
10529 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10530 | }
10531 | wmem_free(NULL((void*)0), tmp);
10532 | break;
10533 |
10534 | case FT_REL_OID:
10535 | bytes = fvalue_get_bytes_data(fi->value);
10536 | name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10537 | tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10538 | if (name) {
10539 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10540 | wmem_free(NULL((void*)0), name);
10541 | } else {
10542 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10543 | }
10544 | wmem_free(NULL((void*)0), tmp);
10545 | break;
10546 |
10547 | case FT_SYSTEM_ID:
10548 | bytes = fvalue_get_bytes_data(fi->value);
10549 | tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10550 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10551 | wmem_free(NULL((void*)0), tmp);
10552 | break;
10553 |
10554 | case FT_EUI64:
10555 | bytes = fvalue_get_bytes_data(fi->value);
10556 | addr.type = AT_EUI64;
10557 | addr.len = EUI64_ADDR_LEN8;
10558 | addr.data = bytes;
10559 |
10560 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10561 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10562 | wmem_free(NULL((void*)0), addr_str);
10563 | break;
10564 | case FT_STRING:
10565 | case FT_STRINGZ:
10566 | case FT_UINT_STRING:
10567 | case FT_STRINGZPAD:
10568 | case FT_STRINGZTRUNC:
10569 | case FT_AX25:
10570 | str = fvalue_get_string(fi->value);
10571 | label_fill(label_str, 0, hfinfo, str, value_pos);
10572 | break;
10573 |
10574 | case FT_IEEE_11073_SFLOAT:
10575 | case FT_IEEE_11073_FLOAT:
10576 | fill_label_ieee_11073_float(fi, label_str, value_pos);
10577 | break;
10578 |
10579 | default:
10580 | 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 ))
10581 | 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 ))
10582 | 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 ))
10583 | 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 ));
10584 | break;
10585 | }
10586 | }
10587 |
10588 | static void
10589 | fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10590 | {
10591 | char *p;
10592 | unsigned bitfield_byte_length = 0;
10593 | int bitwidth;
10594 | uint64_t unshifted_value;
10595 | uint64_t value;
10596 |
10597 | const header_field_info *hfinfo = fi->hfinfo;
10598 |
10599 | value = fvalue_get_uinteger64(fi->value);
10600 | if (hfinfo->bitmask) {
10601 | /* Figure out the bit width */
10602 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10603 |
10604 | /* Un-shift bits */
10605 | unshifted_value = value;
10606 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10607 |
10608 | /* Create the bitfield first */
10609 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10610 | bitfield_byte_length = (unsigned) (p - label_str);
10611 | }
10612 |
10613 | /* Fill in the textual info */
10614 | label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10615 | }
10616 |
10617 | static const char *
10618 | hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10619 | {
10620 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10621 | return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10622 |
10623 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10624 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10625 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10626 | else
10627 | return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10628 | }
10629 |
10630 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10631 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10632 |
10633 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10634 | return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10635 |
10636 | return try_val_to_str(value, (const value_string *) hfinfo->strings);
10637 | }
10638 |
10639 | static const char *
10640 | hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10641 | {
10642 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10643 | if (hfinfo->display & BASE_EXT_STRING0x00000200)
10644 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10645 | else
10646 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10647 | }
10648 |
10649 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10650 | return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10651 |
10652 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10653 | return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10654 |
10655 | /* If this is reached somebody registered a 64-bit field with a 32-bit
10656 | * value-string, which isn't right. */
10657 | 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)
10658 | hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string" , hfinfo->abbrev);
10659 |
10660 | /* This is necessary to squelch MSVC errors; is there
10661 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10662 | never returns? */
10663 | return NULL((void*)0);
10664 | }
10665 |
10666 | static const char *
10667 | hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10668 | {
10669 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10670 | return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10671 |
10672 | 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);
10673 |
10674 | /* This is necessary to squelch MSVC errors; is there
10675 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10676 | never returns? */
10677 | return NULL((void*)0);
10678 | }
10679 |
10680 | static const char *
10681 | hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10682 | {
10683 | const char *str = hf_try_val_to_str(value, hfinfo);
10684 |
10685 | return (str) ? str : unknown_str;
10686 | }
10687 |
10688 | static const char *
10689 | hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10690 | {
10691 | const char *str = hf_try_val64_to_str(value, hfinfo);
10692 |
10693 | return (str) ? str : unknown_str;
10694 | }
10695 |
10696 | /* Fills data for bitfield chars with val_strings */
10697 | static void
10698 | fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10699 | {
10700 | char *p;
10701 | unsigned bitfield_byte_length;
10702 | int bitwidth;
10703 | uint32_t unshifted_value;
10704 | uint32_t value;
10705 |
10706 | char buf[32];
10707 | const char *out;
10708 |
10709 | const header_field_info *hfinfo = fi->hfinfo;
10710 |
10711 | /* Figure out the bit width */
10712 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10713 |
10714 | /* Un-shift bits */
10715 | value = fvalue_get_uinteger(fi->value);
10716 |
10717 | unshifted_value = value;
10718 | if (hfinfo->bitmask) {
10719 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10720 | }
10721 |
10722 | /* Create the bitfield first */
10723 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10724 | bitfield_byte_length = (unsigned) (p - label_str);
10725 |
10726 | /* Fill in the textual info using stored (shifted) value */
10727 | if (hfinfo->display == BASE_CUSTOM) {
10728 | char tmp[ITEM_LABEL_LENGTH240];
10729 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10730 |
10731 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10731, "fmtfunc"))));
10732 | fmtfunc(tmp, value);
10733 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10734 | }
10735 | else if (hfinfo->strings) {
10736 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10737 |
10738 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10739 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10740 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10741 | else
10742 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10743 | }
10744 | else {
10745 | out = hfinfo_char_value_format(hfinfo, buf, value);
10746 |
10747 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10748 | }
10749 | }
10750 |
10751 | /* Fills data for bitfield ints with val_strings */
10752 | static void
10753 | fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10754 | {
10755 | char *p;
10756 | unsigned bitfield_byte_length;
10757 | int bitwidth;
10758 | uint32_t value, unshifted_value;
10759 | char buf[NUMBER_LABEL_LENGTH80];
10760 | const char *out;
10761 |
10762 | const header_field_info *hfinfo = fi->hfinfo;
10763 |
10764 | /* Figure out the bit width */
10765 | if (fi->flags & FI_VARINT0x00040000)
10766 | bitwidth = fi->length*8;
10767 | else
10768 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10769 |
10770 | /* Un-shift bits */
10771 | if (is_signed)
10772 | value = fvalue_get_sinteger(fi->value);
10773 | else
10774 | value = fvalue_get_uinteger(fi->value);
10775 |
10776 | unshifted_value = value;
10777 | if (hfinfo->bitmask) {
10778 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10779 | }
10780 |
10781 | /* Create the bitfield first */
10782 | if (fi->flags & FI_VARINT0x00040000)
10783 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10784 | else
10785 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10786 | bitfield_byte_length = (unsigned) (p - label_str);
10787 |
10788 | /* Fill in the textual info using stored (shifted) value */
10789 | if (hfinfo->display == BASE_CUSTOM) {
10790 | char tmp[ITEM_LABEL_LENGTH240];
10791 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10792 |
10793 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10793, "fmtfunc"))));
10794 | fmtfunc(tmp, value);
10795 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10796 | }
10797 | else if (hfinfo->strings) {
10798 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10799 |
10800 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10801 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10802 | /*
10803 | * Unique values only display value_string string
10804 | * if there is a match. Otherwise it's just a number
10805 | */
10806 | if (val_str) {
10807 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10808 | } else {
10809 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10810 | }
10811 | } else {
10812 | if (val_str == NULL((void*)0))
10813 | val_str = "Unknown";
10814 |
10815 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10816 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10817 | else
10818 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10819 | }
10820 | }
10821 | else {
10822 | out = hfinfo_number_value_format(hfinfo, buf, value);
10823 |
10824 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10825 | }
10826 | }
10827 |
10828 | static void
10829 | fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10830 | {
10831 | char *p;
10832 | unsigned bitfield_byte_length;
10833 | int bitwidth;
10834 | uint64_t value, unshifted_value;
10835 | char buf[NUMBER_LABEL_LENGTH80];
10836 | const char *out;
10837 |
10838 | const header_field_info *hfinfo = fi->hfinfo;
10839 |
10840 | /* Figure out the bit width */
10841 | if (fi->flags & FI_VARINT0x00040000)
10842 | bitwidth = fi->length*8;
10843 | else
10844 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10845 |
10846 | /* Un-shift bits */
10847 | if (is_signed)
10848 | value = fvalue_get_sinteger64(fi->value);
10849 | else
10850 | value = fvalue_get_uinteger64(fi->value);
10851 |
10852 | unshifted_value = value;
10853 | if (hfinfo->bitmask) {
10854 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10855 | }
10856 |
10857 | /* Create the bitfield first */
10858 | if (fi->flags & FI_VARINT0x00040000)
10859 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10860 | else
10861 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10862 | bitfield_byte_length = (unsigned) (p - label_str);
10863 |
10864 | /* Fill in the textual info using stored (shifted) value */
10865 | if (hfinfo->display == BASE_CUSTOM) {
10866 | char tmp[ITEM_LABEL_LENGTH240];
10867 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10868 |
10869 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 10869, "fmtfunc64" ))));
10870 | fmtfunc64(tmp, value);
10871 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10872 | }
10873 | else if (hfinfo->strings) {
10874 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
10875 |
10876 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
10877 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10878 | /*
10879 | * Unique values only display value_string string
10880 | * if there is a match. Otherwise it's just a number
10881 | */
10882 | if (val_str) {
10883 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10884 | } else {
10885 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10886 | }
10887 | } else {
10888 | if (val_str == NULL((void*)0))
10889 | val_str = "Unknown";
10890 |
10891 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10892 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10893 | else
10894 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10895 | }
10896 | }
10897 | else {
10898 | out = hfinfo_number_value_format64(hfinfo, buf, value);
10899 |
10900 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10901 | }
10902 | }
10903 |
10904 | static void
10905 | fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10906 | {
10907 | const header_field_info *hfinfo = fi->hfinfo;
10908 | uint32_t value;
10909 |
10910 | char buf[32];
10911 | const char *out;
10912 |
10913 | value = fvalue_get_uinteger(fi->value);
10914 |
10915 | /* Fill in the textual info */
10916 | if (hfinfo->display == BASE_CUSTOM) {
10917 | char tmp[ITEM_LABEL_LENGTH240];
10918 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10919 |
10920 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10920, "fmtfunc"))));
10921 | fmtfunc(tmp, value);
10922 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10923 | }
10924 | else if (hfinfo->strings) {
10925 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10926 |
10927 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10928 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10929 | }
10930 | else {
10931 | out = hfinfo_char_value_format(hfinfo, buf, value);
10932 |
10933 | label_fill(label_str, 0, hfinfo, out, value_pos);
10934 | }
10935 | }
10936 |
10937 | static void
10938 | fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10939 | {
10940 | const header_field_info *hfinfo = fi->hfinfo;
10941 | uint32_t value;
10942 |
10943 | char buf[NUMBER_LABEL_LENGTH80];
10944 | const char *out;
10945 |
10946 | if (is_signed)
10947 | value = fvalue_get_sinteger(fi->value);
10948 | else
10949 | value = fvalue_get_uinteger(fi->value);
10950 |
10951 | /* Fill in the textual info */
10952 | if (hfinfo->display == BASE_CUSTOM) {
10953 | char tmp[ITEM_LABEL_LENGTH240];
10954 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10955 |
10956 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10956, "fmtfunc"))));
10957 | fmtfunc(tmp, value);
10958 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10959 | }
10960 | else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10961 | /*
10962 | * It makes no sense to have a value-string table for a
10963 | * frame-number field - they're just integers giving
10964 | * the ordinal frame number.
10965 | */
10966 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10967 |
10968 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10969 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10970 | /*
10971 | * Unique values only display value_string string
10972 | * if there is a match. Otherwise it's just a number
10973 | */
10974 | if (val_str) {
10975 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10976 | } else {
10977 | label_fill(label_str, 0, hfinfo, out, value_pos);
10978 | }
10979 | } else {
10980 | if (val_str == NULL((void*)0))
10981 | val_str = "Unknown";
10982 |
10983 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10984 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
10985 | else
10986 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10987 | }
10988 | }
10989 | 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 ))) {
10990 | char tmp[ITEM_LABEL_LENGTH240];
10991 |
10992 | port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10993 | display_to_port_type((field_display_e)hfinfo->display), value);
10994 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10995 | }
10996 | else {
10997 | out = hfinfo_number_value_format(hfinfo, buf, value);
10998 |
10999 | label_fill(label_str, 0, hfinfo, out, value_pos);
11000 | }
11001 | }
11002 |
11003 | static void
11004 | fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
11005 | {
11006 | const header_field_info *hfinfo = fi->hfinfo;
11007 | uint64_t value;
11008 |
11009 | char buf[NUMBER_LABEL_LENGTH80];
11010 | const char *out;
11011 |
11012 | if (is_signed)
11013 | value = fvalue_get_sinteger64(fi->value);
11014 | else
11015 | value = fvalue_get_uinteger64(fi->value);
11016 |
11017 | /* Fill in the textual info */
11018 | if (hfinfo->display == BASE_CUSTOM) {
11019 | char tmp[ITEM_LABEL_LENGTH240];
11020 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
11021 |
11022 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 11022, "fmtfunc64" ))));
11023 | fmtfunc64(tmp, value);
11024 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
11025 | }
11026 | else if (hfinfo->strings) {
11027 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
11028 |
11029 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
11030 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
11031 | /*
11032 | * Unique values only display value_string string
11033 | * if there is a match. Otherwise it's just a number
11034 | */
11035 | if (val_str) {
11036 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11037 | } else {
11038 | label_fill(label_str, 0, hfinfo, out, value_pos);
11039 | }
11040 | } else {
11041 | if (val_str == NULL((void*)0))
11042 | val_str = "Unknown";
11043 |
11044 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
11045 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
11046 | else
11047 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
11048 | }
11049 | }
11050 | else {
11051 | out = hfinfo_number_value_format64(hfinfo, buf, value);
11052 |
11053 | label_fill(label_str, 0, hfinfo, out, value_pos);
11054 | }
11055 | }
11056 |
11057 | static size_t
11058 | fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
11059 | {
11060 | int display;
11061 | int n;
11062 | double value;
11063 |
11064 | if (label_str_size < 12) {
11065 | /* Not enough room to write an entire floating point value. */
11066 | return 0;
11067 | }
11068 |
11069 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11070 | value = fvalue_get_floating(fi->value);
11071 |
11072 | if (display == BASE_CUSTOM) {
11073 | const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
11074 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 11074, "fmtfunc"))));
11075 | fmtfunc(label_str, value);
11076 | return strlen(label_str);
11077 | }
11078 |
11079 | switch (display) {
11080 | case BASE_NONE:
11081 | if (fi->hfinfo->type == FT_FLOAT) {
11082 | n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
11083 | } else {
11084 | n = (int)strlen(dtoa_g_fmt(label_str, value));
11085 | }
11086 | break;
11087 | case BASE_DEC:
11088 | n = snprintf(label_str, label_str_size, "%f", value);
11089 | break;
11090 | case BASE_HEX:
11091 | n = snprintf(label_str, label_str_size, "%a", value);
11092 | break;
11093 | case BASE_EXP:
11094 | n = snprintf(label_str, label_str_size, "%e", value);
11095 | break;
11096 | default:
11097 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 11097 , __func__, "assertion \"not reached\" failed");
11098 | }
11099 | if (n < 0) {
11100 | return 0; /* error */
11101 | }
11102 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11103 | const char *hf_str_val;
11104 | hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
11105 | n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
11106 | }
11107 | if (n > label_str_size) {
11108 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11108, __func__, "label length too small"); } } while (0);
11109 | return strlen(label_str);
11110 | }
11111 |
11112 | return n;
11113 | }
11114 |
11115 | void
11116 | fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
11117 | {
11118 | char tmp[ITEM_LABEL_LENGTH240];
11119 |
11120 | fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
11121 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11122 | }
11123 |
11124 | static size_t
11125 | fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
11126 | {
11127 | int display;
11128 | size_t pos = 0;
11129 | double value;
11130 | char* tmp_str;
11131 |
11132 | if (label_str_size < 12) {
11133 | /* Not enough room to write an entire floating point value. */
11134 | return 0;
11135 | }
11136 |
11137 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
11138 | tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
11139 | pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str, 0);
11140 | wmem_free(NULL((void*)0), tmp_str);
11141 |
11142 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
11143 | const char *hf_str_val;
11144 | fvalue_to_double(fi->value, &value);
11145 | hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
11146 | 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);
11147 | }
11148 | if ((int)pos > label_str_size) {
11149 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11149, __func__, "label length too small"); } } while (0);
11150 | return strlen(label_str);
11151 | }
11152 |
11153 | return pos;
11154 | }
11155 |
11156 | void
11157 | fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
11158 | {
11159 | char tmp[ITEM_LABEL_LENGTH240];
11160 |
11161 | fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
11162 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
11163 | }
11164 |
11165 | int
11166 | hfinfo_bitshift(const header_field_info *hfinfo)
11167 | {
11168 | return ws_ctz(hfinfo->bitmask);
11169 | }
11170 |
11171 |
11172 | static int
11173 | hfinfo_bitoffset(const header_field_info *hfinfo)
11174 | {
11175 | if (!hfinfo->bitmask) {
11176 | return 0;
11177 | }
11178 |
11179 | /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11180 | * as the first bit */
11181 | return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11182 | }
11183 |
11184 | static int
11185 | hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11186 | {
11187 | if (!hfinfo->bitmask) {
11188 | return 0;
11189 | }
11190 |
11191 | /* ilog2 = first set bit, ctz = last set bit */
11192 | return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11193 | }
11194 |
11195 | static int
11196 | hfinfo_type_bitwidth(enum ftenum type)
11197 | {
11198 | int bitwidth = 0;
11199 |
11200 | switch (type) {
11201 | case FT_CHAR:
11202 | case FT_UINT8:
11203 | case FT_INT8:
11204 | bitwidth = 8;
11205 | break;
11206 | case FT_UINT16:
11207 | case FT_INT16:
11208 | bitwidth = 16;
11209 | break;
11210 | case FT_UINT24:
11211 | case FT_INT24:
11212 | bitwidth = 24;
11213 | break;
11214 | case FT_UINT32:
11215 | case FT_INT32:
11216 | bitwidth = 32;
11217 | break;
11218 | case FT_UINT40:
11219 | case FT_INT40:
11220 | bitwidth = 40;
11221 | break;
11222 | case FT_UINT48:
11223 | case FT_INT48:
11224 | bitwidth = 48;
11225 | break;
11226 | case FT_UINT56:
11227 | case FT_INT56:
11228 | bitwidth = 56;
11229 | break;
11230 | case FT_UINT64:
11231 | case FT_INT64:
11232 | bitwidth = 64;
11233 | break;
11234 | default:
11235 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 11235));
11236 | ;
11237 | }
11238 | return bitwidth;
11239 | }
11240 |
11241 |
11242 | static int
11243 | hfinfo_container_bitwidth(const header_field_info *hfinfo)
11244 | {
11245 | if (!hfinfo->bitmask) {
11246 | return 0;
11247 | }
11248 |
11249 | if (hfinfo->type == FT_BOOLEAN) {
11250 | return hfinfo->display; /* hacky? :) */
11251 | }
11252 |
11253 | return hfinfo_type_bitwidth(hfinfo->type);
11254 | }
11255 |
11256 | static int
11257 | hfinfo_hex_digits(const header_field_info *hfinfo)
11258 | {
11259 | int bitwidth;
11260 |
11261 | /* If we have a bitmask, hfinfo->type is the width of the container, so not
11262 | * appropriate to determine the number of hex digits for the field.
11263 | * So instead, we compute it from the bitmask.
11264 | */
11265 | if (hfinfo->bitmask != 0) {
11266 | bitwidth = hfinfo_mask_bitwidth(hfinfo);
11267 | } else {
11268 | bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11269 | }
11270 |
11271 | /* Divide by 4, rounding up, to get number of hex digits. */
11272 | return (bitwidth + 3) / 4;
11273 | }
11274 |
11275 | const char *
11276 | hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11277 | {
11278 | char *ptr = &buf[6];
11279 | static const char hex_digits[16] =
11280 | { '0', '1', '2', '3', '4', '5', '6', '7',
11281 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11282 |
11283 | *ptr = '\0';
11284 | *(--ptr) = '\'';
11285 | /* Properly format value */
11286 | if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11287 | /*
11288 | * Printable, so just show the character, and, if it needs
11289 | * to be escaped, escape it.
11290 | */
11291 | *(--ptr) = value;
11292 | if (value == '\\' || value == '\'')
11293 | *(--ptr) = '\\';
11294 | } else {
11295 | /*
11296 | * Non-printable; show it as an escape sequence.
11297 | */
11298 | switch (value) {
11299 |
11300 | case '\0':
11301 | /*
11302 | * Show a NUL with only one digit.
11303 | */
11304 | *(--ptr) = '0';
11305 | break;
11306 |
11307 | case '\a':
11308 | case '\b':
11309 | case '\f':
11310 | case '\n':
11311 | case '\r':
11312 | case '\t':
11313 | case '\v':
11314 | *(--ptr) = value - '\a' + 'a';
11315 | break;
11316 |
11317 | default:
11318 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11319 |
11320 | case BASE_OCT:
11321 | *(--ptr) = (value & 0x7) + '0';
11322 | value >>= 3;
11323 | *(--ptr) = (value & 0x7) + '0';
11324 | value >>= 3;
11325 | *(--ptr) = (value & 0x7) + '0';
11326 | break;
11327 |
11328 | case BASE_HEX:
11329 | *(--ptr) = hex_digits[value & 0x0F];
11330 | value >>= 4;
11331 | *(--ptr) = hex_digits[value & 0x0F];
11332 | *(--ptr) = 'x';
11333 | break;
11334 |
11335 | default:
11336 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11337 | }
11338 | }
11339 | *(--ptr) = '\\';
11340 | }
11341 | *(--ptr) = '\'';
11342 | return ptr;
11343 | }
11344 |
11345 | static const char *
11346 | hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11347 | {
11348 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11349 | 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 ));
11350 |
11351 | *ptr = '\0';
11352 | /* Properly format value */
11353 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11354 | case BASE_DEC:
11355 | return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11356 |
11357 | case BASE_DEC_HEX:
11358 | *(--ptr) = ')';
11359 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11360 | *(--ptr) = '(';
11361 | *(--ptr) = ' ';
11362 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11363 | return ptr;
11364 |
11365 | case BASE_OCT:
11366 | return oct_to_str_back(ptr, value);
11367 |
11368 | case BASE_HEX:
11369 | return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11370 |
11371 | case BASE_HEX_DEC:
11372 | *(--ptr) = ')';
11373 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11374 | *(--ptr) = '(';
11375 | *(--ptr) = ' ';
11376 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11377 | return ptr;
11378 |
11379 | case BASE_PT_UDP:
11380 | case BASE_PT_TCP:
11381 | case BASE_PT_DCCP:
11382 | case BASE_PT_SCTP:
11383 | port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11384 | display_to_port_type((field_display_e)display), value);
11385 | return buf;
11386 | case BASE_OUI:
11387 | {
11388 | uint8_t p_oui[3];
11389 | const char *manuf_name;
11390 |
11391 | p_oui[0] = value >> 16 & 0xFF;
11392 | p_oui[1] = value >> 8 & 0xFF;
11393 | p_oui[2] = value & 0xFF;
11394 |
11395 | /* Attempt an OUI lookup. */
11396 | manuf_name = uint_get_manuf_name_if_known(value);
11397 | if (manuf_name == NULL((void*)0)) {
11398 | /* Could not find an OUI. */
11399 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11400 | }
11401 | else {
11402 | /* Found an address string. */
11403 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11404 | }
11405 | return buf;
11406 | }
11407 |
11408 | default:
11409 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11410 | }
11411 | return ptr;
11412 | }
11413 |
11414 | static const char *
11415 | hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11416 | {
11417 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11418 | 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 ));
11419 |
11420 | *ptr = '\0';
11421 | /* Properly format value */
11422 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11423 | case BASE_DEC:
11424 | return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11425 |
11426 | case BASE_DEC_HEX:
11427 | *(--ptr) = ')';
11428 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11429 | *(--ptr) = '(';
11430 | *(--ptr) = ' ';
11431 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11432 | return ptr;
11433 |
11434 | case BASE_OCT:
11435 | return oct64_to_str_back(ptr, value);
11436 |
11437 | case BASE_HEX:
11438 | return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11439 |
11440 | case BASE_HEX_DEC:
11441 | *(--ptr) = ')';
11442 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11443 | *(--ptr) = '(';
11444 | *(--ptr) = ' ';
11445 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11446 | return ptr;
11447 |
11448 | default:
11449 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11450 | }
11451 |
11452 | return ptr;
11453 | }
11454 |
11455 | static const char *
11456 | hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11457 | {
11458 | int display = hfinfo->display;
11459 |
11460 | if (hfinfo->type == FT_FRAMENUM) {
11461 | /*
11462 | * Frame numbers are always displayed in decimal.
11463 | */
11464 | display = BASE_DEC;
11465 | }
11466 |
11467 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11468 | }
11469 |
11470 | static const char *
11471 | hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11472 | {
11473 | int display = hfinfo->display;
11474 |
11475 | if (hfinfo->type == FT_FRAMENUM) {
11476 | /*
11477 | * Frame numbers are always displayed in decimal.
11478 | */
11479 | display = BASE_DEC;
11480 | }
11481 |
11482 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11483 | }
11484 |
11485 | static const char *
11486 | hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11487 | {
11488 | /* Get the underlying BASE_ value */
11489 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11490 |
11491 | return hfinfo_char_value_format_display(display, buf, value);
11492 | }
11493 |
11494 | static const char *
11495 | hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11496 | {
11497 | /* Get the underlying BASE_ value */
11498 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11499 |
11500 | if (hfinfo->type == FT_FRAMENUM) {
11501 | /*
11502 | * Frame numbers are always displayed in decimal.
11503 | */
11504 | display = BASE_DEC;
11505 | }
11506 |
11507 | if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)== BASE_PT_DCCP||(display)==BASE_PT_SCTP))) {
11508 | display = BASE_DEC;
11509 | } else if (display == BASE_OUI) {
11510 | display = BASE_HEX;
11511 | }
11512 |
11513 | switch (display) {
11514 | case BASE_NONE:
11515 | /* case BASE_DEC: */
11516 | case BASE_DEC_HEX:
11517 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11518 | case BASE_CUSTOM:
11519 | display = BASE_DEC;
11520 | break;
11521 |
11522 | /* case BASE_HEX: */
11523 | case BASE_HEX_DEC:
11524 | display = BASE_HEX;
11525 | break;
11526 | }
11527 |
11528 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11529 | }
11530 |
11531 | static const char *
11532 | hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11533 | {
11534 | /* Get the underlying BASE_ value */
11535 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11536 |
11537 | if (hfinfo->type == FT_FRAMENUM) {
11538 | /*
11539 | * Frame numbers are always displayed in decimal.
11540 | */
11541 | display = BASE_DEC;
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_display64(hfinfo, display, buf, value);
11560 | }
11561 |
11562 | static const char *
11563 | hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11564 | {
11565 | /* Get the underlying BASE_ value */
11566 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11567 |
11568 | return hfinfo_char_value_format_display(display, buf, value);
11569 | }
11570 |
11571 | static const char *
11572 | hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11573 | {
11574 | /* Get the underlying BASE_ value */
11575 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11576 |
11577 | if (display == BASE_NONE)
11578 | return NULL((void*)0);
11579 |
11580 | if (display == BASE_DEC_HEX)
11581 | display = BASE_DEC;
11582 | if (display == BASE_HEX_DEC)
11583 | display = BASE_HEX;
11584 |
11585 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11586 | }
11587 |
11588 | static const char *
11589 | hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11590 | {
11591 | /* Get the underlying BASE_ value */
11592 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11593 |
11594 | if (display == BASE_NONE)
11595 | return NULL((void*)0);
11596 |
11597 | if (display == BASE_DEC_HEX)
11598 | display = BASE_DEC;
11599 | if (display == BASE_HEX_DEC)
11600 | display = BASE_HEX;
11601 |
11602 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11603 | }
11604 |
11605 | const char *
11606 | proto_registrar_get_name(const int n)
11607 | {
11608 | header_field_info *hfinfo;
11609 |
11610 | 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", 11610 , __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", 11610 , "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", 11610, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11611 | return hfinfo->name;
11612 | }
11613 |
11614 | const char *
11615 | proto_registrar_get_abbrev(const int n)
11616 | {
11617 | header_field_info *hfinfo;
11618 |
11619 | 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", 11619 , __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", 11619 , "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", 11619, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11620 | return hfinfo->abbrev;
11621 | }
11622 |
11623 | enum ftenum
11624 | proto_registrar_get_ftype(const int n)
11625 | {
11626 | header_field_info *hfinfo;
11627 |
11628 | 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", 11628 , __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", 11628 , "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", 11628, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11629 | return hfinfo->type;
11630 | }
11631 |
11632 | int
11633 | proto_registrar_get_parent(const int n)
11634 | {
11635 | header_field_info *hfinfo;
11636 |
11637 | 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", 11637 , __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", 11637 , "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", 11637, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11638 | return hfinfo->parent;
11639 | }
11640 |
11641 | bool_Bool
11642 | proto_registrar_is_protocol(const int n)
11643 | {
11644 | header_field_info *hfinfo;
11645 |
11646 | 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", 11646 , __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", 11646 , "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", 11646, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11647 | return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11648 | }
11649 |
11650 | /* Returns length of field in packet (not necessarily the length
11651 | * in our internal representation, as in the case of IPv4).
11652 | * 0 means undeterminable at time of registration
11653 | * -1 means the field is not registered. */
11654 | int
11655 | proto_registrar_get_length(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 ftype_wire_size(hfinfo->type);
11661 | }
11662 |
11663 | size_t
11664 | proto_registrar_get_count(struct proto_registrar_stats *stats)
11665 | {
11666 | header_field_info *hfinfo;
11667 |
11668 | // Index zero is not used. We have to skip it.
11669 | size_t total_count = gpa_hfinfo.len - 1;
11670 | if (stats == NULL((void*)0)) {
11671 | return total_count;
11672 | }
11673 | for (uint32_t id = 1; id < gpa_hfinfo.len; id++) {
11674 | if (gpa_hfinfo.hfi[id] == NULL((void*)0)) {
11675 | stats->deregistered_count++;
11676 | continue; /* This is a deregistered protocol or header field */
11677 | }
11678 |
11679 | 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", 11679 , __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", 11679, "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", 11679, "gpa_hfinfo.hfi[id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[id];;
11680 |
11681 | if (proto_registrar_is_protocol(id))
11682 | stats->protocol_count++;
11683 |
11684 | if (hfinfo->same_name_prev_id != -1)
11685 | stats->same_name_count++;
11686 | }
11687 |
11688 | return total_count;
11689 | }
11690 |
11691 | /* Looks for a protocol or a field in a proto_tree. Returns true if
11692 | * it exists anywhere, or false if it exists nowhere. */
11693 | bool_Bool
11694 | proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11695 | {
11696 | GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11697 |
11698 | if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11699 | return true1;
11700 | }
11701 | else {
11702 | return false0;
11703 | }
11704 | }
11705 |
11706 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11707 | * This only works if the hfindex was "primed" before the dissection
11708 | * took place, as we just pass back the already-created GPtrArray*.
11709 | * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11710 | * handles that. */
11711 | GPtrArray *
11712 | proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11713 | {
11714 | if (!tree)
11715 | return NULL((void*)0);
11716 |
11717 | if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11718 | return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11719 | GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11720 | else
11721 | return NULL((void*)0);
11722 | }
11723 |
11724 | bool_Bool
11725 | proto_tracking_interesting_fields(const proto_tree *tree)
11726 | {
11727 | GHashTable *interesting_hfids;
11728 |
11729 | if (!tree)
11730 | return false0;
11731 |
11732 | interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11733 |
11734 | return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11735 | }
11736 |
11737 | /* Helper struct for proto_find_info() and proto_all_finfos() */
11738 | typedef struct {
11739 | GPtrArray *array;
11740 | int id;
11741 | } ffdata_t;
11742 |
11743 | /* Helper function for proto_find_info() */
11744 | static bool_Bool
11745 | find_finfo(proto_node *node, void * data)
11746 | {
11747 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11748 | if (fi && fi->hfinfo) {
11749 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11750 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11751 | }
11752 | }
11753 |
11754 | /* Don't stop traversing. */
11755 | return false0;
11756 | }
11757 |
11758 | /* Helper function for proto_find_first_info() */
11759 | static bool_Bool
11760 | find_first_finfo(proto_node *node, void *data)
11761 | {
11762 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11763 | if (fi && fi->hfinfo) {
11764 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11765 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11766 |
11767 | /* Stop traversing. */
11768 | return true1;
11769 | }
11770 | }
11771 |
11772 | /* Continue traversing. */
11773 | return false0;
11774 | }
11775 |
11776 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11777 | * This works on any proto_tree, primed or unprimed, but actually searches
11778 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11779 | * The caller does need to free the returned GPtrArray with
11780 | * g_ptr_array_free(<array>, true).
11781 | */
11782 | GPtrArray *
11783 | proto_find_finfo(proto_tree *tree, const int id)
11784 | {
11785 | ffdata_t ffdata;
11786 |
11787 | ffdata.array = g_ptr_array_new();
11788 | ffdata.id = id;
11789 |
11790 | proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11791 |
11792 | return ffdata.array;
11793 | }
11794 |
11795 | /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11796 | * This works on any proto_tree, primed or unprimed, but actually searches
11797 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11798 | * The caller does need to free the returned GPtrArray with
11799 | * g_ptr_array_free(<array>, true).
11800 | */
11801 | GPtrArray *
11802 | proto_find_first_finfo(proto_tree *tree, const int id)
11803 | {
11804 | ffdata_t ffdata;
11805 |
11806 | ffdata.array = g_ptr_array_new();
11807 | ffdata.id = id;
11808 |
11809 | proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11810 |
11811 | return ffdata.array;
11812 | }
11813 |
11814 | /* Helper function for proto_all_finfos() */
11815 | static bool_Bool
11816 | every_finfo(proto_node *node, void * data)
11817 | {
11818 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11819 | if (fi && fi->hfinfo) {
11820 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11821 | }
11822 |
11823 | /* Don't stop traversing. */
11824 | return false0;
11825 | }
11826 |
11827 | /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11828 | * The caller does need to free the returned GPtrArray with
11829 | * g_ptr_array_free(<array>, true).
11830 | */
11831 | GPtrArray *
11832 | proto_all_finfos(proto_tree *tree)
11833 | {
11834 | ffdata_t ffdata;
11835 |
11836 | /* Pre allocate enough space to hold all fields in most cases */
11837 | ffdata.array = g_ptr_array_sized_new(512);
11838 | ffdata.id = 0;
11839 |
11840 | proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11841 |
11842 | return ffdata.array;
11843 | }
11844 |
11845 |
11846 | typedef struct {
11847 | unsigned offset;
11848 | field_info *finfo;
11849 | tvbuff_t *tvb;
11850 | } offset_search_t;
11851 |
11852 | static bool_Bool
11853 | check_for_offset(proto_node *node, void * data)
11854 | {
11855 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11856 | offset_search_t *offsearch = (offset_search_t *)data;
11857 |
11858 | /* !fi == the top most container node which holds nothing */
11859 | if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11860 | if (offsearch->offset >= (unsigned) fi->start &&
11861 | offsearch->offset < (unsigned) (fi->start + fi->length)) {
11862 |
11863 | offsearch->finfo = fi;
11864 | return false0; /* keep traversing */
11865 | }
11866 | }
11867 | return false0; /* keep traversing */
11868 | }
11869 |
11870 | /* Search a proto_tree backwards (from leaves to root) looking for the field
11871 | * whose start/length occupies 'offset' */
11872 | /* XXX - I couldn't find an easy way to search backwards, so I search
11873 | * forwards, w/o stopping. Therefore, the last finfo I find will the be
11874 | * the one I want to return to the user. This algorithm is inefficient
11875 | * and could be re-done, but I'd have to handle all the children and
11876 | * siblings of each node myself. When I have more time I'll do that.
11877 | * (yeah right) */
11878 | field_info *
11879 | proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11880 | {
11881 | offset_search_t offsearch;
11882 |
11883 | offsearch.offset = offset;
11884 | offsearch.finfo = NULL((void*)0);
11885 | offsearch.tvb = tvb;
11886 |
11887 | proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11888 |
11889 | return offsearch.finfo;
11890 | }
11891 |
11892 | typedef struct {
11893 | unsigned length;
11894 | char *buf;
11895 | } decoded_data_t;
11896 |
11897 | static bool_Bool
11898 | check_for_undecoded(proto_node *node, void * data)
11899 | {
11900 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11901 | decoded_data_t* decoded = (decoded_data_t*)data;
11902 | unsigned i;
11903 | unsigned byte;
11904 | unsigned bit;
11905 |
11906 | if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11907 | for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11908 | byte = i / 8;
11909 | bit = i % 8;
11910 | decoded->buf[byte] |= (1 << bit);
11911 | }
11912 | }
11913 |
11914 | return false0;
11915 | }
11916 |
11917 | char*
11918 | proto_find_undecoded_data(proto_tree *tree, unsigned length)
11919 | {
11920 | decoded_data_t decoded;
11921 | decoded.length = length;
11922 | decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11923 |
11924 | proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11925 | return decoded.buf;
11926 | }
11927 |
11928 | /* Dumps the protocols in the registration database to stdout. An independent
11929 | * program can take this output and format it into nice tables or HTML or
11930 | * whatever.
11931 | *
11932 | * There is one record per line. The fields are tab-delimited.
11933 | *
11934 | * Field 1 = protocol name
11935 | * Field 2 = protocol short name
11936 | * Field 3 = protocol filter name
11937 | * Field 4 = protocol enabled
11938 | * Field 5 = protocol enabled by default
11939 | * Field 6 = protocol can toggle
11940 | */
11941 | void
11942 | proto_registrar_dump_protocols(void)
11943 | {
11944 | protocol_t *protocol;
11945 | int i;
11946 | void *cookie = NULL((void*)0);
11947 |
11948 |
11949 | i = proto_get_first_protocol(&cookie);
11950 | while (i != -1) {
11951 | protocol = find_protocol_by_id(i);
11952 | printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11953 | protocol->name,
11954 | protocol->short_name,
11955 | protocol->filter_name,
11956 | (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11957 | (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11958 | (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11959 | i = proto_get_next_protocol(&cookie);
11960 | }
11961 | }
11962 |
11963 | /* Dumps the value_strings, extended value string headers, range_strings
11964 | * or true/false strings for fields that have them.
11965 | * There is one record per line. Fields are tab-delimited.
11966 | * There are four types of records: Value String, Extended Value String Header,
11967 | * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11968 | * the type of record.
11969 | *
11970 | * Note that a record will be generated only if the value_string,... is referenced
11971 | * in a registered hfinfo entry.
11972 | *
11973 | *
11974 | * Value Strings
11975 | * -------------
11976 | * Field 1 = 'V'
11977 | * Field 2 = Field abbreviation to which this value string corresponds
11978 | * Field 3 = Integer value
11979 | * Field 4 = String
11980 | *
11981 | * Extended Value String Headers
11982 | * -----------------------------
11983 | * Field 1 = 'E'
11984 | * Field 2 = Field abbreviation to which this extended value string header corresponds
11985 | * Field 3 = Extended Value String "Name"
11986 | * Field 4 = Number of entries in the associated value_string array
11987 | * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11988 | *
11989 | * Range Strings
11990 | * -------------
11991 | * Field 1 = 'R'
11992 | * Field 2 = Field abbreviation to which this range string corresponds
11993 | * Field 3 = Integer value: lower bound
11994 | * Field 4 = Integer value: upper bound
11995 | * Field 5 = String
11996 | *
11997 | * True/False Strings
11998 | * ------------------
11999 | * Field 1 = 'T'
12000 | * Field 2 = Field abbreviation to which this true/false string corresponds
12001 | * Field 3 = True String
12002 | * Field 4 = False String
12003 | */
12004 | void
12005 | proto_registrar_dump_values(void)
12006 | {
12007 | header_field_info *hfinfo;
12008 | int i, len, vi;
12009 | const value_string *vals;
12010 | const val64_string *vals64;
12011 | const range_string *range;
12012 | const true_false_string *tfs;
12013 | const unit_name_string *units;
12014 |
12015 | len = gpa_hfinfo.len;
12016 | for (i = 1; i < len ; i++) {
12017 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12018 | continue; /* This is a deregistered protocol or field */
12019 |
12020 | 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", 12020 , __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", 12020 , "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", 12020, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12021 |
12022 | if (hfinfo->id == hf_text_only) {
12023 | continue;
12024 | }
12025 |
12026 | /* ignore protocols */
12027 | if (proto_registrar_is_protocol(i)) {
12028 | continue;
12029 | }
12030 | /* process header fields */
12031 | #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
12032 | /*
12033 | * If this field isn't at the head of the list of
12034 | * fields with this name, skip this field - all
12035 | * fields with the same name are really just versions
12036 | * of the same field stored in different bits, and
12037 | * should have the same type/radix/value list, and
12038 | * just differ in their bit masks. (If a field isn't
12039 | * a bitfield, but can be, say, 1 or 2 bytes long,
12040 | * it can just be made FT_UINT16, meaning the
12041 | * *maximum* length is 2 bytes, and be used
12042 | * for all lengths.)
12043 | */
12044 | if (hfinfo->same_name_prev_id != -1)
12045 | continue;
12046 | #endif
12047 | vals = NULL((void*)0);
12048 | vals64 = NULL((void*)0);
12049 | range = NULL((void*)0);
12050 | tfs = NULL((void*)0);
12051 | units = NULL((void*)0);
12052 |
12053 | if (hfinfo->strings != NULL((void*)0)) {
12054 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
12055 | (hfinfo->type == FT_CHAR ||
12056 | hfinfo->type == FT_UINT8 ||
12057 | hfinfo->type == FT_UINT16 ||
12058 | hfinfo->type == FT_UINT24 ||
12059 | hfinfo->type == FT_UINT32 ||
12060 | hfinfo->type == FT_UINT40 ||
12061 | hfinfo->type == FT_UINT48 ||
12062 | hfinfo->type == FT_UINT56 ||
12063 | hfinfo->type == FT_UINT64 ||
12064 | hfinfo->type == FT_INT8 ||
12065 | hfinfo->type == FT_INT16 ||
12066 | hfinfo->type == FT_INT24 ||
12067 | hfinfo->type == FT_INT32 ||
12068 | hfinfo->type == FT_INT40 ||
12069 | hfinfo->type == FT_INT48 ||
12070 | hfinfo->type == FT_INT56 ||
12071 | hfinfo->type == FT_INT64 ||
12072 | hfinfo->type == FT_FLOAT ||
12073 | hfinfo->type == FT_DOUBLE)) {
12074 |
12075 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
12076 | range = (const range_string *)hfinfo->strings;
12077 | } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12078 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12079 | vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
12080 | } else {
12081 | vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
12082 | }
12083 | } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12084 | vals64 = (const val64_string *)hfinfo->strings;
12085 | } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
12086 | units = (const unit_name_string *)hfinfo->strings;
12087 | } else {
12088 | vals = (const value_string *)hfinfo->strings;
12089 | }
12090 | }
12091 | else if (hfinfo->type == FT_BOOLEAN) {
12092 | tfs = (const struct true_false_string *)hfinfo->strings;
12093 | }
12094 | }
12095 |
12096 | /* Print value strings? */
12097 | if (vals) {
12098 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
12099 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
12100 | val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
12101 | if (!val64_string_ext_validate(vse_p)) {
12102 | ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 12102, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
12103 | continue;
12104 | }
12105 | try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
12106 | printf("E\t%s\t%u\t%s\t%s\n",
12107 | hfinfo->abbrev,
12108 | VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12109 | VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12110 | val64_string_ext_match_type_str(vse_p));
12111 | } else {
12112 | value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
12113 | if (!value_string_ext_validate(vse_p)) {
12114 | ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 12114, __func__, "Invalid value_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
12115 | continue;
12116 | }
12117 | try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
12118 | printf("E\t%s\t%u\t%s\t%s\n",
12119 | hfinfo->abbrev,
12120 | VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
12121 | VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
12122 | value_string_ext_match_type_str(vse_p));
12123 | }
12124 | }
12125 | vi = 0;
12126 | while (vals[vi].strptr) {
12127 | /* Print in the proper base */
12128 | if (hfinfo->type == FT_CHAR) {
12129 | if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT ) != 0)) {
12130 | printf("V\t%s\t'%c'\t%s\n",
12131 | hfinfo->abbrev,
12132 | vals[vi].value,
12133 | vals[vi].strptr);
12134 | } else {
12135 | if (hfinfo->display == BASE_HEX) {
12136 | printf("V\t%s\t'\\x%02x'\t%s\n",
12137 | hfinfo->abbrev,
12138 | vals[vi].value,
12139 | vals[vi].strptr);
12140 | }
12141 | else {
12142 | printf("V\t%s\t'\\%03o'\t%s\n",
12143 | hfinfo->abbrev,
12144 | vals[vi].value,
12145 | vals[vi].strptr);
12146 | }
12147 | }
12148 | } else {
12149 | if (hfinfo->display == BASE_HEX) {
12150 | printf("V\t%s\t0x%x\t%s\n",
12151 | hfinfo->abbrev,
12152 | vals[vi].value,
12153 | vals[vi].strptr);
12154 | }
12155 | else {
12156 | printf("V\t%s\t%u\t%s\n",
12157 | hfinfo->abbrev,
12158 | vals[vi].value,
12159 | vals[vi].strptr);
12160 | }
12161 | }
12162 | vi++;
12163 | }
12164 | }
12165 | else if (vals64) {
12166 | vi = 0;
12167 | while (vals64[vi].strptr) {
12168 | printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
12169 | hfinfo->abbrev,
12170 | vals64[vi].value,
12171 | vals64[vi].strptr);
12172 | vi++;
12173 | }
12174 | }
12175 |
12176 | /* print range strings? */
12177 | else if (range) {
12178 | vi = 0;
12179 | while (range[vi].strptr) {
12180 | /* Print in the proper base */
12181 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
12182 | printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
12183 | hfinfo->abbrev,
12184 | range[vi].value_min,
12185 | range[vi].value_max,
12186 | range[vi].strptr);
12187 | }
12188 | else {
12189 | printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
12190 | hfinfo->abbrev,
12191 | range[vi].value_min,
12192 | range[vi].value_max,
12193 | range[vi].strptr);
12194 | }
12195 | vi++;
12196 | }
12197 | }
12198 |
12199 | /* Print true/false strings? */
12200 | else if (tfs) {
12201 | printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
12202 | tfs->true_string, tfs->false_string);
12203 | }
12204 | /* Print unit strings? */
12205 | else if (units) {
12206 | printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
12207 | units->singular, units->plural ? units->plural : "(no plural)");
12208 | }
12209 | }
12210 | }
12211 |
12212 | /* Prints the number of registered fields.
12213 | * Useful for determining an appropriate value for
12214 | * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12215 | *
12216 | * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12217 | * the number of fields, true otherwise.
12218 | */
12219 | bool_Bool
12220 | proto_registrar_dump_fieldcount(void)
12221 | {
12222 | struct proto_registrar_stats stats = {0, 0, 0};
12223 | size_t total_count = proto_registrar_get_count(&stats);
12224 |
12225 | printf("There are %zu header fields registered, of which:\n"
12226 | "\t%zu are deregistered\n"
12227 | "\t%zu are protocols\n"
12228 | "\t%zu have the same name as another field\n\n",
12229 | total_count, stats.deregistered_count, stats.protocol_count,
12230 | stats.same_name_count);
12231 |
12232 | printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12233 | (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12234 | "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12235 | "\n");
12236 |
12237 | printf("The header field table consumes %u KiB of memory.\n",
12238 | (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12239 | printf("The fields themselves consume %u KiB of memory.\n",
12240 | (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12241 |
12242 | return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12243 | }
12244 |
12245 | static void
12246 | elastic_add_base_mapping(json_dumper *dumper)
12247 | {
12248 | json_dumper_set_member_name(dumper, "index_patterns");
12249 | json_dumper_begin_array(dumper);
12250 | // The index names from write_json_index() in print.c
12251 | json_dumper_value_string(dumper, "packets-*");
12252 | json_dumper_end_array(dumper);
12253 |
12254 | json_dumper_set_member_name(dumper, "settings");
12255 | json_dumper_begin_object(dumper);
12256 | json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12257 | json_dumper_value_anyf(dumper, "%d", 1000000);
12258 | json_dumper_end_object(dumper);
12259 | }
12260 |
12261 | static char*
12262 | ws_type_to_elastic(unsigned type)
12263 | {
12264 | switch(type) {
12265 | case FT_INT8:
12266 | return "byte";
12267 | case FT_UINT8:
12268 | case FT_INT16:
12269 | return "short";
12270 | case FT_UINT16:
12271 | case FT_INT32:
12272 | case FT_UINT24:
12273 | case FT_INT24:
12274 | return "integer";
12275 | case FT_FRAMENUM:
12276 | case FT_UINT32:
12277 | case FT_UINT40:
12278 | case FT_UINT48:
12279 | case FT_UINT56:
12280 | case FT_INT40:
12281 | case FT_INT48:
12282 | case FT_INT56:
12283 | case FT_INT64:
12284 | return "long";
12285 | case FT_UINT64:
12286 | return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12287 | case FT_FLOAT:
12288 | return "float";
12289 | case FT_DOUBLE:
12290 | case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12291 | return "double";
12292 | case FT_IPv6:
12293 | case FT_IPv4:
12294 | return "ip";
12295 | case FT_ABSOLUTE_TIME:
12296 | return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12297 | case FT_BOOLEAN:
12298 | return "boolean";
12299 | default:
12300 | return NULL((void*)0);
12301 | }
12302 | }
12303 |
12304 | static char*
12305 | dot_to_underscore(char* str)
12306 | {
12307 | unsigned i;
12308 | for (i = 0; i < strlen(str); i++) {
12309 | if (str[i] == '.')
12310 | str[i] = '_';
12311 | }
12312 | return str;
12313 | }
12314 |
12315 | /* Dumps a mapping file for ElasticSearch
12316 | * This is the v1 (legacy) _template API.
12317 | * At some point it may need to be updated with the composable templates
12318 | * introduced in Elasticsearch 7.8 (_index_template)
12319 | */
12320 | void
12321 | proto_registrar_dump_elastic(const char* filter)
12322 | {
12323 | header_field_info *hfinfo;
12324 | header_field_info *parent_hfinfo;
12325 | unsigned i;
12326 | bool_Bool open_object = true1;
12327 | const char* prev_proto = NULL((void*)0);
12328 | char* str;
12329 | char** protos = NULL((void*)0);
12330 | char* proto;
12331 | bool_Bool found;
12332 | unsigned j;
12333 | char* type;
12334 | char* prev_item = NULL((void*)0);
12335 |
12336 | /* We have filtering protocols. Extract them. */
12337 | if (filter) {
12338 | protos = g_strsplit(filter, ",", -1);
12339 | }
12340 |
12341 | /*
12342 | * To help tracking down the json tree, objects have been appended with a comment:
12343 | * n.label -> where n is the indentation level and label the name of the object
12344 | */
12345 |
12346 | json_dumper dumper = {
12347 | .output_file = stdoutstdout,
12348 | .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12349 | };
12350 | json_dumper_begin_object(&dumper); // 1.root
12351 | elastic_add_base_mapping(&dumper);
12352 |
12353 | json_dumper_set_member_name(&dumper, "mappings");
12354 | json_dumper_begin_object(&dumper); // 2.mappings
12355 |
12356 | json_dumper_set_member_name(&dumper, "properties");
12357 | json_dumper_begin_object(&dumper); // 3.properties
12358 | json_dumper_set_member_name(&dumper, "timestamp");
12359 | json_dumper_begin_object(&dumper); // 4.timestamp
12360 | json_dumper_set_member_name(&dumper, "type");
12361 | json_dumper_value_string(&dumper, "date");
12362 | json_dumper_end_object(&dumper); // 4.timestamp
12363 |
12364 | json_dumper_set_member_name(&dumper, "layers");
12365 | json_dumper_begin_object(&dumper); // 4.layers
12366 | json_dumper_set_member_name(&dumper, "properties");
12367 | json_dumper_begin_object(&dumper); // 5.properties
12368 |
12369 | for (i = 1; i < gpa_hfinfo.len; i++) {
12370 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12371 | continue; /* This is a deregistered protocol or header field */
12372 |
12373 | 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", 12373 , __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", 12373 , "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", 12373, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12374 |
12375 | /*
12376 | * Skip the pseudo-field for "proto_tree_add_text()" since
12377 | * we don't want it in the list of filterable protocols.
12378 | */
12379 | if (hfinfo->id == hf_text_only)
12380 | continue;
12381 |
12382 | if (!proto_registrar_is_protocol(i)) {
12383 | 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", 12383 , __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", 12383 , "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", 12383 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12384 |
12385 | /*
12386 | * Skip the field if filter protocols have been set and this one's
12387 | * parent is not listed.
12388 | */
12389 | if (protos) {
12390 | found = false0;
12391 | j = 0;
12392 | proto = protos[0];
12393 | while(proto) {
12394 | if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12395 | found = true1;
12396 | break;
12397 | }
12398 | j++;
12399 | proto = protos[j];
12400 | }
12401 | if (!found)
12402 | continue;
12403 | }
12404 |
12405 | if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12406 | json_dumper_end_object(&dumper); // 7.properties
12407 | json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12408 | open_object = true1;
12409 | }
12410 |
12411 | prev_proto = parent_hfinfo->abbrev;
12412 |
12413 | if (open_object) {
12414 | json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12415 | json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12416 | json_dumper_set_member_name(&dumper, "properties");
12417 | json_dumper_begin_object(&dumper); // 7.properties
12418 | open_object = false0;
12419 | }
12420 | /* Skip the fields that would map into string. This is the default in elasticsearch. */
12421 | type = ws_type_to_elastic(hfinfo->type);
12422 | /* when type is NULL, we have the default mapping: string */
12423 | if (type) {
12424 | str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo-> abbrev);
12425 | dot_to_underscore(str);
12426 | if (g_strcmp0(prev_item, str)) {
12427 | json_dumper_set_member_name(&dumper, str);
12428 | json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12429 | json_dumper_set_member_name(&dumper, "type");
12430 | json_dumper_value_string(&dumper, type);
12431 | json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12432 | }
12433 | 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);
12434 | prev_item = str;
12435 | }
12436 | }
12437 | }
12438 | 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);
12439 |
12440 | if (prev_proto) {
12441 | json_dumper_end_object(&dumper); // 7.properties
12442 | json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12443 | }
12444 |
12445 | json_dumper_end_object(&dumper); // 5.properties
12446 | json_dumper_end_object(&dumper); // 4.layers
12447 | json_dumper_end_object(&dumper); // 3.properties
12448 | json_dumper_end_object(&dumper); // 2.mappings
12449 | json_dumper_end_object(&dumper); // 1.root
12450 | bool_Bool ret = json_dumper_finish(&dumper);
12451 | DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12451, "ret"))));
12452 |
12453 | g_strfreev(protos);
12454 | }
12455 |
12456 | /* Dumps the contents of the registration database to stdout. An independent
12457 | * program can take this output and format it into nice tables or HTML or
12458 | * whatever.
12459 | *
12460 | * There is one record per line. Each record is either a protocol or a header
12461 | * field, differentiated by the first field. The fields are tab-delimited.
12462 | *
12463 | * Protocols
12464 | * ---------
12465 | * Field 1 = 'P'
12466 | * Field 2 = descriptive protocol name
12467 | * Field 3 = protocol abbreviation
12468 | *
12469 | * Header Fields
12470 | * -------------
12471 | * Field 1 = 'F'
12472 | * Field 2 = descriptive field name
12473 | * Field 3 = field abbreviation
12474 | * Field 4 = type ( textual representation of the ftenum type )
12475 | * Field 5 = parent protocol abbreviation
12476 | * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12477 | * Field 7 = bitmask: format: hex: 0x....
12478 | * Field 8 = blurb describing field
12479 | */
12480 | void
12481 | proto_registrar_dump_fields(void)
12482 | {
12483 | header_field_info *hfinfo, *parent_hfinfo;
12484 | int i, len;
12485 | const char *enum_name;
12486 | const char *base_name;
12487 | const char *blurb;
12488 | char width[5];
12489 |
12490 | len = gpa_hfinfo.len;
12491 | for (i = 1; i < len ; i++) {
12492 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12493 | continue; /* This is a deregistered protocol or header field */
12494 |
12495 | 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", 12495 , __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", 12495 , "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", 12495, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12496 |
12497 | /*
12498 | * Skip the pseudo-field for "proto_tree_add_text()" since
12499 | * we don't want it in the list of filterable fields.
12500 | */
12501 | if (hfinfo->id == hf_text_only)
12502 | continue;
12503 |
12504 | /* format for protocols */
12505 | if (proto_registrar_is_protocol(i)) {
12506 | printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12507 | }
12508 | /* format for header fields */
12509 | else {
12510 | /*
12511 | * If this field isn't at the head of the list of
12512 | * fields with this name, skip this field - all
12513 | * fields with the same name are really just versions
12514 | * of the same field stored in different bits, and
12515 | * should have the same type/radix/value list, and
12516 | * just differ in their bit masks. (If a field isn't
12517 | * a bitfield, but can be, say, 1 or 2 bytes long,
12518 | * it can just be made FT_UINT16, meaning the
12519 | * *maximum* length is 2 bytes, and be used
12520 | * for all lengths.)
12521 | */
12522 | if (hfinfo->same_name_prev_id != -1)
12523 | continue;
12524 |
12525 | 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", 12525 , __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", 12525 , "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", 12525 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12526 |
12527 | enum_name = ftype_name(hfinfo->type);
12528 | base_name = "";
12529 |
12530 | if (hfinfo->type == FT_CHAR ||
12531 | hfinfo->type == FT_UINT8 ||
12532 | hfinfo->type == FT_UINT16 ||
12533 | hfinfo->type == FT_UINT24 ||
12534 | hfinfo->type == FT_UINT32 ||
12535 | hfinfo->type == FT_UINT40 ||
12536 | hfinfo->type == FT_UINT48 ||
12537 | hfinfo->type == FT_UINT56 ||
12538 | hfinfo->type == FT_UINT64 ||
12539 | hfinfo->type == FT_INT8 ||
12540 | hfinfo->type == FT_INT16 ||
12541 | hfinfo->type == FT_INT24 ||
12542 | hfinfo->type == FT_INT32 ||
12543 | hfinfo->type == FT_INT40 ||
12544 | hfinfo->type == FT_INT48 ||
12545 | hfinfo->type == FT_INT56 ||
12546 | hfinfo->type == FT_INT64) {
12547 |
12548 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12549 | case BASE_NONE:
12550 | case BASE_DEC:
12551 | case BASE_HEX:
12552 | case BASE_OCT:
12553 | case BASE_DEC_HEX:
12554 | case BASE_HEX_DEC:
12555 | case BASE_CUSTOM:
12556 | case BASE_PT_UDP:
12557 | case BASE_PT_TCP:
12558 | case BASE_PT_DCCP:
12559 | case BASE_PT_SCTP:
12560 | case BASE_OUI:
12561 | base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12562 | break;
12563 | default:
12564 | base_name = "????";
12565 | break;
12566 | }
12567 | } else if (hfinfo->type == FT_BOOLEAN) {
12568 | /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12569 | snprintf(width, sizeof(width), "%d", hfinfo->display);
12570 | base_name = width;
12571 | }
12572 |
12573 | blurb = hfinfo->blurb;
12574 | if (blurb == NULL((void*)0))
12575 | blurb = "";
12576 | else if (strlen(blurb) == 0)
12577 | blurb = "\"\"";
12578 |
12579 | printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12580 | hfinfo->name, hfinfo->abbrev, enum_name,
12581 | parent_hfinfo->abbrev, base_name,
12582 | hfinfo->bitmask, blurb);
12583 | }
12584 | }
12585 | }
12586 |
12587 | /* Dumps all abbreviated field and protocol completions of the given string to
12588 | * stdout. An independent program may use this for command-line tab completion
12589 | * of fields.
12590 | */
12591 | bool_Bool
12592 | proto_registrar_dump_field_completions(const char *prefix)
12593 | {
12594 | header_field_info *hfinfo;
12595 | int i, len;
12596 | size_t prefix_len;
12597 | bool_Bool matched = false0;
12598 |
12599 | prefix_len = strlen(prefix);
12600 | len = gpa_hfinfo.len;
12601 | for (i = 1; i < len ; i++) {
12602 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12603 | continue; /* This is a deregistered protocol or header field */
12604 |
12605 | 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", 12605 , __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", 12605 , "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", 12605, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12606 |
12607 | /*
12608 | * Skip the pseudo-field for "proto_tree_add_text()" since
12609 | * we don't want it in the list of filterable fields.
12610 | */
12611 | if (hfinfo->id == hf_text_only)
12612 | continue;
12613 |
12614 | /* format for protocols */
12615 | if (proto_registrar_is_protocol(i)) {
12616 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12617 | matched = true1;
12618 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12619 | }
12620 | }
12621 | /* format for header fields */
12622 | else {
12623 | /*
12624 | * If this field isn't at the head of the list of
12625 | * fields with this name, skip this field - all
12626 | * fields with the same name are really just versions
12627 | * of the same field stored in different bits, and
12628 | * should have the same type/radix/value list, and
12629 | * just differ in their bit masks. (If a field isn't
12630 | * a bitfield, but can be, say, 1 or 2 bytes long,
12631 | * it can just be made FT_UINT16, meaning the
12632 | * *maximum* length is 2 bytes, and be used
12633 | * for all lengths.)
12634 | */
12635 | if (hfinfo->same_name_prev_id != -1)
12636 | continue;
12637 |
12638 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12639 | matched = true1;
12640 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12641 | }
12642 | }
12643 | }
12644 | return matched;
12645 | }
12646 |
12647 | /* Dumps field types and descriptive names to stdout. An independent
12648 | * program can take this output and format it into nice tables or HTML or
12649 | * whatever.
12650 | *
12651 | * There is one record per line. The fields are tab-delimited.
12652 | *
12653 | * Field 1 = field type name, e.g. FT_UINT8
12654 | * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12655 | */
12656 | void
12657 | proto_registrar_dump_ftypes(void)
12658 | {
12659 | int fte;
12660 |
12661 | for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12662 | printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12663 | }
12664 | }
12665 |
12666 | /* This function indicates whether it's possible to construct a
12667 | * "match selected" display filter string for the specified field,
12668 | * returns an indication of whether it's possible, and, if it's
12669 | * possible and "filter" is non-null, constructs the filter and
12670 | * sets "*filter" to point to it.
12671 | * You do not need to [g_]free() this string since it will be automatically
12672 | * freed once the next packet is dissected.
12673 | */
12674 | static bool_Bool
12675 | construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12676 | char **filter)
12677 | {
12678 | const header_field_info *hfinfo;
12679 | int start, length, length_remaining;
12680 |
12681 | if (!finfo)
12682 | return false0;
12683 |
12684 | hfinfo = finfo->hfinfo;
12685 | DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12685, "hfinfo"))));
12686 |
12687 | /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12688 | * then "the numeric value ... is not used when preparing
12689 | * filters for the field in question." If it's any other
12690 | * base, we'll generate the filter normally (which will
12691 | * be numeric, even though the human-readable string does
12692 | * work for filtering.)
12693 | *
12694 | * XXX - It might be nice to use fvalue_to_string_repr() in
12695 | * "proto_item_fill_label()" as well, although, there, you'd
12696 | * have to deal with the base *and* with resolved values for
12697 | * addresses.
12698 | *
12699 | * Perhaps in addition to taking the repr type (DISPLAY
12700 | * or DFILTER) and the display (base), fvalue_to_string_repr()
12701 | * should have the the "strings" values in the header_field_info
12702 | * structure for the field as a parameter, so it can have
12703 | * if the field is Boolean or an enumerated integer type,
12704 | * the tables used to generate human-readable values.
12705 | */
12706 | if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12707 | const char *str = NULL((void*)0);
12708 |
12709 | switch (hfinfo->type) {
12710 |
12711 | case FT_INT8:
12712 | case FT_INT16:
12713 | case FT_INT24:
12714 | case FT_INT32:
12715 | str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12716 | break;
12717 |
12718 | case FT_CHAR:
12719 | case FT_UINT8:
12720 | case FT_UINT16:
12721 | case FT_UINT24:
12722 | case FT_UINT32:
12723 | str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12724 | break;
12725 |
12726 | default:
12727 | break;
12728 | }
12729 |
12730 | if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12731 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12732 | return true1;
12733 | }
12734 | }
12735 |
12736 | switch (hfinfo->type) {
12737 |
12738 | case FT_PROTOCOL:
12739 | if (filter != NULL((void*)0))
12740 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12741 | break;
12742 |
12743 | case FT_NONE:
12744 | /*
12745 | * If the length is 0, just match the name of the
12746 | * field.
12747 | *
12748 | * (Also check for negative values, just in case,
12749 | * as we'll cast it to an unsigned value later.)
12750 | */
12751 | length = finfo->length;
12752 | if (length == 0) {
12753 | if (filter != NULL((void*)0))
12754 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12755 | break;
12756 | }
12757 | if (length < 0)
12758 | return false0;
12759 |
12760 | /*
12761 | * This doesn't have a value, so we'd match
12762 | * on the raw bytes at this address.
12763 | *
12764 | * Should we be allowed to access to the raw bytes?
12765 | * If "edt" is NULL, the answer is "no".
12766 | */
12767 | if (edt == NULL((void*)0))
12768 | return false0;
12769 |
12770 | /*
12771 | * Is this field part of the raw frame tvbuff?
12772 | * If not, we can't use "frame[N:M]" to match
12773 | * it.
12774 | *
12775 | * XXX - should this be frame-relative, or
12776 | * protocol-relative?
12777 | *
12778 | * XXX - does this fallback for non-registered
12779 | * fields even make sense?
12780 | */
12781 | if (finfo->ds_tvb != edt->tvb)
12782 | return false0; /* you lose */
12783 |
12784 | /*
12785 | * Don't go past the end of that tvbuff.
12786 | */
12787 | length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12788 | if (length > length_remaining)
12789 | length = length_remaining;
12790 | if (length <= 0)
12791 | return false0;
12792 |
12793 | if (filter != NULL((void*)0)) {
12794 | start = finfo->start;
12795 | char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12796 | *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12797 | wmem_free(NULL((void*)0), str);
12798 | }
12799 | break;
12800 |
12801 | /* By default, use the fvalue's "to_string_repr" method. */
12802 | default:
12803 | if (filter != NULL((void*)0)) {
12804 | char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12805 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12806 | wmem_free(NULL((void*)0), str);
12807 | }
12808 | break;
12809 | }
12810 |
12811 | return true1;
12812 | }
12813 |
12814 | /*
12815 | * Returns true if we can do a "match selected" on the field, false
12816 | * otherwise.
12817 | */
12818 | bool_Bool
12819 | proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12820 | {
12821 | return construct_match_selected_string(finfo, edt, NULL((void*)0));
12822 | }
12823 |
12824 | /* This function attempts to construct a "match selected" display filter
12825 | * string for the specified field; if it can do so, it returns a pointer
12826 | * to the string, otherwise it returns NULL.
12827 | *
12828 | * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12829 | */
12830 | char *
12831 | proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12832 | {
12833 | char *filter = NULL((void*)0);
12834 |
12835 | if (!construct_match_selected_string(finfo, edt, &filter))
12836 | {
12837 | wmem_free(NULL((void*)0), filter);
12838 | return NULL((void*)0);
12839 | }
12840 | return filter;
12841 | }
12842 |
12843 | /* This function is common code for all proto_tree_add_bitmask... functions.
12844 | */
12845 |
12846 | static bool_Bool
12847 | proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const unsigned offset,
12848 | const int len, const int ett, int * const *fields,
12849 | const int flags, bool_Bool first,
12850 | bool_Bool use_parent_tree,
12851 | proto_tree* tree, uint64_t value)
12852 | {
12853 | uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12854 | uint64_t bitmask = 0;
12855 | uint64_t tmpval;
12856 | header_field_info *hf;
12857 | uint32_t integer32;
12858 | int bit_offset;
12859 | int no_of_bits;
12860 |
12861 | if (!*fields)
12862 | 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" );
12863 |
12864 | if (len < 0 || len > 8)
12865 | REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12866 | /**
12867 | * packet-frame.c uses len=0 since the value is taken from the packet
12868 | * metadata, not the packet bytes. In that case, assume that all bits
12869 | * in the provided value are valid.
12870 | */
12871 | if (len > 0) {
12872 | available_bits >>= (8 - (unsigned)len)*8;
12873 | }
12874 |
12875 | if (use_parent_tree == false0)
12876 | tree = proto_item_add_subtree(item, ett);
12877 |
12878 | while (*fields) {
12879 | uint64_t present_bits;
12880 | 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", 12880, __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", 12880 , "**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", 12880, "gpa_hfinfo.hfi[**fields] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];;
12881 | 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", 12881 , "hf->bitmask != 0", hf->abbrev))));
12882 |
12883 | bitmask |= hf->bitmask;
12884 |
12885 | /* Skip fields that aren't fully present */
12886 | present_bits = available_bits & hf->bitmask;
12887 | if (present_bits != hf->bitmask) {
12888 | fields++;
12889 | continue;
12890 | }
12891 |
12892 | switch (hf->type) {
12893 | case FT_CHAR:
12894 | case FT_UINT8:
12895 | case FT_UINT16:
12896 | case FT_UINT24:
12897 | case FT_UINT32:
12898 | proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12899 | break;
12900 |
12901 | case FT_INT8:
12902 | case FT_INT16:
12903 | case FT_INT24:
12904 | case FT_INT32:
12905 | proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12906 | break;
12907 |
12908 | case FT_UINT40:
12909 | case FT_UINT48:
12910 | case FT_UINT56:
12911 | case FT_UINT64:
12912 | proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12913 | break;
12914 |
12915 | case FT_INT40:
12916 | case FT_INT48:
12917 | case FT_INT56:
12918 | case FT_INT64:
12919 | proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12920 | break;
12921 |
12922 | case FT_BOOLEAN:
12923 | proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12924 | break;
12925 |
12926 | default:
12927 | 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))
12928 | 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))
12929 | 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))
12930 | 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));
12931 | break;
12932 | }
12933 | if (flags & BMT_NO_APPEND0x01) {
12934 | fields++;
12935 | continue;
12936 | }
12937 | tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12938 |
12939 | /* XXX: README.developer and the comments have always defined
12940 | * BMT_NO_INT as "only boolean flags are added to the title /
12941 | * don't add non-boolean (integral) fields", but the
12942 | * implementation has always added BASE_CUSTOM and fields with
12943 | * value_strings, though not fields with unit_strings.
12944 | * Possibly this is because some dissectors use a FT_UINT8
12945 | * with a value_string for fields that should be a FT_BOOLEAN.
12946 | */
12947 | switch (hf->type) {
12948 | case FT_CHAR:
12949 | if (hf->display == BASE_CUSTOM) {
12950 | char lbl[ITEM_LABEL_LENGTH240];
12951 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12952 |
12953 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12953, "fmtfunc"))));
12954 | fmtfunc(lbl, (uint32_t) tmpval);
12955 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12956 | hf->name, lbl);
12957 | first = false0;
12958 | }
12959 | else if (hf->strings) {
12960 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12961 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12962 | first = false0;
12963 | }
12964 | else if (!(flags & BMT_NO_INT0x02)) {
12965 | char buf[32];
12966 | const char *out;
12967 |
12968 | if (!first) {
12969 | proto_item_append_text(item, ", ");
12970 | }
12971 |
12972 | out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12973 | proto_item_append_text(item, "%s: %s", hf->name, out);
12974 | first = false0;
12975 | }
12976 |
12977 | break;
12978 |
12979 | case FT_UINT8:
12980 | case FT_UINT16:
12981 | case FT_UINT24:
12982 | case FT_UINT32:
12983 | if (hf->display == BASE_CUSTOM) {
12984 | char lbl[ITEM_LABEL_LENGTH240];
12985 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12986 |
12987 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12987, "fmtfunc"))));
12988 | fmtfunc(lbl, (uint32_t) tmpval);
12989 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12990 | hf->name, lbl);
12991 | first = false0;
12992 | }
12993 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12994 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12995 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12996 | first = false0;
12997 | }
12998 | else if (!(flags & BMT_NO_INT0x02)) {
12999 | char buf[NUMBER_LABEL_LENGTH80];
13000 | const char *out = NULL((void*)0);
13001 |
13002 | if (!first) {
13003 | proto_item_append_text(item, ", ");
13004 | }
13005 |
13006 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13007 | out = hf_try_val_to_str((uint32_t) tmpval, hf);
13008 | }
13009 | if (out == NULL((void*)0)) {
13010 | out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
13011 | }
13012 | proto_item_append_text(item, "%s: %s", hf->name, out);
13013 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13014 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13015 | }
13016 | first = false0;
13017 | }
13018 |
13019 | break;
13020 |
13021 | case FT_INT8:
13022 | case FT_INT16:
13023 | case FT_INT24:
13024 | case FT_INT32:
13025 | integer32 = (uint32_t) tmpval;
13026 | if (hf->bitmask) {
13027 | no_of_bits = ws_count_ones(hf->bitmask);
13028 | integer32 = ws_sign_ext32(integer32, no_of_bits);
13029 | }
13030 | if (hf->display == BASE_CUSTOM) {
13031 | char lbl[ITEM_LABEL_LENGTH240];
13032 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
13033 |
13034 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13034, "fmtfunc"))));
13035 | fmtfunc(lbl, (int32_t) integer32);
13036 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13037 | hf->name, lbl);
13038 | first = false0;
13039 | }
13040 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13041 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13042 | hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
13043 | first = false0;
13044 | }
13045 | else if (!(flags & BMT_NO_INT0x02)) {
13046 | char buf[NUMBER_LABEL_LENGTH80];
13047 | const char *out = NULL((void*)0);
13048 |
13049 | if (!first) {
13050 | proto_item_append_text(item, ", ");
13051 | }
13052 |
13053 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13054 | out = hf_try_val_to_str((int32_t) integer32, hf);
13055 | }
13056 | if (out == NULL((void*)0)) {
13057 | out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
13058 | }
13059 | proto_item_append_text(item, "%s: %s", hf->name, out);
13060 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13061 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
13062 | }
13063 | first = false0;
13064 | }
13065 |
13066 | break;
13067 |
13068 | case FT_UINT40:
13069 | case FT_UINT48:
13070 | case FT_UINT56:
13071 | case FT_UINT64:
13072 | if (hf->display == BASE_CUSTOM) {
13073 | char lbl[ITEM_LABEL_LENGTH240];
13074 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13075 |
13076 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13076, "fmtfunc"))));
13077 | fmtfunc(lbl, tmpval);
13078 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13079 | hf->name, lbl);
13080 | first = false0;
13081 | }
13082 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13083 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13084 | hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
13085 | first = false0;
13086 | }
13087 | else if (!(flags & BMT_NO_INT0x02)) {
13088 | char buf[NUMBER_LABEL_LENGTH80];
13089 | const char *out = NULL((void*)0);
13090 |
13091 | if (!first) {
13092 | proto_item_append_text(item, ", ");
13093 | }
13094 |
13095 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13096 | out = hf_try_val64_to_str(tmpval, hf);
13097 | }
13098 | if (out == NULL((void*)0)) {
13099 | out = hfinfo_number_value_format64(hf, buf, tmpval);
13100 | }
13101 | proto_item_append_text(item, "%s: %s", hf->name, out);
13102 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13103 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13104 | }
13105 | first = false0;
13106 | }
13107 |
13108 | break;
13109 |
13110 | case FT_INT40:
13111 | case FT_INT48:
13112 | case FT_INT56:
13113 | case FT_INT64:
13114 | if (hf->bitmask) {
13115 | no_of_bits = ws_count_ones(hf->bitmask);
13116 | tmpval = ws_sign_ext64(tmpval, no_of_bits);
13117 | }
13118 | if (hf->display == BASE_CUSTOM) {
13119 | char lbl[ITEM_LABEL_LENGTH240];
13120 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
13121 |
13122 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 13122, "fmtfunc"))));
13123 | fmtfunc(lbl, (int64_t) tmpval);
13124 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13125 | hf->name, lbl);
13126 | first = false0;
13127 | }
13128 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
13129 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13130 | hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
13131 | first = false0;
13132 | }
13133 | else if (!(flags & BMT_NO_INT0x02)) {
13134 | char buf[NUMBER_LABEL_LENGTH80];
13135 | const char *out = NULL((void*)0);
13136 |
13137 | if (!first) {
13138 | proto_item_append_text(item, ", ");
13139 | }
13140 |
13141 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
13142 | out = hf_try_val64_to_str((int64_t) tmpval, hf);
13143 | }
13144 | if (out == NULL((void*)0)) {
13145 | out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
13146 | }
13147 | proto_item_append_text(item, "%s: %s", hf->name, out);
13148 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
13149 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
13150 | }
13151 | first = false0;
13152 | }
13153 |
13154 | break;
13155 |
13156 | case FT_BOOLEAN:
13157 | if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
13158 | /* If we have true/false strings, emit full - otherwise messages
13159 | might look weird */
13160 | const struct true_false_string *tfs =
13161 | (const struct true_false_string *)hf->strings;
13162 |
13163 | if (tmpval) {
13164 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13165 | hf->name, tfs->true_string);
13166 | first = false0;
13167 | } else if (!(flags & BMT_NO_FALSE0x04)) {
13168 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
13169 | hf->name, tfs->false_string);
13170 | first = false0;
13171 | }
13172 | } else if (hf->bitmask & value) {
13173 | /* If the flag is set, show the name */
13174 | proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
13175 | first = false0;
13176 | }
13177 | break;
13178 | default:
13179 | 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))
13180 | 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))
13181 | 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))
13182 | 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));
13183 | break;
13184 | }
13185 |
13186 | fields++;
13187 | }
13188 |
13189 | /* XXX: We don't pass the hfi into this function. Perhaps we should,
13190 | * but then again most dissectors don't set the bitmask field for
13191 | * the higher level bitmask hfi, so calculate the bitmask from the
13192 | * fields present. */
13193 | if (item) {
13194 | bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13195 | no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13196 | 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);
13197 | 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);
13198 | }
13199 | return first;
13200 | }
13201 |
13202 | /* This function will dissect a sequence of bytes that describe a
13203 | * bitmask and supply the value of that sequence through a pointer.
13204 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13205 | * to be dissected.
13206 | * This field will form an expansion under which the individual fields of the
13207 | * bitmask is dissected and displayed.
13208 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13209 | *
13210 | * fields is an array of pointers to int that lists all the fields of the
13211 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13212 | * or another integer of the same type/size as hf_hdr with a mask specified.
13213 | * This array is terminated by a NULL entry.
13214 | *
13215 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13216 | * FT_integer fields that have a value_string attached will have the
13217 | * matched string displayed on the expansion line.
13218 | */
13219 | proto_item *
13220 | proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13221 | const unsigned offset, const int hf_hdr,
13222 | const int ett, int * const *fields,
13223 | const unsigned encoding, uint64_t *retval)
13224 | {
13225 | 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);
13226 | }
13227 |
13228 | /* This function will dissect a sequence of bytes that describe a
13229 | * bitmask.
13230 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13231 | * to be dissected.
13232 | * This field will form an expansion under which the individual fields of the
13233 | * bitmask is dissected and displayed.
13234 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13235 | *
13236 | * fields is an array of pointers to int that lists all the fields of the
13237 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13238 | * or another integer of the same type/size as hf_hdr with a mask specified.
13239 | * This array is terminated by a NULL entry.
13240 | *
13241 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13242 | * FT_integer fields that have a value_string attached will have the
13243 | * matched string displayed on the expansion line.
13244 | */
13245 | proto_item *
13246 | proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13247 | const unsigned offset, const int hf_hdr,
13248 | const int ett, int * const *fields,
13249 | const unsigned encoding)
13250 | {
13251 | return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13252 | }
13253 |
13254 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13255 | * what data is appended to the header.
13256 | */
13257 | proto_item *
13258 | proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13259 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13260 | uint64_t *retval)
13261 | {
13262 | proto_item *item = NULL((void*)0);
13263 | header_field_info *hf;
13264 | int len;
13265 | uint64_t value;
13266 |
13267 | 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", 13267, __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", 13267 , "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", 13267, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13268 | 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", 13268, (hf)->abbrev)));
13269 | len = ftype_wire_size(hf->type);
13270 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13271 |
13272 | if (parent_tree) {
13273 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13274 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13275 | flags, false0, false0, NULL((void*)0), value);
13276 | }
13277 |
13278 | *retval = value;
13279 | if (hf->bitmask) {
13280 | /* Mask out irrelevant portions */
13281 | *retval &= hf->bitmask;
13282 | /* Shift bits */
13283 | *retval >>= hfinfo_bitshift(hf);
13284 | }
13285 |
13286 | return item;
13287 | }
13288 |
13289 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13290 | * what data is appended to the header.
13291 | */
13292 | proto_item *
13293 | proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13294 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13295 | {
13296 | proto_item *item = NULL((void*)0);
13297 | header_field_info *hf;
13298 | int len;
13299 | uint64_t value;
13300 |
13301 | 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", 13301, __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", 13301 , "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", 13301, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13302 | 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", 13302, (hf)->abbrev)));
13303 |
13304 | if (parent_tree) {
13305 | len = ftype_wire_size(hf->type);
13306 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13307 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13308 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13309 | flags, false0, false0, NULL((void*)0), value);
13310 | }
13311 |
13312 | return item;
13313 | }
13314 |
13315 | /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13316 | can't be retrieved directly from tvb) */
13317 | proto_item *
13318 | proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13319 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13320 | {
13321 | return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13322 | hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13323 | }
13324 |
13325 | /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13326 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13327 | proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13328 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13329 | {
13330 | proto_item *item = NULL((void*)0);
13331 | header_field_info *hf;
13332 | int len;
13333 |
13334 | 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", 13334, __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", 13334 , "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", 13334, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13335 | 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", 13335, (hf)->abbrev)));
13336 | /* the proto_tree_add_uint/_uint64() calls below
13337 | will fail if tvb==NULL and len!=0 */
13338 | len = tvb ? ftype_wire_size(hf->type) : 0;
13339 |
13340 | if (parent_tree) {
13341 | if (len <= 4)
13342 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13343 | else
13344 | item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13345 |
13346 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13347 | flags, false0, false0, NULL((void*)0), value);
13348 | }
13349 |
13350 | return item;
13351 | }
13352 |
13353 | /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13354 | void
13355 | proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13356 | const int len, int * const *fields, const unsigned encoding)
13357 | {
13358 | uint64_t value;
13359 |
13360 | if (tree) {
13361 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13362 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13363 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13364 | }
13365 | }
13366 |
13367 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13368 | proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13369 | const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13370 | {
13371 | uint64_t value;
13372 |
13373 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13374 | if (tree) {
13375 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13376 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13377 | }
13378 | if (retval) {
13379 | *retval = value;
13380 | }
13381 | }
13382 |
13383 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13384 | proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13385 | const int len, int * const *fields, const uint64_t value)
13386 | {
13387 | if (tree) {
13388 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13389 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13390 | }
13391 | }
13392 |
13393 |
13394 | /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13395 | * This is intended to support bitmask fields whose lengths can vary, perhaps
13396 | * as the underlying standard evolves over time.
13397 | * With this API there is the possibility of being called to display more or
13398 | * less data than the dissector was coded to support.
13399 | * In such cases, it is assumed that bitmasks are extended on the MSb end.
13400 | * Thus when presented with "too much" or "too little" data, MSbits will be
13401 | * ignored or MSfields sacrificed.
13402 | *
13403 | * Only fields for which all defined bits are available are displayed.
13404 | */
13405 | proto_item *
13406 | proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13407 | const unsigned offset, const unsigned len, const int hf_hdr,
13408 | const int ett, int * const *fields, struct expert_field* exp,
13409 | const unsigned encoding)
13410 | {
13411 | proto_item *item = NULL((void*)0);
13412 | header_field_info *hf;
13413 | unsigned decodable_len;
13414 | unsigned decodable_offset;
13415 | uint32_t decodable_value;
13416 | uint64_t value;
13417 |
13418 | 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", 13418, __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", 13418 , "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", 13418, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13419 | 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", 13419, (hf)->abbrev)));
13420 |
13421 | decodable_offset = offset;
13422 | decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len ) : ((unsigned) ftype_wire_size(hf->type)));
13423 |
13424 | /* If we are ftype_wire_size-limited,
13425 | * make sure we decode as many LSBs as possible.
13426 | */
13427 | if (encoding == ENC_BIG_ENDIAN0x00000000) {
13428 | decodable_offset += (len - decodable_len);
13429 | }
13430 |
13431 | if (parent_tree) {
13432 | decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13433 | decodable_len, encoding);
13434 |
13435 | /* The root item covers all the bytes even if we can't decode them all */
13436 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13437 | decodable_value);
13438 | }
13439 |
13440 | if (decodable_len < len) {
13441 | /* Dissector likely requires updating for new protocol revision */
13442 | expert_add_info_format(NULL((void*)0), item, exp,
13443 | "Only least-significant %d of %d bytes decoded",
13444 | decodable_len, len);
13445 | }
13446 |
13447 | if (item) {
13448 | value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13449 | proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13450 | ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13451 | }
13452 |
13453 | return item;
13454 | }
13455 |
13456 | /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13457 | proto_item *
13458 | proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13459 | const unsigned offset, const unsigned len,
13460 | const char *name, const char *fallback,
13461 | const int ett, int * const *fields,
13462 | const unsigned encoding, const int flags)
13463 | {
13464 | proto_item *item = NULL((void*)0);
13465 | uint64_t value;
13466 |
13467 | if (parent_tree) {
13468 | item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13469 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13470 | if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13471 | flags, true1, false0, NULL((void*)0), value) && fallback) {
13472 | /* Still at first item - append 'fallback' text if any */
13473 | proto_item_append_text(item, "%s", fallback);
13474 | }
13475 | }
13476 |
13477 | return item;
13478 | }
13479 |
13480 | proto_item *
13481 | proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13482 | const unsigned bit_offset, const int no_of_bits,
13483 | const unsigned encoding)
13484 | {
13485 | header_field_info *hfinfo;
13486 | int octet_length;
13487 | unsigned octet_offset;
13488 |
13489 | 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", 13489, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13489 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13489, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13490 |
13491 | if (no_of_bits < 0) {
13492 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13493 | }
13494 | octet_length = (no_of_bits + 7) >> 3;
13495 | octet_offset = bit_offset >> 3;
13496 | test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13497 |
13498 | /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13499 | * but only after doing a bunch more work (which we can, in the common
13500 | * case, shortcut here).
13501 | */
13502 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13503 | 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", 13503 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13503, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13503, "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", 13503, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
13504 |
13505 | return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13506 | }
13507 |
13508 | /*
13509 | * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13510 | * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13511 | * Offset should be given in bits from the start of the tvb.
13512 | */
13513 |
13514 | static proto_item *
13515 | _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13516 | const unsigned bit_offset, const int no_of_bits,
13517 | uint64_t *return_value, const unsigned encoding)
13518 | {
13519 | unsigned offset;
13520 | unsigned length;
13521 | uint8_t tot_no_bits;
13522 | char *bf_str;
13523 | char lbl_str[ITEM_LABEL_LENGTH240];
13524 | uint64_t value = 0;
13525 | uint8_t *bytes = NULL((void*)0);
13526 | size_t bytes_length = 0;
13527 |
13528 | proto_item *pi;
13529 | header_field_info *hf_field;
13530 |
13531 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13532 | 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", 13532, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13532 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13532, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;;
13533 |
13534 | if (hf_field->bitmask != 0) {
13535 | 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)
13536 | " 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)
13537 | 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);
13538 | }
13539 |
13540 | if (no_of_bits < 0) {
13541 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13542 | } else if (no_of_bits == 0) {
13543 | 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)
13544 | 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);
13545 | }
13546 |
13547 | /* Byte align offset */
13548 | offset = bit_offset>>3;
13549 |
13550 | /*
13551 | * Calculate the number of octets used to hold the bits
13552 | */
13553 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13554 | length = (tot_no_bits + 7) >> 3;
13555 |
13556 | if (no_of_bits < 65) {
13557 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13558 | } else if (hf_field->type != FT_BYTES) {
13559 | 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)
13560 | 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);
13561 | return NULL((void*)0);
13562 | }
13563 |
13564 | /* Sign extend for signed types */
13565 | switch (hf_field->type) {
13566 | case FT_INT8:
13567 | case FT_INT16:
13568 | case FT_INT24:
13569 | case FT_INT32:
13570 | case FT_INT40:
13571 | case FT_INT48:
13572 | case FT_INT56:
13573 | case FT_INT64:
13574 | value = ws_sign_ext64(value, no_of_bits);
13575 | break;
13576 |
13577 | default:
13578 | break;
13579 | }
13580 |
13581 | if (return_value) {
13582 | *return_value = value;
13583 | }
13584 |
13585 | /* Coast clear. Try and fake it */
13586 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13587 | 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", 13587 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13587, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13587, "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", 13587, __func__, "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); } } };
13588 |
13589 | bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13590 |
13591 | switch (hf_field->type) {
13592 | case FT_BOOLEAN:
13593 | /* Boolean field */
13594 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13595 | "%s = %s: %s",
13596 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13597 | break;
13598 |
13599 | case FT_CHAR:
13600 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13601 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13602 | break;
13603 |
13604 | case FT_UINT8:
13605 | case FT_UINT16:
13606 | case FT_UINT24:
13607 | case FT_UINT32:
13608 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13609 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13610 | break;
13611 |
13612 | case FT_INT8:
13613 | case FT_INT16:
13614 | case FT_INT24:
13615 | case FT_INT32:
13616 | pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13617 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13618 | break;
13619 |
13620 | case FT_UINT40:
13621 | case FT_UINT48:
13622 | case FT_UINT56:
13623 | case FT_UINT64:
13624 | pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13625 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13626 | break;
13627 |
13628 | case FT_INT40:
13629 | case FT_INT48:
13630 | case FT_INT56:
13631 | case FT_INT64:
13632 | pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13633 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13634 | break;
13635 |
13636 | case FT_BYTES:
13637 | bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13638 | pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13639 | proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13640 | proto_item_set_text(pi, "%s", lbl_str);
13641 | return pi;
13642 |
13643 | /* TODO: should handle FT_UINT_BYTES ? */
13644 |
13645 | default:
13646 | 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))
13647 | 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))
13648 | 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))
13649 | 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));
13650 | return NULL((void*)0);
13651 | }
13652 |
13653 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13654 | return pi;
13655 | }
13656 |
13657 | proto_item *
13658 | proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13659 | const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13660 | uint64_t *return_value)
13661 | {
13662 | proto_item *pi;
13663 | int no_of_bits;
13664 | unsigned octet_offset;
13665 | unsigned mask_initial_bit_offset;
13666 | unsigned mask_greatest_bit_offset;
13667 | unsigned octet_length;
13668 | uint8_t i;
13669 | char bf_str[256];
13670 | char lbl_str[ITEM_LABEL_LENGTH240];
13671 | uint64_t value;
13672 | uint64_t composite_bitmask;
13673 | uint64_t composite_bitmap;
13674 |
13675 | header_field_info *hf_field;
13676 |
13677 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13678 | 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", 13678, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13678 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13678, "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 | →
13679 |
13680 | if (hf_field->bitmask != 0) {
8 | ← | Assuming field 'bitmask' is equal to 0 | →
9 | ← | Taking false branch | →
13681 | 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)
13682 | " 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)
13683 | 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);
13684 | }
13685 |
13686 | mask_initial_bit_offset = bit_offset % 8;
13687 |
13688 | no_of_bits = 0;
13689 | value = 0;
13690 | i = 0;
13691 | mask_greatest_bit_offset = 0;
13692 | composite_bitmask = 0;
13693 | composite_bitmap = 0;
13694 |
13695 | 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 | →
13696 | uint64_t crumb_mask, crumb_value;
13697 | uint8_t crumb_end_bit_offset;
13698 |
13699 | crumb_value = tvb_get_bits64(tvb,
13700 | bit_offset + crumb_spec[i].crumb_bit_offset,
13701 | crumb_spec[i].crumb_bit_length,
13702 | ENC_BIG_ENDIAN0x00000000);
13703 | value += crumb_value;
13704 | no_of_bits += crumb_spec[i].crumb_bit_length;
13705 | 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", 13705 , "no_of_bits <= 64", "a value larger than 64 bits cannot be represented" ))));
12 | ← | Assuming 'no_of_bits' is <= 64 | →
13 | ← | '?' condition is true | →
13706 |
13707 | /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13708 | octet containing the initial offset.
13709 | If the mask is beyond 32 bits, then give up on bit map display.
13710 | This could be improved in future, probably showing a table
13711 | of 32 or 64 bits per row */
13712 | if (mask_greatest_bit_offset
13.1 | 'mask_greatest_bit_offset' is < 32
< 32) {
14 | ← | Taking true branch | →
13713 | crumb_end_bit_offset = mask_initial_bit_offset
13714 | + crumb_spec[i].crumb_bit_offset
13715 | + crumb_spec[i].crumb_bit_length;
13716 | 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' | →
13717 |
13718 | if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17 | ← | Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset' | →
18 | ← | Taking false branch | →
13719 | mask_greatest_bit_offset = crumb_end_bit_offset;
13720 | }
13721 | /* Currently the bitmap of the crumbs are only shown if
13722 | * smaller than 32 bits. Do not bother calculating the
13723 | * mask if it is larger than that. */
13724 | if (crumb_end_bit_offset
18.1 | 'crumb_end_bit_offset' is <= 32
<= 32) {
19 | ← | Taking true branch | →
13725 | 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'
13726 | composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13727 | }
13728 | }
13729 | /* Shift left for the next segment */
13730 | value <<= crumb_spec[++i].crumb_bit_length;
13731 | }
13732 |
13733 | /* Sign extend for signed types */
13734 | switch (hf_field->type) {
13735 | case FT_INT8:
13736 | case FT_INT16:
13737 | case FT_INT24:
13738 | case FT_INT32:
13739 | case FT_INT40:
13740 | case FT_INT48:
13741 | case FT_INT56:
13742 | case FT_INT64:
13743 | value = ws_sign_ext64(value, no_of_bits);
13744 | break;
13745 | default:
13746 | break;
13747 | }
13748 |
13749 | if (return_value) {
13750 | *return_value = value;
13751 | }
13752 |
13753 | /* Coast clear. Try and fake it */
13754 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13755 | 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", 13755 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13755, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13755, "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", 13755, __func__, "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); } } };
13756 |
13757 | /* initialise the format string */
13758 | bf_str[0] = '\0';
13759 |
13760 | octet_offset = bit_offset >> 3;
13761 |
13762 | /* Round up mask length to nearest octet */
13763 | octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13764 | mask_greatest_bit_offset = octet_length << 3;
13765 |
13766 | /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13767 | It would be a useful enhancement to eliminate this restriction. */
13768 | if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13769 | other_decode_bitfield_value(bf_str,
13770 | (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13771 | (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13772 | mask_greatest_bit_offset);
13773 | } else {
13774 | /* If the bitmask is too large, try to describe its contents. */
13775 | snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13776 | }
13777 |
13778 | switch (hf_field->type) {
13779 | case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13780 | /* Boolean field */
13781 | return proto_tree_add_boolean_format(tree, hfindex,
13782 | tvb, octet_offset, octet_length, value,
13783 | "%s = %s: %s",
13784 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13785 | break;
13786 |
13787 | case FT_CHAR:
13788 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13789 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13790 | break;
13791 |
13792 | case FT_UINT8:
13793 | case FT_UINT16:
13794 | case FT_UINT24:
13795 | case FT_UINT32:
13796 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13797 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13798 | break;
13799 |
13800 | case FT_INT8:
13801 | case FT_INT16:
13802 | case FT_INT24:
13803 | case FT_INT32:
13804 | pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13805 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13806 | break;
13807 |
13808 | case FT_UINT40:
13809 | case FT_UINT48:
13810 | case FT_UINT56:
13811 | case FT_UINT64:
13812 | pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13813 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13814 | break;
13815 |
13816 | case FT_INT40:
13817 | case FT_INT48:
13818 | case FT_INT56:
13819 | case FT_INT64:
13820 | pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13821 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13822 | break;
13823 |
13824 | default:
13825 | 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))
13826 | 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))
13827 | 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))
13828 | 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));
13829 | return NULL((void*)0);
13830 | }
13831 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13832 | return pi;
13833 | }
13834 |
13835 | void
13836 | proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13837 | const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13838 | {
13839 | header_field_info *hfinfo;
13840 | unsigned start = bit_offset >> 3;
13841 | int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13842 |
13843 | /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13844 | * so that we can use the tree's memory scope in calculating the string */
13845 | if (length == -1) {
13846 | tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13847 | } else {
13848 | tvb_ensure_bytes_exist(tvb, start, length);
13849 | }
13850 | if (!tree) return;
13851 |
13852 | 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", 13852, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13852 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13852, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13853 | proto_tree_add_text_internal(tree, tvb, start, length,
13854 | "%s crumb %d of %s (decoded above)",
13855 | decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13856 | tvb_get_bits32(tvb,
13857 | bit_offset,
13858 | crumb_spec[crumb_index].crumb_bit_length,
13859 | ENC_BIG_ENDIAN0x00000000),
13860 | ENC_BIG_ENDIAN0x00000000),
13861 | crumb_index,
13862 | hfinfo->name);
13863 | }
13864 |
13865 | proto_item *
13866 | proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13867 | const unsigned bit_offset, const int no_of_bits,
13868 | uint64_t *return_value, const unsigned encoding)
13869 | {
13870 | proto_item *item;
13871 |
13872 | if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13873 | bit_offset, no_of_bits,
13874 | return_value, encoding))) {
13875 | 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);
13876 | 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);
13877 | }
13878 | return item;
13879 | }
13880 |
13881 | static proto_item *
13882 | _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13883 | tvbuff_t *tvb, const unsigned bit_offset,
13884 | const int no_of_bits, void *value_ptr,
13885 | const unsigned encoding, char *value_str)
13886 | {
13887 | unsigned offset;
13888 | unsigned length;
13889 | uint8_t tot_no_bits;
13890 | char *str;
13891 | uint64_t value = 0;
13892 | header_field_info *hf_field;
13893 |
13894 | /* We do not have to return a value, try to fake it as soon as possible */
13895 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13896 | 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", 13896 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13896, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13896, "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", 13896, __func__, "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); } } };
13897 |
13898 | if (hf_field->bitmask != 0) {
13899 | 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)
13900 | " 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)
13901 | 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);
13902 | }
13903 |
13904 | if (no_of_bits < 0) {
13905 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13906 | } else if (no_of_bits == 0) {
13907 | 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)
13908 | 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);
13909 | }
13910 |
13911 | /* Byte align offset */
13912 | offset = bit_offset>>3;
13913 |
13914 | /*
13915 | * Calculate the number of octets used to hold the bits
13916 | */
13917 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13918 | length = tot_no_bits>>3;
13919 | /* If we are using part of the next octet, increase length by 1 */
13920 | if (tot_no_bits & 0x07)
13921 | length++;
13922 |
13923 | if (no_of_bits < 65) {
13924 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13925 | } else {
13926 | 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)
13927 | 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);
13928 | return NULL((void*)0);
13929 | }
13930 |
13931 | str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13932 |
13933 | (void) g_strlcat(str, " = ", 256+64);
13934 | (void) g_strlcat(str, hf_field->name, 256+64);
13935 |
13936 | /*
13937 | * This function does not receive an actual value but a dimensionless pointer to that value.
13938 | * For this reason, the type of the header field is examined in order to determine
13939 | * what kind of value we should read from this address.
13940 | * The caller of this function must make sure that for the specific header field type the address of
13941 | * a compatible value is provided.
13942 | */
13943 | switch (hf_field->type) {
13944 | case FT_BOOLEAN:
13945 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13946 | "%s: %s", str, value_str);
13947 | break;
13948 |
13949 | case FT_CHAR:
13950 | case FT_UINT8:
13951 | case FT_UINT16:
13952 | case FT_UINT24:
13953 | case FT_UINT32:
13954 | return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13955 | "%s: %s", str, value_str);
13956 | break;
13957 |
13958 | case FT_UINT40:
13959 | case FT_UINT48:
13960 | case FT_UINT56:
13961 | case FT_UINT64:
13962 | return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13963 | "%s: %s", str, value_str);
13964 | break;
13965 |
13966 | case FT_INT8:
13967 | case FT_INT16:
13968 | case FT_INT24:
13969 | case FT_INT32:
13970 | return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13971 | "%s: %s", str, value_str);
13972 | break;
13973 |
13974 | case FT_INT40:
13975 | case FT_INT48:
13976 | case FT_INT56:
13977 | case FT_INT64:
13978 | return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13979 | "%s: %s", str, value_str);
13980 | break;
13981 |
13982 | case FT_FLOAT:
13983 | return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13984 | "%s: %s", str, value_str);
13985 | break;
13986 |
13987 | default:
13988 | 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))
13989 | 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))
13990 | 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))
13991 | 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));
13992 | return NULL((void*)0);
13993 | }
13994 | }
13995 |
13996 | static proto_item *
13997 | proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13998 | tvbuff_t *tvb, const unsigned bit_offset,
13999 | const int no_of_bits, void *value_ptr,
14000 | const unsigned encoding, char *value_str)
14001 | {
14002 | proto_item *item;
14003 |
14004 | if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
14005 | tvb, bit_offset, no_of_bits,
14006 | value_ptr, encoding, value_str))) {
14007 | 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);
14008 | 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);
14009 | }
14010 | return item;
14011 | }
14012 |
14013 | #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); \
14014 | va_start(ap, format)__builtin_va_start(ap, format); \
14015 | dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
14016 | va_end(ap)__builtin_va_end(ap);
14017 |
14018 | proto_item *
14019 | proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
14020 | tvbuff_t *tvb, const unsigned bit_offset,
14021 | const int no_of_bits, uint32_t value,
14022 | const unsigned encoding,
14023 | const char *format, ...)
14024 | {
14025 | va_list ap;
14026 | char *dst;
14027 | header_field_info *hf_field;
14028 |
14029 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14030 |
14031 | 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", 14031 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14031, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14031, "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", 14031, __func__, "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); } } };
14032 |
14033 | switch (hf_field->type) {
14034 | case FT_UINT8:
14035 | case FT_UINT16:
14036 | case FT_UINT24:
14037 | case FT_UINT32:
14038 | break;
14039 |
14040 | default:
14041 | 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)
14042 | 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);
14043 | return NULL((void*)0);
14044 | }
14045 |
14046 | 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);;
14047 |
14048 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14049 | }
14050 |
14051 | proto_item *
14052 | proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
14053 | tvbuff_t *tvb, const unsigned bit_offset,
14054 | const int no_of_bits, uint64_t value,
14055 | const unsigned encoding,
14056 | const char *format, ...)
14057 | {
14058 | va_list ap;
14059 | char *dst;
14060 | header_field_info *hf_field;
14061 |
14062 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14063 |
14064 | 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", 14064 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14064, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14064, "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", 14064, __func__, "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); } } };
14065 |
14066 | switch (hf_field->type) {
14067 | case FT_UINT40:
14068 | case FT_UINT48:
14069 | case FT_UINT56:
14070 | case FT_UINT64:
14071 | break;
14072 |
14073 | default:
14074 | 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)
14075 | 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);
14076 | return NULL((void*)0);
14077 | }
14078 |
14079 | 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);;
14080 |
14081 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14082 | }
14083 |
14084 | proto_item *
14085 | proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
14086 | tvbuff_t *tvb, const unsigned bit_offset,
14087 | const int no_of_bits, float value,
14088 | const unsigned encoding,
14089 | const char *format, ...)
14090 | {
14091 | va_list ap;
14092 | char *dst;
14093 | header_field_info *hf_field;
14094 |
14095 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14096 |
14097 | 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", 14097 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14097, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14097, "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", 14097, __func__, "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); } } };
14098 |
14099 | 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", 14099, ((hf_field))->abbrev))));
14100 |
14101 | 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);;
14102 |
14103 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14104 | }
14105 |
14106 | proto_item *
14107 | proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
14108 | tvbuff_t *tvb, const unsigned bit_offset,
14109 | const int no_of_bits, int32_t value,
14110 | const unsigned encoding,
14111 | const char *format, ...)
14112 | {
14113 | va_list ap;
14114 | char *dst;
14115 | header_field_info *hf_field;
14116 |
14117 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14118 |
14119 | 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", 14119 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14119, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14119, "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", 14119, __func__, "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); } } };
14120 |
14121 | switch (hf_field->type) {
14122 | case FT_INT8:
14123 | case FT_INT16:
14124 | case FT_INT24:
14125 | case FT_INT32:
14126 | break;
14127 |
14128 | default:
14129 | 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)
14130 | 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);
14131 | return NULL((void*)0);
14132 | }
14133 |
14134 | 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);;
14135 |
14136 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14137 | }
14138 |
14139 | proto_item *
14140 | proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
14141 | tvbuff_t *tvb, const unsigned bit_offset,
14142 | const int no_of_bits, int64_t value,
14143 | const unsigned encoding,
14144 | const char *format, ...)
14145 | {
14146 | va_list ap;
14147 | char *dst;
14148 | header_field_info *hf_field;
14149 |
14150 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14151 |
14152 | 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", 14152 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14152, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14152, "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", 14152, __func__, "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); } } };
14153 |
14154 | switch (hf_field->type) {
14155 | case FT_INT40:
14156 | case FT_INT48:
14157 | case FT_INT56:
14158 | case FT_INT64:
14159 | break;
14160 |
14161 | default:
14162 | 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)
14163 | 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);
14164 | return NULL((void*)0);
14165 | }
14166 |
14167 | 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);;
14168 |
14169 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14170 | }
14171 |
14172 | proto_item *
14173 | proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
14174 | tvbuff_t *tvb, const unsigned bit_offset,
14175 | const int no_of_bits, uint64_t value,
14176 | const unsigned encoding,
14177 | const char *format, ...)
14178 | {
14179 | va_list ap;
14180 | char *dst;
14181 | header_field_info *hf_field;
14182 |
14183 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14184 |
14185 | 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", 14185 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14185, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14185, "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", 14185, __func__, "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); } } };
14186 |
14187 | 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" , 14187, ((hf_field))->abbrev))));
14188 |
14189 | 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);;
14190 |
14191 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14192 | }
14193 |
14194 | proto_item *
14195 | proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14196 | const unsigned bit_offset, const int no_of_chars)
14197 | {
14198 | proto_item *pi;
14199 | header_field_info *hfinfo;
14200 | int byte_length;
14201 | unsigned byte_offset;
14202 | char *string;
14203 |
14204 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14205 |
14206 | 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", 14206 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14206, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14206, "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", 14206, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14207 |
14208 | 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" , 14208, ((hfinfo))->abbrev))));
14209 |
14210 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14211 | byte_offset = bit_offset >> 3;
14212 |
14213 | string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14214 |
14215 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14216 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14216, "byte_length >= 0" ))));
14217 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14218 |
14219 | return pi;
14220 | }
14221 |
14222 | proto_item *
14223 | proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14224 | const unsigned bit_offset, const int no_of_chars)
14225 | {
14226 | proto_item *pi;
14227 | header_field_info *hfinfo;
14228 | int byte_length;
14229 | unsigned byte_offset;
14230 | char *string;
14231 |
14232 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14233 |
14234 | 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", 14234 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14234, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14234, "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", 14234, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14235 |
14236 | 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" , 14236, ((hfinfo))->abbrev))));
14237 |
14238 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14239 | byte_offset = bit_offset >> 3;
14240 |
14241 | string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14242 |
14243 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14244 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14244, "byte_length >= 0" ))));
14245 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14246 |
14247 | return pi;
14248 | }
14249 |
14250 | const value_string proto_checksum_vals[] = {
14251 | { PROTO_CHECKSUM_E_BAD, "Bad" },
14252 | { PROTO_CHECKSUM_E_GOOD, "Good" },
14253 | { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14254 | { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14255 | { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14256 |
14257 | { 0, NULL((void*)0) }
14258 | };
14259 |
14260 | #define PROTO_CHECKSUM_COMPUTED_USED(0x01|0x02|0x10) (PROTO_CHECKSUM_VERIFY0x01|PROTO_CHECKSUM_GENERATED0x02|PROTO_CHECKSUM_NOT_PRESENT0x10)
14261 |
14262 | proto_item *
14263 | proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14264 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14265 | packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14266 | {
14267 | header_field_info *hfinfo;
14268 | uint32_t checksum;
14269 | uint32_t len;
14270 | proto_item* ti = NULL((void*)0);
14271 | proto_item* ti2;
14272 | bool_Bool incorrect_checksum = true1;
14273 |
14274 | 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", 14274, __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", 14274 , "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", 14274, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14275 |
14276 | switch (hfinfo->type) {
14277 | case FT_UINT8:
14278 | len = 1;
14279 | break;
14280 | case FT_UINT16:
14281 | len = 2;
14282 | break;
14283 | case FT_UINT24:
14284 | len = 3;
14285 | break;
14286 | case FT_UINT32:
14287 | len = 4;
14288 | break;
14289 | default:
14290 | 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)
14291 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32" , hfinfo->abbrev);
14292 | }
14293 |
14294 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14295 | ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14296 | proto_item_set_generated(ti);
14297 | // Backward compatible with use of -1
14298 | if (hf_checksum_status > 0) {
14299 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14300 | proto_item_set_generated(ti2);
14301 | }
14302 | return ti;
14303 | }
14304 |
14305 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14306 | ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14307 | proto_item_set_generated(ti);
14308 | } else {
14309 | ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14310 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14311 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14312 | if (computed_checksum == 0) {
14313 | proto_item_append_text(ti, " [correct]");
14314 | // Backward compatible with use of -1
14315 | if (hf_checksum_status > 0) {
14316 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14317 | proto_item_set_generated(ti2);
14318 | }
14319 | incorrect_checksum = false0;
14320 | } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14321 | computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14322 | /* XXX - This can't distinguish between "shouldbe"
14323 | * 0x0000 and 0xFFFF unless we know whether there
14324 | * were any nonzero bits (other than the checksum).
14325 | * Protocols should not use this path if they might
14326 | * have an all zero packet.
14327 | * Some implementations put the wrong zero; maybe
14328 | * we should have a special expert info for that?
14329 | */
14330 | }
14331 | } else {
14332 | if (checksum == computed_checksum) {
14333 | proto_item_append_text(ti, " [correct]");
14334 | // Backward compatible with use of -1
14335 | if (hf_checksum_status > 0) {
14336 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14337 | proto_item_set_generated(ti2);
14338 | }
14339 | incorrect_checksum = false0;
14340 | }
14341 | }
14342 |
14343 | if (incorrect_checksum) {
14344 | // Backward compatible with use of -1
14345 | if (hf_checksum_status > 0) {
14346 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14347 | proto_item_set_generated(ti2);
14348 | }
14349 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14350 | proto_item_append_text(ti, " [incorrect]");
14351 | if (bad_checksum_expert != NULL((void*)0))
14352 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14353 | } else {
14354 | proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14355 | if (bad_checksum_expert != NULL((void*)0))
14356 | 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);
14357 | }
14358 | }
14359 | } else {
14360 | // Backward compatible with use of -1
14361 | if (hf_checksum_status > 0) {
14362 | proto_item_append_text(ti, " [unverified]");
14363 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14364 | proto_item_set_generated(ti2);
14365 | }
14366 | }
14367 | }
14368 |
14369 | return ti;
14370 | }
14371 |
14372 | proto_item *
14373 | proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14374 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14375 | packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14376 | {
14377 | header_field_info *hfinfo;
14378 | uint8_t *checksum = NULL((void*)0);
14379 | proto_item* ti = NULL((void*)0);
14380 | proto_item* ti2;
14381 | bool_Bool incorrect_checksum = true1;
14382 |
14383 | 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", 14383, __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", 14383 , "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", 14383, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14384 |
14385 | 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", 14385, ((hfinfo))->abbrev))));
14386 |
14387 | /* Make sure a NULL computed_checksum isn't dereferenced.
14388 | * If checksum_len is 0 it probably won't crash, but in the VERIFY
14389 | * case memcmp(NULL, checksum, 0) is UB until C2y, and in the other
14390 | * cases the behavior is unexpected and still a programmer error;
14391 | * proto_tree_add_bytes retrieves it from the tvb, thus neither
14392 | * _NOT_PRESENT nor _GENERATED is correct.
14393 | */
14394 | 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", 14394, "computed_checksum || ((flags & (0x01|0x02|0x10)) == 0x00)" ))));
14395 |
14396 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14397 | ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14398 | proto_item_set_generated(ti);
14399 | // Backward compatible with use of -1
14400 | if (hf_checksum_status > 0) {
14401 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14402 | proto_item_set_generated(ti2);
14403 | }
14404 | return ti;
14405 | }
14406 |
14407 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14408 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14409 | proto_item_set_generated(ti);
14410 | return ti;
14411 | }
14412 |
14413 | checksum = tvb_memdup(pinfo->pool, tvb, offset, checksum_len);
14414 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14415 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14416 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14417 | bool_Bool non_zero_flag = false0;
14418 | for (size_t index = 0; index < checksum_len; index++) {
14419 | if (computed_checksum[index]) {
14420 | non_zero_flag = true1;
14421 | break;
14422 | }
14423 | }
14424 | if (!non_zero_flag) {
14425 | proto_item_append_text(ti, " [correct]");
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, 0, PROTO_CHECKSUM_E_GOOD);
14429 | proto_item_set_generated(ti2);
14430 | }
14431 | incorrect_checksum = false0;
14432 | }
14433 | } else {
14434 | if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14435 | proto_item_append_text(ti, " [correct]");
14436 | // Backward compatible with use of -1
14437 | if (hf_checksum_status > 0) {
14438 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14439 | proto_item_set_generated(ti2);
14440 | }
14441 | incorrect_checksum = false0;
14442 | }
14443 | }
14444 |
14445 | if (incorrect_checksum) {
14446 | // Backward compatible with use of -1
14447 | if (hf_checksum_status > 0) {
14448 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14449 | proto_item_set_generated(ti2);
14450 | }
14451 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14452 | proto_item_append_text(ti, " [incorrect]");
14453 | if (bad_checksum_expert != NULL((void*)0))
14454 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14455 | } else {
14456 | char *computed_checksum_str = bytes_to_str_maxlen(pinfo->pool, computed_checksum, checksum_len, 0);
14457 | proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14458 | if (bad_checksum_expert != NULL((void*)0))
14459 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14460 | }
14461 | }
14462 | } else {
14463 | // Backward compatible with use of -1
14464 | if (hf_checksum_status > 0) {
14465 | proto_item_append_text(ti, " [unverified]");
14466 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14467 | proto_item_set_generated(ti2);
14468 | }
14469 | }
14470 |
14471 | return ti;
14472 | }
14473 |
14474 | unsigned char
14475 | proto_check_field_name(const char *field_name)
14476 | {
14477 | return module_check_valid_name(field_name, false0);
14478 | }
14479 |
14480 | unsigned char
14481 | proto_check_field_name_lower(const char *field_name)
14482 | {
14483 | return module_check_valid_name(field_name, true1);
14484 | }
14485 |
14486 | bool_Bool
14487 | tree_expanded(int tree_type)
14488 | {
14489 | if (tree_type <= 0) {
14490 | return false0;
14491 | }
14492 | 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", 14492, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14493 | return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14494 | }
14495 |
14496 | void
14497 | tree_expanded_set(int tree_type, bool_Bool value)
14498 | {
14499 | 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", 14499, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14500 |
14501 | if (value)
14502 | tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14503 | else
14504 | tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14505 | }
14506 |
14507 | /*
14508 | * Editor modelines - https://www.wireshark.org/tools/modelines.html
14509 | *
14510 | * Local variables:
14511 | * c-basic-offset: 8
14512 | * tab-width: 8
14513 | * indent-tabs-mode: t
14514 | * End:
14515 | *
14516 | * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14517 | * :indentSize=8:tabSize=8:noTabs=false:
14518 | */