### Bug Summary

File: | epan/proto.c
Warning: | line 13533, 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-21/lib/clang/21 -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/libxml2 -isystem /usr/include/lua5.4 -D G_DISABLE_DEPRECATED -D G_DISABLE_SINGLE_INCLUDES -D WS_BUILD_DLL -D WS_DEBUG -D WS_DEBUG_UTF_8 -D epan_EXPORTS -I /builds/wireshark/wireshark/build -I /builds/wireshark/wireshark -I /builds/wireshark/wireshark/include -I /builds/wireshark/wireshark/wiretap -D _GLIBCXX_ASSERTIONS -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fmacro-prefix-map=/builds/wireshark/wireshark/= -fmacro-prefix-map=/builds/wireshark/wireshark/build/= -fmacro-prefix-map=../= -Wno-format-truncation -Wno-format-nonliteral -Wno-pointer-sign -std=gnu11 -ferror-limit 19 -fvisibility=hidden -fwrapv -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 -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/wireshark/wireshark/sbout/2025-10-26-100329-3623-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 | #include "register-int.h"
57 |
58 | #include <wsutil/crash_info.h>
59 | #include <wsutil/epochs.h>
60 |
61 | /* Ptvcursor limits */
62 | #define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
63 | #define SUBTREE_MAX_LEVELS256 256
64 |
65 | typedef struct __subtree_lvl {
66 | int cursor_offset;
67 | proto_item *it;
68 | proto_tree *tree;
69 | } subtree_lvl;
70 |
71 | struct ptvcursor {
72 | wmem_allocator_t *scope;
73 | subtree_lvl *pushed_tree;
74 | uint8_t pushed_tree_index;
75 | uint8_t pushed_tree_max;
76 | proto_tree *tree;
77 | tvbuff_t *tvb;
78 | int offset;
79 | };
80 |
81 | #define cVALS(x)(const value_string*)(x) (const value_string*)(x)
82 |
83 | /** See inlined comments.
84 | @param tree the tree to append this item to
85 | @param free_block a code block to call to free resources if this returns
86 | @return NULL if 'tree' is null */
87 | #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
88 | if (!tree) { \
89 | free_block; \
90 | return NULL((void*)0); \
91 | }
92 |
93 | /** See inlined comments.
94 | @param tree the tree to append this item to
95 | @return NULL if 'tree' is null */
96 | #define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
97 | CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
98 |
99 | /** See inlined comments.
100 | @param length the length of this item
101 | @param cleanup_block a code block to call to free resources if this returns
102 | @return NULL if 'length' is lower -1 or equal 0 */
103 | #define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return ( (void*)0); } \
104 | if (length < -1 || length == 0 ) { \
105 | cleanup_block; \
106 | return NULL((void*)0); \
107 | }
108 |
109 | /** See inlined comments.
110 | @param length the length of this item
111 | @return NULL if 'length' is lower -1 or equal 0 */
112 | #define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); } \
113 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); }
114 |
115 | /** See inlined comments.
116 | @param tree the tree to append this item to
117 | @param hfindex field index
118 | @param hfinfo header_field
119 | @param free_block a code block to call to free resources if this returns
120 | @return the header field matching 'hfinfo' */
121 | #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 121 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 121, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 121, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 121, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { free_block; return proto_tree_add_fake_node(tree, hfinfo ); } } } \
122 | /* If the tree is not visible and this item is not referenced \
123 | we don't have to do much work at all but we should still \
124 | return a node so that referenced field items below this node \
125 | (think proto_item_add_subtree()) will still have somewhere \
126 | to attach to or else filtering will not work (they would be \
127 | ignored since tree would be NULL). \
128 | DON'T try to fake a node where PTREE_FINFO(tree) is visible \
129 | because that means we can change its length or repr, and we \
130 | don't want to do so with calls intended for this faked new \
131 | item, so this item needs a new (hidden) child node. \
132 | We fake FT_PROTOCOL unless some clients have requested us \
133 | not to do so. \
134 | */ \
135 | PTREE_DATA(tree)((tree)->tree_data)->count++; \
136 | 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", 136, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 136, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 136, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; \
137 | if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
138 | free_block; \
139 | if (wireshark_abort_on_too_many_items) \
140 | 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", 141 , __func__, "Adding %s would put more than %d 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 | hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 141 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); \
142 | /* Let the exception handler add items to the tree */ \
143 | PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
144 | 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)))
145 | 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)))
146 | "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)))
147 | 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))); \
148 | } \
149 | if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
150 | if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
151 | if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
152 | && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
153 | && (hfinfo->type != FT_PROTOCOL || \
154 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
155 | free_block; \
156 | /* return fake node with no field info */\
157 | return proto_tree_add_fake_node(tree, hfinfo); \
158 | } \
159 | } \
160 | }
161 |
162 | /** See inlined comments.
163 | @param tree the tree to append this item to
164 | @param hfindex field index
165 | @param hfinfo header_field
166 | @return the header field matching 'hfinfo' */
167 | #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", 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 | 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", 168 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 168, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 168, "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", 168, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } }
169 |
170 |
171 | /** See inlined comments.
172 | @param pi the created protocol item we're about to return */
173 | #define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 173, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; } \
174 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 174, __func__, "assertion failed: %s", "pi" ); } while (0); \
175 | if (!PITEM_FINFO(pi)((pi)->finfo)) \
176 | return pi; \
177 | if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
178 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
179 | /* If the tree (GUI) or item isn't visible it's pointless for \
180 | * us to generate the protocol item's string representation */ \
181 | return pi; \
182 | }
183 | /* Same as above but returning void */
184 | #define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; } \
185 | if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
186 | return; \
187 | if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
188 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
189 | /* If the tree (GUI) or item isn't visible it's pointless for \
190 | * us to generate the protocol item's string representation */ \
191 | return; \
192 | }
193 | /* Similar to above, but allows a NULL tree */
194 | #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; } \
195 | if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
196 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
197 | /* If the tree (GUI) or item isn't visible it's pointless for \
198 | * us to generate the protocol item's string representation */ \
199 | return pi; \
200 | }
201 |
202 | #ifdef ENABLE_CHECK_FILTER
203 | #define CHECK_HF_VALUE(type, spec, start_values) \
204 | { \
205 | const type *current; \
206 | int n, m; \
207 | current = start_values; \
208 | for (n=0; current; n++, current++) { \
209 | /* Drop out if we reached the end. */ \
210 | if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
211 | break; \
212 | } \
213 | /* Check value against all previous */ \
214 | for (m=0; m < n; m++) { \
215 | /* There are lots of duplicates with the same string, \
216 | so only report if different... */ \
217 | if ((start_values[m].value == current->value) && \
218 | (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
219 | ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222 , __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 | " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222 , __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 | hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222 , __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 | current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222 , __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); \
223 | } \
224 | } \
225 | } \
226 | }
227 | #endif
228 |
229 | /* The longest NUMBER-like field label we have is for BASE_OUI, which
230 | * can have up to 64 bytes for the manufacturer name if resolved plus
231 | * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
232 | */
233 | #define NUMBER_LABEL_LENGTH80 80
234 |
235 | static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
236 | static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
237 | static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
238 | static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
239 | static int hfinfo_bitoffset(const header_field_info *hfinfo);
240 | static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
241 | static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
242 |
243 | #define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
244 | ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
245 |
246 | static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
247 | static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
248 |
249 | static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
250 | static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
251 | static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252 | static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
253 | static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
254 | static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255 | static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
256 |
257 | static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
258 | static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
259 | static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
260 | static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
261 |
262 | static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
263 | static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
264 | static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
265 | static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
266 | static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
267 | static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
268 | static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
269 | static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
270 | static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
271 | static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
272 | static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
273 |
274 | static void proto_cleanup_base(void);
275 |
276 | static proto_item *
277 | proto_tree_add_node(proto_tree *tree, field_info *fi);
278 |
279 | static proto_item *
280 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
281 |
282 | static void
283 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
284 | int *item_length, const unsigned encoding);
285 |
286 | static int
287 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
288 | int length, unsigned item_length, const int encoding);
289 |
290 | static field_info *
291 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
292 | const int start, const int item_length);
293 |
294 | static proto_item *
295 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
296 | int start, int *length);
297 |
298 | static void
299 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
300 | static void
301 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
302 |
303 | static void
304 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
305 | static void
306 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
307 | static void
308 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
309 | static void
310 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
311 | static void
312 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
313 | static void
314 | proto_tree_set_string(field_info *fi, const char* value);
315 | static void
316 | proto_tree_set_ax25(field_info *fi, const uint8_t* value);
317 | static void
318 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
319 | static void
320 | proto_tree_set_vines(field_info *fi, const uint8_t* value);
321 | static void
322 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
323 | static void
324 | proto_tree_set_ether(field_info *fi, const uint8_t* value);
325 | static void
326 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
327 | static void
328 | proto_tree_set_ipxnet(field_info *fi, uint32_t value);
329 | static void
330 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
331 | static void
332 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
333 | static void
334 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
335 | static void
336 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
337 | static void
338 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
339 | static void
340 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
341 | static void
342 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
343 | static void
344 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
345 | static void
346 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
347 | static void
348 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
349 | static void
350 | proto_tree_set_boolean(field_info *fi, uint64_t value);
351 | static void
352 | proto_tree_set_float(field_info *fi, float value);
353 | static void
354 | proto_tree_set_double(field_info *fi, double value);
355 | static void
356 | proto_tree_set_uint(field_info *fi, uint32_t value);
357 | static void
358 | proto_tree_set_int(field_info *fi, int32_t value);
359 | static void
360 | proto_tree_set_uint64(field_info *fi, uint64_t value);
361 | static void
362 | proto_tree_set_int64(field_info *fi, int64_t value);
363 | static void
364 | proto_tree_set_eui64(field_info *fi, const uint64_t value);
365 | static void
366 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
367 |
368 | /* Handle type length mismatch (now filterable) expert info */
369 | static int proto_type_length_mismatch;
370 | static expert_field ei_type_length_mismatch_error;
371 | static expert_field ei_type_length_mismatch_warn;
372 | static void register_type_length_mismatch(void);
373 |
374 | /* Handle byte array string decoding errors with expert info */
375 | static int proto_byte_array_string_decoding_error;
376 | static expert_field ei_byte_array_string_decoding_failed_error;
377 | static void register_byte_array_string_decodinws_error(void);
378 |
379 | /* Handle date and time string decoding errors with expert info */
380 | static int proto_date_time_string_decoding_error;
381 | static expert_field ei_date_time_string_decoding_failed_error;
382 | static void register_date_time_string_decodinws_error(void);
383 |
384 | /* Handle string errors expert info */
385 | static int proto_string_errors;
386 | static expert_field ei_string_trailing_characters;
387 | static void register_string_errors(void);
388 |
389 | static int proto_register_field_init(header_field_info *hfinfo, const int parent);
390 |
391 | /* special-case header field used within proto.c */
392 | static header_field_info hfi_text_only =
393 | { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
394 | int hf_text_only;
395 |
396 | /* Structure for information about a protocol */
397 | struct _protocol {
398 | const char *name; /* long description */
399 | const char *short_name; /* short description */
400 | const char *filter_name; /* name of this protocol in filters */
401 | GPtrArray *fields; /* fields for this protocol */
402 | int proto_id; /* field ID for this protocol */
403 | bool_Bool is_enabled; /* true if protocol is enabled */
404 | bool_Bool enabled_by_default; /* true if protocol is enabled by default */
405 | bool_Bool can_toggle; /* true if is_enabled can be changed */
406 | int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
407 | For dissectors that need a protocol name so they
408 | can be added to a dissector table, but use the
409 | parent_proto_id for things like enable/disable */
410 | GList *heur_list; /* Heuristic dissectors associated with this protocol */
411 | };
412 |
413 | /* List of all protocols */
414 | static GList *protocols;
415 |
416 | /* Structure stored for deregistered g_slice */
417 | struct g_slice_data {
418 | size_t block_size;
419 | void *mem_block;
420 | };
421 |
422 | /* Deregistered fields */
423 | static GPtrArray *deregistered_fields;
424 | static GPtrArray *deregistered_data;
425 | static GPtrArray *deregistered_slice;
426 |
427 | /* indexed by prefix, contains initializers */
428 | static GHashTable* prefixes;
429 |
430 | /* Contains information about a field when a dissector calls
431 | * proto_tree_add_item. */
432 | #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)))
433 | #define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
434 |
435 | /* Contains the space for proto_nodes. */
436 | #define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void *)0); node->next = ((void*)0); \
437 | node->first_child = NULL((void*)0); \
438 | node->last_child = NULL((void*)0); \
439 | node->next = NULL((void*)0);
440 |
441 | #define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
442 | wmem_free(pool, node)
443 |
444 | /* String space for protocol and field items for the GUI */
445 | #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; \
446 | il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
447 | il->value_pos = 0; \
448 | il->value_len = 0;
449 | #define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
450 | wmem_free(pool, il);
451 |
452 | #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", 452, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 452, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 452, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex]; \
453 | if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
454 | ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 454 , __func__, "Unregistered hf! index=%d", hfindex); \
455 | 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", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))); \
456 | 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", 456, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))); \
457 | hfinfo = gpa_hfinfo.hfi[hfindex];
458 |
459 | #define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
460 |
461 | /* List which stores protocols and fields that have been registered */
462 | typedef struct _gpa_hfinfo_t {
463 | uint32_t len;
464 | uint32_t allocated_len;
465 | header_field_info **hfi;
466 | } gpa_hfinfo_t;
467 |
468 | static gpa_hfinfo_t gpa_hfinfo;
469 |
470 | /* Hash table of abbreviations and IDs */
471 | static wmem_map_t *gpa_name_map;
472 | static header_field_info *same_name_hfinfo;
473 |
474 | /* Hash table protocol aliases. const char * -> const char * */
475 | static GHashTable *gpa_protocol_aliases;
476 |
477 | /*
478 | * We're called repeatedly with the same field name when sorting a column.
479 | * Cache our last gpa_name_map hit for faster lookups.
480 | */
481 | static char *last_field_name;
482 | static header_field_info *last_hfinfo;
483 |
484 | /* Points to the first element of an array of bits, indexed by
485 | a subtree item type; that array element is true if subtrees of
486 | an item of that type are to be expanded. */
487 | static uint32_t *tree_is_expanded;
488 |
489 | /* Number of elements in that array. The entry with index 0 is not used. */
490 | int num_tree_types = 1;
491 |
492 | /* Name hashtables for fast detection of duplicate names */
493 | static GHashTable* proto_names;
494 | static GHashTable* proto_short_names;
495 | static GHashTable* proto_filter_names;
496 |
497 | static const char *reserved_filter_names[] = {
498 | /* Display filter keywords. */
499 | "eq",
500 | "ne",
501 | "all_eq",
502 | "any_eq",
503 | "all_ne",
504 | "any_ne",
505 | "gt",
506 | "ge",
507 | "lt",
508 | "le",
509 | "bitand",
510 | "bitwise_and",
511 | "contains",
512 | "matches",
513 | "not",
514 | "and",
515 | "or",
516 | "xor",
517 | "in",
518 | "any",
519 | "all",
520 | "true",
521 | "false",
522 | "nan",
523 | "inf",
524 | "infinity",
525 | NULL((void*)0)
526 | };
527 |
528 | static GHashTable *proto_reserved_filter_names;
529 | static GQueue* saved_dir_queue;
530 |
531 | static int
532 | proto_compare_name(const void *p1_arg, const void *p2_arg)
533 | {
534 | const protocol_t *p1 = (const protocol_t *)p1_arg;
535 | const protocol_t *p2 = (const protocol_t *)p2_arg;
536 |
537 | return g_ascii_strcasecmp(p1->short_name, p2->short_name);
538 | }
539 |
540 | static GSList *dissector_plugins;
541 |
542 | #ifdef HAVE_PLUGINS1
543 | void
544 | proto_register_plugin(const proto_plugin *plug)
545 | {
546 | dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
547 | }
548 | #else /* HAVE_PLUGINS */
549 | void
550 | proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
551 | {
552 | ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 552, __func__, "proto_register_plugin: built without support for binary plugins" ); } } while (0);
553 | }
554 | #endif /* HAVE_PLUGINS */
555 |
556 | static void
557 | call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
558 | {
559 | proto_plugin *plug = (proto_plugin *)data;
560 |
561 | if (plug->register_protoinfo) {
562 | plug->register_protoinfo();
563 | }
564 | }
565 |
566 | static void
567 | call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
568 | {
569 | proto_plugin *plug = (proto_plugin *)data;
570 |
571 | if (plug->register_handoff) {
572 | plug->register_handoff();
573 | }
574 | }
575 |
576 | /* initialize data structures and register protocols and fields */
577 | void
578 | proto_init(GSList *register_all_plugin_protocols_list,
579 | GSList *register_all_plugin_handoffs_list,
580 | register_cb cb,
581 | void *client_data)
582 | {
583 | proto_cleanup_base();
584 | saved_dir_queue = g_queue_new();
585 |
586 | proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
587 | proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 | proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
589 |
590 | proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
591 | for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
592 | /* GHashTable has no key destructor so the cast is safe. */
593 | g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
594 | }
595 |
596 | gpa_hfinfo.len = 0;
597 | gpa_hfinfo.allocated_len = 0;
598 | gpa_hfinfo.hfi = NULL((void*)0);
599 | gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
600 | wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
601 | gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
602 | deregistered_fields = g_ptr_array_new();
603 | deregistered_data = g_ptr_array_new();
604 | deregistered_slice = g_ptr_array_new();
605 |
606 | /* Initialize the ftype subsystem */
607 | ftypes_initialize();
608 |
609 | /* Initialize the address type subsystem */
610 | address_types_initialize();
611 |
612 | /* Register one special-case FT_TEXT_ONLY field for use when
613 | converting wireshark to new-style proto_tree. These fields
614 | are merely strings on the GUI tree; they are not filterable */
615 | hf_text_only = proto_register_field_init(&hfi_text_only, -1);
616 |
617 | /* Register the pseudo-protocols used for exceptions. */
618 | register_show_exception();
619 | register_type_length_mismatch();
620 | register_byte_array_string_decodinws_error();
621 | register_date_time_string_decodinws_error();
622 | register_string_errors();
623 | ftypes_register_pseudofields();
624 | col_register_protocol();
625 |
626 | /* Have each built-in dissector register its protocols, fields,
627 | dissector tables, and dissectors to be called through a
628 | handle, and do whatever one-time initialization it needs to
629 | do. */
630 | register_all_protocols(cb, client_data);
631 |
632 | /* Now call the registration routines for all epan plugins. */
633 | for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
634 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
635 | }
636 |
637 | /* Now call the registration routines for all dissector plugins. */
638 | if (cb)
639 | (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
640 | g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
641 |
642 | /* Now call the "handoff registration" routines of all built-in
643 | dissectors; those routines register the dissector in other
644 | dissectors' handoff tables, and fetch any dissector handles
645 | they need. */
646 | register_all_protocol_handoffs(cb, client_data);
647 |
648 | /* Now do the same with epan plugins. */
649 | for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
650 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
651 | }
652 |
653 | /* Now do the same with dissector plugins. */
654 | if (cb)
655 | (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
656 | g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
657 |
658 | /* sort the protocols by protocol name */
659 | protocols = g_list_sort(protocols, proto_compare_name);
660 |
661 | /* sort the dissector handles in dissector tables (for -G reports
662 | * and -d error messages. The GUI sorts the handles itself.) */
663 | packet_all_tables_sort_handles();
664 |
665 | /* We've assigned all the subtree type values; allocate the array
666 | for them, and zero it out. */
667 | 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 )));
668 | }
669 |
670 | static void
671 | proto_cleanup_base(void)
672 | {
673 | protocol_t *protocol;
674 | header_field_info *hfinfo;
675 |
676 | /* Free the abbrev/ID hash table */
677 | if (gpa_name_map) {
678 | // XXX - We don't have a wmem_map_destroy, but
679 | // it does get cleaned up when epan scope is
680 | // destroyed
681 | //g_hash_table_destroy(gpa_name_map);
682 | gpa_name_map = NULL((void*)0);
683 | }
684 | if (gpa_protocol_aliases) {
685 | g_hash_table_destroy(gpa_protocol_aliases);
686 | gpa_protocol_aliases = NULL((void*)0);
687 | }
688 | g_free(last_field_name);
689 | last_field_name = NULL((void*)0);
690 |
691 | while (protocols) {
692 | protocol = (protocol_t *)protocols->data;
693 | 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", 693 , __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", 693, "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", 693, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol-> proto_id];;
694 | 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", 694, "protocol->proto_id == hfinfo->id" ))));
695 |
696 | 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);
697 | if (protocol->parent_proto_id != -1) {
698 | // pino protocol
699 | DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 699, "protocol->fields == ((void*)0)" )))); //helpers should not have any registered fields
700 | 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" , 700, "protocol->heur_list == ((void*)0)")))); //helpers should not have a heuristic list
701 | } else {
702 | if (protocol->fields) {
703 | g_ptr_array_free(protocol->fields, true1);
704 | }
705 | g_list_free(protocol->heur_list);
706 | }
707 | protocols = g_list_remove(protocols, protocol);
708 | g_free(protocol);
709 | }
710 |
711 | if (proto_names) {
712 | g_hash_table_destroy(proto_names);
713 | proto_names = NULL((void*)0);
714 | }
715 |
716 | if (proto_short_names) {
717 | g_hash_table_destroy(proto_short_names);
718 | proto_short_names = NULL((void*)0);
719 | }
720 |
721 | if (proto_filter_names) {
722 | g_hash_table_destroy(proto_filter_names);
723 | proto_filter_names = NULL((void*)0);
724 | }
725 |
726 | if (proto_reserved_filter_names) {
727 | g_hash_table_destroy(proto_reserved_filter_names);
728 | proto_reserved_filter_names = NULL((void*)0);
729 | }
730 |
731 | if (gpa_hfinfo.allocated_len) {
732 | gpa_hfinfo.len = 0;
733 | gpa_hfinfo.allocated_len = 0;
734 | g_free(gpa_hfinfo.hfi);
735 | gpa_hfinfo.hfi = NULL((void*)0);
736 | }
737 |
738 | if (deregistered_fields) {
739 | g_ptr_array_free(deregistered_fields, true1);
740 | deregistered_fields = NULL((void*)0);
741 | }
742 |
743 | if (deregistered_data) {
744 | g_ptr_array_free(deregistered_data, true1);
745 | deregistered_data = NULL((void*)0);
746 | }
747 |
748 | if (deregistered_slice) {
749 | g_ptr_array_free(deregistered_slice, true1);
750 | deregistered_slice = NULL((void*)0);
751 | }
752 |
753 | g_free(tree_is_expanded);
754 | tree_is_expanded = NULL((void*)0);
755 |
756 | if (prefixes)
757 | g_hash_table_destroy(prefixes);
758 |
759 | if (saved_dir_queue != NULL((void*)0)) {
760 | g_queue_clear_full(saved_dir_queue, g_free);
761 | g_queue_free(saved_dir_queue);
762 | saved_dir_queue = NULL((void*)0);
763 | }
764 | }
765 |
766 | void
767 | proto_cleanup(void)
768 | {
769 | proto_free_deregistered_fields();
770 | proto_cleanup_base();
771 |
772 | g_slist_free(dissector_plugins);
773 | dissector_plugins = NULL((void*)0);
774 | }
775 |
776 | static bool_Bool
777 | ws_pushd(const char* dir)
778 | {
779 | //Save the current working directory
780 | const char* save_wd = get_current_working_dir();
781 | if (save_wd != NULL((void*)0))
782 | g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
783 |
784 | //Change to the new one
785 | #ifdef _WIN32
786 | SetCurrentDirectory(utf_8to16(dir));
787 | return true1;
788 | #else
789 | return (chdir(dir) == 0);
790 | #endif
791 | }
792 |
793 | static bool_Bool
794 | ws_popd(void)
795 | {
796 | int ret = 0;
797 | char* saved_wd = g_queue_pop_head(saved_dir_queue);
798 | if (saved_wd == NULL((void*)0))
799 | return false0;
800 |
801 | //Restore the previous one
802 | #ifdef _WIN32
803 | SetCurrentDirectory(utf_8to16(saved_wd));
804 | #else
805 | ret = chdir(saved_wd);
806 | #endif
807 | g_free(saved_wd);
808 | return (ret == 0);
809 | }
810 |
811 | void
812 | proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
813 | {
814 | if (ws_pushd(dir))
815 | {
816 | func(param);
817 | ws_popd();
818 | }
819 | }
820 |
821 | static bool_Bool
822 | // NOLINTNEXTLINE(misc-no-recursion)
823 | proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
824 | void *data)
825 | {
826 | proto_node *pnode = tree;
827 | proto_node *child;
828 | proto_node *current;
829 |
830 | if (func(pnode, data))
831 | return true1;
832 |
833 | child = pnode->first_child;
834 | while (child != NULL((void*)0)) {
835 | /*
836 | * The routine we call might modify the child, e.g. by
837 | * freeing it, so we get the child's successor before
838 | * calling that routine.
839 | */
840 | current = child;
841 | child = current->next;
842 | // We recurse here, but we're limited by prefs.gui_max_tree_depth
843 | if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
844 | return true1;
845 | }
846 |
847 | return false0;
848 | }
849 |
850 | void
851 | proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
852 | void *data)
853 | {
854 | proto_node *node = tree;
855 | proto_node *current;
856 |
857 | if (!node)
858 | return;
859 |
860 | node = node->first_child;
861 | while (node != NULL((void*)0)) {
862 | current = node;
863 | node = current->next;
864 | func((proto_tree *)current, data);
865 | }
866 | }
867 |
868 | static void
869 | free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
870 | {
871 | GPtrArray *ptrs = (GPtrArray *)value;
872 | int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
873 | header_field_info *hfinfo;
874 |
875 | 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", 875, __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", 875, "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", 875, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
876 | if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
877 | /* when a field is referenced by a filter this also
878 | affects the refcount for the parent protocol so we need
879 | to adjust the refcount for the parent as well
880 | */
881 | if (hfinfo->parent != -1) {
882 | header_field_info *parent_hfinfo;
883 | 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", 883 , __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", 883, "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", 883, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)" , "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo ->parent];;
884 | parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
885 | }
886 | hfinfo->ref_type = HF_REF_TYPE_NONE;
887 | }
888 |
889 | g_ptr_array_free(ptrs, true1);
890 | }
891 |
892 | static void
893 | proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
894 | {
895 | field_info *finfo = PNODE_FINFO(node)((node)->finfo);
896 |
897 | proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
898 |
899 | if (finfo) {
900 | fvalue_free(finfo->value);
901 | finfo->value = NULL((void*)0);
902 | }
903 | }
904 |
905 | void
906 | proto_tree_reset(proto_tree *tree)
907 | {
908 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
909 |
910 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
911 |
912 | /* free tree data */
913 | if (tree_data->interesting_hfids) {
914 | /* Free all the GPtrArray's in the interesting_hfids hash. */
915 | g_hash_table_foreach(tree_data->interesting_hfids,
916 | free_GPtrArray_value, NULL((void*)0));
917 |
918 | /* And then remove all values. */
919 | g_hash_table_remove_all(tree_data->interesting_hfids);
920 | }
921 |
922 | /* Reset track of the number of children */
923 | tree_data->count = 0;
924 |
925 | /* Reset our loop checks */
926 | tree_data->idle_count_ds_tvb = NULL((void*)0);
927 | tree_data->max_start = 0;
928 | tree_data->start_idle_count = 0;
929 |
930 | PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void *)0); tree->next = ((void*)0);;
931 | }
932 |
933 | /* frees the resources that the dissection a proto_tree uses */
934 | void
935 | proto_tree_free(proto_tree *tree)
936 | {
937 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
938 |
939 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
940 |
941 | /* free tree data */
942 | if (tree_data->interesting_hfids) {
943 | /* Free all the GPtrArray's in the interesting_hfids hash. */
944 | g_hash_table_foreach(tree_data->interesting_hfids,
945 | free_GPtrArray_value, NULL((void*)0));
946 |
947 | /* And then destroy the hash. */
948 | g_hash_table_destroy(tree_data->interesting_hfids);
949 | }
950 |
951 | 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);
952 |
953 | g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else (void) ((proto_tree*) 0 == (tree)); } while (0);
954 | }
955 |
956 | /* Is the parsing being done for a visible proto_tree or an invisible one?
957 | * By setting this correctly, the proto_tree creation is sped up by not
958 | * having to call vsnprintf and copy strings around.
959 | */
960 | bool_Bool
961 | proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
962 | {
963 | bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
964 |
965 | PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
966 |
967 | return old_visible;
968 | }
969 |
970 | void
971 | proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
972 | {
973 | if (tree)
974 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
975 | }
976 |
977 | /* Assume dissector set only its protocol fields.
978 | This function is called by dissectors and allows the speeding up of filtering
979 | in wireshark; if this function returns false it is safe to reset tree to NULL
980 | and thus skip calling most of the expensive proto_tree_add_...()
981 | functions.
982 | If the tree is visible we implicitly assume the field is referenced.
983 | */
984 | bool_Bool
985 | proto_field_is_referenced(proto_tree *tree, int proto_id)
986 | {
987 | register header_field_info *hfinfo;
988 |
989 |
990 | if (!tree)
991 | return false0;
992 |
993 | if (PTREE_DATA(tree)((tree)->tree_data)->visible)
994 | return true1;
995 |
996 | 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", 996, __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", 996, "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", 996, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
997 | if (hfinfo->ref_type != HF_REF_TYPE_NONE)
998 | return true1;
999 |
1000 | if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1001 | return true1;
1002 |
1003 | return false0;
1004 | }
1005 |
1006 |
1007 | /* Finds a record in the hfinfo array by id. */
1008 | header_field_info *
1009 | proto_registrar_get_nth(unsigned hfindex)
1010 | {
1011 | register header_field_info *hfinfo;
1012 |
1013 | 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", 1013, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1013, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1013, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
1014 | return hfinfo;
1015 | }
1016 |
1017 |
1018 | /* Prefix initialization
1019 | * this allows for a dissector to register a display filter name prefix
1020 | * so that it can delay the initialization of the hf array as long as
1021 | * possible.
1022 | */
1023 |
1024 | /* compute a hash for the part before the dot of a display filter */
1025 | static unsigned
1026 | prefix_hash (const void *key) {
1027 | /* end the string at the dot and compute its hash */
1028 | char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1029 | char* c = copy;
1030 | unsigned tmp;
1031 |
1032 | for (; *c; c++) {
1033 | if (*c == '.') {
1034 | *c = 0;
1035 | break;
1036 | }
1037 | }
1038 |
1039 | tmp = wmem_str_hash(copy);
1040 | g_free(copy);
1041 | return tmp;
1042 | }
1043 |
1044 | /* are both strings equal up to the end or the dot? */
1045 | static gboolean
1046 | prefix_equal (const void *ap, const void *bp) {
1047 | const char* a = (const char *)ap;
1048 | const char* b = (const char *)bp;
1049 |
1050 | do {
1051 | char ac = *a++;
1052 | char bc = *b++;
1053 |
1054 | if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1055 |
1056 | if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1057 | if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1058 |
1059 | if (ac != bc) return FALSE(0);
1060 | } while (1);
1061 |
1062 | return FALSE(0);
1063 | }
1064 |
1065 | /* Register a new prefix for "delayed" initialization of field arrays */
1066 | void
1067 | proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1068 | if (! prefixes ) {
1069 | prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1070 | }
1071 |
1072 | g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1073 | }
1074 |
1075 | /* helper to call all prefix initializers */
1076 | static gboolean
1077 | initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1078 | ((prefix_initializer_t)v)((const char *)k);
1079 | return TRUE(!(0));
1080 | }
1081 |
1082 | /** Initialize every remaining uninitialized prefix. */
1083 | void
1084 | proto_initialize_all_prefixes(void) {
1085 | g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1086 | }
1087 |
1088 | /* Finds a record in the hfinfo array by name.
1089 | * If it fails to find it in the already registered fields,
1090 | * it tries to find and call an initializer in the prefixes
1091 | * table and if so it looks again.
1092 | */
1093 |
1094 | header_field_info *
1095 | proto_registrar_get_byname(const char *field_name)
1096 | {
1097 | header_field_info *hfinfo;
1098 | prefix_initializer_t pi;
1099 |
1100 | if (!field_name)
1101 | return NULL((void*)0);
1102 |
1103 | if (g_strcmp0(field_name, last_field_name) == 0) {
1104 | return last_hfinfo;
1105 | }
1106 |
1107 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1108 |
1109 | if (hfinfo) {
1110 | g_free(last_field_name);
1111 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1112 | last_hfinfo = hfinfo;
1113 | return hfinfo;
1114 | }
1115 |
1116 | if (!prefixes)
1117 | return NULL((void*)0);
1118 |
1119 | if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1120 | pi(field_name);
1121 | g_hash_table_remove(prefixes, field_name);
1122 | } else {
1123 | return NULL((void*)0);
1124 | }
1125 |
1126 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1127 |
1128 | if (hfinfo) {
1129 | g_free(last_field_name);
1130 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1131 | last_hfinfo = hfinfo;
1132 | }
1133 | return hfinfo;
1134 | }
1135 |
1136 | header_field_info*
1137 | proto_registrar_get_byalias(const char *alias_name)
1138 | {
1139 | if (!alias_name) {
1140 | return NULL((void*)0);
1141 | }
1142 |
1143 | /* Find our aliased protocol. */
1144 | char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1145 | char *dot = strchr(an_copy, '.');
1146 | if (dot) {
1147 | *dot = '\0';
1148 | }
1149 | const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1150 | if (!proto_pfx) {
1151 | g_free(an_copy);
1152 | return NULL((void*)0);
1153 | }
1154 |
1155 | /* Construct our aliased field and look it up. */
1156 | GString *filter_name = g_string_new(proto_pfx);
1157 | if (dot) {
1158 | g_string_append_printf(filter_name, ".%s", dot+1);
1159 | }
1160 | header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1161 | g_free(an_copy);
1162 | 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)))));
1163 |
1164 | return hfinfo;
1165 | }
1166 |
1167 | int
1168 | proto_registrar_get_id_byname(const char *field_name)
1169 | {
1170 | header_field_info *hfinfo;
1171 |
1172 | hfinfo = proto_registrar_get_byname(field_name);
1173 |
1174 | if (!hfinfo)
1175 | return -1;
1176 |
1177 | return hfinfo->id;
1178 | }
1179 |
1180 | static int
1181 | label_strcat_flags(const header_field_info *hfinfo)
1182 | {
1183 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1184 | return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1185 |
1186 | return 0;
1187 | }
1188 |
1189 | static char *
1190 | format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1191 | const uint8_t *bytes, unsigned length, size_t max_str_len)
1192 | {
1193 | char *str = NULL((void*)0);
1194 | const uint8_t *p;
1195 | bool_Bool is_printable;
1196 |
1197 | if (bytes) {
1198 | if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1199 | /*
1200 | * If all bytes are valid and printable UTF-8, show the
1201 | * bytes as a string - in quotes to indicate that it's
1202 | * a string.
1203 | */
1204 | if (isprint_utf8_string(bytes, length)) {
1205 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1206 | (int)length, bytes);
1207 | return str;
1208 | }
1209 | } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1210 | /*
1211 | * Check whether all bytes are printable.
1212 | */
1213 | is_printable = true1;
1214 | for (p = bytes; p < bytes+length; p++) {
1215 | if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1216 | /* Not printable. */
1217 | is_printable = false0;
1218 | break;
1219 | }
1220 | }
1221 |
1222 | /*
1223 | * If all bytes are printable ASCII, show the bytes
1224 | * as a string - in quotes to indicate that it's
1225 | * a string.
1226 | */
1227 | if (is_printable) {
1228 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1229 | (int)length, bytes);
1230 | return str;
1231 | }
1232 | }
1233 |
1234 | /*
1235 | * Either it's not printable ASCII, or we don't care whether
1236 | * it's printable ASCII; show it as hex bytes.
1237 | */
1238 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1239 | case SEP_DOT:
1240 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1241 | break;
1242 | case SEP_DASH:
1243 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1244 | break;
1245 | case SEP_COLON:
1246 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1247 | break;
1248 | case SEP_SPACE:
1249 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1250 | break;
1251 | case BASE_NONE:
1252 | default:
1253 | if (prefs.display_byte_fields_with_spaces) {
1254 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1255 | } else {
1256 | str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1257 | }
1258 | break;
1259 | }
1260 | }
1261 | else {
1262 | if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1263 | str = wmem_strdup(scope, "<none>");
1264 | } else {
1265 | str = wmem_strdup(scope, "<MISSING>");
1266 | }
1267 | }
1268 | return str;
1269 | }
1270 |
1271 | static char *
1272 | format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1273 | const uint8_t *bytes, unsigned length)
1274 | {
1275 | return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1276 | }
1277 |
1278 | static void
1279 | ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1280 | {
1281 | subtree_lvl *pushed_tree;
1282 |
1283 | 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" , 1283, "ptvc->pushed_tree_max <= 256-8"))));
1284 | ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1285 |
1286 | pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1287 | DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1287, "pushed_tree != ((void*)0)" ))));
1288 | ptvc->pushed_tree = pushed_tree;
1289 | }
1290 |
1291 | static void
1292 | ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1293 | {
1294 | ptvc->pushed_tree = NULL((void*)0);
1295 | ptvc->pushed_tree_max = 0;
1296 | 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", 1296, "ptvc->pushed_tree_index == 0" ))));
1297 | ptvc->pushed_tree_index = 0;
1298 | }
1299 |
1300 | /* Allocates an initializes a ptvcursor_t with 3 variables:
1301 | * proto_tree, tvbuff, and offset. */
1302 | ptvcursor_t *
1303 | ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1304 | {
1305 | ptvcursor_t *ptvc;
1306 |
1307 | ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1308 | ptvc->scope = scope;
1309 | ptvc->tree = tree;
1310 | ptvc->tvb = tvb;
1311 | ptvc->offset = offset;
1312 | ptvc->pushed_tree = NULL((void*)0);
1313 | ptvc->pushed_tree_max = 0;
1314 | ptvc->pushed_tree_index = 0;
1315 | return ptvc;
1316 | }
1317 |
1318 |
1319 | /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1320 | void
1321 | ptvcursor_free(ptvcursor_t *ptvc)
1322 | {
1323 | ptvcursor_free_subtree_levels(ptvc);
1324 | /*g_free(ptvc);*/
1325 | }
1326 |
1327 | /* Returns tvbuff. */
1328 | tvbuff_t *
1329 | ptvcursor_tvbuff(ptvcursor_t *ptvc)
1330 | {
1331 | return ptvc->tvb;
1332 | }
1333 |
1334 | /* Returns current offset. */
1335 | int
1336 | ptvcursor_current_offset(ptvcursor_t *ptvc)
1337 | {
1338 | return ptvc->offset;
1339 | }
1340 |
1341 | proto_tree *
1342 | ptvcursor_tree(ptvcursor_t *ptvc)
1343 | {
1344 | if (!ptvc)
1345 | return NULL((void*)0);
1346 |
1347 | return ptvc->tree;
1348 | }
1349 |
1350 | void
1351 | ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1352 | {
1353 | ptvc->tree = tree;
1354 | }
1355 |
1356 | /* creates a subtree, sets it as the working tree and pushes the old working tree */
1357 | proto_tree *
1358 | ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1359 | {
1360 | subtree_lvl *subtree;
1361 | if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1362 | ptvcursor_new_subtree_levels(ptvc);
1363 |
1364 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1365 | subtree->tree = ptvc->tree;
1366 | subtree->it= NULL((void*)0);
1367 | ptvc->pushed_tree_index++;
1368 | return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1369 | }
1370 |
1371 | /* pops a subtree */
1372 | void
1373 | ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1374 | {
1375 | subtree_lvl *subtree;
1376 |
1377 | if (ptvc->pushed_tree_index <= 0)
1378 | return;
1379 |
1380 | ptvc->pushed_tree_index--;
1381 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1382 | if (subtree->it != NULL((void*)0))
1383 | proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1384 |
1385 | ptvc->tree = subtree->tree;
1386 | }
1387 |
1388 | /* saves the current tvb offset and the item in the current subtree level */
1389 | static void
1390 | ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1391 | {
1392 | subtree_lvl *subtree;
1393 |
1394 | 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", 1394, "ptvc->pushed_tree_index > 0" ))));
1395 |
1396 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1397 | subtree->it = it;
1398 | subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1399 | }
1400 |
1401 | /* Creates a subtree and adds it to the cursor as the working tree but does not
1402 | * save the old working tree */
1403 | proto_tree *
1404 | ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1405 | {
1406 | ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1407 | return ptvc->tree;
1408 | }
1409 |
1410 | static proto_tree *
1411 | ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1412 | {
1413 | ptvcursor_push_subtree(ptvc, it, ett_subtree);
1414 | if (length == SUBTREE_UNDEFINED_LENGTH-1)
1415 | ptvcursor_subtree_set_item(ptvc, it);
1416 | return ptvcursor_tree(ptvc);
1417 | }
1418 |
1419 | /* Add an item to the tree and create a subtree
1420 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1421 | * In this case, when the subtree will be closed, the parent item length will
1422 | * be equal to the advancement of the cursor since the creation of the subtree.
1423 | */
1424 | proto_tree *
1425 | ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1426 | const unsigned encoding, int ett_subtree)
1427 | {
1428 | proto_item *it;
1429 |
1430 | it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1431 | return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1432 | }
1433 |
1434 | static proto_item *
1435 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1436 |
1437 | /* Add a text node to the tree and create a subtree
1438 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1439 | * In this case, when the subtree will be closed, the item length will be equal
1440 | * to the advancement of the cursor since the creation of the subtree.
1441 | */
1442 | proto_tree *
1443 | ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1444 | int ett_subtree, const char *format, ...)
1445 | {
1446 | proto_item *pi;
1447 | va_list ap;
1448 | header_field_info *hfinfo;
1449 | proto_tree *tree;
1450 |
1451 | tree = ptvcursor_tree(ptvc);
1452 |
1453 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1454 |
1455 | 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", 1455 , __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", 1455, "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", 1455, "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", 1455, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1456 |
1457 | pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1458 | ptvcursor_current_offset(ptvc), length);
1459 |
1460 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1460, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1461 |
1462 | va_start(ap, format)__builtin_va_start(ap, format);
1463 | proto_tree_set_representation(pi, format, ap);
1464 | va_end(ap)__builtin_va_end(ap);
1465 |
1466 | return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1467 | }
1468 |
1469 | /* Add a text-only node, leaving it to our caller to fill the text in */
1470 | static proto_item *
1471 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1472 | {
1473 | proto_item *pi;
1474 |
1475 | if (tree == NULL((void*)0))
1476 | return NULL((void*)0);
1477 |
1478 | pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1479 |
1480 | return pi;
1481 | }
1482 |
1483 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1484 | proto_item *
1485 | proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1486 | const char *format, ...)
1487 | {
1488 | proto_item *pi;
1489 | va_list ap;
1490 | header_field_info *hfinfo;
1491 |
1492 | if (length == -1) {
1493 | length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1494 | } else {
1495 | tvb_ensure_bytes_exist(tvb, start, length);
1496 | }
1497 |
1498 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1499 |
1500 | 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", 1500 , __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", 1500, "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", 1500, "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", 1500, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1501 |
1502 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1503 |
1504 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1504, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1505 |
1506 | va_start(ap, format)__builtin_va_start(ap, format);
1507 | proto_tree_set_representation(pi, format, ap);
1508 | va_end(ap)__builtin_va_end(ap);
1509 |
1510 | return pi;
1511 | }
1512 |
1513 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1514 | proto_item *
1515 | proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1516 | int length, const char *format, va_list ap)
1517 | {
1518 | proto_item *pi;
1519 | header_field_info *hfinfo;
1520 |
1521 | /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1522 | * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1523 | * the length to be what's in the tvbuff if length is -1, and the
1524 | * minimum of length and what's in the tvbuff if not.
1525 | */
1526 |
1527 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1528 |
1529 | TRY_TO_FAKE_THIS_ITEM(tree, hf_text_only, hfinfo)((tree)->tree_data)->count++; if((hf_text_only == 0 || ( unsigned)hf_text_only > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1529 , __func__, "Unregistered hf! index=%d", hf_text_only); ((void ) ((hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1529, "hf_text_only > 0 && (unsigned)hf_text_only < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hf_text_only ] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1529, "gpa_hfinfo.hfi[hf_text_only] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_text_only ];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1529, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
1530 |
1531 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1532 |
1533 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1533, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1534 |
1535 | proto_tree_set_representation(pi, format, ap);
1536 |
1537 | return pi;
1538 | }
1539 |
1540 | /* Add a text-only node that creates a subtree underneath.
1541 | */
1542 | proto_tree *
1543 | proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1544 | {
1545 | return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1546 | }
1547 |
1548 | /* Add a text-only node that creates a subtree underneath.
1549 | */
1550 | proto_tree *
1551 | proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1552 | {
1553 | proto_tree *pt;
1554 | proto_item *pi;
1555 | va_list ap;
1556 |
1557 | va_start(ap, format)__builtin_va_start(ap, format);
1558 | pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1559 | va_end(ap)__builtin_va_end(ap);
1560 |
1561 | if (tree_item != NULL((void*)0))
1562 | *tree_item = pi;
1563 |
1564 | pt = proto_item_add_subtree(pi, idx);
1565 |
1566 | return pt;
1567 | }
1568 |
1569 | /* Add a text-only node for debugging purposes. The caller doesn't need
1570 | * to worry about tvbuff, start, or length. Debug message gets sent to
1571 | * STDOUT, too */
1572 | proto_item *
1573 | proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1574 | {
1575 | proto_item *pi;
1576 | va_list ap;
1577 |
1578 | pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1579 |
1580 | if (pi) {
1581 | va_start(ap, format)__builtin_va_start(ap, format);
1582 | proto_tree_set_representation(pi, format, ap);
1583 | va_end(ap)__builtin_va_end(ap);
1584 | }
1585 | va_start(ap, format)__builtin_va_start(ap, format);
1586 | vprintf(format, ap);
1587 | va_end(ap)__builtin_va_end(ap);
1588 | printf("\n");
1589 |
1590 | return pi;
1591 | }
1592 |
1593 | proto_item *
1594 | proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1595 | {
1596 | proto_item *pi;
1597 | header_field_info *hfinfo;
1598 |
1599 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1600 |
1601 | 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", 1601 , __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", 1601, "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", 1601, "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", 1601, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1602 |
1603 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1604 |
1605 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1605, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1606 |
1607 | proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1608 |
1609 | return pi;
1610 | }
1611 |
1612 | proto_item *
1613 | proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1614 | {
1615 | proto_item *pi;
1616 | header_field_info *hfinfo;
1617 | char *str;
1618 |
1619 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1620 |
1621 | 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", 1621 , __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", 1621, "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", 1621, "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", 1621, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1622 |
1623 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1624 |
1625 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1625, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1626 |
1627 | str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1628 | proto_item_set_text(pi, "%s", str);
1629 | wmem_free(NULL((void*)0), str);
1630 |
1631 | return pi;
1632 | }
1633 |
1634 | void proto_report_dissector_bug(const char *format, ...)
1635 | {
1636 | va_list args;
1637 |
1638 | if (wireshark_abort_on_dissector_bug) {
1639 | /*
1640 | * Try to have the error message show up in the crash
1641 | * information.
1642 | */
1643 | va_start(args, format)__builtin_va_start(args, format);
1644 | ws_vadd_crash_info(format, args);
1645 | va_end(args)__builtin_va_end(args);
1646 |
1647 | /*
1648 | * Print the error message.
1649 | */
1650 | va_start(args, format)__builtin_va_start(args, format);
1651 | vfprintf(stderrstderr, format, args);
1652 | va_end(args)__builtin_va_end(args);
1653 | putc('\n', stderrstderr);
1654 |
1655 | /*
1656 | * And crash.
1657 | */
1658 | abort();
1659 | } else {
1660 | va_start(args, format)__builtin_va_start(args, format);
1661 | VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1662 | va_end(args)__builtin_va_end(args);
1663 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1663 , __func__, "assertion \"not reached\" failed"); /* GCC 12 with ASAN needs this. */
1664 | }
1665 | }
1666 |
1667 | /* We could probably get away with changing is_error to a minimum length value. */
1668 | static void
1669 | report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1670 | {
1671 | if (is_error) {
1672 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1673 | } else {
1674 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1675 | }
1676 |
1677 | if (is_error) {
1678 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1679 | }
1680 | }
1681 |
1682 | static uint32_t
1683 | get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1684 | {
1685 | uint32_t value;
1686 | bool_Bool length_error;
1687 |
1688 | switch (length) {
1689 |
1690 | case 1:
1691 | value = tvb_get_uint8(tvb, offset);
1692 | if (encoding & ENC_ZIGBEE0x40000000) {
1693 | if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1694 | value = 0;
1695 | }
1696 | }
1697 | break;
1698 |
1699 | case 2:
1700 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1701 | : tvb_get_ntohs(tvb, offset);
1702 | if (encoding & ENC_ZIGBEE0x40000000) {
1703 | if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1704 | value = 0;
1705 | }
1706 | }
1707 | break;
1708 |
1709 | case 3:
1710 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1711 | : tvb_get_ntoh24(tvb, offset);
1712 | break;
1713 |
1714 | case 4:
1715 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1716 | : tvb_get_ntohl(tvb, offset);
1717 | break;
1718 |
1719 | default:
1720 | if (length < 1) {
1721 | length_error = true1;
1722 | value = 0;
1723 | } else {
1724 | length_error = false0;
1725 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1726 | : tvb_get_ntohl(tvb, offset);
1727 | }
1728 | report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1729 | break;
1730 | }
1731 | return value;
1732 | }
1733 |
1734 | static inline uint64_t
1735 | get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1736 | {
1737 | uint64_t value;
1738 |
1739 | value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1740 |
1741 | if (length < 1 || length > 8) {
1742 | report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1743 | }
1744 |
1745 | return value;
1746 | }
1747 |
1748 | static int32_t
1749 | get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1750 | {
1751 | int32_t value;
1752 | bool_Bool length_error;
1753 |
1754 | switch (length) {
1755 |
1756 | case 1:
1757 | value = tvb_get_int8(tvb, offset);
1758 | break;
1759 |
1760 | case 2:
1761 | value = encoding ? tvb_get_letohis(tvb, offset)
1762 | : tvb_get_ntohis(tvb, offset);
1763 | break;
1764 |
1765 | case 3:
1766 | value = encoding ? tvb_get_letohi24(tvb, offset)
1767 | : tvb_get_ntohi24(tvb, offset);
1768 | break;
1769 |
1770 | case 4:
1771 | value = encoding ? tvb_get_letohil(tvb, offset)
1772 | : tvb_get_ntohil(tvb, offset);
1773 | break;
1774 |
1775 | default:
1776 | if (length < 1) {
1777 | length_error = true1;
1778 | value = 0;
1779 | } else {
1780 | length_error = false0;
1781 | value = encoding ? tvb_get_letohil(tvb, offset)
1782 | : tvb_get_ntohil(tvb, offset);
1783 | }
1784 | report_type_length_mismatch(tree, "a signed integer", length, length_error);
1785 | break;
1786 | }
1787 | return value;
1788 | }
1789 |
1790 | /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1791 | * be cast-able as a int64_t. This is weird, but what the code has always done.
1792 | */
1793 | static inline uint64_t
1794 | get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1795 | {
1796 | uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1797 |
1798 | switch (length) {
1799 | case 7:
1800 | value = ws_sign_ext64(value, 56);
1801 | break;
1802 | case 6:
1803 | value = ws_sign_ext64(value, 48);
1804 | break;
1805 | case 5:
1806 | value = ws_sign_ext64(value, 40);
1807 | break;
1808 | case 4:
1809 | value = ws_sign_ext64(value, 32);
1810 | break;
1811 | case 3:
1812 | value = ws_sign_ext64(value, 24);
1813 | break;
1814 | case 2:
1815 | value = ws_sign_ext64(value, 16);
1816 | break;
1817 | case 1:
1818 | value = ws_sign_ext64(value, 8);
1819 | break;
1820 | }
1821 |
1822 | return value;
1823 | }
1824 |
1825 | /* For FT_STRING */
1826 | static inline const uint8_t *
1827 | get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1828 | int length, int *ret_length, const unsigned encoding)
1829 | {
1830 | if (length == -1) {
1831 | length = tvb_ensure_captured_length_remaining(tvb, start);
1832 | }
1833 | *ret_length = length;
1834 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1835 | }
1836 |
1837 | /* For FT_STRINGZ */
1838 | static inline const uint8_t *
1839 | get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1840 | int start, int length, int *ret_length, const unsigned encoding)
1841 | {
1842 | const uint8_t *value;
1843 |
1844 | if (length < -1) {
1845 | report_type_length_mismatch(tree, "a string", length, true1);
1846 | }
1847 | if (length == -1) {
1848 | /* This can throw an exception */
1849 | value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1850 | } else {
1851 | /* In this case, length signifies the length of the string.
1852 | *
1853 | * This could either be a null-padded string, which doesn't
1854 | * necessarily have a '\0' at the end, or a null-terminated
1855 | * string, with a trailing '\0'. (Yes, there are cases
1856 | * where you have a string that's both counted and null-
1857 | * terminated.)
1858 | *
1859 | * In the first case, we must allocate a buffer of length
1860 | * "length+1", to make room for a trailing '\0'.
1861 | *
1862 | * In the second case, we don't assume that there is a
1863 | * trailing '\0' there, as the packet might be malformed.
1864 | * (XXX - should we throw an exception if there's no
1865 | * trailing '\0'?) Therefore, we allocate a buffer of
1866 | * length "length+1", and put in a trailing '\0', just to
1867 | * be safe.
1868 | *
1869 | * (XXX - this would change if we made string values counted
1870 | * rather than null-terminated.)
1871 | */
1872 | value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1873 | }
1874 | *ret_length = length;
1875 | return value;
1876 | }
1877 |
1878 | /* For FT_UINT_STRING */
1879 | static inline const uint8_t *
1880 | get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1881 | tvbuff_t *tvb, int start, int length, int *ret_length,
1882 | const unsigned encoding)
1883 | {
1884 | uint32_t n;
1885 | const uint8_t *value;
1886 |
1887 | /* I believe it's ok if this is called with a NULL tree */
1888 | n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1889 | value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1890 | length += n;
1891 | *ret_length = length;
1892 | return value;
1893 | }
1894 |
1895 | /* For FT_STRINGZPAD */
1896 | static inline const uint8_t *
1897 | get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1898 | int length, int *ret_length, const unsigned encoding)
1899 | {
1900 | /*
1901 | * XXX - currently, string values are null-
1902 | * terminated, so a "zero-padded" string
1903 | * isn't special. If we represent string
1904 | * values as something that includes a counted
1905 | * array of bytes, we'll need to strip the
1906 | * trailing NULs.
1907 | */
1908 | if (length == -1) {
1909 | length = tvb_ensure_captured_length_remaining(tvb, start);
1910 | }
1911 | *ret_length = length;
1912 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1913 | }
1914 |
1915 | /* For FT_STRINGZTRUNC */
1916 | static inline const uint8_t *
1917 | get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1918 | int length, int *ret_length, const unsigned encoding)
1919 | {
1920 | /*
1921 | * XXX - currently, string values are null-
1922 | * terminated, so a "zero-truncated" 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 everything
1926 | * starting with the terminating NUL.
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 | /*
1936 | * Deltas between the epochs for various non-UN*X time stamp formats and
1937 | * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1938 | * stamp format.
1939 | */
1940 |
1941 | /*
1942 | * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1943 | * XXX - if it's OK if this is unsigned, can we just use
1944 | * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1945 | */
1946 | #define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1947 |
1948 | /*
1949 | * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1950 | */
1951 | #define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1952 |
1953 | /* this can be called when there is no tree, so tree may be null */
1954 | static void
1955 | get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1956 | const int length, const unsigned encoding, nstime_t *time_stamp,
1957 | const bool_Bool is_relative)
1958 | {
1959 | uint32_t tmpsecs;
1960 | uint64_t tmp64secs;
1961 | uint64_t todusecs;
1962 |
1963 | switch (encoding) {
1964 |
1965 | case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1966 | /*
1967 | * If the length is 16, 8-byte seconds, followed
1968 | * by 8-byte fractional time in nanoseconds,
1969 | * both big-endian.
1970 | *
1971 | * If the length is 12, 8-byte seconds, followed
1972 | * by 4-byte fractional time in nanoseconds,
1973 | * both big-endian.
1974 | *
1975 | * If the length is 8, 4-byte seconds, followed
1976 | * by 4-byte fractional time in nanoseconds,
1977 | * both big-endian.
1978 | *
1979 | * For absolute times, the seconds are seconds
1980 | * since the UN*X epoch.
1981 | */
1982 | if (length == 16) {
1983 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1984 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1985 | } else if (length == 12) {
1986 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1987 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1988 | } else if (length == 8) {
1989 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1990 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1991 | } else if (length == 4) {
1992 | /*
1993 | * Backwards compatibility.
1994 | * ENC_TIME_SECS_NSECS is 0; using
1995 | * ENC_BIG_ENDIAN by itself with a 4-byte
1996 | * time-in-seconds value was done in the
1997 | * past.
1998 | */
1999 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2000 | time_stamp->nsecs = 0;
2001 | } else {
2002 | time_stamp->secs = 0;
2003 | time_stamp->nsecs = 0;
2004 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2005 | }
2006 | break;
2007 |
2008 | case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2009 | /*
2010 | * If the length is 16, 8-byte seconds, followed
2011 | * by 8-byte fractional time in nanoseconds,
2012 | * both little-endian.
2013 | *
2014 | * If the length is 12, 8-byte seconds, followed
2015 | * by 4-byte fractional time in nanoseconds,
2016 | * both little-endian.
2017 | *
2018 | * If the length is 8, 4-byte seconds, followed
2019 | * by 4-byte fractional time in nanoseconds,
2020 | * both little-endian.
2021 | *
2022 | * For absolute times, the seconds are seconds
2023 | * since the UN*X epoch.
2024 | */
2025 | if (length == 16) {
2026 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2027 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2028 | } else if (length == 12) {
2029 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2030 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2031 | } else if (length == 8) {
2032 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2033 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2034 | } else if (length == 4) {
2035 | /*
2036 | * Backwards compatibility.
2037 | * ENC_TIME_SECS_NSECS is 0; using
2038 | * ENC_LITTLE_ENDIAN by itself with a 4-byte
2039 | * time-in-seconds value was done in the
2040 | * past.
2041 | */
2042 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2043 | time_stamp->nsecs = 0;
2044 | } else {
2045 | time_stamp->secs = 0;
2046 | time_stamp->nsecs = 0;
2047 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2048 | }
2049 | break;
2050 |
2051 | case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2052 | /*
2053 | * NTP time stamp, big-endian.
2054 | * Only supported for absolute times.
2055 | */
2056 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2056, "!is_relative" ))));
2057 |
2058 | /* We need a temporary variable here so the unsigned math
2059 | * works correctly (for years > 2036 according to RFC 2030
2060 | * chapter 3).
2061 | *
2062 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2063 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2064 | * If bit 0 is not set, the time is in the range 2036-2104 and
2065 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2066 | */
2067 | tmpsecs = tvb_get_ntohl(tvb, start);
2068 | if ((tmpsecs & 0x80000000) != 0)
2069 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2070 | else
2071 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2072 |
2073 | if (length == 8) {
2074 | tmp64secs = tvb_get_ntoh64(tvb, start);
2075 | if (tmp64secs == 0) {
2076 | //This is "NULL" time
2077 | time_stamp->secs = 0;
2078 | time_stamp->nsecs = 0;
2079 | } else {
2080 | /*
2081 | * Convert 1/2^32s of a second to
2082 | * nanoseconds.
2083 | */
2084 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2085 | }
2086 | } else if (length == 4) {
2087 | /*
2088 | * Backwards compatibility.
2089 | */
2090 | if (tmpsecs == 0) {
2091 | //This is "NULL" time
2092 | time_stamp->secs = 0;
2093 | }
2094 | time_stamp->nsecs = 0;
2095 | } else {
2096 | time_stamp->secs = 0;
2097 | time_stamp->nsecs = 0;
2098 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2099 | }
2100 | break;
2101 |
2102 | case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2103 | /*
2104 | * NTP time stamp, little-endian.
2105 | * Only supported for absolute times.
2106 | *
2107 | * NTP doesn't use this, because it's an Internet format
2108 | * and hence big-endian. Any implementation must decide
2109 | * whether the NTP timestamp is a 64-bit unsigned fixed
2110 | * point number (RFC 1305, RFC 4330) or a 64-bit struct
2111 | * with a 32-bit unsigned seconds field followed by a
2112 | * 32-bit fraction field (cf. RFC 5905, which obsoletes
2113 | * the previous two).
2114 | *
2115 | * XXX: We do the latter, but no dissector uses this format.
2116 | * OTOH, ERF timestamps do the former, so perhaps we
2117 | * should switch the interpretation so that packet-erf.c
2118 | * could use this directly?
2119 | */
2120 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2120, "!is_relative" ))));
2121 |
2122 | /* We need a temporary variable here so the unsigned math
2123 | * works correctly (for years > 2036 according to RFC 2030
2124 | * chapter 3).
2125 | *
2126 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2127 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2128 | * If bit 0 is not set, the time is in the range 2036-2104 and
2129 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2130 | */
2131 | tmpsecs = tvb_get_letohl(tvb, start);
2132 | if ((tmpsecs & 0x80000000) != 0)
2133 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2134 | else
2135 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2136 |
2137 | if (length == 8) {
2138 | tmp64secs = tvb_get_letoh64(tvb, start);
2139 | if (tmp64secs == 0) {
2140 | //This is "NULL" time
2141 | time_stamp->secs = 0;
2142 | time_stamp->nsecs = 0;
2143 | } else {
2144 | /*
2145 | * Convert 1/2^32s of a second to
2146 | * nanoseconds.
2147 | */
2148 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2149 | }
2150 | } else if (length == 4) {
2151 | /*
2152 | * Backwards compatibility.
2153 | */
2154 | if (tmpsecs == 0) {
2155 | //This is "NULL" time
2156 | time_stamp->secs = 0;
2157 | }
2158 | time_stamp->nsecs = 0;
2159 | } else {
2160 | time_stamp->secs = 0;
2161 | time_stamp->nsecs = 0;
2162 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2163 | }
2164 | break;
2165 |
2166 | case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2167 | /*
2168 | * S/3x0 and z/Architecture TOD clock time stamp,
2169 | * big-endian. The epoch is January 1, 1900,
2170 | * 00:00:00 (proleptic?) UTC.
2171 | *
2172 | * Only supported for absolute times.
2173 | */
2174 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2174, "!is_relative" ))));
2175 | DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2175, "length == 8" ))));
2176 |
2177 | if (length == 8) {
2178 | todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2179 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2180 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2181 | } else {
2182 | time_stamp->secs = 0;
2183 | time_stamp->nsecs = 0;
2184 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2185 | }
2186 | break;
2187 |
2188 | case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2189 | /*
2190 | * S/3x0 and z/Architecture TOD clock time stamp,
2191 | * little-endian. The epoch is January 1, 1900,
2192 | * 00:00:00 (proleptic?) UTC.
2193 | *
2194 | * Only supported for absolute times.
2195 | */
2196 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2196, "!is_relative" ))));
2197 |
2198 | if (length == 8) {
2199 | todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2200 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2201 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2202 | } else {
2203 | time_stamp->secs = 0;
2204 | time_stamp->nsecs = 0;
2205 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2206 | }
2207 | break;
2208 |
2209 | case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2210 | /*
2211 | * Time stamp using the same seconds/fraction format
2212 | * as NTP, but with the origin of the time stamp being
2213 | * the UNIX epoch rather than the NTP epoch; big-
2214 | * endian.
2215 | *
2216 | * Only supported for absolute times.
2217 | */
2218 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2218, "!is_relative" ))));
2219 |
2220 | if (length == 8) {
2221 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2222 | /*
2223 | * Convert 1/2^32s of a second to nanoseconds.
2224 | */
2225 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2226 | } else {
2227 | time_stamp->secs = 0;
2228 | time_stamp->nsecs = 0;
2229 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2230 | }
2231 | break;
2232 |
2233 | case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2234 | /*
2235 | * Time stamp using the same seconds/fraction format
2236 | * as NTP, but with the origin of the time stamp being
2237 | * the UNIX epoch rather than the NTP epoch; little-
2238 | * endian.
2239 | *
2240 | * Only supported for absolute times.
2241 | *
2242 | * The RTPS specification explicitly supports Little
2243 | * Endian encoding. In one place, it states that its
2244 | * Time_t representation "is the one defined by ...
2245 | * RFC 1305", but in another explicitly defines it as
2246 | * a struct consisting of an 32 bit unsigned seconds
2247 | * field and a 32 bit unsigned fraction field, not a 64
2248 | * bit fixed point, so we do that here.
2249 | * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2250 | */
2251 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2251, "!is_relative" ))));
2252 |
2253 | if (length == 8) {
2254 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2255 | /*
2256 | * Convert 1/2^32s of a second to nanoseconds.
2257 | */
2258 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2259 | } else {
2260 | time_stamp->secs = 0;
2261 | time_stamp->nsecs = 0;
2262 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2263 | }
2264 | break;
2265 |
2266 | case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2267 | /*
2268 | * MIP6 time stamp, big-endian.
2269 | * A 64-bit unsigned integer field containing a timestamp. The
2270 | * value indicates the number of seconds since January 1, 1970,
2271 | * 00:00 UTC, by using a fixed point format. In this format, the
2272 | * integer number of seconds is contained in the first 48 bits of
2273 | * the field, and the remaining 16 bits indicate the number of
2274 | * 1/65536 fractions of a second.
2275 |
2276 | * Only supported for absolute times.
2277 | */
2278 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2278, "!is_relative" ))));
2279 |
2280 | if (length == 8) {
2281 | /* We need a temporary variable here so the casting and fractions
2282 | * of a second work correctly.
2283 | */
2284 | tmp64secs = tvb_get_ntoh48(tvb, start);
2285 | tmpsecs = tvb_get_ntohs(tvb, start + 6);
2286 | tmpsecs <<= 16;
2287 |
2288 | if ((tmp64secs == 0) && (tmpsecs == 0)) {
2289 | //This is "NULL" time
2290 | time_stamp->secs = 0;
2291 | time_stamp->nsecs = 0;
2292 | } else {
2293 | time_stamp->secs = (time_t)tmp64secs;
2294 | time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2295 | }
2296 | } else {
2297 | time_stamp->secs = 0;
2298 | time_stamp->nsecs = 0;
2299 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2300 | }
2301 | break;
2302 |
2303 | case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2304 | /*
2305 | * If the length is 16, 8-byte seconds, followed
2306 | * by 8-byte fractional time in microseconds,
2307 | * both big-endian.
2308 | *
2309 | * If the length is 12, 8-byte seconds, followed
2310 | * by 4-byte fractional time in microseconds,
2311 | * both big-endian.
2312 | *
2313 | * If the length is 8, 4-byte seconds, followed
2314 | * by 4-byte fractional time in microseconds,
2315 | * both big-endian.
2316 | *
2317 | * For absolute times, the seconds are seconds
2318 | * since the UN*X epoch.
2319 | */
2320 | if (length == 16) {
2321 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2322 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2323 | } else if (length == 12) {
2324 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2325 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2326 | } else if (length == 8) {
2327 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2328 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2329 | } else {
2330 | time_stamp->secs = 0;
2331 | time_stamp->nsecs = 0;
2332 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2333 | }
2334 | break;
2335 |
2336 | case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2337 | /*
2338 | * If the length is 16, 8-byte seconds, followed
2339 | * by 8-byte fractional time in microseconds,
2340 | * both little-endian.
2341 | *
2342 | * If the length is 12, 8-byte seconds, followed
2343 | * by 4-byte fractional time in microseconds,
2344 | * both little-endian.
2345 | *
2346 | * If the length is 8, 4-byte seconds, followed
2347 | * by 4-byte fractional time in microseconds,
2348 | * both little-endian.
2349 | *
2350 | * For absolute times, the seconds are seconds
2351 | * since the UN*X epoch.
2352 | */
2353 | if (length == 16) {
2354 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2355 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2356 | } else if (length == 12) {
2357 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2358 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2359 | } else if (length == 8) {
2360 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2361 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2362 | } else {
2363 | time_stamp->secs = 0;
2364 | time_stamp->nsecs = 0;
2365 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2366 | }
2367 | break;
2368 |
2369 | case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2370 | case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2371 | /*
2372 | * Seconds, 1 to 8 bytes.
2373 | * For absolute times, it's seconds since the
2374 | * UN*X epoch.
2375 | */
2376 | if (length >= 1 && length <= 8) {
2377 | time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2378 | time_stamp->nsecs = 0;
2379 | } else {
2380 | time_stamp->secs = 0;
2381 | time_stamp->nsecs = 0;
2382 | report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2383 | }
2384 | break;
2385 |
2386 | case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2387 | case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2388 | /*
2389 | * Milliseconds, 1 to 8 bytes.
2390 | * For absolute times, it's milliseconds since the
2391 | * UN*X epoch.
2392 | */
2393 | if (length >= 1 && length <= 8) {
2394 | uint64_t msecs;
2395 |
2396 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2397 | time_stamp->secs = (time_t)(msecs / 1000);
2398 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2399 | } else {
2400 | time_stamp->secs = 0;
2401 | time_stamp->nsecs = 0;
2402 | report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2403 | }
2404 | break;
2405 |
2406 | case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2407 | case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2408 | /*
2409 | * Microseconds, 1 to 8 bytes.
2410 | * For absolute times, it's microseconds since the
2411 | * UN*X epoch.
2412 | */
2413 | if (length >= 1 && length <= 8) {
2414 | uint64_t usecs;
2415 |
2416 | usecs = get_uint64_value(tree, tvb, start, length, encoding);
2417 | time_stamp->secs = (time_t)(usecs / 1000000);
2418 | time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2419 | } else {
2420 | time_stamp->secs = 0;
2421 | time_stamp->nsecs = 0;
2422 | report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2423 | }
2424 | break;
2425 |
2426 | case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2427 | case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2428 | /*
2429 | * nanoseconds, 1 to 8 bytes.
2430 | * For absolute times, it's nanoseconds since the
2431 | * UN*X epoch.
2432 | */
2433 |
2434 | if (length >= 1 && length <= 8) {
2435 | uint64_t nsecs;
2436 |
2437 | nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2438 | time_stamp->secs = (time_t)(nsecs / 1000000000);
2439 | time_stamp->nsecs = (int)(nsecs % 1000000000);
2440 | } else {
2441 | time_stamp->secs = 0;
2442 | time_stamp->nsecs = 0;
2443 | report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2444 | }
2445 | break;
2446 |
2447 | case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2448 | /*
2449 | * 1/64ths of a second since the UN*X epoch,
2450 | * big-endian.
2451 | *
2452 | * Only supported for absolute times.
2453 | */
2454 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2454, "!is_relative" ))));
2455 |
2456 | if (length == 8) {
2457 | /*
2458 | * The upper 48 bits are seconds since the
2459 | * UN*X epoch.
2460 | */
2461 | time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2462 | /*
2463 | * The lower 16 bits are 1/2^16s of a second;
2464 | * convert them to nanoseconds.
2465 | *
2466 | * XXX - this may give the impression of higher
2467 | * precision than you actually get.
2468 | */
2469 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2470 | } else {
2471 | time_stamp->secs = 0;
2472 | time_stamp->nsecs = 0;
2473 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2474 | }
2475 | break;
2476 |
2477 | case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2478 | /*
2479 | * 1/64ths of a second since the UN*X epoch,
2480 | * little-endian.
2481 | *
2482 | * Only supported for absolute times.
2483 | */
2484 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2484, "!is_relative" ))));
2485 |
2486 | if (length == 8) {
2487 | /*
2488 | * XXX - this is assuming that, if anybody
2489 | * were ever to use this format - RFC 3971
2490 | * doesn't, because that's an Internet
2491 | * protocol, and those use network byte
2492 | * order, i.e. big-endian - they'd treat it
2493 | * as a 64-bit count of 1/2^16s of a second,
2494 | * putting the upper 48 bits at the end.
2495 | *
2496 | * The lower 48 bits are seconds since the
2497 | * UN*X epoch.
2498 | */
2499 | time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2500 | /*
2501 | * The upper 16 bits are 1/2^16s of a second;
2502 | * convert them to nanoseconds.
2503 | *
2504 | * XXX - this may give the impression of higher
2505 | * precision than you actually get.
2506 | */
2507 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2508 | } else {
2509 | time_stamp->secs = 0;
2510 | time_stamp->nsecs = 0;
2511 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2512 | }
2513 | break;
2514 |
2515 | case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2516 | /*
2517 | * NTP time stamp, with 1-second resolution (i.e.,
2518 | * seconds since the NTP epoch), big-endian.
2519 | * Only supported for absolute times.
2520 | */
2521 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2521, "!is_relative" ))));
2522 |
2523 | if (length == 4) {
2524 | /*
2525 | * We need a temporary variable here so the unsigned math
2526 | * works correctly (for years > 2036 according to RFC 2030
2527 | * chapter 3).
2528 | *
2529 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2530 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2531 | * If bit 0 is not set, the time is in the range 2036-2104 and
2532 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2533 | */
2534 | tmpsecs = tvb_get_ntohl(tvb, start);
2535 | if ((tmpsecs & 0x80000000) != 0)
2536 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2537 | else
2538 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2539 | time_stamp->nsecs = 0;
2540 | } else {
2541 | time_stamp->secs = 0;
2542 | time_stamp->nsecs = 0;
2543 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2544 | }
2545 | break;
2546 |
2547 | case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2548 | /*
2549 | * NTP time stamp, with 1-second resolution (i.e.,
2550 | * seconds since the NTP epoch), little-endian.
2551 | * Only supported for absolute times.
2552 | */
2553 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2553, "!is_relative" ))));
2554 |
2555 | /*
2556 | * We need a temporary variable here so the unsigned math
2557 | * works correctly (for years > 2036 according to RFC 2030
2558 | * chapter 3).
2559 | *
2560 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2561 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2562 | * If bit 0 is not set, the time is in the range 2036-2104 and
2563 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2564 | */
2565 | if (length == 4) {
2566 | tmpsecs = tvb_get_letohl(tvb, start);
2567 | if ((tmpsecs & 0x80000000) != 0)
2568 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2569 | else
2570 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2571 | time_stamp->nsecs = 0;
2572 | } else {
2573 | time_stamp->secs = 0;
2574 | time_stamp->nsecs = 0;
2575 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2576 | }
2577 | break;
2578 |
2579 | case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2580 | /*
2581 | * Milliseconds, 6 to 8 bytes.
2582 | * For absolute times, it's milliseconds since the
2583 | * NTP epoch.
2584 | *
2585 | * ETSI TS 129.274 8.119 defines this as:
2586 | * "a 48 bit unsigned integer in network order format
2587 | * ...encoded as the number of milliseconds since
2588 | * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2589 | * rounded value of 1000 x the value of the 64-bit
2590 | * timestamp (Seconds + (Fraction / (1<<32))) defined
2591 | * in clause 6 of IETF RFC 5905."
2592 | *
2593 | * Taken literally, the part after "i.e." would
2594 | * mean that the value rolls over before reaching
2595 | * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2596 | * when the 64 bit timestamp rolls over, and we have
2597 | * to pick an NTP Era equivalence class to support
2598 | * (such as 1968-01-20 to 2104-02-06).
2599 | *
2600 | * OTOH, the extra room might be used to store Era
2601 | * information instead, in which case times until
2602 | * 10819-08-03 can be represented with 6 bytes without
2603 | * ambiguity. We handle both implementations, and assume
2604 | * that times before 1968-01-20 are not represented.
2605 | *
2606 | * Only 6 bytes or more makes sense as an absolute
2607 | * time. 5 bytes or fewer could express a span of
2608 | * less than 35 years, either 1900-1934 or 2036-2070.
2609 | */
2610 | if (length >= 6 && length <= 8) {
2611 | uint64_t msecs;
2612 |
2613 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2614 | tmp64secs = (msecs / 1000);
2615 | /*
2616 | * Assume that times in the first half of NTP
2617 | * Era 0 really represent times in the NTP
2618 | * Era 1.
2619 | */
2620 | if (tmp64secs >= 0x80000000)
2621 | time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2622 | else
2623 | time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2624 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2625 | }
2626 | else {
2627 | time_stamp->secs = 0;
2628 | time_stamp->nsecs = 0;
2629 | report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2630 | }
2631 | break;
2632 |
2633 | case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2634 | /*
2635 | * MP4 file time stamps, big-endian.
2636 | * Only supported for absolute times.
2637 | */
2638 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2638, "!is_relative" ))));
2639 |
2640 | if (length == 8) {
2641 | tmp64secs = tvb_get_ntoh64(tvb, start);
2642 | time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2643 | time_stamp->nsecs = 0;
2644 | } else if (length == 4) {
2645 | tmpsecs = tvb_get_ntohl(tvb, start);
2646 | time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2647 | time_stamp->nsecs = 0;
2648 | } else {
2649 | time_stamp->secs = 0;
2650 | time_stamp->nsecs = 0;
2651 | report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2652 | }
2653 | break;
2654 |
2655 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2656 | /*
2657 | * Zigbee ZCL time stamps, big-endian.
2658 | * Only supported for absolute times.
2659 | */
2660 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2660, "!is_relative" ))));
2661 |
2662 | if (length == 8) {
2663 | tmp64secs = tvb_get_ntoh64(tvb, start);
2664 | 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);
2665 | time_stamp->nsecs = 0;
2666 | } else if (length == 4) {
2667 | tmpsecs = tvb_get_ntohl(tvb, start);
2668 | time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2669 | time_stamp->nsecs = 0;
2670 | } else {
2671 | time_stamp->secs = 0;
2672 | time_stamp->nsecs = 0;
2673 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2674 | }
2675 | break;
2676 |
2677 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2678 | /*
2679 | * Zigbee ZCL time stamps, little-endian.
2680 | * Only supported for absolute times.
2681 | */
2682 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2682, "!is_relative" ))));
2683 |
2684 | if (length == 8) {
2685 | tmp64secs = tvb_get_letoh64(tvb, start);
2686 | 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);
2687 | time_stamp->nsecs = 0;
2688 | } else if (length == 4) {
2689 | tmpsecs = tvb_get_letohl(tvb, start);
2690 | time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2691 | time_stamp->nsecs = 0;
2692 | } else {
2693 | time_stamp->secs = 0;
2694 | time_stamp->nsecs = 0;
2695 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2696 | }
2697 | break;
2698 |
2699 | default:
2700 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 2700));
2701 | break;
2702 | }
2703 | }
2704 |
2705 | static void
2706 | tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2707 | {
2708 | const header_field_info *hfinfo = fi->hfinfo;
2709 |
2710 | if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2711 | GPtrArray *ptrs = NULL((void*)0);
2712 |
2713 | if (tree_data->interesting_hfids == NULL((void*)0)) {
2714 | /* Initialize the hash because we now know that it is needed */
2715 | tree_data->interesting_hfids =
2716 | g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2717 | } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2718 | ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2719 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2720 | }
2721 |
2722 | if (!ptrs) {
2723 | /* First element triggers the creation of pointer array */
2724 | ptrs = g_ptr_array_new();
2725 | g_hash_table_insert(tree_data->interesting_hfids,
2726 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2727 | }
2728 |
2729 | g_ptr_array_add(ptrs, fi);
2730 | }
2731 | }
2732 |
2733 |
2734 | /*
2735 | * Validates that field length bytes are available starting from
2736 | * start (pos/neg). Throws an exception if they aren't.
2737 | */
2738 | static void
2739 | test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2740 | int start, int length, const unsigned encoding)
2741 | {
2742 | int size = length;
2743 |
2744 | if (!tvb)
2745 | return;
2746 |
2747 | if ((hfinfo->type == FT_STRINGZ) ||
2748 | ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2749 | (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 ))))) {
2750 | /* If we're fetching until the end of the TVB, only validate
2751 | * that the offset is within range.
2752 | */
2753 | if (length == -1)
2754 | size = 0;
2755 | }
2756 |
2757 | tvb_ensure_bytes_exist(tvb, start, size);
2758 | }
2759 |
2760 | static void
2761 | detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2762 | {
2763 | bool_Bool found_stray_character = false0;
2764 |
2765 | if (!string)
2766 | return;
2767 |
2768 | switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2769 | case ENC_ASCII0x00000000:
2770 | case ENC_UTF_80x00000002:
2771 | for (int i = (int)strlen(string); i < length; i++) {
2772 | if (string[i] != '\0') {
2773 | found_stray_character = true1;
2774 | break;
2775 | }
2776 | }
2777 | break;
2778 |
2779 | default:
2780 | break;
2781 | }
2782 |
2783 | if (found_stray_character) {
2784 | expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2785 | }
2786 | }
2787 |
2788 | static void
2789 | free_fvalue_cb(void *data)
2790 | {
2791 | fvalue_t *fv = (fvalue_t*)data;
2792 | fvalue_free(fv);
2793 | }
2794 |
2795 | /* Add an item to a proto_tree, using the text label registered to that item;
2796 | the item is extracted from the tvbuff handed to it. */
2797 | static proto_item *
2798 | proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2799 | tvbuff_t *tvb, int start, int length,
2800 | unsigned encoding)
2801 | {
2802 | proto_item *pi;
2803 | uint32_t value, n;
2804 | uint64_t value64;
2805 | ws_in4_addr ipv4_value;
2806 | float floatval;
2807 | double doubleval;
2808 | const char *stringval = NULL((void*)0);
2809 | nstime_t time_stamp;
2810 | bool_Bool length_error;
2811 |
2812 | /* Ensure that the newly created fvalue_t is freed if we throw an
2813 | * exception before adding it to the tree. (gcc creates clobbering
2814 | * when it optimizes the equivalent TRY..EXCEPT implementation.)
2815 | * XXX: Move the new_field_info() call inside here?
2816 | */
2817 | 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));
2818 |
2819 | switch (new_fi->hfinfo->type) {
2820 | case FT_NONE:
2821 | /* no value to set for FT_NONE */
2822 | break;
2823 |
2824 | case FT_PROTOCOL:
2825 | proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2826 | break;
2827 |
2828 | case FT_BYTES:
2829 | proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2830 | break;
2831 |
2832 | case FT_UINT_BYTES:
2833 | n = get_uint_value(tree, tvb, start, length, encoding);
2834 | proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2835 |
2836 | /* Instead of calling proto_item_set_len(), since we don't yet
2837 | * have a proto_item, we set the field_info's length ourselves. */
2838 | new_fi->length = n + length;
2839 | break;
2840 |
2841 | case FT_BOOLEAN:
2842 | /*
2843 | * Map all non-zero values to little-endian for
2844 | * backwards compatibility.
2845 | */
2846 | if (encoding)
2847 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2848 | proto_tree_set_boolean(new_fi,
2849 | get_uint64_value(tree, tvb, start, length, encoding));
2850 | break;
2851 |
2852 | case FT_CHAR:
2853 | /* XXX - make these just FT_UINT? */
2854 | case FT_UINT8:
2855 | case FT_UINT16:
2856 | case FT_UINT24:
2857 | case FT_UINT32:
2858 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2859 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2860 | value = (uint32_t)value64;
2861 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2862 | new_fi->flags |= FI_VARINT0x00040000;
2863 | }
2864 | }
2865 | else {
2866 | /*
2867 | * Map all non-zero values to little-endian for
2868 | * backwards compatibility.
2869 | */
2870 | if (encoding)
2871 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2872 |
2873 | value = get_uint_value(tree, tvb, start, length, encoding);
2874 | }
2875 | proto_tree_set_uint(new_fi, value);
2876 | break;
2877 |
2878 | case FT_UINT40:
2879 | case FT_UINT48:
2880 | case FT_UINT56:
2881 | case FT_UINT64:
2882 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2883 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2884 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2885 | new_fi->flags |= FI_VARINT0x00040000;
2886 | }
2887 | }
2888 | else {
2889 | /*
2890 | * Map all other non-zero values to little-endian for
2891 | * backwards compatibility.
2892 | */
2893 | if (encoding)
2894 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2895 |
2896 | value64 = get_uint64_value(tree, tvb, start, length, encoding);
2897 | }
2898 | proto_tree_set_uint64(new_fi, value64);
2899 | break;
2900 |
2901 | /* XXX - make these just FT_INT? */
2902 | case FT_INT8:
2903 | case FT_INT16:
2904 | case FT_INT24:
2905 | case FT_INT32:
2906 | /*
2907 | * Map all non-zero values to little-endian for
2908 | * backwards compatibility.
2909 | */
2910 | if (encoding)
2911 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2912 | proto_tree_set_int(new_fi,
2913 | get_int_value(tree, tvb, start, length, encoding));
2914 | break;
2915 |
2916 | case FT_INT40:
2917 | case FT_INT48:
2918 | case FT_INT56:
2919 | case FT_INT64:
2920 | /*
2921 | * Map all non-zero values to little-endian for
2922 | * backwards compatibility.
2923 | */
2924 | if (encoding)
2925 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2926 | proto_tree_set_int64(new_fi,
2927 | get_int64_value(tree, tvb, start, length, encoding));
2928 | break;
2929 |
2930 | case FT_IPv4:
2931 | /*
2932 | * Map all non-zero values to little-endian for
2933 | * backwards compatibility.
2934 | */
2935 | if (encoding)
2936 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2937 | if (length != FT_IPv4_LEN4) {
2938 | length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2939 | report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2940 | }
2941 | ipv4_value = tvb_get_ipv4(tvb, start);
2942 | /*
2943 | * NOTE: to support code written when
2944 | * proto_tree_add_item() took a bool as its
2945 | * last argument, with false meaning "big-endian"
2946 | * and true meaning "little-endian", we treat any
2947 | * non-zero value of "encoding" as meaning
2948 | * "little-endian".
2949 | */
2950 | 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);
2951 | break;
2952 |
2953 | case FT_IPXNET:
2954 | if (length != FT_IPXNET_LEN4) {
2955 | length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2956 | report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2957 | }
2958 | proto_tree_set_ipxnet(new_fi,
2959 | get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2960 | break;
2961 |
2962 | case FT_IPv6:
2963 | if (length != FT_IPv6_LEN16) {
2964 | length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2965 | report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2966 | }
2967 | proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2968 | break;
2969 |
2970 | case FT_FCWWN:
2971 | if (length != FT_FCWWN_LEN8) {
2972 | length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2973 | report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2974 | }
2975 | proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2976 | break;
2977 |
2978 | case FT_AX25:
2979 | if (length != 7) {
2980 | length_error = length < 7 ? true1 : false0;
2981 | report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2982 | }
2983 | proto_tree_set_ax25_tvb(new_fi, tvb, start);
2984 | break;
2985 |
2986 | case FT_VINES:
2987 | if (length != VINES_ADDR_LEN6) {
2988 | length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2989 | report_type_length_mismatch(tree, "a Vines address", length, length_error);
2990 | }
2991 | proto_tree_set_vines_tvb(new_fi, tvb, start);
2992 | break;
2993 |
2994 | case FT_ETHER:
2995 | if (length != FT_ETHER_LEN6) {
2996 | length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2997 | report_type_length_mismatch(tree, "a MAC address", length, length_error);
2998 | }
2999 | proto_tree_set_ether_tvb(new_fi, tvb, start);
3000 | break;
3001 |
3002 | case FT_EUI64:
3003 | /*
3004 | * Map all non-zero values to little-endian for
3005 | * backwards compatibility.
3006 | */
3007 | if (encoding)
3008 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3009 | if (length != FT_EUI64_LEN8) {
3010 | length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3011 | report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3012 | }
3013 | proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3014 | break;
3015 | case FT_GUID:
3016 | /*
3017 | * Map all non-zero values to little-endian for
3018 | * backwards compatibility.
3019 | */
3020 | if (encoding)
3021 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3022 | if (length != FT_GUID_LEN16) {
3023 | length_error = length < FT_GUID_LEN16 ? true1 : false0;
3024 | report_type_length_mismatch(tree, "a GUID", length, length_error);
3025 | }
3026 | proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3027 | break;
3028 |
3029 | case FT_OID:
3030 | case FT_REL_OID:
3031 | proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3032 | break;
3033 |
3034 | case FT_SYSTEM_ID:
3035 | proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3036 | break;
3037 |
3038 | case FT_FLOAT:
3039 | /*
3040 | * NOTE: to support code written when
3041 | * proto_tree_add_item() took a bool as its
3042 | * last argument, with false meaning "big-endian"
3043 | * and true meaning "little-endian", we treat any
3044 | * non-zero value of "encoding" as meaning
3045 | * "little-endian".
3046 | *
3047 | * At some point in the future, we might
3048 | * support non-IEEE-binary floating-point
3049 | * formats in the encoding as well
3050 | * (IEEE decimal, System/3x0, VAX).
3051 | */
3052 | if (encoding)
3053 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3054 | if (length != 4) {
3055 | length_error = length < 4 ? true1 : false0;
3056 | report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3057 | }
3058 | if (encoding)
3059 | floatval = tvb_get_letohieee_float(tvb, start);
3060 | else
3061 | floatval = tvb_get_ntohieee_float(tvb, start);
3062 | proto_tree_set_float(new_fi, floatval);
3063 | break;
3064 |
3065 | case FT_DOUBLE:
3066 | /*
3067 | * NOTE: to support code written when
3068 | * proto_tree_add_item() took a bool as its
3069 | * last argument, with false meaning "big-endian"
3070 | * and true meaning "little-endian", we treat any
3071 | * non-zero value of "encoding" as meaning
3072 | * "little-endian".
3073 | *
3074 | * At some point in the future, we might
3075 | * support non-IEEE-binary floating-point
3076 | * formats in the encoding as well
3077 | * (IEEE decimal, System/3x0, VAX).
3078 | */
3079 | if (encoding == true1)
3080 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3081 | if (length != 8) {
3082 | length_error = length < 8 ? true1 : false0;
3083 | report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3084 | }
3085 | if (encoding)
3086 | doubleval = tvb_get_letohieee_double(tvb, start);
3087 | else
3088 | doubleval = tvb_get_ntohieee_double(tvb, start);
3089 | proto_tree_set_double(new_fi, doubleval);
3090 | break;
3091 |
3092 | case FT_STRING:
3093 | stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3094 | tvb, start, length, &length, encoding);
3095 | proto_tree_set_string(new_fi, stringval);
3096 |
3097 | /* Instead of calling proto_item_set_len(), since we
3098 | * don't yet have a proto_item, we set the
3099 | * field_info's length ourselves.
3100 | *
3101 | * XXX - our caller can't use that length to
3102 | * advance an offset unless they arrange that
3103 | * there always be a protocol tree into which
3104 | * we're putting this item.
3105 | */
3106 | new_fi->length = length;
3107 | break;
3108 |
3109 | case FT_STRINGZ:
3110 | stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3111 | tree, tvb, start, length, &length, encoding);
3112 | proto_tree_set_string(new_fi, stringval);
3113 |
3114 | /* Instead of calling proto_item_set_len(),
3115 | * since we don't yet have a proto_item, we
3116 | * set the field_info's length ourselves.
3117 | *
3118 | * XXX - our caller can't use that length to
3119 | * advance an offset unless they arrange that
3120 | * there always be a protocol tree into which
3121 | * we're putting this item.
3122 | */
3123 | new_fi->length = length;
3124 | break;
3125 |
3126 | case FT_UINT_STRING:
3127 | /*
3128 | * NOTE: to support code written when
3129 | * proto_tree_add_item() took a bool as its
3130 | * last argument, with false meaning "big-endian"
3131 | * and true meaning "little-endian", if the
3132 | * encoding value is true, treat that as
3133 | * ASCII with a little-endian length.
3134 | *
3135 | * This won't work for code that passes
3136 | * arbitrary non-zero values; that code
3137 | * will need to be fixed.
3138 | */
3139 | if (encoding == true1)
3140 | encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3141 | stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3142 | tree, tvb, start, length, &length, encoding);
3143 | proto_tree_set_string(new_fi, stringval);
3144 |
3145 | /* Instead of calling proto_item_set_len(), since we
3146 | * don't yet have a proto_item, we set the
3147 | * field_info's length ourselves.
3148 | *
3149 | * XXX - our caller can't use that length to
3150 | * advance an offset unless they arrange that
3151 | * there always be a protocol tree into which
3152 | * we're putting this item.
3153 | */
3154 | new_fi->length = length;
3155 | break;
3156 |
3157 | case FT_STRINGZPAD:
3158 | stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3159 | tvb, start, length, &length, encoding);
3160 | proto_tree_set_string(new_fi, stringval);
3161 |
3162 | /* Instead of calling proto_item_set_len(), since we
3163 | * don't yet have a proto_item, we set the
3164 | * field_info's length ourselves.
3165 | *
3166 | * XXX - our caller can't use that length to
3167 | * advance an offset unless they arrange that
3168 | * there always be a protocol tree into which
3169 | * we're putting this item.
3170 | */
3171 | new_fi->length = length;
3172 | break;
3173 |
3174 | case FT_STRINGZTRUNC:
3175 | stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3176 | tvb, start, length, &length, encoding);
3177 | proto_tree_set_string(new_fi, stringval);
3178 |
3179 | /* Instead of calling proto_item_set_len(), since we
3180 | * don't yet have a proto_item, we set the
3181 | * field_info's length ourselves.
3182 | *
3183 | * XXX - our caller can't use that length to
3184 | * advance an offset unless they arrange that
3185 | * there always be a protocol tree into which
3186 | * we're putting this item.
3187 | */
3188 | new_fi->length = length;
3189 | break;
3190 |
3191 | case FT_ABSOLUTE_TIME:
3192 | /*
3193 | * Absolute times can be in any of a number of
3194 | * formats, and they can be big-endian or
3195 | * little-endian.
3196 | *
3197 | * Historically FT_TIMEs were only timespecs;
3198 | * the only question was whether they were stored
3199 | * in big- or little-endian format.
3200 | *
3201 | * For backwards compatibility, we interpret an
3202 | * encoding of 1 as meaning "little-endian timespec",
3203 | * so that passing true is interpreted as that.
3204 | */
3205 | if (encoding == true1)
3206 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3207 |
3208 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3209 |
3210 | proto_tree_set_time(new_fi, &time_stamp);
3211 | break;
3212 |
3213 | case FT_RELATIVE_TIME:
3214 | /*
3215 | * Relative times can be in any of a number of
3216 | * formats, and they can be big-endian or
3217 | * little-endian.
3218 | *
3219 | * Historically FT_TIMEs were only timespecs;
3220 | * the only question was whether they were stored
3221 | * in big- or little-endian format.
3222 | *
3223 | * For backwards compatibility, we interpret an
3224 | * encoding of 1 as meaning "little-endian timespec",
3225 | * so that passing true is interpreted as that.
3226 | */
3227 | if (encoding == true1)
3228 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3229 |
3230 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3231 |
3232 | proto_tree_set_time(new_fi, &time_stamp);
3233 | break;
3234 | case FT_IEEE_11073_SFLOAT:
3235 | if (encoding)
3236 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3237 | if (length != 2) {
3238 | length_error = length < 2 ? true1 : false0;
3239 | report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3240 | }
3241 |
3242 | fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3243 |
3244 | break;
3245 | case FT_IEEE_11073_FLOAT:
3246 | if (encoding)
3247 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3248 | if (length != 4) {
3249 | length_error = length < 4 ? true1 : false0;
3250 | report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3251 | }
3252 | fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3253 |
3254 | break;
3255 | default:
3256 | 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))
3257 | 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))
3258 | 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))
3259 | 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));
3260 | break;
3261 | }
3262 | 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);
3263 |
3264 | /* Don't add new node to proto_tree until now so that any exceptions
3265 | * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3266 | /* XXX. wouldn't be better to add this item to tree, with some special
3267 | * flag (FI_EXCEPTION?) to know which item caused exception? For
3268 | * strings and bytes, we would have to set new_fi->value to something
3269 | * non-NULL, or otherwise ensure that proto_item_fill_display_label
3270 | * could handle NULL values. */
3271 | CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context ); }
3272 | pi = proto_tree_add_node(tree, new_fi);
3273 |
3274 | switch (new_fi->hfinfo->type) {
3275 |
3276 | case FT_STRING:
3277 | /* XXX: trailing stray character detection should be done
3278 | * _before_ conversion to UTF-8, because conversion can change
3279 | * the length, or else get_string_length should return a value
3280 | * for the "length in bytes of the string after conversion
3281 | * including internal nulls." (Noting that we do, for other
3282 | * reasons, still need the "length in bytes in the field",
3283 | * especially for FT_STRINGZ.)
3284 | *
3285 | * This is true even for ASCII and UTF-8, because
3286 | * substituting REPLACEMENT CHARACTERS for illegal characters
3287 | * can also do so (and for UTF-8 possibly even make the
3288 | * string _shorter_).
3289 | */
3290 | detect_trailing_stray_characters(encoding, stringval, length, pi);
3291 | break;
3292 |
3293 | default:
3294 | break;
3295 | }
3296 |
3297 | return pi;
3298 | }
3299 |
3300 | proto_item *
3301 | proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3302 | const int start, int length,
3303 | const unsigned encoding, int32_t *retval)
3304 | {
3305 | header_field_info *hfinfo;
3306 | field_info *new_fi;
3307 | int32_t value;
3308 |
3309 | 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", 3309, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3309, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3309, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3310 |
3311 | switch (hfinfo->type) {
3312 | case FT_INT8:
3313 | case FT_INT16:
3314 | case FT_INT24:
3315 | case FT_INT32:
3316 | break;
3317 | case FT_INT64:
3318 | 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)
3319 | hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3320 | default:
3321 | 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)
3322 | hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3323 | }
3324 |
3325 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3326 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3327 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3328 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3329 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3330 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3331 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3332 |
3333 | if (encoding & ENC_STRING0x03000000) {
3334 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3335 | }
3336 | /* I believe it's ok if this is called with a NULL tree */
3337 | value = get_int_value(tree, tvb, start, length, encoding);
3338 |
3339 | if (retval) {
3340 | int no_of_bits;
3341 | *retval = value;
3342 | if (hfinfo->bitmask) {
3343 | /* Mask out irrelevant portions */
3344 | *retval &= (uint32_t)(hfinfo->bitmask);
3345 | /* Shift bits */
3346 | *retval >>= hfinfo_bitshift(hfinfo);
3347 | }
3348 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3349 | *retval = ws_sign_ext32(*retval, no_of_bits);
3350 | }
3351 |
3352 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3353 |
3354 | 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", 3354 , __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", 3354, "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", 3354, "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", 3354, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3355 |
3356 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3357 |
3358 | proto_tree_set_int(new_fi, value);
3359 |
3360 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3361 |
3362 | return proto_tree_add_node(tree, new_fi);
3363 | }
3364 |
3365 | proto_item *
3366 | proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3367 | const int start, int length,
3368 | const unsigned encoding, uint32_t *retval)
3369 | {
3370 | header_field_info *hfinfo;
3371 | field_info *new_fi;
3372 | uint32_t value;
3373 |
3374 | 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", 3374, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3374, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3374, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3375 |
3376 | switch (hfinfo->type) {
3377 | case FT_CHAR:
3378 | case FT_UINT8:
3379 | case FT_UINT16:
3380 | case FT_UINT24:
3381 | case FT_UINT32:
3382 | break;
3383 | default:
3384 | 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)
3385 | 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);
3386 | }
3387 |
3388 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3389 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3390 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3391 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3392 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3393 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3394 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3395 |
3396 | if (encoding & ENC_STRING0x03000000) {
3397 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3398 | }
3399 | /* I believe it's ok if this is called with a NULL tree */
3400 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3401 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3402 | uint64_t temp64;
3403 | tvb_get_varint(tvb, start, length, &temp64, encoding);
3404 | value = (uint32_t)temp64;
3405 | } else {
3406 | value = get_uint_value(tree, tvb, start, length, encoding);
3407 | }
3408 |
3409 | if (retval) {
3410 | *retval = value;
3411 | if (hfinfo->bitmask) {
3412 | /* Mask out irrelevant portions */
3413 | *retval &= (uint32_t)(hfinfo->bitmask);
3414 | /* Shift bits */
3415 | *retval >>= hfinfo_bitshift(hfinfo);
3416 | }
3417 | }
3418 |
3419 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3420 |
3421 | 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", 3421 , __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", 3421, "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", 3421, "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", 3421, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3422 |
3423 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3424 |
3425 | proto_tree_set_uint(new_fi, value);
3426 |
3427 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3428 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3429 | new_fi->flags |= FI_VARINT0x00040000;
3430 | }
3431 | return proto_tree_add_node(tree, new_fi);
3432 | }
3433 |
3434 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3435 | * and returns proto_item* and uint value retrieved*/
3436 | proto_item *
3437 | ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3438 | const unsigned encoding, uint32_t *retval)
3439 | {
3440 | field_info *new_fi;
3441 | header_field_info *hfinfo;
3442 | int item_length;
3443 | int offset;
3444 | uint32_t value;
3445 |
3446 | offset = ptvc->offset;
3447 | 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", 3447, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3447, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3447, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3448 |
3449 | switch (hfinfo->type) {
3450 | case FT_CHAR:
3451 | case FT_UINT8:
3452 | case FT_UINT16:
3453 | case FT_UINT24:
3454 | case FT_UINT32:
3455 | break;
3456 | default:
3457 | 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)
3458 | 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);
3459 | }
3460 |
3461 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3462 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3463 |
3464 | /* I believe it's ok if this is called with a NULL tree */
3465 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3466 | value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3467 |
3468 | if (retval) {
3469 | *retval = value;
3470 | if (hfinfo->bitmask) {
3471 | /* Mask out irrelevant portions */
3472 | *retval &= (uint32_t)(hfinfo->bitmask);
3473 | /* Shift bits */
3474 | *retval >>= hfinfo_bitshift(hfinfo);
3475 | }
3476 | }
3477 |
3478 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3479 |
3480 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3481 |
3482 | /* Coast clear. Try and fake it */
3483 | 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", 3483 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3483, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3483, "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", 3483, __func__, "Adding %s would put more than %d 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); } } };
3484 |
3485 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3486 |
3487 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3488 | offset, length, encoding);
3489 | }
3490 |
3491 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3492 | * and returns proto_item* and int value retrieved*/
3493 | proto_item *
3494 | ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3495 | const unsigned encoding, int32_t *retval)
3496 | {
3497 | field_info *new_fi;
3498 | header_field_info *hfinfo;
3499 | int item_length;
3500 | int offset;
3501 | uint32_t value;
3502 |
3503 | offset = ptvc->offset;
3504 | 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", 3504, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3504, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3504, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3505 |
3506 | switch (hfinfo->type) {
3507 | case FT_INT8:
3508 | case FT_INT16:
3509 | case FT_INT24:
3510 | case FT_INT32:
3511 | break;
3512 | default:
3513 | 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)
3514 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
3515 | }
3516 |
3517 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3518 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3519 |
3520 | /* I believe it's ok if this is called with a NULL tree */
3521 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3522 | value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3523 |
3524 | if (retval) {
3525 | int no_of_bits;
3526 | *retval = value;
3527 | if (hfinfo->bitmask) {
3528 | /* Mask out irrelevant portions */
3529 | *retval &= (uint32_t)(hfinfo->bitmask);
3530 | /* Shift bits */
3531 | *retval >>= hfinfo_bitshift(hfinfo);
3532 | }
3533 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3534 | *retval = ws_sign_ext32(*retval, no_of_bits);
3535 | }
3536 |
3537 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3538 |
3539 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3540 |
3541 | /* Coast clear. Try and fake it */
3542 | 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", 3542 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3542, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3542, "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", 3542, __func__, "Adding %s would put more than %d 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); } } };
3543 |
3544 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3545 |
3546 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3547 | offset, length, encoding);
3548 | }
3549 |
3550 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3551 | * and returns proto_item* and string value retrieved */
3552 | proto_item*
3553 | ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3554 | {
3555 | header_field_info *hfinfo;
3556 | field_info *new_fi;
3557 | const uint8_t *value;
3558 | int item_length;
3559 | int offset;
3560 |
3561 | offset = ptvc->offset;
3562 |
3563 | 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", 3563 , __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", 3563, "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", 3563, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hf];;
3564 |
3565 | switch (hfinfo->type) {
3566 | case FT_STRING:
3567 | value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3568 | break;
3569 | case FT_STRINGZ:
3570 | value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3571 | break;
3572 | case FT_UINT_STRING:
3573 | value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3574 | break;
3575 | case FT_STRINGZPAD:
3576 | value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3577 | break;
3578 | case FT_STRINGZTRUNC:
3579 | value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3580 | break;
3581 | default:
3582 | 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)
3583 | 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);
3584 | }
3585 |
3586 | if (retval)
3587 | *retval = value;
3588 |
3589 | ptvcursor_advance(ptvc, item_length);
3590 |
3591 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3592 |
3593 | 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", 3593, __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", 3593, "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", 3593, "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", 3593 , __func__, "Adding %s would put more than %d 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); } } };
3594 |
3595 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3596 |
3597 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3598 | offset, length, encoding);
3599 | }
3600 |
3601 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3602 | * and returns proto_item* and boolean value retrieved */
3603 | proto_item*
3604 | ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3605 | {
3606 | header_field_info *hfinfo;
3607 | field_info *new_fi;
3608 | int item_length;
3609 | int offset;
3610 | uint64_t value, bitval;
3611 |
3612 | offset = ptvc->offset;
3613 | 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", 3613, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3613, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3613, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3614 |
3615 | if (hfinfo->type != FT_BOOLEAN) {
3616 | 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)
3617 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3618 | }
3619 |
3620 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3621 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3622 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3623 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3624 | *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3625 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3626 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3627 |
3628 | if (encoding & ENC_STRING0x03000000) {
3629 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3630 | }
3631 |
3632 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3633 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3634 |
3635 | /* I believe it's ok if this is called with a NULL tree */
3636 | value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3637 |
3638 | if (retval) {
3639 | bitval = value;
3640 | if (hfinfo->bitmask) {
3641 | /* Mask out irrelevant portions */
3642 | bitval &= hfinfo->bitmask;
3643 | }
3644 | *retval = (bitval != 0);
3645 | }
3646 |
3647 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3648 |
3649 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3650 |
3651 | 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", 3651, __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", 3651, "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", 3651, "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", 3651 , __func__, "Adding %s would put more than %d 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); } } };
3652 |
3653 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3654 |
3655 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3656 | offset, length, encoding);
3657 | }
3658 |
3659 | proto_item *
3660 | proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3661 | const int start, int length, const unsigned encoding, uint64_t *retval)
3662 | {
3663 | header_field_info *hfinfo;
3664 | field_info *new_fi;
3665 | uint64_t value;
3666 |
3667 | 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", 3667, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3667, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3667, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3668 |
3669 | switch (hfinfo->type) {
3670 | case FT_UINT40:
3671 | case FT_UINT48:
3672 | case FT_UINT56:
3673 | case FT_UINT64:
3674 | break;
3675 | default:
3676 | 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)
3677 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64" , hfinfo->abbrev);
3678 | }
3679 |
3680 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3681 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3682 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3683 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3684 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3685 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3686 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3687 |
3688 | if (encoding & ENC_STRING0x03000000) {
3689 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3690 | }
3691 | /* I believe it's ok if this is called with a NULL tree */
3692 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3693 | tvb_get_varint(tvb, start, length, &value, encoding);
3694 | } else {
3695 | value = get_uint64_value(tree, tvb, start, length, encoding);
3696 | }
3697 |
3698 | if (retval) {
3699 | *retval = value;
3700 | if (hfinfo->bitmask) {
3701 | /* Mask out irrelevant portions */
3702 | *retval &= hfinfo->bitmask;
3703 | /* Shift bits */
3704 | *retval >>= hfinfo_bitshift(hfinfo);
3705 | }
3706 | }
3707 |
3708 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3709 |
3710 | 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", 3710 , __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", 3710, "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", 3710, "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", 3710, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3711 |
3712 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3713 |
3714 | proto_tree_set_uint64(new_fi, value);
3715 |
3716 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3717 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3718 | new_fi->flags |= FI_VARINT0x00040000;
3719 | }
3720 |
3721 | return proto_tree_add_node(tree, new_fi);
3722 | }
3723 |
3724 | proto_item *
3725 | proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3726 | const int start, int length, const unsigned encoding, int64_t *retval)
3727 | {
3728 | header_field_info *hfinfo;
3729 | field_info *new_fi;
3730 | int64_t value;
3731 |
3732 | 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", 3732, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3732, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3732, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3733 |
3734 | switch (hfinfo->type) {
3735 | case FT_INT40:
3736 | case FT_INT48:
3737 | case FT_INT56:
3738 | case FT_INT64:
3739 | break;
3740 | default:
3741 | 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)
3742 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
3743 | }
3744 |
3745 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3746 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3747 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3748 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3749 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3750 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3751 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3752 |
3753 | if (encoding & ENC_STRING0x03000000) {
3754 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3755 | }
3756 | /* I believe it's ok if this is called with a NULL tree */
3757 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3758 | tvb_get_varint(tvb, start, length, &value, encoding);
3759 | }
3760 | else {
3761 | value = get_int64_value(tree, tvb, start, length, encoding);
3762 | }
3763 |
3764 | if (retval) {
3765 | *retval = value;
3766 | }
3767 |
3768 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3769 |
3770 | 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", 3770 , __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", 3770, "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", 3770, "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", 3770, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3771 |
3772 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3773 |
3774 | proto_tree_set_int64(new_fi, value);
3775 |
3776 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3777 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3778 | new_fi->flags |= FI_VARINT0x00040000;
3779 | }
3780 |
3781 | return proto_tree_add_node(tree, new_fi);
3782 | }
3783 |
3784 | proto_item *
3785 | proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3786 | const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3787 | {
3788 | header_field_info *hfinfo;
3789 | field_info *new_fi;
3790 | uint64_t value;
3791 |
3792 | 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", 3792, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3792, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3792, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3793 |
3794 | 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 )))) {
3795 | 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)
3796 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT" , hfinfo->abbrev);
3797 | }
3798 |
3799 | /* length validation for native number encoding caught by get_uint64_value() */
3800 | /* length has to be -1 or > 0 regardless of encoding */
3801 | if (length == 0)
3802 | 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)
3803 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint" , length);
3804 |
3805 | if (encoding & ENC_STRING0x03000000) {
3806 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3807 | }
3808 |
3809 | length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3810 |
3811 | if (retval) {
3812 | *retval = value;
3813 | if (hfinfo->bitmask) {
3814 | /* Mask out irrelevant portions */
3815 | *retval &= hfinfo->bitmask;
3816 | /* Shift bits */
3817 | *retval >>= hfinfo_bitshift(hfinfo);
3818 | }
3819 | }
3820 |
3821 | if (lenretval) {
3822 | *lenretval = length;
3823 | }
3824 |
3825 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3826 |
3827 | 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", 3827 , __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", 3827, "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", 3827, "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", 3827, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3828 |
3829 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3830 |
3831 | proto_tree_set_uint64(new_fi, value);
3832 |
3833 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3834 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3835 | new_fi->flags |= FI_VARINT0x00040000;
3836 | }
3837 |
3838 | return proto_tree_add_node(tree, new_fi);
3839 |
3840 | }
3841 |
3842 | proto_item *
3843 | proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3844 | const int start, int length,
3845 | const unsigned encoding, bool_Bool *retval)
3846 | {
3847 | header_field_info *hfinfo;
3848 | field_info *new_fi;
3849 | uint64_t value, bitval;
3850 |
3851 | 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", 3851, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3851, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3851, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3852 |
3853 | if (hfinfo->type != FT_BOOLEAN) {
3854 | 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)
3855 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3856 | }
3857 |
3858 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3859 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3860 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3861 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3862 | *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3863 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3864 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3865 |
3866 | if (encoding & ENC_STRING0x03000000) {
3867 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3868 | }
3869 | /* I believe it's ok if this is called with a NULL tree */
3870 | value = get_uint64_value(tree, tvb, start, length, encoding);
3871 |
3872 | if (retval) {
3873 | bitval = value;
3874 | if (hfinfo->bitmask) {
3875 | /* Mask out irrelevant portions */
3876 | bitval &= hfinfo->bitmask;
3877 | }
3878 | *retval = (bitval != 0);
3879 | }
3880 |
3881 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3882 |
3883 | 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", 3883 , __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", 3883, "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", 3883, "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", 3883, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3884 |
3885 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3886 |
3887 | proto_tree_set_boolean(new_fi, value);
3888 |
3889 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3890 |
3891 | return proto_tree_add_node(tree, new_fi);
3892 | }
3893 |
3894 | proto_item *
3895 | proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3896 | const int start, int length,
3897 | const unsigned encoding, float *retval)
3898 | {
3899 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3900 | field_info *new_fi;
3901 | float value;
3902 |
3903 | 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", 3903, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3904 |
3905 | if (hfinfo->type != FT_FLOAT) {
3906 | 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);
3907 | }
3908 |
3909 | if (length != 4) {
3910 | report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3911 | }
3912 |
3913 | /* treat any nonzero encoding as little endian for backwards compatibility */
3914 | value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3915 | if (retval) {
3916 | *retval = value;
3917 | }
3918 |
3919 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3920 |
3921 | 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", 3921 , __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", 3921, "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", 3921, "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", 3921, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3922 |
3923 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3924 | if (encoding) {
3925 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3926 | }
3927 |
3928 | proto_tree_set_float(new_fi, value);
3929 |
3930 | return proto_tree_add_node(tree, new_fi);
3931 | }
3932 |
3933 | proto_item *
3934 | proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3935 | const int start, int length,
3936 | const unsigned encoding, double *retval)
3937 | {
3938 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3939 | field_info *new_fi;
3940 | double value;
3941 |
3942 | 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", 3942, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3943 |
3944 | if (hfinfo->type != FT_DOUBLE) {
3945 | 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);
3946 | }
3947 |
3948 | if (length != 8) {
3949 | report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3950 | }
3951 |
3952 | /* treat any nonzero encoding as little endian for backwards compatibility */
3953 | value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3954 | if (retval) {
3955 | *retval = value;
3956 | }
3957 |
3958 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3959 |
3960 | 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", 3960 , __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", 3960, "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", 3960, "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", 3960, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3961 |
3962 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3963 | if (encoding) {
3964 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3965 | }
3966 |
3967 | proto_tree_set_double(new_fi, value);
3968 |
3969 | return proto_tree_add_node(tree, new_fi);
3970 | }
3971 |
3972 | proto_item *
3973 | proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3974 | const int start, int length,
3975 | const unsigned encoding, ws_in4_addr *retval)
3976 | {
3977 | header_field_info *hfinfo;
3978 | field_info *new_fi;
3979 | ws_in4_addr value;
3980 |
3981 | 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", 3981, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3981, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3981, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3982 |
3983 | switch (hfinfo->type) {
3984 | case FT_IPv4:
3985 | break;
3986 | default:
3987 | 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)
3988 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4", hfinfo->abbrev);
3989 | }
3990 |
3991 | if (length != FT_IPv4_LEN4)
3992 | 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)
3993 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4" , length);
3994 |
3995 | if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3996 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3997 | }
3998 |
3999 | /*
4000 | * NOTE: to support code written when proto_tree_add_item() took
4001 | * a bool as its last argument, with false meaning "big-endian"
4002 | * and true meaning "little-endian", we treat any non-zero value
4003 | * of "encoding" as meaning "little-endian".
4004 | */
4005 | value = tvb_get_ipv4(tvb, start);
4006 | if (encoding)
4007 | 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))));
4008 |
4009 | if (retval) {
4010 | *retval = value;
4011 | }
4012 |
4013 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4014 |
4015 | 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", 4015 , __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", 4015, "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", 4015, "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", 4015, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4016 |
4017 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4018 |
4019 | proto_tree_set_ipv4(new_fi, value);
4020 |
4021 | new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4022 | return proto_tree_add_node(tree, new_fi);
4023 | }
4024 |
4025 | proto_item *
4026 | proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4027 | const int start, int length,
4028 | const unsigned encoding, ws_in6_addr *addr)
4029 | {
4030 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4031 | field_info *new_fi;
4032 |
4033 | 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", 4033, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4034 |
4035 | switch (hfinfo->type) {
4036 | case FT_IPv6:
4037 | break;
4038 | default:
4039 | 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)
4040 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6", hfinfo->abbrev);
4041 | }
4042 |
4043 | if (length != FT_IPv6_LEN16)
4044 | 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)
4045 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6" , length);
4046 |
4047 | if (encoding) {
4048 | 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" );
4049 | }
4050 |
4051 | tvb_get_ipv6(tvb, start, addr);
4052 |
4053 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4054 |
4055 | 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", 4055 , __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", 4055, "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", 4055, "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", 4055, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4056 |
4057 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4058 |
4059 | proto_tree_set_ipv6(new_fi, addr);
4060 |
4061 | return proto_tree_add_node(tree, new_fi);
4062 | }
4063 |
4064 | proto_item *
4065 | proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4066 | const int start, int length, const unsigned encoding, uint8_t *retval) {
4067 |
4068 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4069 | field_info *new_fi;
4070 |
4071 | 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", 4071, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4072 |
4073 | switch (hfinfo->type) {
4074 | case FT_ETHER:
4075 | break;
4076 | default:
4077 | 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)
4078 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER" , hfinfo->abbrev);
4079 | }
4080 |
4081 | if (length != FT_ETHER_LEN6)
4082 | 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)
4083 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether" , length);
4084 |
4085 | if (encoding) {
4086 | 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" );
4087 | }
4088 |
4089 | tvb_memcpy(tvb, retval, start, length);
4090 |
4091 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4092 |
4093 | TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4093 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4093, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4093, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4093, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4094 |
4095 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4096 |
4097 | proto_tree_set_ether(new_fi, retval);
4098 |
4099 | return proto_tree_add_node(tree, new_fi);
4100 | }
4101 |
4102 |
4103 | proto_item *
4104 | proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4105 | tvbuff_t *tvb,
4106 | const int start, int length,
4107 | const unsigned encoding,
4108 | wmem_allocator_t *scope,
4109 | const uint8_t **retval,
4110 | int *lenretval)
4111 | {
4112 | proto_item *pi;
4113 | header_field_info *hfinfo;
4114 | field_info *new_fi;
4115 | const uint8_t *value;
4116 |
4117 | 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", 4117, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4117, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4117, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4118 |
4119 | switch (hfinfo->type) {
4120 | case FT_STRING:
4121 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4122 | break;
4123 | case FT_STRINGZ:
4124 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4125 | break;
4126 | case FT_UINT_STRING:
4127 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4128 | break;
4129 | case FT_STRINGZPAD:
4130 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4131 | break;
4132 | case FT_STRINGZTRUNC:
4133 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4134 | break;
4135 | default:
4136 | 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)
4137 | 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);
4138 | }
4139 |
4140 | if (retval)
4141 | *retval = value;
4142 |
4143 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4144 |
4145 | 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", 4145 , __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", 4145, "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", 4145, "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", 4145, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4146 |
4147 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4148 |
4149 | proto_tree_set_string(new_fi, value);
4150 |
4151 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4152 |
4153 | pi = proto_tree_add_node(tree, new_fi);
4154 |
4155 | switch (hfinfo->type) {
4156 |
4157 | case FT_STRINGZ:
4158 | case FT_STRINGZPAD:
4159 | case FT_STRINGZTRUNC:
4160 | case FT_UINT_STRING:
4161 | break;
4162 |
4163 | case FT_STRING:
4164 | detect_trailing_stray_characters(encoding, value, length, pi);
4165 | break;
4166 |
4167 | default:
4168 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4168 , __func__, "assertion \"not reached\" failed");
4169 | }
4170 |
4171 | return pi;
4172 | }
4173 |
4174 | proto_item *
4175 | proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4176 | const int start, int length,
4177 | const unsigned encoding, wmem_allocator_t *scope,
4178 | const uint8_t **retval)
4179 | {
4180 | return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4181 | tvb, start, length, encoding, scope, retval, &length);
4182 | }
4183 |
4184 | proto_item *
4185 | proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4186 | tvbuff_t *tvb,
4187 | const int start, int length,
4188 | const unsigned encoding,
4189 | wmem_allocator_t *scope,
4190 | char **retval,
4191 | int *lenretval)
4192 | {
4193 | proto_item *pi;
4194 | header_field_info *hfinfo;
4195 | field_info *new_fi;
4196 | const uint8_t *value;
4197 | uint32_t n = 0;
4198 |
4199 | 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", 4199, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4199, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4199, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4200 |
4201 | switch (hfinfo->type) {
4202 | case FT_STRING:
4203 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4204 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4205 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4206 | break;
4207 | case FT_STRINGZ:
4208 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4209 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4210 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4211 | break;
4212 | case FT_UINT_STRING:
4213 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4214 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4215 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4216 | break;
4217 | case FT_STRINGZPAD:
4218 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4219 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4220 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4221 | break;
4222 | case FT_STRINGZTRUNC:
4223 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4224 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4225 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4226 | break;
4227 | case FT_BYTES:
4228 | tvb_ensure_bytes_exist(tvb, start, length);
4229 | value = tvb_get_ptr(tvb, start, length);
4230 | *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4231 | *lenretval = length;
4232 | break;
4233 | case FT_UINT_BYTES:
4234 | n = get_uint_value(tree, tvb, start, length, encoding);
4235 | tvb_ensure_bytes_exist(tvb, start + length, n);
4236 | value = tvb_get_ptr(tvb, start + length, n);
4237 | *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4238 | *lenretval = length + n;
4239 | break;
4240 | default:
4241 | 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)
4242 | 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);
4243 | }
4244 |
4245 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4246 |
4247 | 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", 4247 , __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", 4247, "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", 4247, "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", 4247, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4248 |
4249 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4250 |
4251 | switch (hfinfo->type) {
4252 |
4253 | case FT_STRING:
4254 | case FT_STRINGZ:
4255 | case FT_UINT_STRING:
4256 | case FT_STRINGZPAD:
4257 | case FT_STRINGZTRUNC:
4258 | proto_tree_set_string(new_fi, value);
4259 | break;
4260 |
4261 | case FT_BYTES:
4262 | proto_tree_set_bytes(new_fi, value, length);
4263 | break;
4264 |
4265 | case FT_UINT_BYTES:
4266 | proto_tree_set_bytes(new_fi, value, n);
4267 | break;
4268 |
4269 | default:
4270 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4270 , __func__, "assertion \"not reached\" failed");
4271 | }
4272 |
4273 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4274 |
4275 | pi = proto_tree_add_node(tree, new_fi);
4276 |
4277 | switch (hfinfo->type) {
4278 |
4279 | case FT_STRINGZ:
4280 | case FT_STRINGZPAD:
4281 | case FT_STRINGZTRUNC:
4282 | case FT_UINT_STRING:
4283 | break;
4284 |
4285 | case FT_STRING:
4286 | detect_trailing_stray_characters(encoding, value, length, pi);
4287 | break;
4288 |
4289 | case FT_BYTES:
4290 | case FT_UINT_BYTES:
4291 | break;
4292 |
4293 | default:
4294 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4294 , __func__, "assertion \"not reached\" failed");
4295 | }
4296 |
4297 | return pi;
4298 | }
4299 |
4300 | proto_item *
4301 | proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4302 | tvbuff_t *tvb,
4303 | const int start, int length,
4304 | const unsigned encoding,
4305 | wmem_allocator_t *scope,
4306 | char **retval)
4307 | {
4308 | return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4309 | tvb, start, length, encoding, scope, retval, &length);
4310 | }
4311 |
4312 | proto_item *
4313 | proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4314 | tvbuff_t *tvb,
4315 | const int start, int length, const unsigned encoding,
4316 | wmem_allocator_t *scope, char **retval)
4317 | {
4318 | header_field_info *hfinfo;
4319 | field_info *new_fi;
4320 | nstime_t time_stamp;
4321 | int flags;
4322 |
4323 | 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", 4323, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4323, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4323, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4324 |
4325 | switch (hfinfo->type) {
4326 | case FT_ABSOLUTE_TIME:
4327 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4328 | flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4329 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4330 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4331 | }
4332 | *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4333 | break;
4334 | case FT_RELATIVE_TIME:
4335 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4336 | *retval = rel_time_to_secs_str(scope, &time_stamp);
4337 | break;
4338 | default:
4339 | 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)
4340 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME" , hfinfo->abbrev);
4341 | }
4342 |
4343 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4344 |
4345 | 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", 4345 , __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", 4345, "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", 4345, "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", 4345, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4346 |
4347 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4348 |
4349 | switch (hfinfo->type) {
4350 |
4351 | case FT_ABSOLUTE_TIME:
4352 | case FT_RELATIVE_TIME:
4353 | proto_tree_set_time(new_fi, &time_stamp);
4354 | break;
4355 | default:
4356 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4356 , __func__, "assertion \"not reached\" failed");
4357 | }
4358 |
4359 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4360 |
4361 | return proto_tree_add_node(tree, new_fi);
4362 | }
4363 |
4364 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
4365 | and returns proto_item* */
4366 | proto_item *
4367 | ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4368 | const unsigned encoding)
4369 | {
4370 | field_info *new_fi;
4371 | header_field_info *hfinfo;
4372 | int item_length;
4373 | int offset;
4374 |
4375 | offset = ptvc->offset;
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 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4378 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4379 |
4380 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4381 |
4382 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4383 |
4384 | /* Coast clear. Try and fake it */
4385 | 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", 4385 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4385, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4385, "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", 4385, __func__, "Adding %s would put more than %d 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); } } };
4386 |
4387 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4388 |
4389 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4390 | offset, length, encoding);
4391 | }
4392 |
4393 | /* Add an item to a proto_tree, using the text label registered to that item;
4394 | the item is extracted from the tvbuff handed to it. */
4395 | proto_item *
4396 | proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4397 | const int start, int length, const unsigned encoding)
4398 | {
4399 | field_info *new_fi;
4400 | int item_length;
4401 |
4402 | 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", 4402, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4403 |
4404 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4405 | test_length(hfinfo, tvb, start, item_length, encoding);
4406 |
4407 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4408 |
4409 | 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", 4409 , __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", 4409, "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", 4409, "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", 4409, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4410 |
4411 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4412 |
4413 | return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4414 | }
4415 |
4416 | proto_item *
4417 | proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4418 | const int start, int length, const unsigned encoding)
4419 | {
4420 | register header_field_info *hfinfo;
4421 |
4422 | 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", 4422, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4422, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4422, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4423 | return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4424 | }
4425 |
4426 | /* Add an item to a proto_tree, using the text label registered to that item;
4427 | the item is extracted from the tvbuff handed to it.
4428 |
4429 | Return the length of the item through the pointer. */
4430 | proto_item *
4431 | proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4432 | tvbuff_t *tvb, const int start,
4433 | int length, const unsigned encoding,
4434 | int *lenretval)
4435 | {
4436 | field_info *new_fi;
4437 | int item_length;
4438 | proto_item *item;
4439 |
4440 | 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", 4440, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4441 |
4442 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4443 | test_length(hfinfo, tvb, start, item_length, encoding);
4444 |
4445 | if (!tree) {
4446 | /*
4447 | * We need to get the correct item length here.
4448 | * That's normally done by proto_tree_new_item(),
4449 | * but we won't be calling it.
4450 | */
4451 | *lenretval = get_full_length(hfinfo, tvb, start, length,
4452 | item_length, encoding);
4453 | return NULL((void*)0);
4454 | }
4455 |
4456 | 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", 4463 , __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", 4463, "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", 4463, "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", 4463 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4457 | /*((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", 4463 , __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", 4463, "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", 4463, "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", 4463 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4458 | * 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", 4463 , __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", 4463, "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", 4463, "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", 4463 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4459 | * 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", 4463 , __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", 4463, "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", 4463, "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", 4463 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4460 | */((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", 4463 , __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", 4463, "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", 4463, "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", 4463 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4461 | *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", 4463 , __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", 4463, "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", 4463, "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", 4463 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4462 | 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", 4463 , __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", 4463, "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", 4463, "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", 4463 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4463 | })((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", 4463 , __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", 4463, "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", 4463, "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", 4463 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } };
4464 |
4465 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4466 |
4467 | item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4468 | *lenretval = new_fi->length;
4469 | return item;
4470 | }
4471 |
4472 | proto_item *
4473 | proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4474 | const int start, int length,
4475 | const unsigned encoding, int *lenretval)
4476 | {
4477 | register header_field_info *hfinfo;
4478 |
4479 | 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", 4479, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4479, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4479, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4480 | return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4481 | }
4482 |
4483 | /* which FT_ types can use proto_tree_add_bytes_item() */
4484 | static inline bool_Bool
4485 | validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4486 | {
4487 | return (type == FT_BYTES ||
4488 | type == FT_UINT_BYTES ||
4489 | type == FT_OID ||
4490 | type == FT_REL_OID ||
4491 | type == FT_SYSTEM_ID );
4492 | }
4493 |
4494 | /* Note: this does no validation that the byte array of an FT_OID or
4495 | FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4496 | so I think it's ok to continue not validating it?
4497 | */
4498 | proto_item *
4499 | proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4500 | const int start, int length, const unsigned encoding,
4501 | GByteArray *retval, int *endoff, int *err)
4502 | {
4503 | field_info *new_fi;
4504 | GByteArray *bytes = retval;
4505 | GByteArray *created_bytes = NULL((void*)0);
4506 | bool_Bool failed = false0;
4507 | uint32_t n = 0;
4508 | header_field_info *hfinfo;
4509 | bool_Bool generate = (bytes || tree) ? true1 : false0;
4510 |
4511 | 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", 4511, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4511, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4511, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4512 |
4513 | 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", 4513, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4514 |
4515 | 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", 4516, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))))
4516 | "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", 4516, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))));
4517 |
4518 | CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); };
4519 |
4520 | if (encoding & ENC_STR_NUM0x01000000) {
4521 | 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" );
4522 | }
4523 |
4524 | if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4525 | if (hfinfo->type == FT_UINT_BYTES) {
4526 | /* can't decode FT_UINT_BYTES from strings */
4527 | 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")
4528 | "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");
4529 | }
4530 |
4531 | unsigned hex_encoding = encoding;
4532 | if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4533 | /* If none of the separator values are used,
4534 | * assume no separator (the common case). */
4535 | hex_encoding |= ENC_SEP_NONE0x00010000;
4536 | #if 0
4537 | 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")
4538 | "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");
4539 | #endif
4540 | }
4541 |
4542 | if (!bytes) {
4543 | /* caller doesn't care about return value, but we need it to
4544 | call tvb_get_string_bytes() and set the tree later */
4545 | bytes = created_bytes = g_byte_array_new();
4546 | }
4547 |
4548 | /*
4549 | * bytes might be NULL after this, but can't add expert
4550 | * error until later; if it's NULL, just note that
4551 | * it failed.
4552 | */
4553 | bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4554 | if (bytes == NULL((void*)0))
4555 | failed = true1;
4556 | }
4557 | else if (generate) {
4558 | tvb_ensure_bytes_exist(tvb, start, length);
4559 |
4560 | if (hfinfo->type == FT_UINT_BYTES) {
4561 | n = length; /* n is now the "header" length */
4562 | length = get_uint_value(tree, tvb, start, n, encoding);
4563 | /* length is now the value's length; only store the value in the array */
4564 | tvb_ensure_bytes_exist(tvb, start + n, length);
4565 | if (!bytes) {
4566 | /* caller doesn't care about return value, but
4567 | * we may need it to set the tree later */
4568 | bytes = created_bytes = g_byte_array_new();
4569 | }
4570 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4571 | }
4572 | else if (length > 0) {
4573 | if (!bytes) {
4574 | /* caller doesn't care about return value, but
4575 | * we may need it to set the tree later */
4576 | bytes = created_bytes = g_byte_array_new();
4577 | }
4578 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4579 | }
4580 |
4581 | if (endoff)
4582 | *endoff = start + n + length;
4583 | }
4584 |
4585 | if (err)
4586 | *err = failed ? EINVAL22 : 0;
4587 |
4588 | 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); }
4589 | {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4590 | 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); }
4591 | 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); }
4592 | 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); }
4593 | bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4594 | } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); };
4595 |
4596 | 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", 4602 , __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", 4602, "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", 4602, "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", 4602 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4597 | {((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", 4602 , __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", 4602, "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", 4602, "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", 4602 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4598 | 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", 4602 , __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", 4602, "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", 4602, "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", 4602 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4599 | 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", 4602 , __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", 4602, "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", 4602, "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", 4602 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4600 | 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", 4602 , __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", 4602, "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", 4602, "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", 4602 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4601 | 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", 4602 , __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", 4602, "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", 4602, "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", 4602 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4602 | } )((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", 4602 , __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", 4602, "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", 4602, "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", 4602 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } };
4603 |
4604 | /* n will be zero except when it's a FT_UINT_BYTES */
4605 | new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4606 |
4607 | if (encoding & ENC_STRING0x03000000) {
4608 | if (failed)
4609 | expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4610 |
4611 | if (bytes)
4612 | proto_tree_set_bytes_gbytearray(new_fi, bytes);
4613 | else
4614 | proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4615 |
4616 | if (created_bytes)
4617 | g_byte_array_free(created_bytes, true1);
4618 | }
4619 | else {
4620 | /* n will be zero except when it's a FT_UINT_BYTES */
4621 | proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4622 |
4623 | /* XXX: If we have a non-NULL tree but NULL retval, we don't
4624 | * use the byte array created above in this case.
4625 | */
4626 | if (created_bytes)
4627 | g_byte_array_free(created_bytes, true1);
4628 |
4629 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4630 | (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);
4631 | }
4632 |
4633 | return proto_tree_add_node(tree, new_fi);
4634 | }
4635 |
4636 |
4637 | proto_item *
4638 | proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4639 | const int start, int length, const unsigned encoding,
4640 | nstime_t *retval, int *endoff, int *err)
4641 | {
4642 | field_info *new_fi;
4643 | nstime_t time_stamp;
4644 | int saved_err = 0;
4645 | header_field_info *hfinfo;
4646 |
4647 | 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", 4647, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4647, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4647, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4648 |
4649 | 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", 4649, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4650 |
4651 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4652 | {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4653 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4654 | {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4655 | nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4656 | }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4657 | } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); };
4658 |
4659 | nstime_set_zero(&time_stamp);
4660 |
4661 | if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4662 | 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", 4662, ((hfinfo))->abbrev))));
4663 | /* The only string format that could be a relative time is
4664 | * ENC_ISO_8601_TIME, and that is treated as an absolute time
4665 | * relative to "now" currently.
4666 | */
4667 | if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4668 | saved_err = EINVAL22;
4669 | }
4670 | else {
4671 | 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", 4671, ((hfinfo))->abbrev))));
4672 | const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4673 |
4674 | tvb_ensure_bytes_exist(tvb, start, length);
4675 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4676 | if (endoff) *endoff = start + length;
4677 | }
4678 |
4679 | if (err) *err = saved_err;
4680 |
4681 | if (retval) {
4682 | retval->secs = time_stamp.secs;
4683 | retval->nsecs = time_stamp.nsecs;
4684 | }
4685 |
4686 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4687 |
4688 | 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", 4688 , __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", 4688, "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", 4688, "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", 4688, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4689 |
4690 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4691 |
4692 | proto_tree_set_time(new_fi, &time_stamp);
4693 |
4694 | if (encoding & ENC_STRING0x03000000) {
4695 | if (saved_err)
4696 | expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4697 | }
4698 | else {
4699 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4700 | (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);
4701 | }
4702 |
4703 | return proto_tree_add_node(tree, new_fi);
4704 | }
4705 |
4706 | /* Add a FT_NONE to a proto_tree */
4707 | proto_item *
4708 | proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4709 | const int start, int length, const char *format,
4710 | ...)
4711 | {
4712 | proto_item *pi;
4713 | va_list ap;
4714 | header_field_info *hfinfo;
4715 |
4716 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4717 |
4718 | 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", 4718 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4718, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4718, "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", 4718, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4719 |
4720 | 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", 4720 , ((hfinfo))->abbrev))));
4721 |
4722 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4723 |
4724 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4724, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4725 |
4726 | va_start(ap, format)__builtin_va_start(ap, format);
4727 | proto_tree_set_representation(pi, format, ap);
4728 | va_end(ap)__builtin_va_end(ap);
4729 |
4730 | /* no value to set for FT_NONE */
4731 | return pi;
4732 | }
4733 |
4734 | /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4735 | * offset, and returns proto_item* */
4736 | proto_item *
4737 | ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4738 | const unsigned encoding)
4739 | {
4740 | proto_item *item;
4741 |
4742 | item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4743 | length, encoding);
4744 |
4745 | return item;
4746 | }
4747 |
4748 | /* Advance the ptvcursor's offset within its tvbuff without
4749 | * adding anything to the proto_tree. */
4750 | void
4751 | ptvcursor_advance(ptvcursor_t* ptvc, int length)
4752 | {
4753 | if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc ->offset))) {
4754 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4755 | }
4756 | }
4757 |
4758 |
4759 | static void
4760 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4761 | {
4762 | fvalue_set_protocol(fi->value, tvb, field_data, length);
4763 | }
4764 |
4765 | /* Add a FT_PROTOCOL to a proto_tree */
4766 | proto_item *
4767 | proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4768 | int start, int length, const char *format, ...)
4769 | {
4770 | proto_item *pi;
4771 | tvbuff_t *protocol_tvb;
4772 | va_list ap;
4773 | header_field_info *hfinfo;
4774 | char* protocol_rep;
4775 |
4776 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4777 |
4778 | 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", 4778 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4778, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4778, "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", 4778, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4779 |
4780 | 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" , 4780, ((hfinfo))->abbrev))));
4781 |
4782 | /*
4783 | * This can throw an exception, so do it before we allocate anything.
4784 | */
4785 | protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4786 |
4787 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4788 |
4789 | va_start(ap, format)__builtin_va_start(ap, format);
4790 | protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4791 | proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4792 | g_free(protocol_rep);
4793 | va_end(ap)__builtin_va_end(ap);
4794 |
4795 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4795, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4796 |
4797 | va_start(ap, format)__builtin_va_start(ap, format);
4798 | proto_tree_set_representation(pi, format, ap);
4799 | va_end(ap)__builtin_va_end(ap);
4800 |
4801 | return pi;
4802 | }
4803 |
4804 | /* Add a FT_BYTES to a proto_tree */
4805 | proto_item *
4806 | proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4807 | int length, const uint8_t *start_ptr)
4808 | {
4809 | proto_item *pi;
4810 | header_field_info *hfinfo;
4811 | int item_length;
4812 |
4813 | 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", 4813, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4813, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4813, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4814 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4815 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4816 |
4817 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4818 |
4819 | 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", 4819 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4819, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4819, "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", 4819, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4820 |
4821 | 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", 4821, ((hfinfo))->abbrev))));
4822 |
4823 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4824 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4825 |
4826 | return pi;
4827 | }
4828 |
4829 | /* Add a FT_BYTES to a proto_tree */
4830 | proto_item *
4831 | proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4832 | int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4833 | {
4834 | proto_item *pi;
4835 | header_field_info *hfinfo;
4836 | int item_length;
4837 |
4838 | 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", 4838, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4838, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4838, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4839 | get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4840 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4841 |
4842 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4843 |
4844 | 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", 4844 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4844, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4844, "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", 4844, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4845 |
4846 | 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", 4846, ((hfinfo))->abbrev))));
4847 |
4848 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4849 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4850 |
4851 | return pi;
4852 | }
4853 |
4854 | proto_item *
4855 | proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4856 | int start, int length,
4857 | const uint8_t *start_ptr,
4858 | const char *format, ...)
4859 | {
4860 | proto_item *pi;
4861 | va_list ap;
4862 |
4863 | if (start_ptr == NULL((void*)0))
4864 | start_ptr = tvb_get_ptr(tvb, start, length);
4865 |
4866 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4867 |
4868 | 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; };
4869 |
4870 | va_start(ap, format)__builtin_va_start(ap, format);
4871 | proto_tree_set_representation_value(pi, format, ap);
4872 | va_end(ap)__builtin_va_end(ap);
4873 |
4874 | return pi;
4875 | }
4876 |
4877 | proto_item *
4878 | proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4879 | int start, int length, const uint8_t *start_ptr,
4880 | const char *format, ...)
4881 | {
4882 | proto_item *pi;
4883 | va_list ap;
4884 |
4885 | if (start_ptr == NULL((void*)0))
4886 | start_ptr = tvb_get_ptr(tvb, start, length);
4887 |
4888 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4889 |
4890 | 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; };
4891 |
4892 | va_start(ap, format)__builtin_va_start(ap, format);
4893 | proto_tree_set_representation(pi, format, ap);
4894 | va_end(ap)__builtin_va_end(ap);
4895 |
4896 | return pi;
4897 | }
4898 |
4899 | static void
4900 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4901 | {
4902 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4902, "length >= 0" ))));
4903 | 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", 4903, "start_ptr != ((void*)0) || length == 0" ))));
4904 |
4905 | fvalue_set_bytes_data(fi->value, start_ptr, length);
4906 | }
4907 |
4908 |
4909 | static void
4910 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4911 | {
4912 | tvb_ensure_bytes_exist(tvb, offset, length);
4913 | proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4914 | }
4915 |
4916 | static void
4917 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4918 | {
4919 | GByteArray *bytes;
4920 |
4921 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4921, "value != ((void*)0)" ))));
4922 |
4923 | bytes = byte_array_dup(value);
4924 |
4925 | fvalue_set_byte_array(fi->value, bytes);
4926 | }
4927 |
4928 | /* Add a FT_*TIME to a proto_tree */
4929 | proto_item *
4930 | proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4931 | int length, const nstime_t *value_ptr)
4932 | {
4933 | proto_item *pi;
4934 | header_field_info *hfinfo;
4935 |
4936 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4937 |
4938 | TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4938 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4938, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4938, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4938, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4939 |
4940 | DISSECTOR_ASSERT_FIELD_TYPE_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", 4940, ((hfinfo))->abbrev))));
4941 |
4942 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4943 | proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4944 |
4945 | return pi;
4946 | }
4947 |
4948 | proto_item *
4949 | proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4950 | int start, int length, nstime_t *value_ptr,
4951 | const char *format, ...)
4952 | {
4953 | proto_item *pi;
4954 | va_list ap;
4955 |
4956 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4957 | if (pi != tree) {
4958 | va_start(ap, format)__builtin_va_start(ap, format);
4959 | proto_tree_set_representation_value(pi, format, ap);
4960 | va_end(ap)__builtin_va_end(ap);
4961 | }
4962 |
4963 | return pi;
4964 | }
4965 |
4966 | proto_item *
4967 | proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4968 | int start, int length, nstime_t *value_ptr,
4969 | const char *format, ...)
4970 | {
4971 | proto_item *pi;
4972 | va_list ap;
4973 |
4974 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4975 | if (pi != tree) {
4976 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4976, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4977 |
4978 | va_start(ap, format)__builtin_va_start(ap, format);
4979 | proto_tree_set_representation(pi, format, ap);
4980 | va_end(ap)__builtin_va_end(ap);
4981 | }
4982 |
4983 | return pi;
4984 | }
4985 |
4986 | /* Set the FT_*TIME value */
4987 | static void
4988 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4989 | {
4990 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4990, "value_ptr != ((void*)0)" ))));
4991 |
4992 | fvalue_set_time(fi->value, value_ptr);
4993 | }
4994 |
4995 | /* Add a FT_IPXNET to a proto_tree */
4996 | proto_item *
4997 | proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4998 | int length, uint32_t value)
4999 | {
5000 | proto_item *pi;
5001 | header_field_info *hfinfo;
5002 |
5003 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5004 |
5005 | 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", 5005 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5005, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5005, "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", 5005, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5006 |
5007 | 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" , 5007, ((hfinfo))->abbrev))));
5008 |
5009 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5010 | proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5011 |
5012 | return pi;
5013 | }
5014 |
5015 | proto_item *
5016 | proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5017 | int start, int length, uint32_t value,
5018 | const char *format, ...)
5019 | {
5020 | proto_item *pi;
5021 | va_list ap;
5022 |
5023 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5024 | if (pi != tree) {
5025 | va_start(ap, format)__builtin_va_start(ap, format);
5026 | proto_tree_set_representation_value(pi, format, ap);
5027 | va_end(ap)__builtin_va_end(ap);
5028 | }
5029 |
5030 | return pi;
5031 | }
5032 |
5033 | proto_item *
5034 | proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5035 | int start, int length, uint32_t value,
5036 | const char *format, ...)
5037 | {
5038 | proto_item *pi;
5039 | va_list ap;
5040 |
5041 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5042 | if (pi != tree) {
5043 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5043, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5044 |
5045 | va_start(ap, format)__builtin_va_start(ap, format);
5046 | proto_tree_set_representation(pi, format, ap);
5047 | va_end(ap)__builtin_va_end(ap);
5048 | }
5049 |
5050 | return pi;
5051 | }
5052 |
5053 | /* Set the FT_IPXNET value */
5054 | static void
5055 | proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5056 | {
5057 | fvalue_set_uinteger(fi->value, value);
5058 | }
5059 |
5060 | /* Add a FT_IPv4 to a proto_tree */
5061 | proto_item *
5062 | proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5063 | int length, ws_in4_addr value)
5064 | {
5065 | proto_item *pi;
5066 | header_field_info *hfinfo;
5067 |
5068 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5069 |
5070 | 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", 5070 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5070, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5070, "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", 5070, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5071 |
5072 | 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", 5072 , ((hfinfo))->abbrev))));
5073 |
5074 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5075 | proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5076 |
5077 | return pi;
5078 | }
5079 |
5080 | proto_item *
5081 | proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5082 | int start, int length, ws_in4_addr value,
5083 | const char *format, ...)
5084 | {
5085 | proto_item *pi;
5086 | va_list ap;
5087 |
5088 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5089 | if (pi != tree) {
5090 | va_start(ap, format)__builtin_va_start(ap, format);
5091 | proto_tree_set_representation_value(pi, format, ap);
5092 | va_end(ap)__builtin_va_end(ap);
5093 | }
5094 |
5095 | return pi;
5096 | }
5097 |
5098 | proto_item *
5099 | proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5100 | int start, int length, ws_in4_addr value,
5101 | const char *format, ...)
5102 | {
5103 | proto_item *pi;
5104 | va_list ap;
5105 |
5106 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5107 | if (pi != tree) {
5108 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5108, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5109 |
5110 | va_start(ap, format)__builtin_va_start(ap, format);
5111 | proto_tree_set_representation(pi, format, ap);
5112 | va_end(ap)__builtin_va_end(ap);
5113 | }
5114 |
5115 | return pi;
5116 | }
5117 |
5118 | /* Set the FT_IPv4 value */
5119 | static void
5120 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5121 | {
5122 | ipv4_addr_and_mask ipv4;
5123 | ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5124 | fvalue_set_ipv4(fi->value, &ipv4);
5125 | }
5126 |
5127 | /* Add a FT_IPv6 to a proto_tree */
5128 | proto_item *
5129 | proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5130 | int length, const ws_in6_addr *value)
5131 | {
5132 | proto_item *pi;
5133 | header_field_info *hfinfo;
5134 |
5135 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5136 |
5137 | 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", 5137 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5137, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5137, "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", 5137, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5138 |
5139 | 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", 5139 , ((hfinfo))->abbrev))));
5140 |
5141 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5142 | proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5143 |
5144 | return pi;
5145 | }
5146 |
5147 | proto_item *
5148 | proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5149 | int start, int length,
5150 | const ws_in6_addr *value_ptr,
5151 | const char *format, ...)
5152 | {
5153 | proto_item *pi;
5154 | va_list ap;
5155 |
5156 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5157 | if (pi != tree) {
5158 | va_start(ap, format)__builtin_va_start(ap, format);
5159 | proto_tree_set_representation_value(pi, format, ap);
5160 | va_end(ap)__builtin_va_end(ap);
5161 | }
5162 |
5163 | return pi;
5164 | }
5165 |
5166 | proto_item *
5167 | proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5168 | int start, int length,
5169 | const ws_in6_addr *value_ptr,
5170 | const char *format, ...)
5171 | {
5172 | proto_item *pi;
5173 | va_list ap;
5174 |
5175 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5176 | if (pi != tree) {
5177 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5177, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5178 |
5179 | va_start(ap, format)__builtin_va_start(ap, format);
5180 | proto_tree_set_representation(pi, format, ap);
5181 | va_end(ap)__builtin_va_end(ap);
5182 | }
5183 |
5184 | return pi;
5185 | }
5186 |
5187 | /* Set the FT_IPv6 value */
5188 | static void
5189 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5190 | {
5191 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5191, "value != ((void*)0)" ))));
5192 | ipv6_addr_and_prefix ipv6;
5193 | ipv6.addr = *value;
5194 | ipv6.prefix = 128;
5195 | fvalue_set_ipv6(fi->value, &ipv6);
5196 | }
5197 |
5198 | static void
5199 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5200 | {
5201 | proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5202 | }
5203 |
5204 | /* Set the FT_FCWWN value */
5205 | static void
5206 | proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5207 | {
5208 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5208, "value_ptr != ((void*)0)" ))));
5209 | fvalue_set_fcwwn(fi->value, value_ptr);
5210 | }
5211 |
5212 | static void
5213 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5214 | {
5215 | proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5216 | }
5217 |
5218 | /* Add a FT_GUID to a proto_tree */
5219 | proto_item *
5220 | proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5221 | int length, const e_guid_t *value_ptr)
5222 | {
5223 | proto_item *pi;
5224 | header_field_info *hfinfo;
5225 |
5226 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5227 |
5228 | 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", 5228 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5228, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5228, "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", 5228, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5229 |
5230 | 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", 5230 , ((hfinfo))->abbrev))));
5231 |
5232 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5233 | proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5234 |
5235 | return pi;
5236 | }
5237 |
5238 | proto_item *
5239 | proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5240 | int start, int length,
5241 | const e_guid_t *value_ptr,
5242 | const char *format, ...)
5243 | {
5244 | proto_item *pi;
5245 | va_list ap;
5246 |
5247 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5248 | if (pi != tree) {
5249 | va_start(ap, format)__builtin_va_start(ap, format);
5250 | proto_tree_set_representation_value(pi, format, ap);
5251 | va_end(ap)__builtin_va_end(ap);
5252 | }
5253 |
5254 | return pi;
5255 | }
5256 |
5257 | proto_item *
5258 | proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5259 | int start, int length, const e_guid_t *value_ptr,
5260 | const char *format, ...)
5261 | {
5262 | proto_item *pi;
5263 | va_list ap;
5264 |
5265 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5266 | if (pi != tree) {
5267 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5267, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5268 |
5269 | va_start(ap, format)__builtin_va_start(ap, format);
5270 | proto_tree_set_representation(pi, format, ap);
5271 | va_end(ap)__builtin_va_end(ap);
5272 | }
5273 |
5274 | return pi;
5275 | }
5276 |
5277 | /* Set the FT_GUID value */
5278 | static void
5279 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5280 | {
5281 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5281, "value_ptr != ((void*)0)" ))));
5282 | fvalue_set_guid(fi->value, value_ptr);
5283 | }
5284 |
5285 | static void
5286 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5287 | const unsigned encoding)
5288 | {
5289 | e_guid_t guid;
5290 |
5291 | tvb_get_guid(tvb, start, &guid, encoding);
5292 | proto_tree_set_guid(fi, &guid);
5293 | }
5294 |
5295 | /* Add a FT_OID to a proto_tree */
5296 | proto_item *
5297 | proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5298 | int length, const uint8_t* value_ptr)
5299 | {
5300 | proto_item *pi;
5301 | header_field_info *hfinfo;
5302 |
5303 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5304 |
5305 | 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", 5305 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5305, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5305, "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", 5305, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5306 |
5307 | 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", 5307 , ((hfinfo))->abbrev))));
5308 |
5309 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5310 | proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5311 |
5312 | return pi;
5313 | }
5314 |
5315 | proto_item *
5316 | proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5317 | int start, int length,
5318 | const uint8_t* value_ptr,
5319 | const char *format, ...)
5320 | {
5321 | proto_item *pi;
5322 | va_list ap;
5323 |
5324 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5325 | if (pi != tree) {
5326 | va_start(ap, format)__builtin_va_start(ap, format);
5327 | proto_tree_set_representation_value(pi, format, ap);
5328 | va_end(ap)__builtin_va_end(ap);
5329 | }
5330 |
5331 | return pi;
5332 | }
5333 |
5334 | proto_item *
5335 | proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5336 | int start, int length, const uint8_t* value_ptr,
5337 | const char *format, ...)
5338 | {
5339 | proto_item *pi;
5340 | va_list ap;
5341 |
5342 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5343 | if (pi != tree) {
5344 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5344, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5345 |
5346 | va_start(ap, format)__builtin_va_start(ap, format);
5347 | proto_tree_set_representation(pi, format, ap);
5348 | va_end(ap)__builtin_va_end(ap);
5349 | }
5350 |
5351 | return pi;
5352 | }
5353 |
5354 | /* Set the FT_OID value */
5355 | static void
5356 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5357 | {
5358 | GByteArray *bytes;
5359 |
5360 | 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", 5360, "value_ptr != ((void*)0) || length == 0" ))));
5361 |
5362 | bytes = g_byte_array_new();
5363 | if (length > 0) {
5364 | g_byte_array_append(bytes, value_ptr, length);
5365 | }
5366 | fvalue_set_byte_array(fi->value, bytes);
5367 | }
5368 |
5369 | static void
5370 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5371 | {
5372 | proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5373 | }
5374 |
5375 | /* Set the FT_SYSTEM_ID value */
5376 | static void
5377 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5378 | {
5379 | GByteArray *bytes;
5380 |
5381 | 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", 5381, "value_ptr != ((void*)0) || length == 0" ))));
5382 |
5383 | bytes = g_byte_array_new();
5384 | if (length > 0) {
5385 | g_byte_array_append(bytes, value_ptr, length);
5386 | }
5387 | fvalue_set_byte_array(fi->value, bytes);
5388 | }
5389 |
5390 | static void
5391 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5392 | {
5393 | proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5394 | }
5395 |
5396 | /* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5397 | * proto_tree. Creates own copy of string, and frees it when the proto_tree
5398 | * is destroyed. */
5399 | proto_item *
5400 | proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5401 | int length, const char* value)
5402 | {
5403 | proto_item *pi;
5404 | header_field_info *hfinfo;
5405 | int item_length;
5406 |
5407 | 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", 5407, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5407, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5407, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
5408 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5409 | /*
5410 | * Special case - if the length is 0, skip the test, so that
5411 | * we can have an empty string right after the end of the
5412 | * packet. (This handles URL-encoded forms where the last field
5413 | * has no value so the form ends right after the =.)
5414 | */
5415 | if (item_length != 0)
5416 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5417 |
5418 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5419 |
5420 | 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", 5420 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5420, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5420, "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", 5420, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5421 |
5422 | 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", 5422, ((hfinfo))->abbrev))));
5423 |
5424 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5425 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5425, "length >= 0" ))));
5426 |
5427 | 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", 5427, __func__, value, -1, __uni_endptr); } } while (0); } } while (0);
5428 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5429 |
5430 | return pi;
5431 | }
5432 |
5433 | proto_item *
5434 | proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5435 | int start, int length, const char* value,
5436 | const char *format,
5437 | ...)
5438 | {
5439 | proto_item *pi;
5440 | va_list ap;
5441 |
5442 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5443 | if (pi != tree) {
5444 | va_start(ap, format)__builtin_va_start(ap, format);
5445 | proto_tree_set_representation_value(pi, format, ap);
5446 | va_end(ap)__builtin_va_end(ap);
5447 | }
5448 |
5449 | return pi;
5450 | }
5451 |
5452 | proto_item *
5453 | proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5454 | int start, int length, const char* value,
5455 | const char *format, ...)
5456 | {
5457 | proto_item *pi;
5458 | va_list ap;
5459 |
5460 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5461 | if (pi != tree) {
5462 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5462, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5463 |
5464 | va_start(ap, format)__builtin_va_start(ap, format);
5465 | proto_tree_set_representation(pi, format, ap);
5466 | va_end(ap)__builtin_va_end(ap);
5467 | }
5468 |
5469 | return pi;
5470 | }
5471 |
5472 | /* Set the FT_STRING value */
5473 | static void
5474 | proto_tree_set_string(field_info *fi, const char* value)
5475 | {
5476 | if (value) {
5477 | fvalue_set_string(fi->value, value);
5478 | } else {
5479 | /*
5480 | * XXX - why is a null value for a string field
5481 | * considered valid?
5482 | */
5483 | fvalue_set_string(fi->value, "[ Null ]");
5484 | }
5485 | }
5486 |
5487 | /* Set the FT_AX25 value */
5488 | static void
5489 | proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5490 | {
5491 | fvalue_set_ax25(fi->value, value);
5492 | }
5493 |
5494 | static void
5495 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5496 | {
5497 | proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5498 | }
5499 |
5500 | /* Set the FT_VINES value */
5501 | static void
5502 | proto_tree_set_vines(field_info *fi, const uint8_t* value)
5503 | {
5504 | fvalue_set_vines(fi->value, value);
5505 | }
5506 |
5507 | static void
5508 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5509 | {
5510 | proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5511 | }
5512 |
5513 | /* Add a FT_ETHER to a proto_tree */
5514 | proto_item *
5515 | proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5516 | int length, const uint8_t* value)
5517 | {
5518 | proto_item *pi;
5519 | header_field_info *hfinfo;
5520 |
5521 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5522 |
5523 | 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", 5523 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5523, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5523, "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", 5523, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5524 |
5525 | 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", 5525, ((hfinfo))->abbrev))));
5526 |
5527 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5528 | proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5529 |
5530 | return pi;
5531 | }
5532 |
5533 | proto_item *
5534 | proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5535 | int start, int length, const uint8_t* value,
5536 | const char *format, ...)
5537 | {
5538 | proto_item *pi;
5539 | va_list ap;
5540 |
5541 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5542 | if (pi != tree) {
5543 | va_start(ap, format)__builtin_va_start(ap, format);
5544 | proto_tree_set_representation_value(pi, format, ap);
5545 | va_end(ap)__builtin_va_end(ap);
5546 | }
5547 |
5548 | return pi;
5549 | }
5550 |
5551 | proto_item *
5552 | proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5553 | int start, int length, const uint8_t* value,
5554 | const char *format, ...)
5555 | {
5556 | proto_item *pi;
5557 | va_list ap;
5558 |
5559 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5560 | if (pi != tree) {
5561 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5561, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5562 |
5563 | va_start(ap, format)__builtin_va_start(ap, format);
5564 | proto_tree_set_representation(pi, format, ap);
5565 | va_end(ap)__builtin_va_end(ap);
5566 | }
5567 |
5568 | return pi;
5569 | }
5570 |
5571 | /* Set the FT_ETHER value */
5572 | static void
5573 | proto_tree_set_ether(field_info *fi, const uint8_t* value)
5574 | {
5575 | fvalue_set_ether(fi->value, value);
5576 | }
5577 |
5578 | static void
5579 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5580 | {
5581 | proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5582 | }
5583 |
5584 | /* Add a FT_BOOLEAN to a proto_tree */
5585 | proto_item *
5586 | proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5587 | int length, uint64_t value)
5588 | {
5589 | proto_item *pi;
5590 | header_field_info *hfinfo;
5591 |
5592 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5593 |
5594 | 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", 5594 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5594, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5594, "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", 5594, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5595 |
5596 | 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" , 5596, ((hfinfo))->abbrev))));
5597 |
5598 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5599 | proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5600 |
5601 | return pi;
5602 | }
5603 |
5604 | proto_item *
5605 | proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5606 | tvbuff_t *tvb, int start, int length,
5607 | uint64_t value, const char *format, ...)
5608 | {
5609 | proto_item *pi;
5610 | va_list ap;
5611 |
5612 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5613 | if (pi != tree) {
5614 | va_start(ap, format)__builtin_va_start(ap, format);
5615 | proto_tree_set_representation_value(pi, format, ap);
5616 | va_end(ap)__builtin_va_end(ap);
5617 | }
5618 |
5619 | return pi;
5620 | }
5621 |
5622 | proto_item *
5623 | proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5624 | int start, int length, uint64_t value,
5625 | const char *format, ...)
5626 | {
5627 | proto_item *pi;
5628 | va_list ap;
5629 |
5630 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5631 | if (pi != tree) {
5632 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5632, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5633 |
5634 | va_start(ap, format)__builtin_va_start(ap, format);
5635 | proto_tree_set_representation(pi, format, ap);
5636 | va_end(ap)__builtin_va_end(ap);
5637 | }
5638 |
5639 | return pi;
5640 | }
5641 |
5642 | /* Set the FT_BOOLEAN value */
5643 | static void
5644 | proto_tree_set_boolean(field_info *fi, uint64_t value)
5645 | {
5646 | proto_tree_set_uint64(fi, value);
5647 | }
5648 |
5649 | /* Generate, into "buf", a string showing the bits of a bitfield.
5650 | Return a pointer to the character after that string. */
5651 | static char *
5652 | other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5653 | {
5654 | int i = 0;
5655 | uint64_t bit;
5656 | char *p;
5657 |
5658 | p = buf;
5659 |
5660 | /* This is a devel error. It is safer to stop here. */
5661 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5661, "width >= 1" ))));
5662 |
5663 | bit = UINT64_C(1)1UL << (width - 1);
5664 | for (;;) {
5665 | if (mask & bit) {
5666 | /* This bit is part of the field. Show its value. */
5667 | if (val & bit)
5668 | *p++ = '1';
5669 | else
5670 | *p++ = '0';
5671 | } else {
5672 | /* This bit is not part of the field. */
5673 | *p++ = '.';
5674 | }
5675 | bit >>= 1;
5676 | i++;
5677 | if (i >= width)
5678 | break;
5679 | if (i % 4 == 0)
5680 | *p++ = ' ';
5681 | }
5682 | *p = '\0';
5683 | return p;
5684 | }
5685 |
5686 | static char *
5687 | decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5688 | {
5689 | char *p;
5690 |
5691 | p = other_decode_bitfield_value(buf, val, mask, width);
5692 | p = g_stpcpy(p, " = ");
5693 |
5694 | return p;
5695 | }
5696 |
5697 | static char *
5698 | other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5699 | {
5700 | int i = 0;
5701 | uint64_t bit;
5702 | char *p;
5703 |
5704 | p = buf;
5705 |
5706 | /* This is a devel error. It is safer to stop here. */
5707 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5707, "width >= 1" ))));
5708 |
5709 | bit = UINT64_C(1)1UL << (width - 1);
5710 | for (;;) {
5711 | if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5712 | (mask & bit)) {
5713 | /* This bit is part of the field. Show its value. */
5714 | if (val & bit)
5715 | *p++ = '1';
5716 | else
5717 | *p++ = '0';
5718 | } else {
5719 | /* This bit is not part of the field. */
5720 | *p++ = '.';
5721 | }
5722 | bit >>= 1;
5723 | i++;
5724 | if (i >= width)
5725 | break;
5726 | if (i % 4 == 0)
5727 | *p++ = ' ';
5728 | }
5729 |
5730 | *p = '\0';
5731 | return p;
5732 | }
5733 |
5734 | static char *
5735 | decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5736 | {
5737 | char *p;
5738 |
5739 | p = other_decode_bitfield_varint_value(buf, val, mask, width);
5740 | p = g_stpcpy(p, " = ");
5741 |
5742 | return p;
5743 | }
5744 |
5745 | /* Add a FT_FLOAT to a proto_tree */
5746 | proto_item *
5747 | proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5748 | int length, float value)
5749 | {
5750 | proto_item *pi;
5751 | header_field_info *hfinfo;
5752 |
5753 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5754 |
5755 | 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", 5755 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5755, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5755, "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", 5755, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5756 |
5757 | 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", 5757, ((hfinfo))->abbrev))));
5758 |
5759 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5760 | proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5761 |
5762 | return pi;
5763 | }
5764 |
5765 | proto_item *
5766 | proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5767 | int start, int length, float value,
5768 | const char *format, ...)
5769 | {
5770 | proto_item *pi;
5771 | va_list ap;
5772 |
5773 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5774 | if (pi != tree) {
5775 | va_start(ap, format)__builtin_va_start(ap, format);
5776 | proto_tree_set_representation_value(pi, format, ap);
5777 | va_end(ap)__builtin_va_end(ap);
5778 | }
5779 |
5780 | return pi;
5781 | }
5782 |
5783 | proto_item *
5784 | proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5785 | int start, int length, float value,
5786 | const char *format, ...)
5787 | {
5788 | proto_item *pi;
5789 | va_list ap;
5790 |
5791 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5792 | if (pi != tree) {
5793 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5793, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5794 |
5795 | va_start(ap, format)__builtin_va_start(ap, format);
5796 | proto_tree_set_representation(pi, format, ap);
5797 | va_end(ap)__builtin_va_end(ap);
5798 | }
5799 |
5800 | return pi;
5801 | }
5802 |
5803 | /* Set the FT_FLOAT value */
5804 | static void
5805 | proto_tree_set_float(field_info *fi, float value)
5806 | {
5807 | fvalue_set_floating(fi->value, value);
5808 | }
5809 |
5810 | /* Add a FT_DOUBLE to a proto_tree */
5811 | proto_item *
5812 | proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5813 | int length, double 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_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" , 5822, ((hfinfo))->abbrev))));
5823 |
5824 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5825 | proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5826 |
5827 | return pi;
5828 | }
5829 |
5830 | proto_item *
5831 | proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5832 | int start, int length, double value,
5833 | const char *format, ...)
5834 | {
5835 | proto_item *pi;
5836 | va_list ap;
5837 |
5838 | pi = proto_tree_add_double(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_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5850 | int start, int length, double value,
5851 | const char *format, ...)
5852 | {
5853 | proto_item *pi;
5854 | va_list ap;
5855 |
5856 | pi = proto_tree_add_double(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_DOUBLE value */
5869 | static void
5870 | proto_tree_set_double(field_info *fi, double value)
5871 | {
5872 | fvalue_set_floating(fi->value, value);
5873 | }
5874 |
5875 | /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5876 | proto_item *
5877 | proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5878 | int length, uint32_t value)
5879 | {
5880 | proto_item *pi = NULL((void*)0);
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 | switch (hfinfo->type) {
5888 | case FT_CHAR:
5889 | case FT_UINT8:
5890 | case FT_UINT16:
5891 | case FT_UINT24:
5892 | case FT_UINT32:
5893 | case FT_FRAMENUM:
5894 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5895 | proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5896 | break;
5897 |
5898 | default:
5899 | 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)
5900 | 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);
5901 | }
5902 |
5903 | return pi;
5904 | }
5905 |
5906 | proto_item *
5907 | proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5908 | int start, int length, uint32_t value,
5909 | const char *format, ...)
5910 | {
5911 | proto_item *pi;
5912 | va_list ap;
5913 |
5914 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5915 | if (pi != tree) {
5916 | va_start(ap, format)__builtin_va_start(ap, format);
5917 | proto_tree_set_representation_value(pi, format, ap);
5918 | va_end(ap)__builtin_va_end(ap);
5919 | }
5920 |
5921 | return pi;
5922 | }
5923 |
5924 | proto_item *
5925 | proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5926 | int start, int length, uint32_t value,
5927 | const char *format, ...)
5928 | {
5929 | proto_item *pi;
5930 | va_list ap;
5931 |
5932 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5933 | if (pi != tree) {
5934 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5934, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5935 |
5936 | va_start(ap, format)__builtin_va_start(ap, format);
5937 | proto_tree_set_representation(pi, format, ap);
5938 | va_end(ap)__builtin_va_end(ap);
5939 | }
5940 |
5941 | return pi;
5942 | }
5943 |
5944 | /* Set the FT_UINT{8,16,24,32} value */
5945 | static void
5946 | proto_tree_set_uint(field_info *fi, uint32_t value)
5947 | {
5948 | const header_field_info *hfinfo;
5949 | uint32_t integer;
5950 |
5951 | hfinfo = fi->hfinfo;
5952 | integer = value;
5953 |
5954 | if (hfinfo->bitmask) {
5955 | /* Mask out irrelevant portions */
5956 | integer &= (uint32_t)(hfinfo->bitmask);
5957 |
5958 | /* Shift bits */
5959 | integer >>= hfinfo_bitshift(hfinfo);
5960 |
5961 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
5962 | 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);
5963 | }
5964 |
5965 | fvalue_set_uinteger(fi->value, integer);
5966 | }
5967 |
5968 | /* Add FT_UINT{40,48,56,64} to a proto_tree */
5969 | proto_item *
5970 | proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5971 | int length, uint64_t value)
5972 | {
5973 | proto_item *pi = NULL((void*)0);
5974 | header_field_info *hfinfo;
5975 |
5976 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5977 |
5978 | 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", 5978 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5978, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5978, "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", 5978, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5979 |
5980 | switch (hfinfo->type) {
5981 | case FT_UINT40:
5982 | case FT_UINT48:
5983 | case FT_UINT56:
5984 | case FT_UINT64:
5985 | case FT_FRAMENUM:
5986 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5987 | proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5988 | break;
5989 |
5990 | default:
5991 | 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)
5992 | 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);
5993 | }
5994 |
5995 | return pi;
5996 | }
5997 |
5998 | proto_item *
5999 | proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6000 | int start, int length, uint64_t value,
6001 | const char *format, ...)
6002 | {
6003 | proto_item *pi;
6004 | va_list ap;
6005 |
6006 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6007 | if (pi != tree) {
6008 | va_start(ap, format)__builtin_va_start(ap, format);
6009 | proto_tree_set_representation_value(pi, format, ap);
6010 | va_end(ap)__builtin_va_end(ap);
6011 | }
6012 |
6013 | return pi;
6014 | }
6015 |
6016 | proto_item *
6017 | proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6018 | int start, int length, uint64_t value,
6019 | const char *format, ...)
6020 | {
6021 | proto_item *pi;
6022 | va_list ap;
6023 |
6024 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6025 | if (pi != tree) {
6026 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6026, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6027 |
6028 | va_start(ap, format)__builtin_va_start(ap, format);
6029 | proto_tree_set_representation(pi, format, ap);
6030 | va_end(ap)__builtin_va_end(ap);
6031 | }
6032 |
6033 | return pi;
6034 | }
6035 |
6036 | /* Set the FT_UINT{40,48,56,64} value */
6037 | static void
6038 | proto_tree_set_uint64(field_info *fi, uint64_t value)
6039 | {
6040 | const header_field_info *hfinfo;
6041 | uint64_t integer;
6042 |
6043 | hfinfo = fi->hfinfo;
6044 | integer = value;
6045 |
6046 | if (hfinfo->bitmask) {
6047 | /* Mask out irrelevant portions */
6048 | integer &= hfinfo->bitmask;
6049 |
6050 | /* Shift bits */
6051 | integer >>= hfinfo_bitshift(hfinfo);
6052 |
6053 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6054 | FI_SET_FLAG(fi, FI_BITS_SIZE(hfinfo_mask_bitwidth(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_mask_bitwidth (hfinfo)) & 63) << 12)); } while(0);
6055 | }
6056 |
6057 | fvalue_set_uinteger64(fi->value, integer);
6058 | }
6059 |
6060 | /* Add FT_INT{8,16,24,32} to a proto_tree */
6061 | proto_item *
6062 | proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6063 | int length, int32_t value)
6064 | {
6065 | proto_item *pi = NULL((void*)0);
6066 | header_field_info *hfinfo;
6067 |
6068 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6069 |
6070 | TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6070 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6070, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6070, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 6070, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
6071 |
6072 | switch (hfinfo->type) {
6073 | case FT_INT8:
6074 | case FT_INT16:
6075 | case FT_INT24:
6076 | case FT_INT32:
6077 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6078 | proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6079 | break;
6080 |
6081 | default:
6082 | 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)
6083 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
6084 | }
6085 |
6086 | return pi;
6087 | }
6088 |
6089 | proto_item *
6090 | proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6091 | int start, int length, int32_t value,
6092 | const char *format, ...)
6093 | {
6094 | proto_item *pi;
6095 | va_list ap;
6096 |
6097 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6098 | if (pi != tree) {
6099 | va_start(ap, format)__builtin_va_start(ap, format);
6100 | proto_tree_set_representation_value(pi, format, ap);
6101 | va_end(ap)__builtin_va_end(ap);
6102 | }
6103 |
6104 | return pi;
6105 | }
6106 |
6107 | proto_item *
6108 | proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6109 | int start, int length, int32_t value,
6110 | const char *format, ...)
6111 | {
6112 | proto_item *pi;
6113 | va_list ap;
6114 |
6115 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6116 | if (pi != tree) {
6117 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6117, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6118 |
6119 | va_start(ap, format)__builtin_va_start(ap, format);
6120 | proto_tree_set_representation(pi, format, ap);
6121 | va_end(ap)__builtin_va_end(ap);
6122 | }
6123 |
6124 | return pi;
6125 | }
6126 |
6127 | /* Set the FT_INT{8,16,24,32} value */
6128 | static void
6129 | proto_tree_set_int(field_info *fi, int32_t value)
6130 | {
6131 | const header_field_info *hfinfo;
6132 | uint32_t integer;
6133 | int no_of_bits;
6134 |
6135 | hfinfo = fi->hfinfo;
6136 | integer = (uint32_t) value;
6137 |
6138 | if (hfinfo->bitmask) {
6139 | /* Mask out irrelevant portions */
6140 | integer &= (uint32_t)(hfinfo->bitmask);
6141 |
6142 | /* Shift bits */
6143 | integer >>= hfinfo_bitshift(hfinfo);
6144 |
6145 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6146 | integer = ws_sign_ext32(integer, no_of_bits);
6147 |
6148 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6149 | 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);
6150 | }
6151 |
6152 | fvalue_set_sinteger(fi->value, integer);
6153 | }
6154 |
6155 | /* Add FT_INT{40,48,56,64} to a proto_tree */
6156 | proto_item *
6157 | proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6158 | int length, int64_t value)
6159 | {
6160 | proto_item *pi = NULL((void*)0);
6161 | header_field_info *hfinfo;
6162 |
6163 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6164 |
6165 | 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", 6165 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6165, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6165, "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", 6165, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6166 |
6167 | switch (hfinfo->type) {
6168 | case FT_INT40:
6169 | case FT_INT48:
6170 | case FT_INT56:
6171 | case FT_INT64:
6172 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6173 | proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6174 | break;
6175 |
6176 | default:
6177 | 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)
6178 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
6179 | }
6180 |
6181 | return pi;
6182 | }
6183 |
6184 | proto_item *
6185 | proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6186 | int start, int length, int64_t value,
6187 | const char *format, ...)
6188 | {
6189 | proto_item *pi;
6190 | va_list ap;
6191 |
6192 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6193 | if (pi != tree) {
6194 | va_start(ap, format)__builtin_va_start(ap, format);
6195 | proto_tree_set_representation_value(pi, format, ap);
6196 | va_end(ap)__builtin_va_end(ap);
6197 | }
6198 |
6199 | return pi;
6200 | }
6201 |
6202 | /* Set the FT_INT{40,48,56,64} value */
6203 | static void
6204 | proto_tree_set_int64(field_info *fi, int64_t value)
6205 | {
6206 | const header_field_info *hfinfo;
6207 | uint64_t integer;
6208 | int no_of_bits;
6209 |
6210 | hfinfo = fi->hfinfo;
6211 | integer = value;
6212 |
6213 | if (hfinfo->bitmask) {
6214 | /* Mask out irrelevant portions */
6215 | integer &= hfinfo->bitmask;
6216 |
6217 | /* Shift bits */
6218 | integer >>= hfinfo_bitshift(hfinfo);
6219 |
6220 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6221 | integer = ws_sign_ext64(integer, no_of_bits);
6222 |
6223 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6224 | 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);
6225 | }
6226 |
6227 | fvalue_set_sinteger64(fi->value, integer);
6228 | }
6229 |
6230 | proto_item *
6231 | proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6232 | int start, int length, int64_t value,
6233 | const char *format, ...)
6234 | {
6235 | proto_item *pi;
6236 | va_list ap;
6237 |
6238 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6239 | if (pi != tree) {
6240 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6240, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6241 |
6242 | va_start(ap, format)__builtin_va_start(ap, format);
6243 | proto_tree_set_representation(pi, format, ap);
6244 | va_end(ap)__builtin_va_end(ap);
6245 | }
6246 |
6247 | return pi;
6248 | }
6249 |
6250 | /* Add a FT_EUI64 to a proto_tree */
6251 | proto_item *
6252 | proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6253 | int length, const uint64_t value)
6254 | {
6255 | proto_item *pi;
6256 | header_field_info *hfinfo;
6257 |
6258 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6259 |
6260 | 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", 6260 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6260, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6260, "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", 6260, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6261 |
6262 | 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", 6262, ((hfinfo))->abbrev))));
6263 |
6264 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6265 | proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6266 |
6267 | return pi;
6268 | }
6269 |
6270 | proto_item *
6271 | proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6272 | int start, int length, const uint64_t value,
6273 | const char *format, ...)
6274 | {
6275 | proto_item *pi;
6276 | va_list ap;
6277 |
6278 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6279 | if (pi != tree) {
6280 | va_start(ap, format)__builtin_va_start(ap, format);
6281 | proto_tree_set_representation_value(pi, format, ap);
6282 | va_end(ap)__builtin_va_end(ap);
6283 | }
6284 |
6285 | return pi;
6286 | }
6287 |
6288 | proto_item *
6289 | proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6290 | int start, int length, const uint64_t value,
6291 | const char *format, ...)
6292 | {
6293 | proto_item *pi;
6294 | va_list ap;
6295 |
6296 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6297 | if (pi != tree) {
6298 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6298, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6299 |
6300 | va_start(ap, format)__builtin_va_start(ap, format);
6301 | proto_tree_set_representation(pi, format, ap);
6302 | va_end(ap)__builtin_va_end(ap);
6303 | }
6304 |
6305 | return pi;
6306 | }
6307 |
6308 | /* Set the FT_EUI64 value */
6309 | static void
6310 | proto_tree_set_eui64(field_info *fi, const uint64_t value)
6311 | {
6312 | uint8_t v[FT_EUI64_LEN8];
6313 | phtonu64(v, value);
6314 | fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6315 | }
6316 |
6317 | static void
6318 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6319 | {
6320 | if (encoding)
6321 | {
6322 | proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6323 | } else {
6324 | proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6325 | }
6326 | }
6327 |
6328 | proto_item *
6329 | proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6330 | const mac_hf_list_t *list_generic,
6331 | int idx, tvbuff_t *tvb,
6332 | proto_tree *tree, int offset)
6333 | {
6334 | uint8_t addr[6];
6335 | const char *addr_name = NULL((void*)0);
6336 | const char *oui_name = NULL((void*)0);
6337 | proto_item *addr_item = NULL((void*)0);
6338 | proto_tree *addr_tree = NULL((void*)0);
6339 | proto_item *ret_val = NULL((void*)0);
6340 |
6341 | if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6342 | return NULL((void*)0);
6343 | }
6344 |
6345 | /* Resolve what we can of the address */
6346 | tvb_memcpy(tvb, addr, offset, sizeof addr);
6347 | if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6348 | addr_name = get_ether_name(addr);
6349 | }
6350 | if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6351 | oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6352 | }
6353 |
6354 | /* Add the item for the specific address type */
6355 | ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6356 | if (idx >= 0) {
6357 | addr_tree = proto_item_add_subtree(ret_val, idx);
6358 | }
6359 | else {
6360 | addr_tree = tree;
6361 | }
6362 |
6363 | if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6364 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6365 | tvb, offset, 6, addr_name);
6366 | proto_item_set_generated(addr_item);
6367 | proto_item_set_hidden(addr_item);
6368 | }
6369 |
6370 | if (list_specific->hf_oui != NULL((void*)0)) {
6371 | addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6372 | proto_item_set_generated(addr_item);
6373 | proto_item_set_hidden(addr_item);
6374 |
6375 | if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6376 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6377 | proto_item_set_generated(addr_item);
6378 | proto_item_set_hidden(addr_item);
6379 | }
6380 | }
6381 |
6382 | if (list_specific->hf_lg != NULL((void*)0)) {
6383 | proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6384 | }
6385 | if (list_specific->hf_ig != NULL((void*)0)) {
6386 | proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6387 | }
6388 |
6389 | /* Were we given a list for generic address fields? If not, stop here */
6390 | if (list_generic == NULL((void*)0)) {
6391 | return ret_val;
6392 | }
6393 |
6394 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6395 | proto_item_set_hidden(addr_item);
6396 |
6397 | if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6398 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6399 | tvb, offset, 6, addr_name);
6400 | proto_item_set_generated(addr_item);
6401 | proto_item_set_hidden(addr_item);
6402 | }
6403 |
6404 | if (list_generic->hf_oui != NULL((void*)0)) {
6405 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6406 | proto_item_set_generated(addr_item);
6407 | proto_item_set_hidden(addr_item);
6408 |
6409 | if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6410 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6411 | proto_item_set_generated(addr_item);
6412 | proto_item_set_hidden(addr_item);
6413 | }
6414 | }
6415 |
6416 | if (list_generic->hf_lg != NULL((void*)0)) {
6417 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6418 | proto_item_set_hidden(addr_item);
6419 | }
6420 | if (list_generic->hf_ig != NULL((void*)0)) {
6421 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6422 | proto_item_set_hidden(addr_item);
6423 | }
6424 | return ret_val;
6425 | }
6426 |
6427 | static proto_item *
6428 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6429 | {
6430 | proto_node *pnode, *tnode, *sibling;
6431 | field_info *tfi;
6432 | unsigned depth = 1;
6433 |
6434 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6434, __func__, "assertion failed: %s", "tree" ); } while (0);
6435 |
6436 | /*
6437 | * Restrict our depth. proto_tree_traverse_pre_order and
6438 | * proto_tree_traverse_post_order (and possibly others) are recursive
6439 | * so we need to be mindful of our stack size.
6440 | */
6441 | if (tree->first_child == NULL((void*)0)) {
6442 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6443 | depth++;
6444 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6445 | 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__)), 6448)))
6446 | "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__)), 6448)))
6447 | 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__)), 6448)))
6448 | 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__)), 6448)));
6449 | }
6450 | }
6451 | }
6452 |
6453 | /*
6454 | * Make sure "tree" is ready to have subtrees under it, by
6455 | * checking whether it's been given an ett_ value.
6456 | *
6457 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6458 | * node of the protocol tree. That node is not displayed,
6459 | * so it doesn't need an ett_ value to remember whether it
6460 | * was expanded.
6461 | */
6462 | tnode = tree;
6463 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6464 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6465 | 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" , 6466)
6466 | 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" , 6466);
6467 | /* XXX - is it safe to continue here? */
6468 | }
6469 |
6470 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6471 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6472 | pnode->parent = tnode;
6473 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6474 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6475 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6476 |
6477 | if (tnode->last_child != NULL((void*)0)) {
6478 | sibling = tnode->last_child;
6479 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6479, "sibling->next == ((void*)0)" ))));
6480 | sibling->next = pnode;
6481 | } else
6482 | tnode->first_child = pnode;
6483 | tnode->last_child = pnode;
6484 |
6485 | /* We should not be adding a fake node for an interesting field */
6486 | 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", 6486, __func__, "assertion failed: %s" , "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT" ); } while (0);
6487 |
6488 | /* XXX - Should the proto_item have a header_field_info member, at least
6489 | * for faked items, to know what hfi was faked? (Some dissectors look at
6490 | * the tree items directly.)
6491 | */
6492 | return (proto_item *)pnode;
6493 | }
6494 |
6495 | /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6496 | static proto_item *
6497 | proto_tree_add_node(proto_tree *tree, field_info *fi)
6498 | {
6499 | proto_node *pnode, *tnode, *sibling;
6500 | field_info *tfi;
6501 | unsigned depth = 1;
6502 |
6503 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6503, __func__, "assertion failed: %s", "tree" ); } while (0);
6504 |
6505 | /*
6506 | * Restrict our depth. proto_tree_traverse_pre_order and
6507 | * proto_tree_traverse_post_order (and possibly others) are recursive
6508 | * so we need to be mindful of our stack size.
6509 | */
6510 | if (tree->first_child == NULL((void*)0)) {
6511 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6512 | depth++;
6513 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6514 | fvalue_free(fi->value);
6515 | fi->value = NULL((void*)0);
6516 | 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__)), 6519)))
6517 | "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__)), 6519)))
6518 | 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__)), 6519)))
6519 | 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__)), 6519)));
6520 | }
6521 | }
6522 | }
6523 |
6524 | /*
6525 | * Make sure "tree" is ready to have subtrees under it, by
6526 | * checking whether it's been given an ett_ value.
6527 | *
6528 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6529 | * node of the protocol tree. That node is not displayed,
6530 | * so it doesn't need an ett_ value to remember whether it
6531 | * was expanded.
6532 | */
6533 | tnode = tree;
6534 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6535 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6536 | /* Since we are not adding fi to a node, its fvalue won't get
6537 | * freed by proto_tree_free_node(), so free it now.
6538 | */
6539 | fvalue_free(fi->value);
6540 | fi->value = NULL((void*)0);
6541 | 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", 6542)
6542 | 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", 6542);
6543 | /* XXX - is it safe to continue here? */
6544 | }
6545 |
6546 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6547 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6548 | pnode->parent = tnode;
6549 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6550 | PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6551 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6552 |
6553 | if (tnode->last_child != NULL((void*)0)) {
6554 | sibling = tnode->last_child;
6555 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6555, "sibling->next == ((void*)0)" ))));
6556 | sibling->next = pnode;
6557 | } else
6558 | tnode->first_child = pnode;
6559 | tnode->last_child = pnode;
6560 |
6561 | tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6562 |
6563 | return (proto_item *)pnode;
6564 | }
6565 |
6566 |
6567 | /* Generic way to allocate field_info and add to proto_tree.
6568 | * Sets *pfi to address of newly-allocated field_info struct */
6569 | static proto_item *
6570 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6571 | int *length)
6572 | {
6573 | proto_item *pi;
6574 | field_info *fi;
6575 | int item_length;
6576 |
6577 | get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6578 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6579 | pi = proto_tree_add_node(tree, fi);
6580 |
6581 | return pi;
6582 | }
6583 |
6584 |
6585 | static void
6586 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6587 | int *item_length, const unsigned encoding)
6588 | {
6589 | int length_remaining;
6590 |
6591 | /*
6592 | * We only allow a null tvbuff if the item has a zero length,
6593 | * i.e. if there's no data backing it.
6594 | */
6595 | 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", 6595, "tvb != ((void*)0) || *length == 0" ))));
6596 |
6597 | /*
6598 | * XXX - in some protocols, there are 32-bit unsigned length
6599 | * fields, so lengths in protocol tree and tvbuff routines
6600 | * should really be unsigned. We should have, for those
6601 | * field types for which "to the end of the tvbuff" makes sense,
6602 | * additional routines that take no length argument and
6603 | * add fields that run to the end of the tvbuff.
6604 | */
6605 | if (*length == -1) {
6606 | /*
6607 | * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6608 | * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6609 | * of -1 means "set the length to what remains in the
6610 | * tvbuff".
6611 | *
6612 | * The assumption is either that
6613 | *
6614 | * 1) the length of the item can only be determined
6615 | * by dissection (typically true of items with
6616 | * subitems, which are probably FT_NONE or
6617 | * FT_PROTOCOL)
6618 | *
6619 | * or
6620 | *
6621 | * 2) if the tvbuff is "short" (either due to a short
6622 | * snapshot length or due to lack of reassembly of
6623 | * fragments/segments/whatever), we want to display
6624 | * what's available in the field (probably FT_BYTES
6625 | * or FT_STRING) and then throw an exception later
6626 | *
6627 | * or
6628 | *
6629 | * 3) the field is defined to be "what's left in the
6630 | * packet"
6631 | *
6632 | * so we set the length to what remains in the tvbuff so
6633 | * that, if we throw an exception while dissecting, it
6634 | * has what is probably the right value.
6635 | *
6636 | * For FT_STRINGZ, it means "the string is null-terminated,
6637 | * not null-padded; set the length to the actual length
6638 | * of the string", and if the tvbuff if short, we just
6639 | * throw an exception.
6640 | *
6641 | * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6642 | * it means "find the end of the string",
6643 | * and if the tvbuff if short, we just throw an exception.
6644 | *
6645 | * It's not valid for any other type of field. For those
6646 | * fields, we treat -1 the same way we treat other
6647 | * negative values - we assume the length is a Really
6648 | * Big Positive Number, and throw a ReportedBoundsError
6649 | * exception, under the assumption that the Really Big
6650 | * Length would run past the end of the packet.
6651 | */
6652 | 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 )))) {
6653 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6654 | /*
6655 | * Leave the length as -1, so our caller knows
6656 | * it was -1.
6657 | */
6658 | *item_length = *length;
6659 | return;
6660 | } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6661 | switch (tvb_get_uint8(tvb, start) >> 6)
6662 | {
6663 | case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6664 | *item_length = 1;
6665 | break;
6666 | case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6667 | *item_length = 2;
6668 | break;
6669 | case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6670 | *item_length = 4;
6671 | break;
6672 | case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6673 | *item_length = 8;
6674 | break;
6675 | }
6676 | }
6677 | }
6678 |
6679 | switch (hfinfo->type) {
6680 |
6681 | case FT_PROTOCOL:
6682 | case FT_NONE:
6683 | case FT_BYTES:
6684 | case FT_STRING:
6685 | case FT_STRINGZPAD:
6686 | case FT_STRINGZTRUNC:
6687 | /*
6688 | * We allow FT_PROTOCOLs to be zero-length -
6689 | * for example, an ONC RPC NULL procedure has
6690 | * neither arguments nor reply, so the
6691 | * payload for that protocol is empty.
6692 | *
6693 | * We also allow the others to be zero-length -
6694 | * because that's the way the code has been for a
6695 | * long, long time.
6696 | *
6697 | * However, we want to ensure that the start
6698 | * offset is not *past* the byte past the end
6699 | * of the tvbuff: we throw an exception in that
6700 | * case.
6701 | */
6702 | *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6703 | DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6703, "*length >= 0" ))));
6704 | break;
6705 |
6706 | case FT_STRINGZ:
6707 | /*
6708 | * Leave the length as -1, so our caller knows
6709 | * it was -1.
6710 | */
6711 | break;
6712 |
6713 | default:
6714 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6715 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 6715));
6716 | }
6717 | *item_length = *length;
6718 | } else {
6719 | *item_length = *length;
6720 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6721 | /*
6722 | * These types are for interior nodes of the
6723 | * tree, and don't have data associated with
6724 | * them; if the length is negative (XXX - see
6725 | * above) or goes past the end of the tvbuff,
6726 | * cut it short at the end of the tvbuff.
6727 | * That way, if this field is selected in
6728 | * Wireshark, we don't highlight stuff past
6729 | * the end of the data.
6730 | */
6731 | /* XXX - what to do, if we don't have a tvb? */
6732 | if (tvb) {
6733 | length_remaining = tvb_captured_length_remaining(tvb, start);
6734 | if (*item_length < 0 ||
6735 | (*item_length > 0 &&
6736 | (length_remaining < *item_length)))
6737 | *item_length = length_remaining;
6738 | }
6739 | }
6740 | if (*item_length < 0) {
6741 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6742 | }
6743 | }
6744 | }
6745 |
6746 | static int
6747 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6748 | int length, unsigned item_length, const int encoding)
6749 | {
6750 | uint32_t n;
6751 |
6752 | /*
6753 | * We need to get the correct item length here.
6754 | * That's normally done by proto_tree_new_item(),
6755 | * but we won't be calling it.
6756 | */
6757 | switch (hfinfo->type) {
6758 |
6759 | case FT_NONE:
6760 | case FT_PROTOCOL:
6761 | case FT_BYTES:
6762 | /*
6763 | * The length is the specified length.
6764 | */
6765 | break;
6766 |
6767 | case FT_UINT_BYTES:
6768 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6769 | item_length += n;
6770 | if ((int)item_length < length) {
6771 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6772 | }
6773 | break;
6774 |
6775 | /* XXX - make these just FT_UINT? */
6776 | case FT_UINT8:
6777 | case FT_UINT16:
6778 | case FT_UINT24:
6779 | case FT_UINT32:
6780 | case FT_UINT40:
6781 | case FT_UINT48:
6782 | case FT_UINT56:
6783 | case FT_UINT64:
6784 | /* XXX - make these just FT_INT? */
6785 | case FT_INT8:
6786 | case FT_INT16:
6787 | case FT_INT24:
6788 | case FT_INT32:
6789 | case FT_INT40:
6790 | case FT_INT48:
6791 | case FT_INT56:
6792 | case FT_INT64:
6793 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6794 | if (length < -1) {
6795 | report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6796 | }
6797 | if (length == -1) {
6798 | uint64_t dummy;
6799 | /* This can throw an exception */
6800 | /* XXX - do this without fetching the varint? */
6801 | length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6802 | if (length == 0) {
6803 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6804 | }
6805 | }
6806 | item_length = length;
6807 | break;
6808 | }
6809 |
6810 | /*
6811 | * The length is the specified length.
6812 | */
6813 | break;
6814 |
6815 | case FT_BOOLEAN:
6816 | case FT_CHAR:
6817 | case FT_IPv4:
6818 | case FT_IPXNET:
6819 | case FT_IPv6:
6820 | case FT_FCWWN:
6821 | case FT_AX25:
6822 | case FT_VINES:
6823 | case FT_ETHER:
6824 | case FT_EUI64:
6825 | case FT_GUID:
6826 | case FT_OID:
6827 | case FT_REL_OID:
6828 | case FT_SYSTEM_ID:
6829 | case FT_FLOAT:
6830 | case FT_DOUBLE:
6831 | case FT_STRING:
6832 | /*
6833 | * The length is the specified length.
6834 | */
6835 | break;
6836 |
6837 | case FT_STRINGZ:
6838 | if (length < -1) {
6839 | report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6840 | }
6841 | if (length == -1) {
6842 | /* This can throw an exception */
6843 | /* XXX - do this without fetching the string? */
6844 | wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6845 | }
6846 | item_length = length;
6847 | break;
6848 |
6849 | case FT_UINT_STRING:
6850 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6851 | item_length += n;
6852 | if ((int)item_length < length) {
6853 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6854 | }
6855 | break;
6856 |
6857 | case FT_STRINGZPAD:
6858 | case FT_STRINGZTRUNC:
6859 | case FT_ABSOLUTE_TIME:
6860 | case FT_RELATIVE_TIME:
6861 | case FT_IEEE_11073_SFLOAT:
6862 | case FT_IEEE_11073_FLOAT:
6863 | /*
6864 | * The length is the specified length.
6865 | */
6866 | break;
6867 |
6868 | default:
6869 | 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 ))
6870 | 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 ))
6871 | 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 ))
6872 | 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 ));
6873 | break;
6874 | }
6875 | return item_length;
6876 | }
6877 |
6878 | // This was arbitrarily chosen, but if you're adding 50K items to the tree
6879 | // without advancing the offset you should probably take a long, hard look
6880 | // at what you're doing.
6881 | // We *could* make this a configurable option, but I (Gerald) would like to
6882 | // avoid adding yet another nerd knob.
6883 | # define PROTO_TREE_MAX_IDLE50000 50000
6884 | static field_info *
6885 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6886 | const int start, const int item_length)
6887 | {
6888 | field_info *fi;
6889 |
6890 | FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo ->pool)), sizeof(field_info)));
6891 |
6892 | fi->hfinfo = hfinfo;
6893 | fi->start = start;
6894 | fi->start += (tvb)?tvb_raw_offset(tvb):0;
6895 | /* add the data source tvbuff */
6896 | fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6897 |
6898 | // If our start offset hasn't advanced after adding many items it probably
6899 | // means we're in a large or infinite loop.
6900 | if (fi->start > 0) {
6901 | if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6902 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6903 | DISSECTOR_ASSERT_HINT(PTREE_DATA(tree)->start_idle_count < PROTO_TREE_MAX_IDLE, fi->hfinfo->abbrev)((void) ((((tree)->tree_data)->start_idle_count < 50000 ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6903, "((tree)->tree_data)->start_idle_count < 50000" , fi->hfinfo->abbrev))));
6904 | } else {
6905 | PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6906 | PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6907 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6908 | }
6909 | }
6910 | fi->length = item_length;
6911 | fi->tree_type = -1;
6912 | fi->flags = 0;
6913 | if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6914 | /* If the tree is not visible, set the item hidden, unless we
6915 | * need the representation or length and can't fake them.
6916 | */
6917 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6918 | FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); } while(0);
6919 | }
6920 | }
6921 | fi->value = fvalue_new(fi->hfinfo->type);
6922 | fi->rep = NULL((void*)0);
6923 |
6924 | fi->appendix_start = 0;
6925 | fi->appendix_length = 0;
6926 |
6927 | fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6928 | fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6929 |
6930 | return fi;
6931 | }
6932 |
6933 | static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6934 | {
6935 | if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6936 | return 0;
6937 | }
6938 |
6939 | /* Search for field name */
6940 | char *ptr = strstr(representation, hfinfo->name);
6941 | if (!ptr) {
6942 | return 0;
6943 | }
6944 |
6945 | /* Check if field name ends with the ": " delimiter */
6946 | ptr += strlen(hfinfo->name);
6947 | if (strncmp(ptr, ": ", 2) == 0) {
6948 | ptr += 2;
6949 | }
6950 |
6951 | /* Return offset to after field name */
6952 | return ptr - representation;
6953 | }
6954 |
6955 | static size_t label_find_name_pos(const item_label_t *rep)
6956 | {
6957 | size_t name_pos = 0;
6958 |
6959 | /* If the value_pos is too small or too large, we can't find the expected format */
6960 | if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6961 | return 0;
6962 | }
6963 |
6964 | /* Check if the format looks like "label: value", then set name_pos before ':'. */
6965 | if (rep->representation[rep->value_pos-2] == ':') {
6966 | name_pos = rep->value_pos - 2;
6967 | }
6968 |
6969 | return name_pos;
6970 | }
6971 |
6972 | /* If the protocol tree is to be visible, set the representation of a
6973 | proto_tree entry with the name of the field for the item and with
6974 | the value formatted with the supplied printf-style format and
6975 | argument list. */
6976 | static void
6977 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6978 | {
6979 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6979, __func__, "assertion failed: %s", "pi" ); } while (0);
6980 |
6981 | /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6982 | * items string representation */
6983 | if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6984 | size_t name_pos, ret = 0;
6985 | char *str;
6986 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6987 | const header_field_info *hf;
6988 |
6989 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 6989, "fi"))));
6990 |
6991 | hf = fi->hfinfo;
6992 |
6993 | 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;;
6994 | 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)))) {
6995 | uint64_t val;
6996 | char *p;
6997 |
6998 | 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))
6999 | val = fvalue_get_uinteger(fi->value);
7000 | else
7001 | val = fvalue_get_uinteger64(fi->value);
7002 |
7003 | val <<= hfinfo_bitshift(hf);
7004 |
7005 | p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7006 | ret = (p - fi->rep->representation);
7007 | }
7008 |
7009 | /* put in the hf name */
7010 | name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf-> name, 0);
7011 |
7012 | ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": " , 0);
7013 | /* If possible, Put in the value of the string */
7014 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7015 | 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" , 7015, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7016 | fi->rep->value_pos = ret;
7017 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
7018 | if (ret >= ITEM_LABEL_LENGTH240) {
7019 | /* Uh oh, we don't have enough room. Tell the user
7020 | * that the field is truncated.
7021 | */
7022 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7023 | }
7024 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7025 | }
7026 | }
7027 |
7028 | /* If the protocol tree is to be visible, set the representation of a
7029 | proto_tree entry with the representation formatted with the supplied
7030 | printf-style format and argument list. */
7031 | static void
7032 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7033 | {
7034 | size_t ret; /*tmp return value */
7035 | char *str;
7036 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7037 |
7038 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7038, "fi"))));
7039 |
7040 | if (!proto_item_is_hidden(pi)) {
7041 | 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;;
7042 |
7043 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7044 | 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" , 7044, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7045 | fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7046 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7047 | if (ret >= ITEM_LABEL_LENGTH240) {
7048 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7049 | size_t name_pos = label_find_name_pos(fi->rep);
7050 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7051 | }
7052 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7053 | }
7054 | }
7055 |
7056 | static int
7057 | proto_strlcpy(char *dest, const char *src, size_t dest_size)
7058 | {
7059 | if (dest_size == 0) return 0;
7060 |
7061 | size_t res = g_strlcpy(dest, src, dest_size);
7062 |
7063 | /* At most dest_size - 1 characters will be copied
7064 | * (unless dest_size is 0). */
7065 | if (res >= dest_size)
7066 | res = dest_size - 1;
7067 | return (int) res;
7068 | }
7069 |
7070 | static header_field_info *
7071 | hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7072 | {
7073 | header_field_info *dup_hfinfo;
7074 |
7075 | if (hfinfo->same_name_prev_id == -1)
7076 | return NULL((void*)0);
7077 | 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", 7077 , __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", 7077, "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", 7077, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo ->same_name_prev_id];;
7078 | return dup_hfinfo;
7079 | }
7080 |
7081 | static void
7082 | hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7083 | {
7084 | g_free(last_field_name);
7085 | last_field_name = NULL((void*)0);
7086 |
7087 | if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7088 | /* No hfinfo with the same name */
7089 | wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7090 | return;
7091 | }
7092 |
7093 | if (hfinfo->same_name_next) {
7094 | hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7095 | }
7096 |
7097 | if (hfinfo->same_name_prev_id != -1) {
7098 | header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7099 | same_name_prev->same_name_next = hfinfo->same_name_next;
7100 | if (!hfinfo->same_name_next) {
7101 | /* It's always the latest added hfinfo which is stored in gpa_name_map */
7102 | wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7103 | }
7104 | }
7105 | }
7106 |
7107 | int
7108 | proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7109 | {
7110 | const header_field_info *hfinfo = finfo->hfinfo;
7111 | int label_len = 0;
7112 | char *tmp_str;
7113 | const char *str;
7114 | const uint8_t *bytes;
7115 | uint32_t number;
7116 | uint64_t number64;
7117 | const char *hf_str_val;
7118 | char number_buf[NUMBER_LABEL_LENGTH80];
7119 | const char *number_out;
7120 | address addr;
7121 | const ipv4_addr_and_mask *ipv4;
7122 | const ipv6_addr_and_prefix *ipv6;
7123 |
7124 | switch (hfinfo->type) {
7125 |
7126 | case FT_NONE:
7127 | case FT_PROTOCOL:
7128 | return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7129 |
7130 | case FT_UINT_BYTES:
7131 | case FT_BYTES:
7132 | tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7133 | hfinfo,
7134 | fvalue_get_bytes_data(finfo->value),
7135 | (unsigned)fvalue_length2(finfo->value),
7136 | label_str_size);
7137 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7138 | wmem_free(NULL((void*)0), tmp_str);
7139 | break;
7140 |
7141 | case FT_ABSOLUTE_TIME:
7142 | {
7143 | const nstime_t *value = fvalue_get_time(finfo->value);
7144 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7145 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7146 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7147 | }
7148 | if (hfinfo->strings) {
7149 | const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7150 | if (time_string != NULL((void*)0)) {
7151 | label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7152 | break;
7153 | }
7154 | }
7155 | tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7156 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7157 | wmem_free(NULL((void*)0), tmp_str);
7158 | break;
7159 | }
7160 |
7161 | case FT_RELATIVE_TIME:
7162 | tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7163 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7164 | wmem_free(NULL((void*)0), tmp_str);
7165 | break;
7166 |
7167 | case FT_BOOLEAN:
7168 | number64 = fvalue_get_uinteger64(finfo->value);
7169 | label_len = proto_strlcpy(display_label_str,
7170 | tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7171 | break;
7172 |
7173 | case FT_CHAR:
7174 | number = fvalue_get_uinteger(finfo->value);
7175 |
7176 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7177 | char tmp[ITEM_LABEL_LENGTH240];
7178 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7179 |
7180 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7180, "fmtfunc"))));
7181 | fmtfunc(tmp, number);
7182 |
7183 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7184 |
7185 | } else if (hfinfo->strings) {
7186 | number_out = hf_try_val_to_str(number, hfinfo);
7187 |
7188 | if (!number_out) {
7189 | number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7190 | }
7191 |
7192 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7193 |
7194 | } else {
7195 | number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7196 |
7197 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7198 | }
7199 |
7200 | break;
7201 |
7202 | /* XXX - make these just FT_NUMBER? */
7203 | case FT_INT8:
7204 | case FT_INT16:
7205 | case FT_INT24:
7206 | case FT_INT32:
7207 | case FT_UINT8:
7208 | case FT_UINT16:
7209 | case FT_UINT24:
7210 | case FT_UINT32:
7211 | case FT_FRAMENUM:
7212 | hf_str_val = NULL((void*)0);
7213 | 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 )) ?
7214 | (uint32_t) fvalue_get_sinteger(finfo->value) :
7215 | fvalue_get_uinteger(finfo->value);
7216 |
7217 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7218 | char tmp[ITEM_LABEL_LENGTH240];
7219 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7220 |
7221 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7221, "fmtfunc"))));
7222 | fmtfunc(tmp, number);
7223 |
7224 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7225 |
7226 | } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7227 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7228 | number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7229 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7230 | hf_str_val = hf_try_val_to_str(number, hfinfo);
7231 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7232 | } else {
7233 | number_out = hf_try_val_to_str(number, hfinfo);
7234 |
7235 | if (!number_out) {
7236 | number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7237 | }
7238 |
7239 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7240 | }
7241 | } else {
7242 | number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7243 |
7244 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7245 | }
7246 |
7247 | break;
7248 |
7249 | case FT_INT40:
7250 | case FT_INT48:
7251 | case FT_INT56:
7252 | case FT_INT64:
7253 | case FT_UINT40:
7254 | case FT_UINT48:
7255 | case FT_UINT56:
7256 | case FT_UINT64:
7257 | hf_str_val = NULL((void*)0);
7258 | 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 )) ?
7259 | (uint64_t) fvalue_get_sinteger64(finfo->value) :
7260 | fvalue_get_uinteger64(finfo->value);
7261 |
7262 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7263 | char tmp[ITEM_LABEL_LENGTH240];
7264 | custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7265 |
7266 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 7266, "fmtfunc64" ))));
7267 | fmtfunc64(tmp, number64);
7268 |
7269 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7270 | } else if (hfinfo->strings) {
7271 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7272 | number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7273 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7274 | hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7275 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7276 | } else {
7277 | number_out = hf_try_val64_to_str(number64, hfinfo);
7278 |
7279 | if (!number_out)
7280 | number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7281 |
7282 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7283 | }
7284 | } else {
7285 | number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7286 |
7287 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7288 | }
7289 |
7290 | break;
7291 |
7292 | case FT_EUI64:
7293 | set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7294 | tmp_str = address_to_display(NULL((void*)0), &addr);
7295 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7296 | wmem_free(NULL((void*)0), tmp_str);
7297 | break;
7298 |
7299 | case FT_IPv4:
7300 | ipv4 = fvalue_get_ipv4(finfo->value);
7301 | //XXX: Should we ignore the mask?
7302 | set_address_ipv4(&addr, ipv4);
7303 | tmp_str = address_to_display(NULL((void*)0), &addr);
7304 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7305 | wmem_free(NULL((void*)0), tmp_str);
7306 | free_address(&addr);
7307 | break;
7308 |
7309 | case FT_IPv6:
7310 | ipv6 = fvalue_get_ipv6(finfo->value);
7311 | set_address_ipv6(&addr, ipv6);
7312 | tmp_str = address_to_display(NULL((void*)0), &addr);
7313 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7314 | wmem_free(NULL((void*)0), tmp_str);
7315 | free_address(&addr);
7316 | break;
7317 |
7318 | case FT_FCWWN:
7319 | set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7320 | tmp_str = address_to_display(NULL((void*)0), &addr);
7321 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7322 | wmem_free(NULL((void*)0), tmp_str);
7323 | break;
7324 |
7325 | case FT_ETHER:
7326 | set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7327 | tmp_str = address_to_display(NULL((void*)0), &addr);
7328 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7329 | wmem_free(NULL((void*)0), tmp_str);
7330 | break;
7331 |
7332 | case FT_GUID:
7333 | tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7334 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7335 | wmem_free(NULL((void*)0), tmp_str);
7336 | break;
7337 |
7338 | case FT_REL_OID:
7339 | bytes = fvalue_get_bytes_data(finfo->value);
7340 | tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7341 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7342 | wmem_free(NULL((void*)0), tmp_str);
7343 | break;
7344 |
7345 | case FT_OID:
7346 | bytes = fvalue_get_bytes_data(finfo->value);
7347 | tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7348 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7349 | wmem_free(NULL((void*)0), tmp_str);
7350 | break;
7351 |
7352 | case FT_SYSTEM_ID:
7353 | bytes = fvalue_get_bytes_data(finfo->value);
7354 | tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7355 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7356 | wmem_free(NULL((void*)0), tmp_str);
7357 | break;
7358 |
7359 | case FT_FLOAT:
7360 | case FT_DOUBLE:
7361 | label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7362 | break;
7363 |
7364 | case FT_IEEE_11073_SFLOAT:
7365 | case FT_IEEE_11073_FLOAT:
7366 | label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7367 | break;
7368 |
7369 | case FT_STRING:
7370 | case FT_STRINGZ:
7371 | case FT_UINT_STRING:
7372 | case FT_STRINGZPAD:
7373 | case FT_STRINGZTRUNC:
7374 | str = fvalue_get_string(finfo->value);
7375 | label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7376 | if (label_len >= label_str_size) {
7377 | /* Truncation occurred. Get the real length
7378 | * copied (not including '\0') */
7379 | label_len = label_str_size ? label_str_size - 1 : 0;
7380 | }
7381 | break;
7382 |
7383 | default:
7384 | /* First try ftype string representation */
7385 | tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7386 | if (!tmp_str) {
7387 | /* Default to show as bytes */
7388 | bytes = fvalue_get_bytes_data(finfo->value);
7389 | tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo-> value), 36);
7390 | }
7391 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7392 | wmem_free(NULL((void*)0), tmp_str);
7393 | break;
7394 | }
7395 | return label_len;
7396 | }
7397 |
7398 | const char *
7399 | proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7400 | char *result, char *expr, const int size)
7401 | {
7402 | int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7403 | GPtrArray *finfos;
7404 | field_info *finfo = NULL((void*)0);
7405 | header_field_info* hfinfo;
7406 | const char *abbrev = NULL((void*)0);
7407 |
7408 | char *str;
7409 | col_custom_t *field_idx;
7410 | int field_id;
7411 | int ii = 0;
7412 |
7413 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7413, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7414 | while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7415 | field_id = field_idx->field_id;
7416 | if (field_id == 0) {
7417 | GPtrArray *fvals = NULL((void*)0);
7418 | bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7419 | if (fvals != NULL((void*)0)) {
7420 |
7421 | // XXX - Handling occurrences is unusual when more
7422 | // than one field is involved, e.g. there's four
7423 | // results for tcp.port + tcp.port. We may really
7424 | // want to apply it to the operands, not the output.
7425 | // Note that occurrences are not quite the same as
7426 | // the layer operator (should the grammar support
7427 | // both?)
7428 | /* Calculate single index or set outer boundaries */
7429 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7430 | if (occurrence < 0) {
7431 | i = occurrence + len;
7432 | last = i;
7433 | } else if (occurrence > 0) {
7434 | i = occurrence - 1;
7435 | last = i;
7436 | } else {
7437 | i = 0;
7438 | last = len - 1;
7439 | }
7440 | if (i < 0 || i >= len) {
7441 | g_ptr_array_unref(fvals);
7442 | continue;
7443 | }
7444 | for (; i <= last; i++) {
7445 | /* XXX - We could have a "resolved" result
7446 | * for types where the value depends only
7447 | * on the type, e.g. FT_IPv4, and not on
7448 | * hfinfo->strings. Supporting the latter
7449 | * requires knowing which hfinfo matched
7450 | * if there are multiple with the same
7451 | * abbreviation. In any case, we need to
7452 | * know the expected return type of the
7453 | * field expression.
7454 | */
7455 | str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7456 | if (offset_r && (offset_r < (size - 1)))
7457 | result[offset_r++] = ',';
7458 | if (offset_e && (offset_e < (size - 1)))
7459 | expr[offset_e++] = ',';
7460 | offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7461 | // col_{add,append,set}_* calls ws_label_strcpy
7462 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7463 |
7464 | g_free(str);
7465 | }
7466 | g_ptr_array_unref(fvals);
7467 | } else if (passed) {
7468 | // XXX - Occurrence doesn't make sense for a test
7469 | // output, it should be applied to the operands.
7470 | if (offset_r && (offset_r < (size - 1)))
7471 | result[offset_r++] = ',';
7472 | if (offset_e && (offset_e < (size - 1)))
7473 | expr[offset_e++] = ',';
7474 | /* Prevent multiple check marks */
7475 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7476 | offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7477 | } else {
7478 | result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7479 | }
7480 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7481 | offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7482 | } else {
7483 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7484 | }
7485 | }
7486 | continue;
7487 | }
7488 | 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", 7488 , __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", 7488, "(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", 7488, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7489 |
7490 | /* do we need to rewind ? */
7491 | if (!hfinfo)
7492 | return "";
7493 |
7494 | if (occurrence < 0) {
7495 | /* Search other direction */
7496 | while (hfinfo->same_name_prev_id != -1) {
7497 | 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", 7497 , __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", 7497, "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", 7497, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7498 | }
7499 | }
7500 |
7501 | prev_len = 0; /* Reset handled occurrences */
7502 |
7503 | while (hfinfo) {
7504 | finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7505 |
7506 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7507 | if (occurrence < 0) {
7508 | hfinfo = hfinfo->same_name_next;
7509 | } else {
7510 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7511 | }
7512 | continue;
7513 | }
7514 |
7515 | /* Are there enough occurrences of the field? */
7516 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7517 | if (occurrence < 0) {
7518 | hfinfo = hfinfo->same_name_next;
7519 | } else {
7520 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7521 | }
7522 | prev_len += len;
7523 | continue;
7524 | }
7525 |
7526 | /* Calculate single index or set outer boundaries */
7527 | if (occurrence < 0) {
7528 | i = occurrence + len + prev_len;
7529 | last = i;
7530 | } else if (occurrence > 0) {
7531 | i = occurrence - 1 - prev_len;
7532 | last = i;
7533 | } else {
7534 | i = 0;
7535 | last = len - 1;
7536 | }
7537 |
7538 | prev_len += len; /* Count handled occurrences */
7539 |
7540 | while (i <= last) {
7541 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7542 |
7543 | if (offset_r && (offset_r < (size - 1)))
7544 | result[offset_r++] = ',';
7545 |
7546 | if (display_details) {
7547 | char representation[ITEM_LABEL_LENGTH240];
7548 | size_t offset = 0;
7549 |
7550 | if (finfo->rep && finfo->rep->value_len) {
7551 | g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7552 | MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo-> rep->value_len + 1) : (240)));
7553 | } else {
7554 | proto_item_fill_label(finfo, representation, &offset);
7555 | }
7556 | offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7557 | } else {
7558 | switch (hfinfo->type) {
7559 |
7560 | case FT_NONE:
7561 | case FT_PROTOCOL:
7562 | /* Prevent multiple check marks */
7563 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7564 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7565 | } else {
7566 | result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7567 | }
7568 | break;
7569 |
7570 | default:
7571 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7572 | break;
7573 | }
7574 | }
7575 |
7576 | if (offset_e && (offset_e < (size - 1)))
7577 | expr[offset_e++] = ',';
7578 |
7579 | 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 )))) {
7580 | const char *hf_str_val;
7581 | /* Integer types with BASE_NONE never get the numeric value. */
7582 | if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16 || (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32 )) {
7583 | hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7584 | } 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 )) {
7585 | hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7586 | } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48 || (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64 )) {
7587 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7588 | } else { // if (FT_IS_UINT64(hfinfo->type)) {
7589 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7590 | }
7591 | snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7592 | offset_e = (int)strlen(expr);
7593 | } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7594 | /* Prevent multiple check marks */
7595 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7596 | offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7597 | } else {
7598 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7599 | }
7600 | } else {
7601 | str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7602 | // col_{add,append,set}_* calls ws_label_strcpy
7603 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7604 | wmem_free(NULL((void*)0), str);
7605 | }
7606 | i++;
7607 | }
7608 |
7609 | /* XXX: Why is only the first abbreviation returned for a multifield
7610 | * custom column? */
7611 | if (!abbrev) {
7612 | /* Store abbrev for return value */
7613 | abbrev = hfinfo->abbrev;
7614 | }
7615 |
7616 | if (occurrence == 0) {
7617 | /* Fetch next hfinfo with same name (abbrev) */
7618 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7619 | } else {
7620 | hfinfo = NULL((void*)0);
7621 | }
7622 | }
7623 | }
7624 |
7625 | if (offset_r >= (size - 1)) {
7626 | mark_truncated(result, 0, size, NULL((void*)0));
7627 | }
7628 | if (offset_e >= (size - 1)) {
7629 | mark_truncated(expr, 0, size, NULL((void*)0));
7630 | }
7631 | return abbrev ? abbrev : "";
7632 | }
7633 |
7634 | char *
7635 | proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7636 | {
7637 | int len, prev_len, last, i;
7638 | GPtrArray *finfos;
7639 | field_info *finfo = NULL((void*)0);
7640 | header_field_info* hfinfo;
7641 |
7642 | char *filter = NULL((void*)0);
7643 | GPtrArray *filter_array;
7644 |
7645 | col_custom_t *col_custom;
7646 | int field_id;
7647 |
7648 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7648, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7649 | filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7650 | for (GSList *iter = field_ids; iter; iter = iter->next) {
7651 | col_custom = (col_custom_t*)iter->data;
7652 | field_id = col_custom->field_id;
7653 | if (field_id == 0) {
7654 | GPtrArray *fvals = NULL((void*)0);
7655 | bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7656 | if (fvals != NULL((void*)0)) {
7657 | // XXX - Handling occurrences is unusual when more
7658 | // than one field is involved, e.g. there's four
7659 | // results for tcp.port + tcp.port. We really
7660 | // want to apply it to the operands, not the output.
7661 | /* Calculate single index or set outer boundaries */
7662 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7663 | if (occurrence < 0) {
7664 | i = occurrence + len;
7665 | last = i;
7666 | } else if (occurrence > 0) {
7667 | i = occurrence - 1;
7668 | last = i;
7669 | } else {
7670 | i = 0;
7671 | last = len - 1;
7672 | }
7673 | if (i < 0 || i >= len) {
7674 | g_ptr_array_unref(fvals);
7675 | continue;
7676 | }
7677 | for (; i <= last; i++) {
7678 | /* XXX - Should multiple values for one
7679 | * field use set membership to reduce
7680 | * verbosity, here and below? */
7681 | char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7682 | filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7683 | wmem_free(NULL((void*)0), str);
7684 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7685 | g_ptr_array_add(filter_array, filter);
7686 | }
7687 | }
7688 | g_ptr_array_unref(fvals);
7689 | } else if (passed) {
7690 | filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7691 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7692 | g_ptr_array_add(filter_array, filter);
7693 | }
7694 | } else {
7695 | filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7696 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7697 | g_ptr_array_add(filter_array, filter);
7698 | }
7699 | }
7700 | continue;
7701 | }
7702 |
7703 | 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", 7703 , __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", 7703, "(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", 7703, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7704 |
7705 | /* do we need to rewind ? */
7706 | if (!hfinfo)
7707 | return NULL((void*)0);
7708 |
7709 | if (occurrence < 0) {
7710 | /* Search other direction */
7711 | while (hfinfo->same_name_prev_id != -1) {
7712 | 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", 7712 , __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", 7712, "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", 7712, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7713 | }
7714 | }
7715 |
7716 | prev_len = 0; /* Reset handled occurrences */
7717 |
7718 | while (hfinfo) {
7719 | finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7720 |
7721 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7722 | if (occurrence < 0) {
7723 | hfinfo = hfinfo->same_name_next;
7724 | } else {
7725 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7726 | }
7727 | continue;
7728 | }
7729 |
7730 | /* Are there enough occurrences of the field? */
7731 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7732 | if (occurrence < 0) {
7733 | hfinfo = hfinfo->same_name_next;
7734 | } else {
7735 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7736 | }
7737 | prev_len += len;
7738 | continue;
7739 | }
7740 |
7741 | /* Calculate single index or set outer boundaries */
7742 | if (occurrence < 0) {
7743 | i = occurrence + len + prev_len;
7744 | last = i;
7745 | } else if (occurrence > 0) {
7746 | i = occurrence - 1 - prev_len;
7747 | last = i;
7748 | } else {
7749 | i = 0;
7750 | last = len - 1;
7751 | }
7752 |
7753 | prev_len += len; /* Count handled occurrences */
7754 |
7755 | while (i <= last) {
7756 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7757 |
7758 | filter = proto_construct_match_selected_string(finfo, edt);
7759 | if (filter) {
7760 | /* Only add the same expression once (especially for FT_PROTOCOL).
7761 | * The ptr array doesn't have NULL entries so g_str_equal is fine.
7762 | */
7763 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7764 | g_ptr_array_add(filter_array, filter);
7765 | }
7766 | }
7767 | i++;
7768 | }
7769 |
7770 | if (occurrence == 0) {
7771 | /* Fetch next hfinfo with same name (abbrev) */
7772 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7773 | } else {
7774 | hfinfo = NULL((void*)0);
7775 | }
7776 | }
7777 | }
7778 |
7779 | g_ptr_array_add(filter_array, NULL((void*)0));
7780 |
7781 | /* XXX: Should this be || or && ? */
7782 | char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7783 |
7784 | g_ptr_array_free(filter_array, true1);
7785 |
7786 | return output;
7787 | }
7788 |
7789 | /* Set text of proto_item after having already been created. */
7790 | void
7791 | proto_item_set_text(proto_item *pi, const char *format, ...)
7792 | {
7793 | field_info *fi = NULL((void*)0);
7794 | va_list ap;
7795 |
7796 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7797 |
7798 | fi = PITEM_FINFO(pi)((pi)->finfo);
7799 | if (fi == NULL((void*)0))
7800 | return;
7801 |
7802 | if (fi->rep) {
7803 | ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep );;
7804 | fi->rep = NULL((void*)0);
7805 | }
7806 |
7807 | va_start(ap, format)__builtin_va_start(ap, format);
7808 | proto_tree_set_representation(pi, format, ap);
7809 | va_end(ap)__builtin_va_end(ap);
7810 | }
7811 |
7812 | /* Append to text of proto_item after having already been created. */
7813 | void
7814 | proto_item_append_text(proto_item *pi, const char *format, ...)
7815 | {
7816 | field_info *fi = NULL((void*)0);
7817 | size_t curlen;
7818 | char *str;
7819 | va_list ap;
7820 |
7821 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7822 |
7823 | fi = PITEM_FINFO(pi)((pi)->finfo);
7824 | if (fi == NULL((void*)0)) {
7825 | return;
7826 | }
7827 |
7828 | if (!proto_item_is_hidden(pi)) {
7829 | /*
7830 | * If we don't already have a representation,
7831 | * generate the default representation.
7832 | */
7833 | if (fi->rep == NULL((void*)0)) {
7834 | 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;;
7835 | proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7836 | /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7837 | if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7838 | (strncmp(format, ": ", 2) == 0)) {
7839 | fi->rep->value_pos += 2;
7840 | }
7841 | }
7842 | if (fi->rep) {
7843 | curlen = strlen(fi->rep->representation);
7844 | /* curlen doesn't include the \0 byte.
7845 | * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7846 | * the representation has already been truncated (of an up
7847 | * to 4 byte UTF-8 character) or is just at the maximum length
7848 | * unless we search for " [truncated]" (which may not be
7849 | * at the start.)
7850 | * It's safer to do nothing.
7851 | */
7852 | if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7853 | va_start(ap, format)__builtin_va_start(ap, format);
7854 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7855 | va_end(ap)__builtin_va_end(ap);
7856 | 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" , 7856, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7857 | /* Keep fi->rep->value_pos */
7858 | curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7859 | if (curlen >= ITEM_LABEL_LENGTH240) {
7860 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7861 | size_t name_pos = label_find_name_pos(fi->rep);
7862 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7863 | }
7864 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7865 | }
7866 | }
7867 | }
7868 | }
7869 |
7870 | /* Prepend to text of proto_item after having already been created. */
7871 | void
7872 | proto_item_prepend_text(proto_item *pi, const char *format, ...)
7873 | {
7874 | field_info *fi = NULL((void*)0);
7875 | size_t pos;
7876 | char representation[ITEM_LABEL_LENGTH240];
7877 | char *str;
7878 | va_list ap;
7879 |
7880 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7881 |
7882 | fi = PITEM_FINFO(pi)((pi)->finfo);
7883 | if (fi == NULL((void*)0)) {
7884 | return;
7885 | }
7886 |
7887 | if (!proto_item_is_hidden(pi)) {
7888 | /*
7889 | * If we don't already have a representation,
7890 | * generate the default representation.
7891 | */
7892 | if (fi->rep == NULL((void*)0)) {
7893 | 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;;
7894 | proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7895 | } else
7896 | (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7897 |
7898 | va_start(ap, format)__builtin_va_start(ap, format);
7899 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7900 | va_end(ap)__builtin_va_end(ap);
7901 | 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" , 7901, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7902 | fi->rep->value_pos += strlen(str);
7903 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7904 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7905 | /* XXX: As above, if the old representation is close to the label
7906 | * length, it might already be marked as truncated. */
7907 | if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7908 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7909 | size_t name_pos = label_find_name_pos(fi->rep);
7910 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7911 | }
7912 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7913 | }
7914 | }
7915 |
7916 | static void
7917 | finfo_set_len(field_info *fi, const int length)
7918 | {
7919 | int length_remaining;
7920 |
7921 | DISSECTOR_ASSERT_HINT(length >= 0, fi->hfinfo->abbrev)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 7921, "length >= 0", fi->hfinfo->abbrev))));
7922 | length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7923 | if (length > length_remaining)
7924 | fi->length = length_remaining;
7925 | else
7926 | fi->length = length;
7927 |
7928 | /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7929 | if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7930 | fvalue_set_protocol_length(fi->value, fi->length);
7931 | }
7932 |
7933 | /*
7934 | * You cannot just make the "len" field of a GByteArray
7935 | * larger, if there's no data to back that length;
7936 | * you can only make it smaller.
7937 | */
7938 | if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7939 | GBytes *bytes = fvalue_get_bytes(fi->value);
7940 | size_t size;
7941 | const void *data = g_bytes_get_data(bytes, &size);
7942 | if ((size_t)fi->length <= size) {
7943 | fvalue_set_bytes_data(fi->value, data, fi->length);
7944 | }
7945 | g_bytes_unref(bytes);
7946 | }
7947 | }
7948 |
7949 | void
7950 | proto_item_set_len(proto_item *pi, const int length)
7951 | {
7952 | field_info *fi;
7953 |
7954 | if (pi == NULL((void*)0))
7955 | return;
7956 |
7957 | fi = PITEM_FINFO(pi)((pi)->finfo);
7958 | if (fi == NULL((void*)0))
7959 | return;
7960 |
7961 | finfo_set_len(fi, length);
7962 | }
7963 |
7964 | /*
7965 | * Sets the length of the item based on its start and on the specified
7966 | * offset, which is the offset past the end of the item; as the start
7967 | * in the item is relative to the beginning of the data source tvbuff,
7968 | * we need to pass in a tvbuff - the end offset is relative to the beginning
7969 | * of that tvbuff.
7970 | */
7971 | void
7972 | proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7973 | {
7974 | field_info *fi;
7975 | int length;
7976 |
7977 | if (pi == NULL((void*)0))
7978 | return;
7979 |
7980 | fi = PITEM_FINFO(pi)((pi)->finfo);
7981 | if (fi == NULL((void*)0))
7982 | return;
7983 |
7984 | end += tvb_raw_offset(tvb);
7985 | DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7985, "end >= fi->start" ))));
7986 | length = end - fi->start;
7987 |
7988 | finfo_set_len(fi, length);
7989 | }
7990 |
7991 | int
7992 | proto_item_get_len(const proto_item *pi)
7993 | {
7994 | field_info *fi;
7995 |
7996 | if (!pi)
7997 | return -1;
7998 | fi = PITEM_FINFO(pi)((pi)->finfo);
7999 | return fi ? fi->length : -1;
8000 | }
8001 |
8002 | void
8003 | proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8004 | if (!ti) {
8005 | return;
8006 | }
8007 | 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);
8008 | 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);
8009 | }
8010 |
8011 | char *
8012 | proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8013 | {
8014 | field_info *fi;
8015 |
8016 | if (!pi)
8017 | return wmem_strdup(scope, "");
8018 | fi = PITEM_FINFO(pi)((pi)->finfo);
8019 | if (!fi)
8020 | return wmem_strdup(scope, "");
8021 | DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8021, "fi->hfinfo != ((void*)0)" ))));
8022 | return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8023 | }
8024 |
8025 | proto_tree *
8026 | proto_tree_create_root(packet_info *pinfo)
8027 | {
8028 | proto_node *pnode;
8029 |
8030 | /* Initialize the proto_node */
8031 | pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8032 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
8033 | pnode->parent = NULL((void*)0);
8034 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8035 | pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8036 |
8037 | /* Make sure we can access pinfo everywhere */
8038 | pnode->tree_data->pinfo = pinfo;
8039 |
8040 | /* Don't initialize the tree_data_t. Wait until we know we need it */
8041 | pnode->tree_data->interesting_hfids = NULL((void*)0);
8042 |
8043 | /* Set the default to false so it's easier to
8044 | * find errors; if we expect to see the protocol tree
8045 | * but for some reason the default 'visible' is not
8046 | * changed, then we'll find out very quickly. */
8047 | pnode->tree_data->visible = false0;
8048 |
8049 | /* Make sure that we fake protocols (if possible) */
8050 | pnode->tree_data->fake_protocols = true1;
8051 |
8052 | /* Keep track of the number of children */
8053 | pnode->tree_data->count = 0;
8054 |
8055 | /* Initialize our loop checks */
8056 | pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8057 | pnode->tree_data->max_start = 0;
8058 | pnode->tree_data->start_idle_count = 0;
8059 |
8060 | return (proto_tree *)pnode;
8061 | }
8062 |
8063 |
8064 | /* "prime" a proto_tree with a single hfid that a dfilter
8065 | * is interested in. */
8066 | void
8067 | proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8068 | {
8069 | header_field_info *hfinfo;
8070 |
8071 | 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", 8071, __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", 8071, "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", 8071, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8072 | /* this field is referenced by a filter so increase the refcount.
8073 | also increase the refcount for the parent, i.e the protocol.
8074 | Don't increase the refcount if we're already printing the
8075 | type, as that is a superset of direct reference.
8076 | */
8077 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8078 | hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8079 | }
8080 | /* only increase the refcount if there is a parent.
8081 | if this is a protocol and not a field then parent will be -1
8082 | and there is no parent to add any refcounting for.
8083 | */
8084 | if (hfinfo->parent != -1) {
8085 | header_field_info *parent_hfinfo;
8086 | 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", 8086 , __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", 8086, "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", 8086, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8087 |
8088 | /* Mark parent as indirectly referenced unless it is already directly
8089 | * referenced, i.e. the user has specified the parent in a filter.
8090 | */
8091 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8092 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8093 | }
8094 | }
8095 |
8096 | /* "prime" a proto_tree with a single hfid that a dfilter
8097 | * is interested in. */
8098 | void
8099 | proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8100 | {
8101 | header_field_info *hfinfo;
8102 |
8103 | 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", 8103, __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", 8103, "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", 8103, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8104 | /* this field is referenced by an (output) filter so increase the refcount.
8105 | also increase the refcount for the parent, i.e the protocol.
8106 | */
8107 | hfinfo->ref_type = HF_REF_TYPE_PRINT;
8108 | /* only increase the refcount if there is a parent.
8109 | if this is a protocol and not a field then parent will be -1
8110 | and there is no parent to add any refcounting for.
8111 | */
8112 | if (hfinfo->parent != -1) {
8113 | header_field_info *parent_hfinfo;
8114 | 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", 8114 , __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", 8114, "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", 8114, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8115 |
8116 | /* Mark parent as indirectly referenced unless it is already directly
8117 | * referenced, i.e. the user has specified the parent in a filter.
8118 | */
8119 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8120 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8121 | }
8122 | }
8123 |
8124 | proto_tree *
8125 | proto_item_add_subtree(proto_item *pi, const int idx) {
8126 | field_info *fi;
8127 |
8128 | if (!pi)
8129 | return NULL((void*)0);
8130 |
8131 | 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", 8131, "idx >= 0 && idx < num_tree_types" ))));
8132 |
8133 | fi = PITEM_FINFO(pi)((pi)->finfo);
8134 | if (!fi)
8135 | return (proto_tree *)pi;
8136 |
8137 | fi->tree_type = idx;
8138 |
8139 | return (proto_tree *)pi;
8140 | }
8141 |
8142 | proto_tree *
8143 | proto_item_get_subtree(proto_item *pi) {
8144 | field_info *fi;
8145 |
8146 | if (!pi)
8147 | return NULL((void*)0);
8148 | fi = PITEM_FINFO(pi)((pi)->finfo);
8149 | if ( (fi) && (fi->tree_type == -1) )
8150 | return NULL((void*)0);
8151 | return (proto_tree *)pi;
8152 | }
8153 |
8154 | proto_item *
8155 | proto_item_get_parent(const proto_item *ti) {
8156 | if (!ti)
8157 | return NULL((void*)0);
8158 | return ti->parent;
8159 | }
8160 |
8161 | proto_item *
8162 | proto_item_get_parent_nth(proto_item *ti, int gen) {
8163 | if (!ti)
8164 | return NULL((void*)0);
8165 | while (gen--) {
8166 | ti = ti->parent;
8167 | if (!ti)
8168 | return NULL((void*)0);
8169 | }
8170 | return ti;
8171 | }
8172 |
8173 |
8174 | proto_item *
8175 | proto_tree_get_parent(proto_tree *tree) {
8176 | if (!tree)
8177 | return NULL((void*)0);
8178 | return (proto_item *)tree;
8179 | }
8180 |
8181 | proto_tree *
8182 | proto_tree_get_parent_tree(proto_tree *tree) {
8183 | if (!tree)
8184 | return NULL((void*)0);
8185 |
8186 | /* we're the root tree, there's no parent
8187 | return ourselves so the caller has at least a tree to attach to */
8188 | if (!tree->parent)
8189 | return tree;
8190 |
8191 | return (proto_tree *)tree->parent;
8192 | }
8193 |
8194 | proto_tree *
8195 | proto_tree_get_root(proto_tree *tree) {
8196 | if (!tree)
8197 | return NULL((void*)0);
8198 | while (tree->parent) {
8199 | tree = tree->parent;
8200 | }
8201 | return tree;
8202 | }
8203 |
8204 | void
8205 | proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8206 | proto_item *item_to_move)
8207 | {
8208 | /* This function doesn't generate any values. It only reorganizes the protocol tree
8209 | * so we can bail out immediately if it isn't visible. */
8210 | if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8211 | return;
8212 |
8213 | 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", 8213, "item_to_move->parent == tree" ))));
8214 | 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", 8214, "fixed_item->parent == tree" ))));
8215 |
8216 | /*** cut item_to_move out ***/
8217 |
8218 | /* is item_to_move the first? */
8219 | if (tree->first_child == item_to_move) {
8220 | /* simply change first child to next */
8221 | tree->first_child = item_to_move->next;
8222 |
8223 | 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", 8223, "tree->last_child != item_to_move" ))));
8224 | } else {
8225 | proto_item *curr_item;
8226 | /* find previous and change it's next */
8227 | for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8228 | if (curr_item->next == item_to_move) {
8229 | break;
8230 | }
8231 | }
8232 |
8233 | DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 8233, "curr_item" ))));
8234 |
8235 | curr_item->next = item_to_move->next;
8236 |
8237 | /* fix last_child if required */
8238 | if (tree->last_child == item_to_move) {
8239 | tree->last_child = curr_item;
8240 | }
8241 | }
8242 |
8243 | /*** insert to_move after fixed ***/
8244 | item_to_move->next = fixed_item->next;
8245 | fixed_item->next = item_to_move;
8246 | if (tree->last_child == fixed_item) {
8247 | tree->last_child = item_to_move;
8248 | }
8249 | }
8250 |
8251 | void
8252 | proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8253 | const int length)
8254 | {
8255 | field_info *fi;
8256 |
8257 | if (tree == NULL((void*)0))
8258 | return;
8259 |
8260 | fi = PTREE_FINFO(tree)((tree)->finfo);
8261 | if (fi == NULL((void*)0))
8262 | return;
8263 |
8264 | start += tvb_raw_offset(tvb);
8265 | DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8265, "start >= 0" ))));
8266 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8266, "length >= 0" ))));
8267 |
8268 | fi->appendix_start = start;
8269 | fi->appendix_length = length;
8270 | }
8271 |
8272 | static void
8273 | check_protocol_filter_name_or_fail(const char *filter_name)
8274 | {
8275 | /* Require at least two characters. */
8276 | if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8277 | 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);
8278 | }
8279 |
8280 | if (proto_check_field_name(filter_name) != '\0') {
8281 | 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)
8282 | " 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)
8283 | " 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);
8284 | }
8285 |
8286 | /* Check that it doesn't match some very common numeric forms. */
8287 | if (filter_name[0] == '0' &&
8288 | (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8289 | filter_name[1] == 'b' || filter_name[1] == 'B')) {
8290 | 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])
8291 | 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]);
8292 | }
8293 |
8294 | /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8295 |
8296 | /* Check that it contains at least one letter. */
8297 | bool_Bool have_letter = false0;
8298 | for (const char *s = filter_name; *s != '\0'; s++) {
8299 | if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8300 | have_letter = true1;
8301 | break;
8302 | }
8303 | }
8304 | if (!have_letter) {
8305 | 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)
8306 | filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z." , filter_name);
8307 | }
8308 |
8309 | /* Check for reserved keywords. */
8310 | if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8311 | 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)
8312 | " 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);
8313 | }
8314 | }
8315 |
8316 | int
8317 | proto_register_protocol(const char *name, const char *short_name,
8318 | const char *filter_name)
8319 | {
8320 | protocol_t *protocol;
8321 | header_field_info *hfinfo;
8322 |
8323 | check_protocol_filter_name_or_fail(filter_name);
8324 |
8325 | /*
8326 | * Add this protocol to the list of known protocols;
8327 | * the list is sorted by protocol short name.
8328 | */
8329 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8330 | protocol->name = name;
8331 | protocol->short_name = short_name;
8332 | protocol->filter_name = filter_name;
8333 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8334 | protocol->is_enabled = true1; /* protocol is enabled by default */
8335 | protocol->enabled_by_default = true1; /* see previous comment */
8336 | protocol->can_toggle = true1;
8337 | protocol->parent_proto_id = -1;
8338 | protocol->heur_list = NULL((void*)0);
8339 |
8340 | /* List will be sorted later by name, when all protocols completed registering */
8341 | protocols = g_list_prepend(protocols, protocol);
8342 | /*
8343 | * Make sure there's not already a protocol with any of those
8344 | * names. Crash if there is, as that's an error in the code
8345 | * or an inappropriate plugin.
8346 | * This situation has to be fixed to not register more than one
8347 | * protocol with the same name.
8348 | */
8349 | if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8350 | /* ws_error will terminate the program */
8351 | 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)
8352 | " 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);
8353 | }
8354 | if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8355 | 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)
8356 | " 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);
8357 | }
8358 | if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8359 | 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)
8360 | " 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);
8361 | }
8362 |
8363 | /* Here we allocate a new header_field_info struct */
8364 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info )));
8365 | hfinfo->name = name;
8366 | hfinfo->abbrev = filter_name;
8367 | hfinfo->type = FT_PROTOCOL;
8368 | hfinfo->display = BASE_NONE;
8369 | hfinfo->strings = protocol;
8370 | hfinfo->bitmask = 0;
8371 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8372 | hfinfo->blurb = NULL((void*)0);
8373 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8374 |
8375 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8376 | return protocol->proto_id;
8377 | }
8378 |
8379 | int
8380 | proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8381 | {
8382 | protocol_t *protocol;
8383 | header_field_info *hfinfo;
8384 |
8385 | /*
8386 | * Helper protocols don't need the strict rules as a "regular" protocol
8387 | * Just register it in a list and make a hf_ field from it
8388 | */
8389 | if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8390 | 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);
8391 | }
8392 |
8393 | if (parent_proto <= 0) {
8394 | 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)
8395 | " 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);
8396 | }
8397 |
8398 | check_protocol_filter_name_or_fail(filter_name);
8399 |
8400 | /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8401 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8402 | protocol->name = name;
8403 | protocol->short_name = short_name;
8404 | protocol->filter_name = filter_name;
8405 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8406 |
8407 | /* Enabling and toggling is really determined by parent protocol,
8408 | but provide default values here */
8409 | protocol->is_enabled = true1;
8410 | protocol->enabled_by_default = true1;
8411 | protocol->can_toggle = true1;
8412 |
8413 | protocol->parent_proto_id = parent_proto;
8414 | protocol->heur_list = NULL((void*)0);
8415 |
8416 | /* List will be sorted later by name, when all protocols completed registering */
8417 | protocols = g_list_prepend(protocols, protocol);
8418 |
8419 | /* Here we allocate a new header_field_info struct */
8420 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info )));
8421 | hfinfo->name = name;
8422 | hfinfo->abbrev = filter_name;
8423 | hfinfo->type = field_type;
8424 | hfinfo->display = BASE_NONE;
8425 | if (field_type == FT_BYTES) {
8426 | hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8427 | }
8428 | hfinfo->strings = protocol;
8429 | hfinfo->bitmask = 0;
8430 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8431 | hfinfo->blurb = NULL((void*)0);
8432 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8433 |
8434 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8435 | return protocol->proto_id;
8436 | }
8437 |
8438 | bool_Bool
8439 | proto_deregister_protocol(const char *short_name)
8440 | {
8441 | protocol_t *protocol;
8442 | header_field_info *hfinfo;
8443 | int proto_id;
8444 | unsigned i;
8445 |
8446 | proto_id = proto_get_id_by_short_name(short_name);
8447 | protocol = find_protocol_by_id(proto_id);
8448 | if (protocol == NULL((void*)0))
8449 | return false0;
8450 |
8451 | g_hash_table_remove(proto_names, protocol->name);
8452 | g_hash_table_remove(proto_short_names, (void *)short_name);
8453 | g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8454 |
8455 | if (protocol->fields) {
8456 | for (i = 0; i < protocol->fields->len; i++) {
8457 | hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8458 | hfinfo_remove_from_gpa_name_map(hfinfo);
8459 | expert_deregister_expertinfo(hfinfo->abbrev);
8460 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8461 | }
8462 | g_ptr_array_free(protocol->fields, true1);
8463 | protocol->fields = NULL((void*)0);
8464 | }
8465 |
8466 | g_list_free(protocol->heur_list);
8467 |
8468 | /* Remove this protocol from the list of known protocols */
8469 | protocols = g_list_remove(protocols, protocol);
8470 |
8471 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8472 | wmem_map_remove(gpa_name_map, protocol->filter_name);
8473 |
8474 | g_free(last_field_name);
8475 | last_field_name = NULL((void*)0);
8476 |
8477 | return true1;
8478 | }
8479 |
8480 | void
8481 | proto_register_alias(const int proto_id, const char *alias_name)
8482 | {
8483 | protocol_t *protocol;
8484 |
8485 | protocol = find_protocol_by_id(proto_id);
8486 | if (alias_name && protocol) {
8487 | g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8488 | }
8489 | }
8490 |
8491 | /*
8492 | * Routines to use to iterate over the protocols.
8493 | * The argument passed to the iterator routines is an opaque cookie to
8494 | * their callers; it's the GList pointer for the current element in
8495 | * the list.
8496 | * The ID of the protocol is returned, or -1 if there is no protocol.
8497 | */
8498 | int
8499 | proto_get_first_protocol(void **cookie)
8500 | {
8501 | protocol_t *protocol;
8502 |
8503 | if (protocols == NULL((void*)0))
8504 | return -1;
8505 | *cookie = protocols;
8506 | protocol = (protocol_t *)protocols->data;
8507 | return protocol->proto_id;
8508 | }
8509 |
8510 | int
8511 | proto_get_data_protocol(void *cookie)
8512 | {
8513 | GList *list_item = (GList *)cookie;
8514 |
8515 | protocol_t *protocol = (protocol_t *)list_item->data;
8516 | return protocol->proto_id;
8517 | }
8518 |
8519 | int
8520 | proto_get_next_protocol(void **cookie)
8521 | {
8522 | GList *list_item = (GList *)*cookie;
8523 | protocol_t *protocol;
8524 |
8525 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8526 | if (list_item == NULL((void*)0))
8527 | return -1;
8528 | *cookie = list_item;
8529 | protocol = (protocol_t *)list_item->data;
8530 | return protocol->proto_id;
8531 | }
8532 |
8533 | header_field_info *
8534 | proto_get_first_protocol_field(const int proto_id, void **cookie)
8535 | {
8536 | protocol_t *protocol = find_protocol_by_id(proto_id);
8537 |
8538 | if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8539 | return NULL((void*)0);
8540 |
8541 | *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8542 | return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8543 | }
8544 |
8545 | header_field_info *
8546 | proto_get_next_protocol_field(const int proto_id, void **cookie)
8547 | {
8548 | protocol_t *protocol = find_protocol_by_id(proto_id);
8549 | unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8550 |
8551 | i++;
8552 |
8553 | if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8554 | return NULL((void*)0);
8555 |
8556 | *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8557 | return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8558 | }
8559 |
8560 | protocol_t *
8561 | find_protocol_by_id(const int proto_id)
8562 | {
8563 | header_field_info *hfinfo;
8564 |
8565 | if (proto_id <= 0)
8566 | return NULL((void*)0);
8567 |
8568 | 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", 8568, __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", 8568, "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", 8568, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
8569 | if (hfinfo->type != FT_PROTOCOL) {
8570 | 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", 8570, "hfinfo->display & 0x00004000" ))));
8571 | }
8572 | return (protocol_t *)hfinfo->strings;
8573 | }
8574 |
8575 | int
8576 | proto_get_id(const protocol_t *protocol)
8577 | {
8578 | return protocol->proto_id;
8579 | }
8580 |
8581 | bool_Bool
8582 | proto_name_already_registered(const char *name)
8583 | {
8584 | DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 8584, "name", "No name present"))));
8585 |
8586 | if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8587 | return true1;
8588 | return false0;
8589 | }
8590 |
8591 | int
8592 | proto_get_id_by_filter_name(const char *filter_name)
8593 | {
8594 | const protocol_t *protocol = NULL((void*)0);
8595 |
8596 | 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", 8596, "filter_name", "No filter name present"))));
8597 |
8598 | protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8599 |
8600 | if (protocol == NULL((void*)0))
8601 | return -1;
8602 | return protocol->proto_id;
8603 | }
8604 |
8605 | int
8606 | proto_get_id_by_short_name(const char *short_name)
8607 | {
8608 | const protocol_t *protocol = NULL((void*)0);
8609 |
8610 | 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", 8610, "short_name", "No short name present"))));
8611 |
8612 | protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8613 |
8614 | if (protocol == NULL((void*)0))
8615 | return -1;
8616 | return protocol->proto_id;
8617 | }
8618 |
8619 | const char *
8620 | proto_get_protocol_name(const int proto_id)
8621 | {
8622 | protocol_t *protocol;
8623 |
8624 | protocol = find_protocol_by_id(proto_id);
8625 |
8626 | if (protocol == NULL((void*)0))
8627 | return NULL((void*)0);
8628 | return protocol->name;
8629 | }
8630 |
8631 | const char *
8632 | proto_get_protocol_short_name(const protocol_t *protocol)
8633 | {
8634 | if (protocol == NULL((void*)0))
8635 | return "(none)";
8636 | return protocol->short_name;
8637 | }
8638 |
8639 | const char *
8640 | proto_get_protocol_long_name(const protocol_t *protocol)
8641 | {
8642 | if (protocol == NULL((void*)0))
8643 | return "(none)";
8644 | return protocol->name;
8645 | }
8646 |
8647 | const char *
8648 | proto_get_protocol_filter_name(const int proto_id)
8649 | {
8650 | protocol_t *protocol;
8651 |
8652 | protocol = find_protocol_by_id(proto_id);
8653 | if (protocol == NULL((void*)0))
8654 | return "(none)";
8655 | return protocol->filter_name;
8656 | }
8657 |
8658 | void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8659 | {
8660 | heur_dtbl_entry_t* heuristic_dissector;
8661 |
8662 | if (protocol == NULL((void*)0))
8663 | return;
8664 |
8665 | heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8666 | if (heuristic_dissector != NULL((void*)0))
8667 | {
8668 | protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8669 | }
8670 | }
8671 |
8672 | void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8673 | {
8674 | if (protocol == NULL((void*)0))
8675 | return;
8676 |
8677 | g_list_foreach(protocol->heur_list, func, user_data);
8678 | }
8679 |
8680 | void
8681 | proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8682 | bool_Bool *is_tcp, bool_Bool *is_udp,
8683 | bool_Bool *is_sctp, bool_Bool *is_tls,
8684 | bool_Bool *is_rtp,
8685 | bool_Bool *is_lte_rlc)
8686 | {
8687 | wmem_list_frame_t *protos = wmem_list_head(layers);
8688 | int proto_id;
8689 | const char *proto_name;
8690 |
8691 | /* Walk the list of a available protocols in the packet and
8692 | attempt to find "major" ones. */
8693 | /* It might make more sense to assemble and return a bitfield. */
8694 | while (protos != NULL((void*)0))
8695 | {
8696 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8697 | proto_name = proto_get_protocol_filter_name(proto_id);
8698 |
8699 | if (is_ip && ((!strcmp(proto_name, "ip")) ||
8700 | (!strcmp(proto_name, "ipv6")))) {
8701 | *is_ip = true1;
8702 | } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8703 | *is_tcp = true1;
8704 | } else if (is_udp && !strcmp(proto_name, "udp")) {
8705 | *is_udp = true1;
8706 | } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8707 | *is_sctp = true1;
8708 | } else if (is_tls && !strcmp(proto_name, "tls")) {
8709 | *is_tls = true1;
8710 | } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8711 | *is_rtp = true1;
8712 | } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8713 | *is_lte_rlc = true1;
8714 | }
8715 |
8716 | protos = wmem_list_frame_next(protos);
8717 | }
8718 | }
8719 |
8720 | bool_Bool
8721 | proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8722 | {
8723 | wmem_list_frame_t *protos = wmem_list_head(layers);
8724 | int proto_id;
8725 | const char *name;
8726 |
8727 | /* Walk the list of a available protocols in the packet and
8728 | attempt to find the specified protocol. */
8729 | while (protos != NULL((void*)0))
8730 | {
8731 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8732 | name = proto_get_protocol_filter_name(proto_id);
8733 |
8734 | if (!strcmp(name, proto_name))
8735 | {
8736 | return true1;
8737 | }
8738 |
8739 | protos = wmem_list_frame_next(protos);
8740 | }
8741 |
8742 | return false0;
8743 | }
8744 |
8745 | char *
8746 | proto_list_layers(const packet_info *pinfo)
8747 | {
8748 | wmem_strbuf_t *buf;
8749 | wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8750 |
8751 | buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8752 |
8753 | /* Walk the list of layers in the packet and
8754 | return a string of all entries. */
8755 | while (layers != NULL((void*)0))
8756 | {
8757 | wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8758 |
8759 | layers = wmem_list_frame_next(layers);
8760 | if (layers != NULL((void*)0)) {
8761 | wmem_strbuf_append_c(buf, ':');
8762 | }
8763 | }
8764 |
8765 | return wmem_strbuf_finalize(buf);
8766 | }
8767 |
8768 | uint8_t
8769 | proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8770 | {
8771 | int *proto_layer_num_ptr;
8772 |
8773 | proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8774 | if (proto_layer_num_ptr == NULL((void*)0)) {
8775 | return 0;
8776 | }
8777 |
8778 | return (uint8_t)*proto_layer_num_ptr;
8779 | }
8780 |
8781 | bool_Bool
8782 | proto_is_pino(const protocol_t *protocol)
8783 | {
8784 | return (protocol->parent_proto_id != -1);
8785 | }
8786 |
8787 | bool_Bool
8788 | // NOLINTNEXTLINE(misc-no-recursion)
8789 | proto_is_protocol_enabled(const protocol_t *protocol)
8790 | {
8791 | if (protocol == NULL((void*)0))
8792 | return false0;
8793 |
8794 | //parent protocol determines enable/disable for helper dissectors
8795 | if (proto_is_pino(protocol))
8796 | return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8797 |
8798 | return protocol->is_enabled;
8799 | }
8800 |
8801 | bool_Bool
8802 | // NOLINTNEXTLINE(misc-no-recursion)
8803 | proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8804 | {
8805 | //parent protocol determines enable/disable for helper dissectors
8806 | if (proto_is_pino(protocol))
8807 | return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8808 |
8809 | return protocol->enabled_by_default;
8810 | }
8811 |
8812 | bool_Bool
8813 | // NOLINTNEXTLINE(misc-no-recursion)
8814 | proto_can_toggle_protocol(const int proto_id)
8815 | {
8816 | protocol_t *protocol;
8817 |
8818 | protocol = find_protocol_by_id(proto_id);
8819 | //parent protocol determines toggling for helper dissectors
8820 | if (proto_is_pino(protocol))
8821 | return proto_can_toggle_protocol(protocol->parent_proto_id);
8822 |
8823 | return protocol->can_toggle;
8824 | }
8825 |
8826 | void
8827 | proto_disable_by_default(const int proto_id)
8828 | {
8829 | protocol_t *protocol;
8830 |
8831 | protocol = find_protocol_by_id(proto_id);
8832 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8832, "protocol->can_toggle" ))));
8833 | 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", 8833, "proto_is_pino(protocol) == 0" ))));
8834 | protocol->is_enabled = false0;
8835 | protocol->enabled_by_default = false0;
8836 | }
8837 |
8838 | void
8839 | proto_set_decoding(const int proto_id, const bool_Bool enabled)
8840 | {
8841 | protocol_t *protocol;
8842 |
8843 | protocol = find_protocol_by_id(proto_id);
8844 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8844, "protocol->can_toggle" ))));
8845 | 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", 8845, "proto_is_pino(protocol) == 0" ))));
8846 | protocol->is_enabled = enabled;
8847 | }
8848 |
8849 | void
8850 | proto_disable_all(void)
8851 | {
8852 | /* This doesn't explicitly disable heuristic protocols,
8853 | * but the heuristic doesn't get called if the parent
8854 | * protocol isn't enabled.
8855 | */
8856 | protocol_t *protocol;
8857 | GList *list_item = protocols;
8858 |
8859 | if (protocols == NULL((void*)0))
8860 | return;
8861 |
8862 | while (list_item) {
8863 | protocol = (protocol_t *)list_item->data;
8864 | if (protocol->can_toggle) {
8865 | protocol->is_enabled = false0;
8866 | }
8867 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8868 | }
8869 | }
8870 |
8871 | static void
8872 | heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8873 | {
8874 | heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8875 |
8876 | heur->enabled = heur->enabled_by_default;
8877 | }
8878 |
8879 | void
8880 | proto_reenable_all(void)
8881 | {
8882 | protocol_t *protocol;
8883 | GList *list_item = protocols;
8884 |
8885 | if (protocols == NULL((void*)0))
8886 | return;
8887 |
8888 | while (list_item) {
8889 | protocol = (protocol_t *)list_item->data;
8890 | if (protocol->can_toggle)
8891 | protocol->is_enabled = protocol->enabled_by_default;
8892 | proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8893 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8894 | }
8895 | }
8896 |
8897 | void
8898 | proto_set_cant_toggle(const int proto_id)
8899 | {
8900 | protocol_t *protocol;
8901 |
8902 | protocol = find_protocol_by_id(proto_id);
8903 | protocol->can_toggle = false0;
8904 | }
8905 |
8906 | static int
8907 | proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8908 | {
8909 | g_ptr_array_add(proto->fields, hfi);
8910 |
8911 | return proto_register_field_init(hfi, parent);
8912 | }
8913 |
8914 | /* for use with static arrays only, since we don't allocate our own copies
8915 | of the header_field_info struct contained within the hf_register_info struct */
8916 | void
8917 | proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8918 | {
8919 | hf_register_info *ptr = hf;
8920 | protocol_t *proto;
8921 | int i;
8922 |
8923 | proto = find_protocol_by_id(parent);
8924 |
8925 | /* if (proto == NULL) - error or return? */
8926 |
8927 | if (proto->fields == NULL((void*)0)) {
8928 | /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8929 | * GLib introduced g_ptr_array_new_from_array, which might have
8930 | * given a reason to actually use it. (#17774)
8931 | */
8932 | proto->fields = g_ptr_array_sized_new(num_records);
8933 | }
8934 |
8935 | for (i = 0; i < num_records; i++, ptr++) {
8936 | /*
8937 | * Make sure we haven't registered this yet.
8938 | * Most fields have variables associated with them that
8939 | * are initialized to 0; some are initialized to -1 (which
8940 | * was the standard before 4.4).
8941 | *
8942 | * XXX - Since this is called almost 300000 times at startup,
8943 | * it might be nice to compare to only 0 and require
8944 | * dissectors to pass in zero for unregistered fields.
8945 | */
8946 | if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8947 | REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev)
8948 | "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)
8949 | ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev);
8950 | return;
8951 | }
8952 |
8953 | *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8954 | }
8955 | }
8956 |
8957 | /* deregister already registered fields */
8958 | void
8959 | proto_deregister_field (const int parent, int hf_id)
8960 | {
8961 | header_field_info *hfi;
8962 | protocol_t *proto;
8963 | unsigned i;
8964 |
8965 | g_free(last_field_name);
8966 | last_field_name = NULL((void*)0);
8967 |
8968 | if (hf_id == -1 || hf_id == 0)
8969 | return;
8970 |
8971 | proto = find_protocol_by_id (parent);
8972 | if (!proto || proto->fields == NULL((void*)0)) {
8973 | return;
8974 | }
8975 |
8976 | for (i = 0; i < proto->fields->len; i++) {
8977 | hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8978 | if (hfi->id == hf_id) {
8979 | /* Found the hf_id in this protocol */
8980 | wmem_map_remove(gpa_name_map, hfi->abbrev);
8981 | g_ptr_array_remove_index_fast(proto->fields, i);
8982 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8983 | return;
8984 | }
8985 | }
8986 | }
8987 |
8988 | /* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8989 | void
8990 | proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8991 | {
8992 | header_field_info *hfinfo;
8993 | protocol_t *proto;
8994 |
8995 | g_free(last_field_name);
8996 | last_field_name = NULL((void*)0);
8997 |
8998 | proto = find_protocol_by_id(parent);
8999 | if (proto && proto->fields && proto->fields->len > 0) {
9000 | guint i = proto->fields->len;
9001 | do {
9002 | i--;
9003 |
9004 | hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9005 | 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) )) {
9006 | hfinfo_remove_from_gpa_name_map(hfinfo);
9007 | expert_deregister_expertinfo(hfinfo->abbrev);
9008 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9009 | g_ptr_array_remove_index_fast(proto->fields, i);
9010 | }
9011 | } while (i > 0);
9012 | }
9013 | }
9014 |
9015 | void
9016 | proto_add_deregistered_data (void *data)
9017 | {
9018 | g_ptr_array_add(deregistered_data, data);
9019 | }
9020 |
9021 | void
9022 | proto_add_deregistered_slice (size_t block_size, void *mem_block)
9023 | {
9024 | 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 )));
9025 |
9026 | slice_data->block_size = block_size;
9027 | slice_data->mem_block = mem_block;
9028 |
9029 | g_ptr_array_add(deregistered_slice, slice_data);
9030 | }
9031 |
9032 | void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9033 | {
9034 | if (field_strings == NULL((void*)0)) {
9035 | return;
9036 | }
9037 |
9038 | switch (field_type) {
9039 | case FT_FRAMENUM:
9040 | /* This is just an integer represented as a pointer */
9041 | break;
9042 | case FT_PROTOCOL: {
9043 | protocol_t *protocol = (protocol_t *)field_strings;
9044 | g_free((char *)protocol->short_name);
9045 | break;
9046 | }
9047 | case FT_BOOLEAN: {
9048 | true_false_string *tf = (true_false_string *)field_strings;
9049 | g_free((char *)tf->true_string);
9050 | g_free((char *)tf->false_string);
9051 | break;
9052 | }
9053 | case FT_UINT40:
9054 | case FT_INT40:
9055 | case FT_UINT48:
9056 | case FT_INT48:
9057 | case FT_UINT56:
9058 | case FT_INT56:
9059 | case FT_UINT64:
9060 | case FT_INT64: {
9061 | if (field_display & BASE_UNIT_STRING0x00001000) {
9062 | unit_name_string *unit = (unit_name_string *)field_strings;
9063 | g_free((char *)unit->singular);
9064 | g_free((char *)unit->plural);
9065 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9066 | range_string *rs = (range_string *)field_strings;
9067 | while (rs->strptr) {
9068 | g_free((char *)rs->strptr);
9069 | rs++;
9070 | }
9071 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9072 | val64_string_ext *vse = (val64_string_ext *)field_strings;
9073 | val64_string *vs = (val64_string *)vse->_vs_p;
9074 | while (vs->strptr) {
9075 | g_free((char *)vs->strptr);
9076 | vs++;
9077 | }
9078 | val64_string_ext_free(vse);
9079 | field_strings = NULL((void*)0);
9080 | } else if (field_display == BASE_CUSTOM) {
9081 | /* this will be a pointer to a function, don't free that */
9082 | field_strings = NULL((void*)0);
9083 | } else {
9084 | val64_string *vs64 = (val64_string *)field_strings;
9085 | while (vs64->strptr) {
9086 | g_free((char *)vs64->strptr);
9087 | vs64++;
9088 | }
9089 | }
9090 | break;
9091 | }
9092 | case FT_CHAR:
9093 | case FT_UINT8:
9094 | case FT_INT8:
9095 | case FT_UINT16:
9096 | case FT_INT16:
9097 | case FT_UINT24:
9098 | case FT_INT24:
9099 | case FT_UINT32:
9100 | case FT_INT32:
9101 | case FT_FLOAT:
9102 | case FT_DOUBLE: {
9103 | if (field_display & BASE_UNIT_STRING0x00001000) {
9104 | unit_name_string *unit = (unit_name_string *)field_strings;
9105 | g_free((char *)unit->singular);
9106 | g_free((char *)unit->plural);
9107 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9108 | range_string *rs = (range_string *)field_strings;
9109 | while (rs->strptr) {
9110 | g_free((char *)rs->strptr);
9111 | rs++;
9112 | }
9113 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9114 | value_string_ext *vse = (value_string_ext *)field_strings;
9115 | value_string *vs = (value_string *)vse->_vs_p;
9116 | while (vs->strptr) {
9117 | g_free((char *)vs->strptr);
9118 | vs++;
9119 | }
9120 | value_string_ext_free(vse);
9121 | field_strings = NULL((void*)0);
9122 | } else if (field_display == BASE_CUSTOM) {
9123 | /* this will be a pointer to a function, don't free that */
9124 | field_strings = NULL((void*)0);
9125 | } else {
9126 | value_string *vs = (value_string *)field_strings;
9127 | while (vs->strptr) {
9128 | g_free((char *)vs->strptr);
9129 | vs++;
9130 | }
9131 | }
9132 | break;
9133 | default:
9134 | break;
9135 | }
9136 | }
9137 |
9138 | if (field_type != FT_FRAMENUM) {
9139 | g_free((void *)field_strings);
9140 | }
9141 | }
9142 |
9143 | static void
9144 | free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9145 | {
9146 | header_field_info *hfi = (header_field_info *) data;
9147 | int hf_id = hfi->id;
9148 |
9149 | g_free((char *)hfi->name);
9150 | g_free((char *)hfi->abbrev);
9151 | g_free((char *)hfi->blurb);
9152 |
9153 | proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9154 |
9155 | if (hfi->parent == -1)
9156 | 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);
9157 |
9158 | gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9159 | }
9160 |
9161 | static void
9162 | free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9163 | {
9164 | g_free (data);
9165 | }
9166 |
9167 | static void
9168 | free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9169 | {
9170 | struct g_slice_data *slice_data = (struct g_slice_data *)data;
9171 |
9172 | g_slice_free1(slice_data->block_size, slice_data->mem_block);
9173 | 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);
9174 | }
9175 |
9176 | /* free deregistered fields and data */
9177 | void
9178 | proto_free_deregistered_fields (void)
9179 | {
9180 | expert_free_deregistered_expertinfos();
9181 |
9182 | g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9183 | g_ptr_array_free(deregistered_fields, true1);
9184 | deregistered_fields = g_ptr_array_new();
9185 |
9186 | g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9187 | g_ptr_array_free(deregistered_data, true1);
9188 | deregistered_data = g_ptr_array_new();
9189 |
9190 | g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9191 | g_ptr_array_free(deregistered_slice, true1);
9192 | deregistered_slice = g_ptr_array_new();
9193 | }
9194 |
9195 | static const value_string hf_display[] = {
9196 | { BASE_NONE, "BASE_NONE" },
9197 | { BASE_DEC, "BASE_DEC" },
9198 | { BASE_HEX, "BASE_HEX" },
9199 | { BASE_OCT, "BASE_OCT" },
9200 | { BASE_DEC_HEX, "BASE_DEC_HEX" },
9201 | { BASE_HEX_DEC, "BASE_HEX_DEC" },
9202 | { BASE_CUSTOM, "BASE_CUSTOM" },
9203 | { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9204 | { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9205 | { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9206 | { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9207 | { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9208 | { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9209 | { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9210 | { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9211 | { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9212 | { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9213 | { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9214 | { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9215 | { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9216 | { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9217 | { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9218 | { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9219 | { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9220 | { BASE_PT_UDP, "BASE_PT_UDP" },
9221 | { BASE_PT_TCP, "BASE_PT_TCP" },
9222 | { BASE_PT_DCCP, "BASE_PT_DCCP" },
9223 | { BASE_PT_SCTP, "BASE_PT_SCTP" },
9224 | { BASE_OUI, "BASE_OUI" },
9225 | { 0, NULL((void*)0) } };
9226 |
9227 | const char* proto_field_display_to_string(int field_display)
9228 | {
9229 | return val_to_str_const(field_display, hf_display, "Unknown");
9230 | }
9231 |
9232 | static inline port_type
9233 | display_to_port_type(field_display_e e)
9234 | {
9235 | switch (e) {
9236 | case BASE_PT_UDP:
9237 | return PT_UDP;
9238 | case BASE_PT_TCP:
9239 | return PT_TCP;
9240 | case BASE_PT_DCCP:
9241 | return PT_DCCP;
9242 | case BASE_PT_SCTP:
9243 | return PT_SCTP;
9244 | default:
9245 | break;
9246 | }
9247 | return PT_NONE;
9248 | }
9249 |
9250 | /* temporary function containing assert part for easier profiling */
9251 | static void
9252 | tmp_fld_check_assert(header_field_info *hfinfo)
9253 | {
9254 | char* tmp_str;
9255 |
9256 | /* The field must have a name (with length > 0) */
9257 | if (!hfinfo->name || !hfinfo->name[0]) {
9258 | if (hfinfo->abbrev)
9259 | /* Try to identify the field */
9260 | 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)
9261 | hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name" , hfinfo->abbrev);
9262 | else
9263 | /* Hum, no luck */
9264 | 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)" );
9265 | }
9266 |
9267 | /* fields with an empty string for an abbreviation aren't filterable */
9268 | if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9269 | 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);
9270 |
9271 | /* TODO: This check is a significant percentage of startup time (~10%),
9272 | although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9273 | It might be nice to have a way to disable this check when, e.g.,
9274 | running TShark many times with the same configuration. */
9275 | /* Check that the filter name (abbreviation) is legal;
9276 | * it must contain only alphanumerics, '-', "_", and ".". */
9277 | unsigned char c;
9278 | c = module_check_valid_name(hfinfo->abbrev, false0);
9279 | if (c) {
9280 | if (c == '.') {
9281 | 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);
9282 | } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9283 | 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);
9284 | } else {
9285 | 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);
9286 | }
9287 | }
9288 |
9289 | /* These types of fields are allowed to have value_strings,
9290 | * true_false_strings or a protocol_t struct
9291 | */
9292 | if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9293 | switch (hfinfo->type) {
9294 |
9295 | /*
9296 | * These types are allowed to support display value_strings,
9297 | * value64_strings, the extended versions of the previous
9298 | * two, range strings, or unit strings.
9299 | */
9300 | case FT_CHAR:
9301 | case FT_UINT8:
9302 | case FT_UINT16:
9303 | case FT_UINT24:
9304 | case FT_UINT32:
9305 | case FT_UINT40:
9306 | case FT_UINT48:
9307 | case FT_UINT56:
9308 | case FT_UINT64:
9309 | case FT_INT8:
9310 | case FT_INT16:
9311 | case FT_INT24:
9312 | case FT_INT32:
9313 | case FT_INT40:
9314 | case FT_INT48:
9315 | case FT_INT56:
9316 | case FT_INT64:
9317 | case FT_BOOLEAN:
9318 | case FT_PROTOCOL:
9319 | break;
9320 |
9321 | /*
9322 | * This is allowed to have a value of type
9323 | * enum ft_framenum_type to indicate what relationship
9324 | * the frame in question has to the frame in which
9325 | * the field is put.
9326 | */
9327 | case FT_FRAMENUM:
9328 | break;
9329 |
9330 | /*
9331 | * These types are allowed to support only unit strings.
9332 | */
9333 | case FT_FLOAT:
9334 | case FT_DOUBLE:
9335 | case FT_IEEE_11073_SFLOAT:
9336 | case FT_IEEE_11073_FLOAT:
9337 | if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9338 | 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))
9339 | " (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))
9340 | 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));
9341 | }
9342 | break;
9343 |
9344 | /*
9345 | * These types are allowed to support display
9346 | * time_value_strings.
9347 | */
9348 | case FT_ABSOLUTE_TIME:
9349 | if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9350 | hfinfo->display & BASE_EXT_STRING0x00000200 ||
9351 | hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9352 | hfinfo->display & BASE_UNIT_STRING0x00001000) {
9353 | 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))
9354 | " (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))
9355 | 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));
9356 | }
9357 | break;
9358 |
9359 | /*
9360 | * This type is only allowed to support a string if it's
9361 | * a protocol (for pinos).
9362 | */
9363 | case FT_BYTES:
9364 | if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9365 | 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))
9366 | " (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))
9367 | 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));
9368 | }
9369 | break;
9370 |
9371 | default:
9372 | 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))
9373 | " (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))
9374 | 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));
9375 | }
9376 | }
9377 |
9378 | /* TODO: This check may slow down startup, and output quite a few warnings.
9379 | It would be good to be able to enable this (and possibly other checks?)
9380 | in non-release builds. */
9381 | #ifdef ENABLE_CHECK_FILTER
9382 | /* Check for duplicate value_string values.
9383 | There are lots that have the same value *and* string, so for now only
9384 | report those that have same value but different string. */
9385 | if ((hfinfo->strings != NULL((void*)0)) &&
9386 | !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9387 | !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9388 | !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9389 | (
9390 | (hfinfo->type == FT_CHAR) ||
9391 | (hfinfo->type == FT_UINT8) ||
9392 | (hfinfo->type == FT_UINT16) ||
9393 | (hfinfo->type == FT_UINT24) ||
9394 | (hfinfo->type == FT_UINT32) ||
9395 | (hfinfo->type == FT_INT8) ||
9396 | (hfinfo->type == FT_INT16) ||
9397 | (hfinfo->type == FT_INT24) ||
9398 | (hfinfo->type == FT_INT32) )) {
9399 |
9400 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9401 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9402 | const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9403 | CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9404 | } else {
9405 | const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9406 | CHECK_HF_VALUE(value_string, "u", start_values);
9407 | }
9408 | } else {
9409 | const value_string *start_values = (const value_string*)hfinfo->strings;
9410 | CHECK_HF_VALUE(value_string, "u", start_values);
9411 | }
9412 | }
9413 |
9414 | if (hfinfo->type == FT_BOOLEAN) {
9415 | const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9416 | if (tfs) {
9417 | if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9418 | ws_warning("Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")",do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9420, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string); } } while (0)
9419 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9420, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string); } } while (0)
9420 | tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9420, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string); } } while (0);
9421 | }
9422 | }
9423 | }
9424 |
9425 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9426 | const range_string *rs = (const range_string*)(hfinfo->strings);
9427 | if (rs) {
9428 | const range_string *this_it = rs;
9429 |
9430 | do {
9431 | if (this_it->value_max < this_it->value_min) {
9432 | 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" , 9436, __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)
9433 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9436, __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)
9434 | this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9436, __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)
9435 | this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9436, __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)
9436 | this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9436, __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);
9437 | ++this_it;
9438 | continue;
9439 | }
9440 |
9441 | for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9442 | /* Not OK if this one is completely hidden by an earlier one! */
9443 | if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9444 | 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" , 9450, __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)
9445 | "(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" , 9450, __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)
9446 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9450, __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)
9447 | prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9450, __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)
9448 | prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9450, __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)
9449 | this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9450, __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)
9450 | this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9450, __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);
9451 | }
9452 | }
9453 | ++this_it;
9454 | } while (this_it->strptr);
9455 | }
9456 | }
9457 | #endif
9458 |
9459 | switch (hfinfo->type) {
9460 |
9461 | case FT_CHAR:
9462 | /* Require the char type to have BASE_HEX, BASE_OCT,
9463 | * BASE_CUSTOM, or BASE_NONE as its base.
9464 | *
9465 | * If the display value is BASE_NONE and there is a
9466 | * strings conversion then the dissector writer is
9467 | * telling us that the field's numerical value is
9468 | * meaningless; we'll avoid showing the value to the
9469 | * user.
9470 | */
9471 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9472 | case BASE_HEX:
9473 | case BASE_OCT:
9474 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9475 | break;
9476 | case BASE_NONE:
9477 | if (hfinfo->strings == NULL((void*)0))
9478 | 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 ))
9479 | " 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 ))
9480 | " 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 ))
9481 | 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 ))
9482 | 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 ));
9483 | break;
9484 | default:
9485 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9486 | 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)
9487 | " 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)
9488 | 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)
9489 | 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);
9490 | //wmem_free(NULL, tmp_str);
9491 | }
9492 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9493 | 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 ))
9494 | 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 ))
9495 | 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 ));
9496 | }
9497 | break;
9498 | case FT_INT8:
9499 | case FT_INT16:
9500 | case FT_INT24:
9501 | case FT_INT32:
9502 | case FT_INT40:
9503 | case FT_INT48:
9504 | case FT_INT56:
9505 | case FT_INT64:
9506 | /* Hexadecimal and octal are, in printf() and everywhere
9507 | * else, unsigned so don't allow dissectors to register a
9508 | * signed field to be displayed unsigned. (Else how would
9509 | * we display negative values?)
9510 | */
9511 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9512 | case BASE_HEX:
9513 | case BASE_OCT:
9514 | case BASE_DEC_HEX:
9515 | case BASE_HEX_DEC:
9516 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9517 | 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)
9518 | 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)
9519 | 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);
9520 | //wmem_free(NULL, tmp_str);
9521 | }
9522 | /* FALL THROUGH */
9523 | case FT_UINT8:
9524 | case FT_UINT16:
9525 | case FT_UINT24:
9526 | case FT_UINT32:
9527 | case FT_UINT40:
9528 | case FT_UINT48:
9529 | case FT_UINT56:
9530 | case FT_UINT64:
9531 | 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 ))) {
9532 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9533 | if (hfinfo->type != FT_UINT16) {
9534 | 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))
9535 | 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))
9536 | 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));
9537 | }
9538 | if (hfinfo->strings != NULL((void*)0)) {
9539 | 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)
9540 | 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)
9541 | 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);
9542 | }
9543 | if (hfinfo->bitmask != 0) {
9544 | 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)
9545 | 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)
9546 | 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);
9547 | }
9548 | wmem_free(NULL((void*)0), tmp_str);
9549 | break;
9550 | }
9551 |
9552 | if (hfinfo->display == BASE_OUI) {
9553 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9554 | if (hfinfo->type != FT_UINT24) {
9555 | 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))
9556 | 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))
9557 | 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));
9558 | }
9559 | if (hfinfo->strings != NULL((void*)0)) {
9560 | 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)
9561 | 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)
9562 | 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);
9563 | }
9564 | if (hfinfo->bitmask != 0) {
9565 | 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)
9566 | 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)
9567 | 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);
9568 | }
9569 | wmem_free(NULL((void*)0), tmp_str);
9570 | break;
9571 | }
9572 |
9573 | /* Require integral types (other than frame number,
9574 | * which is always displayed in decimal) to have a
9575 | * number base.
9576 | *
9577 | * If the display value is BASE_NONE and there is a
9578 | * strings conversion then the dissector writer is
9579 | * telling us that the field's numerical value is
9580 | * meaningless; we'll avoid showing the value to the
9581 | * user.
9582 | */
9583 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9584 | case BASE_DEC:
9585 | case BASE_HEX:
9586 | case BASE_OCT:
9587 | case BASE_DEC_HEX:
9588 | case BASE_HEX_DEC:
9589 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9590 | break;
9591 | case BASE_NONE:
9592 | if (hfinfo->strings == NULL((void*)0)) {
9593 | 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 ))
9594 | " 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 ))
9595 | " 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 ))
9596 | 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 ))
9597 | 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 ));
9598 | }
9599 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9600 | 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 ))
9601 | " 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 ))
9602 | " 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 ))
9603 | 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 ))
9604 | 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 ));
9605 | }
9606 | break;
9607 |
9608 | default:
9609 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9610 | 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)
9611 | " 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)
9612 | 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)
9613 | 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);
9614 | //wmem_free(NULL, tmp_str);
9615 | }
9616 | break;
9617 | case FT_BYTES:
9618 | case FT_UINT_BYTES:
9619 | /* Require bytes to have a "display type" that could
9620 | * add a character between displayed bytes.
9621 | */
9622 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9623 | case BASE_NONE:
9624 | case SEP_DOT:
9625 | case SEP_DASH:
9626 | case SEP_COLON:
9627 | case SEP_SPACE:
9628 | break;
9629 | default:
9630 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9631 | 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)
9632 | 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);
9633 | //wmem_free(NULL, tmp_str);
9634 | }
9635 | if (hfinfo->bitmask != 0)
9636 | 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 ))
9637 | 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 ))
9638 | 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 ));
9639 | //allowed to support string if its a protocol (for pinos)
9640 | if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9641 | 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 ))
9642 | 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 ))
9643 | 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 ));
9644 | break;
9645 |
9646 | case FT_PROTOCOL:
9647 | case FT_FRAMENUM:
9648 | if (hfinfo->display != BASE_NONE) {
9649 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9650 | 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)
9651 | 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)
9652 | 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);
9653 | //wmem_free(NULL, tmp_str);
9654 | }
9655 | if (hfinfo->bitmask != 0)
9656 | 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 ))
9657 | 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 ))
9658 | 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 ));
9659 | break;
9660 |
9661 | case FT_BOOLEAN:
9662 | break;
9663 |
9664 | case FT_ABSOLUTE_TIME:
9665 | if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL && ((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)) {
9666 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9667 | 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)
9668 | 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);
9669 | //wmem_free(NULL, tmp_str);
9670 | }
9671 | if (hfinfo->bitmask != 0)
9672 | 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 ))
9673 | 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 ))
9674 | 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 ));
9675 | break;
9676 |
9677 | case FT_STRING:
9678 | case FT_STRINGZ:
9679 | case FT_UINT_STRING:
9680 | case FT_STRINGZPAD:
9681 | case FT_STRINGZTRUNC:
9682 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9683 | case BASE_NONE:
9684 | case BASE_STR_WSP:
9685 | break;
9686 |
9687 | default:
9688 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9689 | 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)
9690 | " 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)
9691 | 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)
9692 | 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);
9693 | //wmem_free(NULL, tmp_str);
9694 | }
9695 |
9696 | if (hfinfo->bitmask != 0)
9697 | 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 ))
9698 | 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 ))
9699 | 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 ));
9700 | if (hfinfo->strings != NULL((void*)0))
9701 | 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 ))
9702 | 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 ))
9703 | 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 ));
9704 | break;
9705 |
9706 | case FT_IPv4:
9707 | switch (hfinfo->display) {
9708 | case BASE_NONE:
9709 | case BASE_NETMASK:
9710 | break;
9711 |
9712 | default:
9713 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9714 | 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)
9715 | " 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)
9716 | 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)
9717 | 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);
9718 | //wmem_free(NULL, tmp_str);
9719 | break;
9720 | }
9721 | break;
9722 | case FT_FLOAT:
9723 | case FT_DOUBLE:
9724 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9725 | case BASE_NONE:
9726 | case BASE_DEC:
9727 | case BASE_HEX:
9728 | case BASE_EXP:
9729 | case BASE_CUSTOM:
9730 | break;
9731 | default:
9732 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9733 | 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)
9734 | " 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)
9735 | 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)
9736 | 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);
9737 | //wmem_free(NULL, tmp_str);
9738 | }
9739 | if (hfinfo->bitmask != 0)
9740 | 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 ))
9741 | 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 ))
9742 | 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 ));
9743 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9744 | 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 ))
9745 | 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 ))
9746 | 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 ));
9747 | break;
9748 | case FT_IEEE_11073_SFLOAT:
9749 | case FT_IEEE_11073_FLOAT:
9750 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9751 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9752 | 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)
9753 | 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)
9754 | 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)
9755 | 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);
9756 | //wmem_free(NULL, tmp_str);
9757 | }
9758 | if (hfinfo->bitmask != 0)
9759 | 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 ))
9760 | 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 ))
9761 | 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 ));
9762 | if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9763 | 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 ))
9764 | 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 ))
9765 | 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 ));
9766 | break;
9767 | default:
9768 | if (hfinfo->display != BASE_NONE) {
9769 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9770 | 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)
9771 | 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)
9772 | 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)
9773 | 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);
9774 | //wmem_free(NULL, tmp_str);
9775 | }
9776 | if (hfinfo->bitmask != 0)
9777 | 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 ))
9778 | 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 ))
9779 | 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 ));
9780 | if (hfinfo->strings != NULL((void*)0))
9781 | 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 ))
9782 | 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 ))
9783 | 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 ));
9784 | break;
9785 | }
9786 | }
9787 |
9788 | static void
9789 | register_type_length_mismatch(void)
9790 | {
9791 | static ei_register_info ei[] = {
9792 | { &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)}} }},
9793 | { &ei_type_length_mismatch_warn, { "_ws.type_length.mismatch", 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)}} }},
9794 | };
9795 |
9796 | expert_module_t* expert_type_length_mismatch;
9797 |
9798 | proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9799 |
9800 | expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9801 | expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9802 |
9803 | /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9804 | disabling them makes no sense. */
9805 | proto_set_cant_toggle(proto_type_length_mismatch);
9806 | }
9807 |
9808 | static void
9809 | register_byte_array_string_decodinws_error(void)
9810 | {
9811 | static ei_register_info ei[] = {
9812 | { &ei_byte_array_string_decoding_failed_error,
9813 | { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9814 | "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)}}
9815 | }
9816 | },
9817 | };
9818 |
9819 | expert_module_t* expert_byte_array_string_decoding_error;
9820 |
9821 | proto_byte_array_string_decoding_error =
9822 | proto_register_protocol("Byte Array-String Decoding Error",
9823 | "Byte Array-string decoding error",
9824 | "_ws.byte_array_string.decoding_error");
9825 |
9826 | expert_byte_array_string_decoding_error =
9827 | expert_register_protocol(proto_byte_array_string_decoding_error);
9828 | expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9829 |
9830 | /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9831 | disabling them makes no sense. */
9832 | proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9833 | }
9834 |
9835 | static void
9836 | register_date_time_string_decodinws_error(void)
9837 | {
9838 | static ei_register_info ei[] = {
9839 | { &ei_date_time_string_decoding_failed_error,
9840 | { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9841 | "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)}}
9842 | }
9843 | },
9844 | };
9845 |
9846 | expert_module_t* expert_date_time_string_decoding_error;
9847 |
9848 | proto_date_time_string_decoding_error =
9849 | proto_register_protocol("Date and Time-String Decoding Error",
9850 | "Date and Time-string decoding error",
9851 | "_ws.date_time_string.decoding_error");
9852 |
9853 | expert_date_time_string_decoding_error =
9854 | expert_register_protocol(proto_date_time_string_decoding_error);
9855 | expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9856 |
9857 | /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9858 | disabling them makes no sense. */
9859 | proto_set_cant_toggle(proto_date_time_string_decoding_error);
9860 | }
9861 |
9862 | static void
9863 | register_string_errors(void)
9864 | {
9865 | static ei_register_info ei[] = {
9866 | { &ei_string_trailing_characters,
9867 | { "_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)}} }
9868 | },
9869 | };
9870 |
9871 | expert_module_t* expert_string_errors;
9872 |
9873 | proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9874 |
9875 | expert_string_errors = expert_register_protocol(proto_string_errors);
9876 | expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9877 |
9878 | /* "String Errors" isn't really a protocol, it's an error indication;
9879 | disabling them makes no sense. */
9880 | proto_set_cant_toggle(proto_string_errors);
9881 | }
9882 |
9883 | static int
9884 | proto_register_field_init(header_field_info *hfinfo, const int parent)
9885 | {
9886 |
9887 | tmp_fld_check_assert(hfinfo);
9888 |
9889 | hfinfo->parent = parent;
9890 | hfinfo->same_name_next = NULL((void*)0);
9891 | hfinfo->same_name_prev_id = -1;
9892 |
9893 | /* if we always add and never delete, then id == len - 1 is correct */
9894 | if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9895 | if (!gpa_hfinfo.hfi) {
9896 | gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9897 | gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9898 | /* The entry with index 0 is not used. */
9899 | gpa_hfinfo.hfi[0] = NULL((void*)0);
9900 | gpa_hfinfo.len = 1;
9901 | } else {
9902 | gpa_hfinfo.allocated_len += 1000;
9903 | gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9904 | sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9905 | /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9906 | }
9907 | }
9908 | gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9909 | gpa_hfinfo.len++;
9910 | hfinfo->id = gpa_hfinfo.len - 1;
9911 |
9912 | /* if we have real names, enter this field in the name tree */
9913 | /* Already checked in tmp_fld_check_assert */
9914 | /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9915 | {
9916 |
9917 | header_field_info *same_name_next_hfinfo;
9918 |
9919 | /* We allow multiple hfinfo's to be registered under the same
9920 | * abbreviation. This was done for X.25, as, depending
9921 | * on whether it's modulo-8 or modulo-128 operation,
9922 | * some bitfield fields may be in different bits of
9923 | * a byte, and we want to be able to refer to that field
9924 | * with one name regardless of whether the packets
9925 | * are modulo-8 or modulo-128 packets. */
9926 |
9927 | /* wmem_map_insert - if key is already present the previous
9928 | * hfinfo with the same key/name is returned, otherwise NULL */
9929 | same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9930 | if (same_name_hfinfo) {
9931 | /* There's already a field with this name.
9932 | * Put the current field *before* that field
9933 | * in the list of fields with this name, Thus,
9934 | * we end up with an effectively
9935 | * doubly-linked-list of same-named hfinfo's,
9936 | * with the head of the list (stored in the
9937 | * hash) being the last seen hfinfo.
9938 | */
9939 | same_name_next_hfinfo =
9940 | same_name_hfinfo->same_name_next;
9941 |
9942 | hfinfo->same_name_next = same_name_next_hfinfo;
9943 | if (same_name_next_hfinfo)
9944 | same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9945 |
9946 | same_name_hfinfo->same_name_next = hfinfo;
9947 | hfinfo->same_name_prev_id = same_name_hfinfo->id;
9948 | #ifdef ENABLE_CHECK_FILTER
9949 | while (same_name_hfinfo) {
9950 | if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9951 | ws_warning("'%s' exists multiple times with incompatible types: %s and %s", hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name(same_name_hfinfo->type))do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9951, __func__, "'%s' exists multiple times with incompatible types: %s and %s" , hfinfo->abbrev, ftype_name(hfinfo->type), ftype_name( same_name_hfinfo->type)); } } while (0);
9952 | same_name_hfinfo = same_name_hfinfo->same_name_next;
9953 | }
9954 | #endif
9955 | }
9956 | }
9957 |
9958 | return hfinfo->id;
9959 | }
9960 |
9961 | void
9962 | proto_register_subtree_array(int * const *indices, const int num_indices)
9963 | {
9964 | int i;
9965 | int *const *ptr = indices;
9966 |
9967 | /*
9968 | * If we've already allocated the array of tree types, expand
9969 | * it; this lets plugins such as mate add tree types after
9970 | * the initial startup. (If we haven't already allocated it,
9971 | * we don't allocate it; on the first pass, we just assign
9972 | * ett values and keep track of how many we've assigned, and
9973 | * when we're finished registering all dissectors we allocate
9974 | * the array, so that we do only one allocation rather than
9975 | * wasting CPU time and memory by growing the array for each
9976 | * dissector that registers ett values.)
9977 | */
9978 | if (tree_is_expanded != NULL((void*)0)) {
9979 | tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9980 |
9981 | /* set new items to 0 */
9982 | /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9983 | for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9984 | tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9985 | }
9986 |
9987 | /*
9988 | * Assign "num_indices" subtree numbers starting at "num_tree_types",
9989 | * returning the indices through the pointers in the array whose
9990 | * first element is pointed to by "indices", and update
9991 | * "num_tree_types" appropriately.
9992 | */
9993 | for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9994 | if (**ptr != -1 && **ptr != 0) {
9995 | 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.")
9996 | " 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.")
9997 | " 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.")
9998 | " 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.");
9999 | }
10000 | **ptr = num_tree_types;
10001 | }
10002 | }
10003 |
10004 | static void
10005 | mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10006 | {
10007 | static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10008 | const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10009 | char *last_char;
10010 |
10011 | /* ..... field_name: dataaaaaaaaaaaaa
10012 | * |
10013 | * ^^^^^ name_pos
10014 | *
10015 | * ..... field_name […]: dataaaaaaaaaaaaa
10016 | *
10017 | * name_pos==0 means that we have only data or only a field_name
10018 | */
10019 |
10020 | ws_assert(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10020, __func__, "assertion failed: %s" , "size > trunc_len"); } while (0);
10021 |
10022 | if (name_pos >= size - trunc_len) {
10023 | /* No room for trunc_str after the field_name, put it first. */
10024 | name_pos = 0;
10025 | }
10026 |
10027 | memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10028 | if (name_pos == 0) {
10029 | /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10030 | memcpy(label_str, trunc_str + 1, trunc_len);
10031 | } else {
10032 | memcpy(label_str + name_pos, trunc_str, trunc_len);
10033 | }
10034 | /* in general, label_str is UTF-8
10035 | we can truncate it only at the beginning of a new character
10036 | we go backwards from the byte right after our buffer and
10037 | find the next starting byte of a UTF-8 character, this is
10038 | where we cut
10039 | there's no need to use g_utf8_find_prev_char(), the search
10040 | will always succeed since we copied trunc_str into the
10041 | buffer */
10042 | /* g_utf8_prev_char does not deference the memory address
10043 | * passed in (until after decrementing it, so it is perfectly
10044 | * legal to pass in a pointer one past the last element.
10045 | */
10046 | last_char = g_utf8_prev_char(label_str + size);
10047 | *last_char = '\0';
10048 |
10049 | if (value_pos && *value_pos > 0) {
10050 | if (name_pos == 0) {
10051 | *value_pos += trunc_len;
10052 | } else {
10053 | /* Move one back to include trunc_str in the value. */
10054 | *value_pos -= 1;
10055 | }
10056 | }
10057 |
10058 | /* Check if value_pos is past label_str. */
10059 | if (value_pos && *value_pos >= size) {
10060 | *value_pos = size - 1;
10061 | }
10062 | }
10063 |
10064 | static void
10065 | label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10066 | {
10067 | mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10068 | }
10069 |
10070 | static size_t
10071 | label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10072 | {
10073 | size_t name_pos;
10074 |
10075 | /* "%s: %s", hfinfo->name, text */
10076 | name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10077 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10078 | pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10079 | if (value_pos) {
10080 | *value_pos = pos;
10081 | }
10082 | pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
10083 | }
10084 |
10085 | if (pos >= ITEM_LABEL_LENGTH240) {
10086 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10087 | label_mark_truncated(label_str, name_pos, value_pos);
10088 | }
10089 |
10090 | return pos;
10091 | }
10092 |
10093 | static size_t
10094 | label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10095 | {
10096 | size_t name_pos;
10097 |
10098 | /* "%s: %s (%s)", hfinfo->name, text, descr */
10099 | name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10100 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10101 | pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10102 | if (value_pos) {
10103 | *value_pos = pos;
10104 | }
10105 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10106 | pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)" , 0);
10107 | pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0 );
10108 | } else {
10109 | pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0 );
10110 | pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10111 | pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)" , 0);
10112 | pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10113 | }
10114 | }
10115 |
10116 | if (pos >= ITEM_LABEL_LENGTH240) {
10117 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10118 | label_mark_truncated(label_str, name_pos, value_pos);
10119 | }
10120 |
10121 | return pos;
10122 | }
10123 |
10124 | void
10125 | proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10126 | {
10127 | const header_field_info *hfinfo;
10128 | const char *str;
10129 | const uint8_t *bytes;
10130 | uint32_t integer;
10131 | const ipv4_addr_and_mask *ipv4;
10132 | const ipv6_addr_and_prefix *ipv6;
10133 | const e_guid_t *guid;
10134 | char *name;
10135 | address addr;
10136 | char *addr_str;
10137 | char *tmp;
10138 |
10139 | if (!label_str) {
10140 | ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10140, __func__, "NULL label_str passed to proto_item_fill_label." ); } } while (0);
10141 | return;
10142 | }
10143 |
10144 | label_str[0]= '\0';
10145 |
10146 | if (!fi) {
10147 | return;
10148 | }
10149 |
10150 | hfinfo = fi->hfinfo;
10151 |
10152 | switch (hfinfo->type) {
10153 | case FT_NONE:
10154 | case FT_PROTOCOL:
10155 | (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10156 | if (value_pos) {
10157 | *value_pos = strlen(hfinfo->name);
10158 | }
10159 | break;
10160 |
10161 | case FT_BOOLEAN:
10162 | fill_label_boolean(fi, label_str, value_pos);
10163 | break;
10164 |
10165 | case FT_BYTES:
10166 | case FT_UINT_BYTES:
10167 | tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10168 | fvalue_get_bytes_data(fi->value),
10169 | (unsigned)fvalue_length2(fi->value));
10170 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10171 | wmem_free(NULL((void*)0), tmp);
10172 | break;
10173 |
10174 | case FT_CHAR:
10175 | if (hfinfo->bitmask) {
10176 | fill_label_bitfield_char(fi, label_str, value_pos);
10177 | } else {
10178 | fill_label_char(fi, label_str, value_pos);
10179 | }
10180 | break;
10181 |
10182 | /* Four types of integers to take care of:
10183 | * Bitfield, with val_string
10184 | * Bitfield, w/o val_string
10185 | * Non-bitfield, with val_string
10186 | * Non-bitfield, w/o val_string
10187 | */
10188 | case FT_UINT8:
10189 | case FT_UINT16:
10190 | case FT_UINT24:
10191 | case FT_UINT32:
10192 | if (hfinfo->bitmask) {
10193 | fill_label_bitfield(fi, label_str, value_pos, false0);
10194 | } else {
10195 | fill_label_number(fi, label_str, value_pos, false0);
10196 | }
10197 | break;
10198 |
10199 | case FT_FRAMENUM:
10200 | fill_label_number(fi, label_str, value_pos, false0);
10201 | break;
10202 |
10203 | case FT_UINT40:
10204 | case FT_UINT48:
10205 | case FT_UINT56:
10206 | case FT_UINT64:
10207 | if (hfinfo->bitmask) {
10208 | fill_label_bitfield64(fi, label_str, value_pos, false0);
10209 | } else {
10210 | fill_label_number64(fi, label_str, value_pos, false0);
10211 | }
10212 | break;
10213 |
10214 | case FT_INT8:
10215 | case FT_INT16:
10216 | case FT_INT24:
10217 | case FT_INT32:
10218 | if (hfinfo->bitmask) {
10219 | fill_label_bitfield(fi, label_str, value_pos, true1);
10220 | } else {
10221 | fill_label_number(fi, label_str, value_pos, true1);
10222 | }
10223 | break;
10224 |
10225 | case FT_INT40:
10226 | case FT_INT48:
10227 | case FT_INT56:
10228 | case FT_INT64:
10229 | if (hfinfo->bitmask) {
10230 | fill_label_bitfield64(fi, label_str, value_pos, true1);
10231 | } else {
10232 | fill_label_number64(fi, label_str, value_pos, true1);
10233 | }
10234 | break;
10235 |
10236 | case FT_FLOAT:
10237 | case FT_DOUBLE:
10238 | fill_label_float(fi, label_str, value_pos);
10239 | break;
10240 |
10241 | case FT_ABSOLUTE_TIME:
10242 | {
10243 | const nstime_t *value = fvalue_get_time(fi->value);
10244 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10245 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10246 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10247 | }
10248 | if (hfinfo->strings) {
10249 | /*
10250 | * Table of time valus to be displayed
10251 | * specially.
10252 | */
10253 | const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10254 | if (time_string != NULL((void*)0)) {
10255 | label_fill(label_str, 0, hfinfo, time_string, value_pos);
10256 | break;
10257 | }
10258 | }
10259 | tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10260 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10261 | wmem_free(NULL((void*)0), tmp);
10262 | break;
10263 | }
10264 | case FT_RELATIVE_TIME:
10265 | tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10266 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10267 | wmem_free(NULL((void*)0), tmp);
10268 | break;
10269 |
10270 | case FT_IPXNET:
10271 | integer = fvalue_get_uinteger(fi->value);
10272 | tmp = get_ipxnet_name(NULL((void*)0), integer);
10273 | addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10274 | label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10275 | wmem_free(NULL((void*)0), tmp);
10276 | wmem_free(NULL((void*)0), addr_str);
10277 | break;
10278 |
10279 | case FT_VINES:
10280 | addr.type = AT_VINES;
10281 | addr.len = VINES_ADDR_LEN6;
10282 | addr.data = fvalue_get_bytes_data(fi->value);
10283 |
10284 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10285 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10286 | wmem_free(NULL((void*)0), addr_str);
10287 | break;
10288 |
10289 | case FT_ETHER:
10290 | bytes = fvalue_get_bytes_data(fi->value);
10291 |
10292 | addr.type = AT_ETHER;
10293 | addr.len = 6;
10294 | addr.data = bytes;
10295 |
10296 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10297 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10298 | wmem_free(NULL((void*)0), addr_str);
10299 | break;
10300 |
10301 | case FT_IPv4:
10302 | ipv4 = fvalue_get_ipv4(fi->value);
10303 | set_address_ipv4(&addr, ipv4);
10304 |
10305 | if (hfinfo->display == BASE_NETMASK) {
10306 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10307 | } else {
10308 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10309 | }
10310 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10311 | wmem_free(NULL((void*)0), addr_str);
10312 | free_address(&addr);
10313 | break;
10314 |
10315 | case FT_IPv6:
10316 | ipv6 = fvalue_get_ipv6(fi->value);
10317 | set_address_ipv6(&addr, ipv6);
10318 |
10319 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10320 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10321 | wmem_free(NULL((void*)0), addr_str);
10322 | free_address(&addr);
10323 | break;
10324 |
10325 | case FT_FCWWN:
10326 | bytes = fvalue_get_bytes_data(fi->value);
10327 | addr.type = AT_FCWWN;
10328 | addr.len = FCWWN_ADDR_LEN8;
10329 | addr.data = bytes;
10330 |
10331 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10332 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10333 | wmem_free(NULL((void*)0), addr_str);
10334 | break;
10335 |
10336 | case FT_GUID:
10337 | guid = fvalue_get_guid(fi->value);
10338 | tmp = guid_to_str(NULL((void*)0), guid);
10339 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10340 | wmem_free(NULL((void*)0), tmp);
10341 | break;
10342 |
10343 | case FT_OID:
10344 | bytes = fvalue_get_bytes_data(fi->value);
10345 | name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10346 | tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10347 | if (name) {
10348 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10349 | wmem_free(NULL((void*)0), name);
10350 | } else {
10351 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10352 | }
10353 | wmem_free(NULL((void*)0), tmp);
10354 | break;
10355 |
10356 | case FT_REL_OID:
10357 | bytes = fvalue_get_bytes_data(fi->value);
10358 | name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10359 | tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10360 | if (name) {
10361 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10362 | wmem_free(NULL((void*)0), name);
10363 | } else {
10364 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10365 | }
10366 | wmem_free(NULL((void*)0), tmp);
10367 | break;
10368 |
10369 | case FT_SYSTEM_ID:
10370 | bytes = fvalue_get_bytes_data(fi->value);
10371 | tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10372 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10373 | wmem_free(NULL((void*)0), tmp);
10374 | break;
10375 |
10376 | case FT_EUI64:
10377 | bytes = fvalue_get_bytes_data(fi->value);
10378 | addr.type = AT_EUI64;
10379 | addr.len = EUI64_ADDR_LEN8;
10380 | addr.data = bytes;
10381 |
10382 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10383 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10384 | wmem_free(NULL((void*)0), addr_str);
10385 | break;
10386 | case FT_STRING:
10387 | case FT_STRINGZ:
10388 | case FT_UINT_STRING:
10389 | case FT_STRINGZPAD:
10390 | case FT_STRINGZTRUNC:
10391 | case FT_AX25:
10392 | str = fvalue_get_string(fi->value);
10393 | label_fill(label_str, 0, hfinfo, str, value_pos);
10394 | break;
10395 |
10396 | case FT_IEEE_11073_SFLOAT:
10397 | case FT_IEEE_11073_FLOAT:
10398 | fill_label_ieee_11073_float(fi, label_str, value_pos);
10399 | break;
10400 |
10401 | default:
10402 | 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 ))
10403 | 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 ))
10404 | 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 ))
10405 | 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 ));
10406 | break;
10407 | }
10408 | }
10409 |
10410 | static void
10411 | fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10412 | {
10413 | char *p;
10414 | int bitfield_byte_length = 0, bitwidth;
10415 | uint64_t unshifted_value;
10416 | uint64_t value;
10417 |
10418 | const header_field_info *hfinfo = fi->hfinfo;
10419 |
10420 | value = fvalue_get_uinteger64(fi->value);
10421 | if (hfinfo->bitmask) {
10422 | /* Figure out the bit width */
10423 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10424 |
10425 | /* Un-shift bits */
10426 | unshifted_value = value;
10427 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10428 |
10429 | /* Create the bitfield first */
10430 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10431 | bitfield_byte_length = (int) (p - label_str);
10432 | }
10433 |
10434 | /* Fill in the textual info */
10435 | label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10436 | }
10437 |
10438 | static const char *
10439 | hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10440 | {
10441 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10442 | return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10443 |
10444 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10445 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10446 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10447 | else
10448 | return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10449 | }
10450 |
10451 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10452 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10453 |
10454 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10455 | return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10456 |
10457 | return try_val_to_str(value, (const value_string *) hfinfo->strings);
10458 | }
10459 |
10460 | static const char *
10461 | hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10462 | {
10463 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10464 | if (hfinfo->display & BASE_EXT_STRING0x00000200)
10465 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10466 | else
10467 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10468 | }
10469 |
10470 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10471 | return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10472 |
10473 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10474 | return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10475 |
10476 | /* If this is reached somebody registered a 64-bit field with a 32-bit
10477 | * value-string, which isn't right. */
10478 | 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)
10479 | hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string" , hfinfo->abbrev);
10480 |
10481 | /* This is necessary to squelch MSVC errors; is there
10482 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10483 | never returns? */
10484 | return NULL((void*)0);
10485 | }
10486 |
10487 | static const char *
10488 | hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10489 | {
10490 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10491 | return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10492 |
10493 | 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);
10494 |
10495 | /* This is necessary to squelch MSVC errors; is there
10496 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10497 | never returns? */
10498 | return NULL((void*)0);
10499 | }
10500 |
10501 | static const char *
10502 | hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10503 | {
10504 | const char *str = hf_try_val_to_str(value, hfinfo);
10505 |
10506 | return (str) ? str : unknown_str;
10507 | }
10508 |
10509 | static const char *
10510 | hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10511 | {
10512 | const char *str = hf_try_val64_to_str(value, hfinfo);
10513 |
10514 | return (str) ? str : unknown_str;
10515 | }
10516 |
10517 | /* Fills data for bitfield chars with val_strings */
10518 | static void
10519 | fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10520 | {
10521 | char *p;
10522 | int bitfield_byte_length, bitwidth;
10523 | uint32_t unshifted_value;
10524 | uint32_t value;
10525 |
10526 | char buf[32];
10527 | const char *out;
10528 |
10529 | const header_field_info *hfinfo = fi->hfinfo;
10530 |
10531 | /* Figure out the bit width */
10532 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10533 |
10534 | /* Un-shift bits */
10535 | value = fvalue_get_uinteger(fi->value);
10536 |
10537 | unshifted_value = value;
10538 | if (hfinfo->bitmask) {
10539 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10540 | }
10541 |
10542 | /* Create the bitfield first */
10543 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10544 | bitfield_byte_length = (int) (p - label_str);
10545 |
10546 | /* Fill in the textual info using stored (shifted) value */
10547 | if (hfinfo->display == BASE_CUSTOM) {
10548 | char tmp[ITEM_LABEL_LENGTH240];
10549 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10550 |
10551 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10551, "fmtfunc"))));
10552 | fmtfunc(tmp, value);
10553 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10554 | }
10555 | else if (hfinfo->strings) {
10556 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10557 |
10558 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10559 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10560 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10561 | else
10562 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10563 | }
10564 | else {
10565 | out = hfinfo_char_value_format(hfinfo, buf, value);
10566 |
10567 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10568 | }
10569 | }
10570 |
10571 | /* Fills data for bitfield ints with val_strings */
10572 | static void
10573 | fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10574 | {
10575 | char *p;
10576 | int bitfield_byte_length, bitwidth;
10577 | uint32_t value, unshifted_value;
10578 | char buf[NUMBER_LABEL_LENGTH80];
10579 | const char *out;
10580 |
10581 | const header_field_info *hfinfo = fi->hfinfo;
10582 |
10583 | /* Figure out the bit width */
10584 | if (fi->flags & FI_VARINT0x00040000)
10585 | bitwidth = fi->length*8;
10586 | else
10587 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10588 |
10589 | /* Un-shift bits */
10590 | if (is_signed)
10591 | value = fvalue_get_sinteger(fi->value);
10592 | else
10593 | value = fvalue_get_uinteger(fi->value);
10594 |
10595 | unshifted_value = value;
10596 | if (hfinfo->bitmask) {
10597 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10598 | }
10599 |
10600 | /* Create the bitfield first */
10601 | if (fi->flags & FI_VARINT0x00040000)
10602 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10603 | else
10604 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10605 | bitfield_byte_length = (int) (p - label_str);
10606 |
10607 | /* Fill in the textual info using stored (shifted) value */
10608 | if (hfinfo->display == BASE_CUSTOM) {
10609 | char tmp[ITEM_LABEL_LENGTH240];
10610 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10611 |
10612 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10612, "fmtfunc"))));
10613 | fmtfunc(tmp, value);
10614 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10615 | }
10616 | else if (hfinfo->strings) {
10617 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10618 |
10619 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10620 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10621 | /*
10622 | * Unique values only display value_string string
10623 | * if there is a match. Otherwise it's just a number
10624 | */
10625 | if (val_str) {
10626 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10627 | } else {
10628 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10629 | }
10630 | } else {
10631 | if (val_str == NULL((void*)0))
10632 | val_str = "Unknown";
10633 |
10634 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10635 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10636 | else
10637 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10638 | }
10639 | }
10640 | else {
10641 | out = hfinfo_number_value_format(hfinfo, buf, value);
10642 |
10643 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10644 | }
10645 | }
10646 |
10647 | static void
10648 | fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10649 | {
10650 | char *p;
10651 | int bitfield_byte_length, bitwidth;
10652 | uint64_t value, unshifted_value;
10653 | char buf[NUMBER_LABEL_LENGTH80];
10654 | const char *out;
10655 |
10656 | const header_field_info *hfinfo = fi->hfinfo;
10657 |
10658 | /* Figure out the bit width */
10659 | if (fi->flags & FI_VARINT0x00040000)
10660 | bitwidth = fi->length*8;
10661 | else
10662 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10663 |
10664 | /* Un-shift bits */
10665 | if (is_signed)
10666 | value = fvalue_get_sinteger64(fi->value);
10667 | else
10668 | value = fvalue_get_uinteger64(fi->value);
10669 |
10670 | unshifted_value = value;
10671 | if (hfinfo->bitmask) {
10672 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10673 | }
10674 |
10675 | /* Create the bitfield first */
10676 | if (fi->flags & FI_VARINT0x00040000)
10677 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10678 | else
10679 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10680 | bitfield_byte_length = (int) (p - label_str);
10681 |
10682 | /* Fill in the textual info using stored (shifted) value */
10683 | if (hfinfo->display == BASE_CUSTOM) {
10684 | char tmp[ITEM_LABEL_LENGTH240];
10685 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10686 |
10687 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 10687, "fmtfunc64" ))));
10688 | fmtfunc64(tmp, value);
10689 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10690 | }
10691 | else if (hfinfo->strings) {
10692 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
10693 |
10694 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
10695 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10696 | /*
10697 | * Unique values only display value_string string
10698 | * if there is a match. Otherwise it's just a number
10699 | */
10700 | if (val_str) {
10701 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10702 | } else {
10703 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10704 | }
10705 | } else {
10706 | if (val_str == NULL((void*)0))
10707 | val_str = "Unknown";
10708 |
10709 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10710 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10711 | else
10712 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10713 | }
10714 | }
10715 | else {
10716 | out = hfinfo_number_value_format64(hfinfo, buf, value);
10717 |
10718 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10719 | }
10720 | }
10721 |
10722 | static void
10723 | fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10724 | {
10725 | const header_field_info *hfinfo = fi->hfinfo;
10726 | uint32_t value;
10727 |
10728 | char buf[32];
10729 | const char *out;
10730 |
10731 | value = fvalue_get_uinteger(fi->value);
10732 |
10733 | /* Fill in the textual info */
10734 | if (hfinfo->display == BASE_CUSTOM) {
10735 | char tmp[ITEM_LABEL_LENGTH240];
10736 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10737 |
10738 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10738, "fmtfunc"))));
10739 | fmtfunc(tmp, value);
10740 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10741 | }
10742 | else if (hfinfo->strings) {
10743 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10744 |
10745 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10746 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10747 | }
10748 | else {
10749 | out = hfinfo_char_value_format(hfinfo, buf, value);
10750 |
10751 | label_fill(label_str, 0, hfinfo, out, value_pos);
10752 | }
10753 | }
10754 |
10755 | static void
10756 | fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10757 | {
10758 | const header_field_info *hfinfo = fi->hfinfo;
10759 | uint32_t value;
10760 |
10761 | char buf[NUMBER_LABEL_LENGTH80];
10762 | const char *out;
10763 |
10764 | if (is_signed)
10765 | value = fvalue_get_sinteger(fi->value);
10766 | else
10767 | value = fvalue_get_uinteger(fi->value);
10768 |
10769 | /* Fill in the textual info */
10770 | if (hfinfo->display == BASE_CUSTOM) {
10771 | char tmp[ITEM_LABEL_LENGTH240];
10772 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10773 |
10774 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10774, "fmtfunc"))));
10775 | fmtfunc(tmp, value);
10776 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10777 | }
10778 | else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10779 | /*
10780 | * It makes no sense to have a value-string table for a
10781 | * frame-number field - they're just integers giving
10782 | * the ordinal frame number.
10783 | */
10784 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10785 |
10786 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10787 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10788 | /*
10789 | * Unique values only display value_string string
10790 | * if there is a match. Otherwise it's just a number
10791 | */
10792 | if (val_str) {
10793 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10794 | } else {
10795 | label_fill(label_str, 0, hfinfo, out, value_pos);
10796 | }
10797 | } else {
10798 | if (val_str == NULL((void*)0))
10799 | val_str = "Unknown";
10800 |
10801 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10802 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
10803 | else
10804 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10805 | }
10806 | }
10807 | 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 ))) {
10808 | char tmp[ITEM_LABEL_LENGTH240];
10809 |
10810 | port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10811 | display_to_port_type((field_display_e)hfinfo->display), value);
10812 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10813 | }
10814 | else {
10815 | out = hfinfo_number_value_format(hfinfo, buf, value);
10816 |
10817 | label_fill(label_str, 0, hfinfo, out, value_pos);
10818 | }
10819 | }
10820 |
10821 | static void
10822 | fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10823 | {
10824 | const header_field_info *hfinfo = fi->hfinfo;
10825 | uint64_t value;
10826 |
10827 | char buf[NUMBER_LABEL_LENGTH80];
10828 | const char *out;
10829 |
10830 | if (is_signed)
10831 | value = fvalue_get_sinteger64(fi->value);
10832 | else
10833 | value = fvalue_get_uinteger64(fi->value);
10834 |
10835 | /* Fill in the textual info */
10836 | if (hfinfo->display == BASE_CUSTOM) {
10837 | char tmp[ITEM_LABEL_LENGTH240];
10838 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10839 |
10840 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 10840, "fmtfunc64" ))));
10841 | fmtfunc64(tmp, value);
10842 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10843 | }
10844 | else if (hfinfo->strings) {
10845 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
10846 |
10847 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
10848 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10849 | /*
10850 | * Unique values only display value_string string
10851 | * if there is a match. Otherwise it's just a number
10852 | */
10853 | if (val_str) {
10854 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10855 | } else {
10856 | label_fill(label_str, 0, hfinfo, out, value_pos);
10857 | }
10858 | } else {
10859 | if (val_str == NULL((void*)0))
10860 | val_str = "Unknown";
10861 |
10862 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10863 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
10864 | else
10865 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10866 | }
10867 | }
10868 | else {
10869 | out = hfinfo_number_value_format64(hfinfo, buf, value);
10870 |
10871 | label_fill(label_str, 0, hfinfo, out, value_pos);
10872 | }
10873 | }
10874 |
10875 | static size_t
10876 | fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10877 | {
10878 | int display;
10879 | int n;
10880 | double value;
10881 |
10882 | if (label_str_size < 12) {
10883 | /* Not enough room to write an entire floating point value. */
10884 | return 0;
10885 | }
10886 |
10887 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10888 | value = fvalue_get_floating(fi->value);
10889 |
10890 | if (display == BASE_CUSTOM) {
10891 | const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10892 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10892, "fmtfunc"))));
10893 | fmtfunc(label_str, value);
10894 | return strlen(label_str);
10895 | }
10896 |
10897 | switch (display) {
10898 | case BASE_NONE:
10899 | if (fi->hfinfo->type == FT_FLOAT) {
10900 | n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10901 | } else {
10902 | n = (int)strlen(dtoa_g_fmt(label_str, value));
10903 | }
10904 | break;
10905 | case BASE_DEC:
10906 | n = snprintf(label_str, label_str_size, "%f", value);
10907 | break;
10908 | case BASE_HEX:
10909 | n = snprintf(label_str, label_str_size, "%a", value);
10910 | break;
10911 | case BASE_EXP:
10912 | n = snprintf(label_str, label_str_size, "%e", value);
10913 | break;
10914 | default:
10915 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10915 , __func__, "assertion \"not reached\" failed");
10916 | }
10917 | if (n < 0) {
10918 | return 0; /* error */
10919 | }
10920 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10921 | const char *hf_str_val;
10922 | hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10923 | n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10924 | }
10925 | if (n > label_str_size) {
10926 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10926, __func__, "label length too small"); } } while (0);
10927 | return strlen(label_str);
10928 | }
10929 |
10930 | return n;
10931 | }
10932 |
10933 | void
10934 | fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10935 | {
10936 | char tmp[ITEM_LABEL_LENGTH240];
10937 |
10938 | fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10939 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10940 | }
10941 |
10942 | static size_t
10943 | fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10944 | {
10945 | int display;
10946 | size_t pos = 0;
10947 | double value;
10948 | char* tmp_str;
10949 |
10950 | if (label_str_size < 12) {
10951 | /* Not enough room to write an entire floating point value. */
10952 | return 0;
10953 | }
10954 |
10955 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10956 | tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10957 | pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10958 | wmem_free(NULL((void*)0), tmp_str);
10959 |
10960 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10961 | const char *hf_str_val;
10962 | fvalue_to_double(fi->value, &value);
10963 | hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10964 | pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10965 | }
10966 | if ((int)pos > label_str_size) {
10967 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10967, __func__, "label length too small"); } } while (0);
10968 | return strlen(label_str);
10969 | }
10970 |
10971 | return pos;
10972 | }
10973 |
10974 | void
10975 | fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10976 | {
10977 | char tmp[ITEM_LABEL_LENGTH240];
10978 |
10979 | fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10980 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10981 | }
10982 |
10983 | int
10984 | hfinfo_bitshift(const header_field_info *hfinfo)
10985 | {
10986 | return ws_ctz(hfinfo->bitmask);
10987 | }
10988 |
10989 |
10990 | static int
10991 | hfinfo_bitoffset(const header_field_info *hfinfo)
10992 | {
10993 | if (!hfinfo->bitmask) {
10994 | return 0;
10995 | }
10996 |
10997 | /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10998 | * as the first bit */
10999 | return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11000 | }
11001 |
11002 | static int
11003 | hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11004 | {
11005 | if (!hfinfo->bitmask) {
11006 | return 0;
11007 | }
11008 |
11009 | /* ilog2 = first set bit, ctz = last set bit */
11010 | return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11011 | }
11012 |
11013 | static int
11014 | hfinfo_type_bitwidth(enum ftenum type)
11015 | {
11016 | int bitwidth = 0;
11017 |
11018 | switch (type) {
11019 | case FT_CHAR:
11020 | case FT_UINT8:
11021 | case FT_INT8:
11022 | bitwidth = 8;
11023 | break;
11024 | case FT_UINT16:
11025 | case FT_INT16:
11026 | bitwidth = 16;
11027 | break;
11028 | case FT_UINT24:
11029 | case FT_INT24:
11030 | bitwidth = 24;
11031 | break;
11032 | case FT_UINT32:
11033 | case FT_INT32:
11034 | bitwidth = 32;
11035 | break;
11036 | case FT_UINT40:
11037 | case FT_INT40:
11038 | bitwidth = 40;
11039 | break;
11040 | case FT_UINT48:
11041 | case FT_INT48:
11042 | bitwidth = 48;
11043 | break;
11044 | case FT_UINT56:
11045 | case FT_INT56:
11046 | bitwidth = 56;
11047 | break;
11048 | case FT_UINT64:
11049 | case FT_INT64:
11050 | bitwidth = 64;
11051 | break;
11052 | default:
11053 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 11053));
11054 | ;
11055 | }
11056 | return bitwidth;
11057 | }
11058 |
11059 |
11060 | static int
11061 | hfinfo_container_bitwidth(const header_field_info *hfinfo)
11062 | {
11063 | if (!hfinfo->bitmask) {
11064 | return 0;
11065 | }
11066 |
11067 | if (hfinfo->type == FT_BOOLEAN) {
11068 | return hfinfo->display; /* hacky? :) */
11069 | }
11070 |
11071 | return hfinfo_type_bitwidth(hfinfo->type);
11072 | }
11073 |
11074 | static int
11075 | hfinfo_hex_digits(const header_field_info *hfinfo)
11076 | {
11077 | int bitwidth;
11078 |
11079 | /* If we have a bitmask, hfinfo->type is the width of the container, so not
11080 | * appropriate to determine the number of hex digits for the field.
11081 | * So instead, we compute it from the bitmask.
11082 | */
11083 | if (hfinfo->bitmask != 0) {
11084 | bitwidth = hfinfo_mask_bitwidth(hfinfo);
11085 | } else {
11086 | bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11087 | }
11088 |
11089 | /* Divide by 4, rounding up, to get number of hex digits. */
11090 | return (bitwidth + 3) / 4;
11091 | }
11092 |
11093 | const char *
11094 | hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11095 | {
11096 | char *ptr = &buf[6];
11097 | static const char hex_digits[16] =
11098 | { '0', '1', '2', '3', '4', '5', '6', '7',
11099 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11100 |
11101 | *ptr = '\0';
11102 | *(--ptr) = '\'';
11103 | /* Properly format value */
11104 | if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11105 | /*
11106 | * Printable, so just show the character, and, if it needs
11107 | * to be escaped, escape it.
11108 | */
11109 | *(--ptr) = value;
11110 | if (value == '\\' || value == '\'')
11111 | *(--ptr) = '\\';
11112 | } else {
11113 | /*
11114 | * Non-printable; show it as an escape sequence.
11115 | */
11116 | switch (value) {
11117 |
11118 | case '\0':
11119 | /*
11120 | * Show a NUL with only one digit.
11121 | */
11122 | *(--ptr) = '0';
11123 | break;
11124 |
11125 | case '\a':
11126 | case '\b':
11127 | case '\f':
11128 | case '\n':
11129 | case '\r':
11130 | case '\t':
11131 | case '\v':
11132 | *(--ptr) = value - '\a' + 'a';
11133 | break;
11134 |
11135 | default:
11136 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11137 |
11138 | case BASE_OCT:
11139 | *(--ptr) = (value & 0x7) + '0';
11140 | value >>= 3;
11141 | *(--ptr) = (value & 0x7) + '0';
11142 | value >>= 3;
11143 | *(--ptr) = (value & 0x7) + '0';
11144 | break;
11145 |
11146 | case BASE_HEX:
11147 | *(--ptr) = hex_digits[value & 0x0F];
11148 | value >>= 4;
11149 | *(--ptr) = hex_digits[value & 0x0F];
11150 | *(--ptr) = 'x';
11151 | break;
11152 |
11153 | default:
11154 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11155 | }
11156 | }
11157 | *(--ptr) = '\\';
11158 | }
11159 | *(--ptr) = '\'';
11160 | return ptr;
11161 | }
11162 |
11163 | static const char *
11164 | hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11165 | {
11166 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11167 | 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 ));
11168 |
11169 | *ptr = '\0';
11170 | /* Properly format value */
11171 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11172 | case BASE_DEC:
11173 | return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11174 |
11175 | case BASE_DEC_HEX:
11176 | *(--ptr) = ')';
11177 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11178 | *(--ptr) = '(';
11179 | *(--ptr) = ' ';
11180 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11181 | return ptr;
11182 |
11183 | case BASE_OCT:
11184 | return oct_to_str_back(ptr, value);
11185 |
11186 | case BASE_HEX:
11187 | return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11188 |
11189 | case BASE_HEX_DEC:
11190 | *(--ptr) = ')';
11191 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11192 | *(--ptr) = '(';
11193 | *(--ptr) = ' ';
11194 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11195 | return ptr;
11196 |
11197 | case BASE_PT_UDP:
11198 | case BASE_PT_TCP:
11199 | case BASE_PT_DCCP:
11200 | case BASE_PT_SCTP:
11201 | port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11202 | display_to_port_type((field_display_e)display), value);
11203 | return buf;
11204 | case BASE_OUI:
11205 | {
11206 | uint8_t p_oui[3];
11207 | const char *manuf_name;
11208 |
11209 | p_oui[0] = value >> 16 & 0xFF;
11210 | p_oui[1] = value >> 8 & 0xFF;
11211 | p_oui[2] = value & 0xFF;
11212 |
11213 | /* Attempt an OUI lookup. */
11214 | manuf_name = uint_get_manuf_name_if_known(value);
11215 | if (manuf_name == NULL((void*)0)) {
11216 | /* Could not find an OUI. */
11217 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11218 | }
11219 | else {
11220 | /* Found an address string. */
11221 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11222 | }
11223 | return buf;
11224 | }
11225 |
11226 | default:
11227 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11228 | }
11229 | return ptr;
11230 | }
11231 |
11232 | static const char *
11233 | hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11234 | {
11235 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11236 | 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 ));
11237 |
11238 | *ptr = '\0';
11239 | /* Properly format value */
11240 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11241 | case BASE_DEC:
11242 | return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11243 |
11244 | case BASE_DEC_HEX:
11245 | *(--ptr) = ')';
11246 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11247 | *(--ptr) = '(';
11248 | *(--ptr) = ' ';
11249 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11250 | return ptr;
11251 |
11252 | case BASE_OCT:
11253 | return oct64_to_str_back(ptr, value);
11254 |
11255 | case BASE_HEX:
11256 | return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11257 |
11258 | case BASE_HEX_DEC:
11259 | *(--ptr) = ')';
11260 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11261 | *(--ptr) = '(';
11262 | *(--ptr) = ' ';
11263 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11264 | return ptr;
11265 |
11266 | default:
11267 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11268 | }
11269 |
11270 | return ptr;
11271 | }
11272 |
11273 | static const char *
11274 | hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11275 | {
11276 | int display = hfinfo->display;
11277 |
11278 | if (hfinfo->type == FT_FRAMENUM) {
11279 | /*
11280 | * Frame numbers are always displayed in decimal.
11281 | */
11282 | display = BASE_DEC;
11283 | }
11284 |
11285 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11286 | }
11287 |
11288 | static const char *
11289 | hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11290 | {
11291 | int display = hfinfo->display;
11292 |
11293 | if (hfinfo->type == FT_FRAMENUM) {
11294 | /*
11295 | * Frame numbers are always displayed in decimal.
11296 | */
11297 | display = BASE_DEC;
11298 | }
11299 |
11300 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11301 | }
11302 |
11303 | static const char *
11304 | hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11305 | {
11306 | /* Get the underlying BASE_ value */
11307 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11308 |
11309 | return hfinfo_char_value_format_display(display, buf, value);
11310 | }
11311 |
11312 | static const char *
11313 | hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11314 | {
11315 | /* Get the underlying BASE_ value */
11316 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11317 |
11318 | if (hfinfo->type == FT_FRAMENUM) {
11319 | /*
11320 | * Frame numbers are always displayed in decimal.
11321 | */
11322 | display = BASE_DEC;
11323 | }
11324 |
11325 | if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)== BASE_PT_DCCP||(display)==BASE_PT_SCTP))) {
11326 | display = BASE_DEC;
11327 | } else if (display == BASE_OUI) {
11328 | display = BASE_HEX;
11329 | }
11330 |
11331 | switch (display) {
11332 | case BASE_NONE:
11333 | /* case BASE_DEC: */
11334 | case BASE_DEC_HEX:
11335 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11336 | case BASE_CUSTOM:
11337 | display = BASE_DEC;
11338 | break;
11339 |
11340 | /* case BASE_HEX: */
11341 | case BASE_HEX_DEC:
11342 | display = BASE_HEX;
11343 | break;
11344 | }
11345 |
11346 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11347 | }
11348 |
11349 | static const char *
11350 | hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11351 | {
11352 | /* Get the underlying BASE_ value */
11353 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11354 |
11355 | if (hfinfo->type == FT_FRAMENUM) {
11356 | /*
11357 | * Frame numbers are always displayed in decimal.
11358 | */
11359 | display = BASE_DEC;
11360 | }
11361 |
11362 | switch (display) {
11363 | case BASE_NONE:
11364 | /* case BASE_DEC: */
11365 | case BASE_DEC_HEX:
11366 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11367 | case BASE_CUSTOM:
11368 | display = BASE_DEC;
11369 | break;
11370 |
11371 | /* case BASE_HEX: */
11372 | case BASE_HEX_DEC:
11373 | display = BASE_HEX;
11374 | break;
11375 | }
11376 |
11377 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11378 | }
11379 |
11380 | static const char *
11381 | hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11382 | {
11383 | /* Get the underlying BASE_ value */
11384 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11385 |
11386 | return hfinfo_char_value_format_display(display, buf, value);
11387 | }
11388 |
11389 | static const char *
11390 | hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11391 | {
11392 | /* Get the underlying BASE_ value */
11393 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11394 |
11395 | if (display == BASE_NONE)
11396 | return NULL((void*)0);
11397 |
11398 | if (display == BASE_DEC_HEX)
11399 | display = BASE_DEC;
11400 | if (display == BASE_HEX_DEC)
11401 | display = BASE_HEX;
11402 |
11403 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11404 | }
11405 |
11406 | static const char *
11407 | hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11408 | {
11409 | /* Get the underlying BASE_ value */
11410 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11411 |
11412 | if (display == BASE_NONE)
11413 | return NULL((void*)0);
11414 |
11415 | if (display == BASE_DEC_HEX)
11416 | display = BASE_DEC;
11417 | if (display == BASE_HEX_DEC)
11418 | display = BASE_HEX;
11419 |
11420 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11421 | }
11422 |
11423 | const char *
11424 | proto_registrar_get_name(const int n)
11425 | {
11426 | header_field_info *hfinfo;
11427 |
11428 | 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", 11428 , __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", 11428 , "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", 11428, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11429 | return hfinfo->name;
11430 | }
11431 |
11432 | const char *
11433 | proto_registrar_get_abbrev(const int n)
11434 | {
11435 | header_field_info *hfinfo;
11436 |
11437 | 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", 11437 , __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", 11437 , "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", 11437, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11438 | return hfinfo->abbrev;
11439 | }
11440 |
11441 | enum ftenum
11442 | proto_registrar_get_ftype(const int n)
11443 | {
11444 | header_field_info *hfinfo;
11445 |
11446 | 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", 11446 , __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", 11446 , "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", 11446, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11447 | return hfinfo->type;
11448 | }
11449 |
11450 | int
11451 | proto_registrar_get_parent(const int n)
11452 | {
11453 | header_field_info *hfinfo;
11454 |
11455 | 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", 11455 , __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", 11455 , "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", 11455, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11456 | return hfinfo->parent;
11457 | }
11458 |
11459 | bool_Bool
11460 | proto_registrar_is_protocol(const int n)
11461 | {
11462 | header_field_info *hfinfo;
11463 |
11464 | 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", 11464 , __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", 11464 , "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", 11464, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11465 | return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11466 | }
11467 |
11468 | /* Returns length of field in packet (not necessarily the length
11469 | * in our internal representation, as in the case of IPv4).
11470 | * 0 means undeterminable at time of registration
11471 | * -1 means the field is not registered. */
11472 | int
11473 | proto_registrar_get_length(const int n)
11474 | {
11475 | header_field_info *hfinfo;
11476 |
11477 | 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", 11477 , __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", 11477 , "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", 11477, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11478 | return ftype_wire_size(hfinfo->type);
11479 | }
11480 |
11481 | /* Looks for a protocol or a field in a proto_tree. Returns true if
11482 | * it exists anywhere, or false if it exists nowhere. */
11483 | bool_Bool
11484 | proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11485 | {
11486 | GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11487 |
11488 | if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11489 | return true1;
11490 | }
11491 | else {
11492 | return false0;
11493 | }
11494 | }
11495 |
11496 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11497 | * This only works if the hfindex was "primed" before the dissection
11498 | * took place, as we just pass back the already-created GPtrArray*.
11499 | * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11500 | * handles that. */
11501 | GPtrArray *
11502 | proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11503 | {
11504 | if (!tree)
11505 | return NULL((void*)0);
11506 |
11507 | if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11508 | return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11509 | GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11510 | else
11511 | return NULL((void*)0);
11512 | }
11513 |
11514 | bool_Bool
11515 | proto_tracking_interesting_fields(const proto_tree *tree)
11516 | {
11517 | GHashTable *interesting_hfids;
11518 |
11519 | if (!tree)
11520 | return false0;
11521 |
11522 | interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11523 |
11524 | return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11525 | }
11526 |
11527 | /* Helper struct for proto_find_info() and proto_all_finfos() */
11528 | typedef struct {
11529 | GPtrArray *array;
11530 | int id;
11531 | } ffdata_t;
11532 |
11533 | /* Helper function for proto_find_info() */
11534 | static bool_Bool
11535 | find_finfo(proto_node *node, void * data)
11536 | {
11537 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11538 | if (fi && fi->hfinfo) {
11539 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11540 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11541 | }
11542 | }
11543 |
11544 | /* Don't stop traversing. */
11545 | return false0;
11546 | }
11547 |
11548 | /* Helper function for proto_find_first_info() */
11549 | static bool_Bool
11550 | find_first_finfo(proto_node *node, void *data)
11551 | {
11552 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11553 | if (fi && fi->hfinfo) {
11554 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11555 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11556 |
11557 | /* Stop traversing. */
11558 | return true1;
11559 | }
11560 | }
11561 |
11562 | /* Continue traversing. */
11563 | return false0;
11564 | }
11565 |
11566 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11567 | * This works on any proto_tree, primed or unprimed, but actually searches
11568 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11569 | * The caller does need to free the returned GPtrArray with
11570 | * g_ptr_array_free(<array>, true).
11571 | */
11572 | GPtrArray *
11573 | proto_find_finfo(proto_tree *tree, const int id)
11574 | {
11575 | ffdata_t ffdata;
11576 |
11577 | ffdata.array = g_ptr_array_new();
11578 | ffdata.id = id;
11579 |
11580 | proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11581 |
11582 | return ffdata.array;
11583 | }
11584 |
11585 | /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11586 | * This works on any proto_tree, primed or unprimed, but actually searches
11587 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11588 | * The caller does need to free the returned GPtrArray with
11589 | * g_ptr_array_free(<array>, true).
11590 | */
11591 | GPtrArray *
11592 | proto_find_first_finfo(proto_tree *tree, const int id)
11593 | {
11594 | ffdata_t ffdata;
11595 |
11596 | ffdata.array = g_ptr_array_new();
11597 | ffdata.id = id;
11598 |
11599 | proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11600 |
11601 | return ffdata.array;
11602 | }
11603 |
11604 | /* Helper function for proto_all_finfos() */
11605 | static bool_Bool
11606 | every_finfo(proto_node *node, void * data)
11607 | {
11608 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11609 | if (fi && fi->hfinfo) {
11610 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11611 | }
11612 |
11613 | /* Don't stop traversing. */
11614 | return false0;
11615 | }
11616 |
11617 | /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11618 | * The caller does need to free the returned GPtrArray with
11619 | * g_ptr_array_free(<array>, true).
11620 | */
11621 | GPtrArray *
11622 | proto_all_finfos(proto_tree *tree)
11623 | {
11624 | ffdata_t ffdata;
11625 |
11626 | /* Pre allocate enough space to hold all fields in most cases */
11627 | ffdata.array = g_ptr_array_sized_new(512);
11628 | ffdata.id = 0;
11629 |
11630 | proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11631 |
11632 | return ffdata.array;
11633 | }
11634 |
11635 |
11636 | typedef struct {
11637 | unsigned offset;
11638 | field_info *finfo;
11639 | tvbuff_t *tvb;
11640 | } offset_search_t;
11641 |
11642 | static bool_Bool
11643 | check_for_offset(proto_node *node, void * data)
11644 | {
11645 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11646 | offset_search_t *offsearch = (offset_search_t *)data;
11647 |
11648 | /* !fi == the top most container node which holds nothing */
11649 | if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11650 | if (offsearch->offset >= (unsigned) fi->start &&
11651 | offsearch->offset < (unsigned) (fi->start + fi->length)) {
11652 |
11653 | offsearch->finfo = fi;
11654 | return false0; /* keep traversing */
11655 | }
11656 | }
11657 | return false0; /* keep traversing */
11658 | }
11659 |
11660 | /* Search a proto_tree backwards (from leaves to root) looking for the field
11661 | * whose start/length occupies 'offset' */
11662 | /* XXX - I couldn't find an easy way to search backwards, so I search
11663 | * forwards, w/o stopping. Therefore, the last finfo I find will the be
11664 | * the one I want to return to the user. This algorithm is inefficient
11665 | * and could be re-done, but I'd have to handle all the children and
11666 | * siblings of each node myself. When I have more time I'll do that.
11667 | * (yeah right) */
11668 | field_info *
11669 | proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11670 | {
11671 | offset_search_t offsearch;
11672 |
11673 | offsearch.offset = offset;
11674 | offsearch.finfo = NULL((void*)0);
11675 | offsearch.tvb = tvb;
11676 |
11677 | proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11678 |
11679 | return offsearch.finfo;
11680 | }
11681 |
11682 | typedef struct {
11683 | int length;
11684 | char *buf;
11685 | } decoded_data_t;
11686 |
11687 | static bool_Bool
11688 | check_for_undecoded(proto_node *node, void * data)
11689 | {
11690 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11691 | decoded_data_t* decoded = (decoded_data_t*)data;
11692 | int i;
11693 | unsigned byte;
11694 | unsigned bit;
11695 |
11696 | if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11697 | for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11698 | byte = i / 8;
11699 | bit = i % 8;
11700 | decoded->buf[byte] |= (1 << bit);
11701 | }
11702 | }
11703 |
11704 | return false0;
11705 | }
11706 |
11707 | char*
11708 | proto_find_undecoded_data(proto_tree *tree, unsigned length)
11709 | {
11710 | decoded_data_t decoded;
11711 | decoded.length = length;
11712 | decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11713 |
11714 | proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11715 | return decoded.buf;
11716 | }
11717 |
11718 | /* Dumps the protocols in the registration database to stdout. An independent
11719 | * program can take this output and format it into nice tables or HTML or
11720 | * whatever.
11721 | *
11722 | * There is one record per line. The fields are tab-delimited.
11723 | *
11724 | * Field 1 = protocol name
11725 | * Field 2 = protocol short name
11726 | * Field 3 = protocol filter name
11727 | * Field 4 = protocol enabled
11728 | * Field 5 = protocol enabled by default
11729 | * Field 6 = protocol can toggle
11730 | */
11731 | void
11732 | proto_registrar_dump_protocols(void)
11733 | {
11734 | protocol_t *protocol;
11735 | int i;
11736 | void *cookie = NULL((void*)0);
11737 |
11738 |
11739 | i = proto_get_first_protocol(&cookie);
11740 | while (i != -1) {
11741 | protocol = find_protocol_by_id(i);
11742 | printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11743 | protocol->name,
11744 | protocol->short_name,
11745 | protocol->filter_name,
11746 | (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11747 | (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11748 | (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11749 | i = proto_get_next_protocol(&cookie);
11750 | }
11751 | }
11752 |
11753 | /* Dumps the value_strings, extended value string headers, range_strings
11754 | * or true/false strings for fields that have them.
11755 | * There is one record per line. Fields are tab-delimited.
11756 | * There are four types of records: Value String, Extended Value String Header,
11757 | * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11758 | * the type of record.
11759 | *
11760 | * Note that a record will be generated only if the value_string,... is referenced
11761 | * in a registered hfinfo entry.
11762 | *
11763 | *
11764 | * Value Strings
11765 | * -------------
11766 | * Field 1 = 'V'
11767 | * Field 2 = Field abbreviation to which this value string corresponds
11768 | * Field 3 = Integer value
11769 | * Field 4 = String
11770 | *
11771 | * Extended Value String Headers
11772 | * -----------------------------
11773 | * Field 1 = 'E'
11774 | * Field 2 = Field abbreviation to which this extended value string header corresponds
11775 | * Field 3 = Extended Value String "Name"
11776 | * Field 4 = Number of entries in the associated value_string array
11777 | * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11778 | *
11779 | * Range Strings
11780 | * -------------
11781 | * Field 1 = 'R'
11782 | * Field 2 = Field abbreviation to which this range string corresponds
11783 | * Field 3 = Integer value: lower bound
11784 | * Field 4 = Integer value: upper bound
11785 | * Field 5 = String
11786 | *
11787 | * True/False Strings
11788 | * ------------------
11789 | * Field 1 = 'T'
11790 | * Field 2 = Field abbreviation to which this true/false string corresponds
11791 | * Field 3 = True String
11792 | * Field 4 = False String
11793 | */
11794 | void
11795 | proto_registrar_dump_values(void)
11796 | {
11797 | header_field_info *hfinfo;
11798 | int i, len, vi;
11799 | const value_string *vals;
11800 | const val64_string *vals64;
11801 | const range_string *range;
11802 | const true_false_string *tfs;
11803 | const unit_name_string *units;
11804 |
11805 | len = gpa_hfinfo.len;
11806 | for (i = 0; i < len ; i++) {
11807 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11808 | continue; /* This is a deregistered protocol or field */
11809 |
11810 | 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", 11810 , __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", 11810 , "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", 11810, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
11811 |
11812 | if (hfinfo->id == hf_text_only) {
11813 | continue;
11814 | }
11815 |
11816 | /* ignore protocols */
11817 | if (proto_registrar_is_protocol(i)) {
11818 | continue;
11819 | }
11820 | /* process header fields */
11821 | #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11822 | /*
11823 | * If this field isn't at the head of the list of
11824 | * fields with this name, skip this field - all
11825 | * fields with the same name are really just versions
11826 | * of the same field stored in different bits, and
11827 | * should have the same type/radix/value list, and
11828 | * just differ in their bit masks. (If a field isn't
11829 | * a bitfield, but can be, say, 1 or 2 bytes long,
11830 | * it can just be made FT_UINT16, meaning the
11831 | * *maximum* length is 2 bytes, and be used
11832 | * for all lengths.)
11833 | */
11834 | if (hfinfo->same_name_prev_id != -1)
11835 | continue;
11836 | #endif
11837 | vals = NULL((void*)0);
11838 | vals64 = NULL((void*)0);
11839 | range = NULL((void*)0);
11840 | tfs = NULL((void*)0);
11841 | units = NULL((void*)0);
11842 |
11843 | if (hfinfo->strings != NULL((void*)0)) {
11844 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11845 | (hfinfo->type == FT_CHAR ||
11846 | hfinfo->type == FT_UINT8 ||
11847 | hfinfo->type == FT_UINT16 ||
11848 | hfinfo->type == FT_UINT24 ||
11849 | hfinfo->type == FT_UINT32 ||
11850 | hfinfo->type == FT_UINT40 ||
11851 | hfinfo->type == FT_UINT48 ||
11852 | hfinfo->type == FT_UINT56 ||
11853 | hfinfo->type == FT_UINT64 ||
11854 | hfinfo->type == FT_INT8 ||
11855 | hfinfo->type == FT_INT16 ||
11856 | hfinfo->type == FT_INT24 ||
11857 | hfinfo->type == FT_INT32 ||
11858 | hfinfo->type == FT_INT40 ||
11859 | hfinfo->type == FT_INT48 ||
11860 | hfinfo->type == FT_INT56 ||
11861 | hfinfo->type == FT_INT64 ||
11862 | hfinfo->type == FT_FLOAT ||
11863 | hfinfo->type == FT_DOUBLE)) {
11864 |
11865 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11866 | range = (const range_string *)hfinfo->strings;
11867 | } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11868 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11869 | vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11870 | } else {
11871 | vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11872 | }
11873 | } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11874 | vals64 = (const val64_string *)hfinfo->strings;
11875 | } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11876 | units = (const unit_name_string *)hfinfo->strings;
11877 | } else {
11878 | vals = (const value_string *)hfinfo->strings;
11879 | }
11880 | }
11881 | else if (hfinfo->type == FT_BOOLEAN) {
11882 | tfs = (const struct true_false_string *)hfinfo->strings;
11883 | }
11884 | }
11885 |
11886 | /* Print value strings? */
11887 | if (vals) {
11888 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11889 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11890 | val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11891 | if (!val64_string_ext_validate(vse_p)) {
11892 | ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11892, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
11893 | continue;
11894 | }
11895 | try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11896 | printf("E\t%s\t%u\t%s\t%s\n",
11897 | hfinfo->abbrev,
11898 | VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11899 | VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11900 | val64_string_ext_match_type_str(vse_p));
11901 | } else {
11902 | value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11903 | if (!value_string_ext_validate(vse_p)) {
11904 | ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11904, __func__, "Invalid value_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
11905 | continue;
11906 | }
11907 | try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11908 | printf("E\t%s\t%u\t%s\t%s\n",
11909 | hfinfo->abbrev,
11910 | VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11911 | VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11912 | value_string_ext_match_type_str(vse_p));
11913 | }
11914 | }
11915 | vi = 0;
11916 | while (vals[vi].strptr) {
11917 | /* Print in the proper base */
11918 | if (hfinfo->type == FT_CHAR) {
11919 | if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT ) != 0)) {
11920 | printf("V\t%s\t'%c'\t%s\n",
11921 | hfinfo->abbrev,
11922 | vals[vi].value,
11923 | vals[vi].strptr);
11924 | } else {
11925 | if (hfinfo->display == BASE_HEX) {
11926 | printf("V\t%s\t'\\x%02x'\t%s\n",
11927 | hfinfo->abbrev,
11928 | vals[vi].value,
11929 | vals[vi].strptr);
11930 | }
11931 | else {
11932 | printf("V\t%s\t'\\%03o'\t%s\n",
11933 | hfinfo->abbrev,
11934 | vals[vi].value,
11935 | vals[vi].strptr);
11936 | }
11937 | }
11938 | } else {
11939 | if (hfinfo->display == BASE_HEX) {
11940 | printf("V\t%s\t0x%x\t%s\n",
11941 | hfinfo->abbrev,
11942 | vals[vi].value,
11943 | vals[vi].strptr);
11944 | }
11945 | else {
11946 | printf("V\t%s\t%u\t%s\n",
11947 | hfinfo->abbrev,
11948 | vals[vi].value,
11949 | vals[vi].strptr);
11950 | }
11951 | }
11952 | vi++;
11953 | }
11954 | }
11955 | else if (vals64) {
11956 | vi = 0;
11957 | while (vals64[vi].strptr) {
11958 | printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11959 | hfinfo->abbrev,
11960 | vals64[vi].value,
11961 | vals64[vi].strptr);
11962 | vi++;
11963 | }
11964 | }
11965 |
11966 | /* print range strings? */
11967 | else if (range) {
11968 | vi = 0;
11969 | while (range[vi].strptr) {
11970 | /* Print in the proper base */
11971 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11972 | printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11973 | hfinfo->abbrev,
11974 | range[vi].value_min,
11975 | range[vi].value_max,
11976 | range[vi].strptr);
11977 | }
11978 | else {
11979 | printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11980 | hfinfo->abbrev,
11981 | range[vi].value_min,
11982 | range[vi].value_max,
11983 | range[vi].strptr);
11984 | }
11985 | vi++;
11986 | }
11987 | }
11988 |
11989 | /* Print true/false strings? */
11990 | else if (tfs) {
11991 | printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11992 | tfs->true_string, tfs->false_string);
11993 | }
11994 | /* Print unit strings? */
11995 | else if (units) {
11996 | printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11997 | units->singular, units->plural ? units->plural : "(no plural)");
11998 | }
11999 | }
12000 | }
12001 |
12002 | /* Prints the number of registered fields.
12003 | * Useful for determining an appropriate value for
12004 | * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12005 | *
12006 | * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12007 | * the number of fields, true otherwise.
12008 | */
12009 | bool_Bool
12010 | proto_registrar_dump_fieldcount(void)
12011 | {
12012 | uint32_t i;
12013 | header_field_info *hfinfo;
12014 | uint32_t deregistered_count = 0;
12015 | uint32_t same_name_count = 0;
12016 | uint32_t protocol_count = 0;
12017 |
12018 | for (i = 0; i < gpa_hfinfo.len; i++) {
12019 | if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
12020 | deregistered_count++;
12021 | continue; /* This is a deregistered protocol or header field */
12022 | }
12023 |
12024 | 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", 12024 , __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", 12024 , "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", 12024, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12025 |
12026 | if (proto_registrar_is_protocol(i))
12027 | protocol_count++;
12028 |
12029 | if (hfinfo->same_name_prev_id != -1)
12030 | same_name_count++;
12031 | }
12032 |
12033 | printf("There are %u header fields registered, of which:\n"
12034 | "\t%u are deregistered\n"
12035 | "\t%u are protocols\n"
12036 | "\t%u have the same name as another field\n\n",
12037 | gpa_hfinfo.len, deregistered_count, protocol_count,
12038 | same_name_count);
12039 |
12040 | printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12041 | (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12042 | "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12043 | "\n");
12044 |
12045 | printf("The header field table consumes %u KiB of memory.\n",
12046 | (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12047 | printf("The fields themselves consume %u KiB of memory.\n",
12048 | (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12049 |
12050 | return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12051 | }
12052 |
12053 | static void
12054 | elastic_add_base_mapping(json_dumper *dumper)
12055 | {
12056 | json_dumper_set_member_name(dumper, "index_patterns");
12057 | json_dumper_begin_array(dumper);
12058 | // The index names from write_json_index() in print.c
12059 | json_dumper_value_string(dumper, "packets-*");
12060 | json_dumper_end_array(dumper);
12061 |
12062 | json_dumper_set_member_name(dumper, "settings");
12063 | json_dumper_begin_object(dumper);
12064 | json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12065 | json_dumper_value_anyf(dumper, "%d", 1000000);
12066 | json_dumper_end_object(dumper);
12067 | }
12068 |
12069 | static char*
12070 | ws_type_to_elastic(unsigned type)
12071 | {
12072 | switch(type) {
12073 | case FT_INT8:
12074 | return "byte";
12075 | case FT_UINT8:
12076 | case FT_INT16:
12077 | return "short";
12078 | case FT_UINT16:
12079 | case FT_INT32:
12080 | case FT_UINT24:
12081 | case FT_INT24:
12082 | return "integer";
12083 | case FT_FRAMENUM:
12084 | case FT_UINT32:
12085 | case FT_UINT40:
12086 | case FT_UINT48:
12087 | case FT_UINT56:
12088 | case FT_INT40:
12089 | case FT_INT48:
12090 | case FT_INT56:
12091 | case FT_INT64:
12092 | return "long";
12093 | case FT_UINT64:
12094 | return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12095 | case FT_FLOAT:
12096 | return "float";
12097 | case FT_DOUBLE:
12098 | case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12099 | return "double";
12100 | case FT_IPv6:
12101 | case FT_IPv4:
12102 | return "ip";
12103 | case FT_ABSOLUTE_TIME:
12104 | return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12105 | case FT_BOOLEAN:
12106 | return "boolean";
12107 | default:
12108 | return NULL((void*)0);
12109 | }
12110 | }
12111 |
12112 | static char*
12113 | dot_to_underscore(char* str)
12114 | {
12115 | unsigned i;
12116 | for (i = 0; i < strlen(str); i++) {
12117 | if (str[i] == '.')
12118 | str[i] = '_';
12119 | }
12120 | return str;
12121 | }
12122 |
12123 | /* Dumps a mapping file for ElasticSearch
12124 | * This is the v1 (legacy) _template API.
12125 | * At some point it may need to be updated with the composable templates
12126 | * introduced in Elasticsearch 7.8 (_index_template)
12127 | */
12128 | void
12129 | proto_registrar_dump_elastic(const char* filter)
12130 | {
12131 | header_field_info *hfinfo;
12132 | header_field_info *parent_hfinfo;
12133 | unsigned i;
12134 | bool_Bool open_object = true1;
12135 | const char* prev_proto = NULL((void*)0);
12136 | char* str;
12137 | char** protos = NULL((void*)0);
12138 | char* proto;
12139 | bool_Bool found;
12140 | unsigned j;
12141 | char* type;
12142 | char* prev_item = NULL((void*)0);
12143 |
12144 | /* We have filtering protocols. Extract them. */
12145 | if (filter) {
12146 | protos = g_strsplit(filter, ",", -1);
12147 | }
12148 |
12149 | /*
12150 | * To help tracking down the json tree, objects have been appended with a comment:
12151 | * n.label -> where n is the indentation level and label the name of the object
12152 | */
12153 |
12154 | json_dumper dumper = {
12155 | .output_file = stdoutstdout,
12156 | .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12157 | };
12158 | json_dumper_begin_object(&dumper); // 1.root
12159 | elastic_add_base_mapping(&dumper);
12160 |
12161 | json_dumper_set_member_name(&dumper, "mappings");
12162 | json_dumper_begin_object(&dumper); // 2.mappings
12163 |
12164 | json_dumper_set_member_name(&dumper, "properties");
12165 | json_dumper_begin_object(&dumper); // 3.properties
12166 | json_dumper_set_member_name(&dumper, "timestamp");
12167 | json_dumper_begin_object(&dumper); // 4.timestamp
12168 | json_dumper_set_member_name(&dumper, "type");
12169 | json_dumper_value_string(&dumper, "date");
12170 | json_dumper_end_object(&dumper); // 4.timestamp
12171 |
12172 | json_dumper_set_member_name(&dumper, "layers");
12173 | json_dumper_begin_object(&dumper); // 4.layers
12174 | json_dumper_set_member_name(&dumper, "properties");
12175 | json_dumper_begin_object(&dumper); // 5.properties
12176 |
12177 | for (i = 0; i < gpa_hfinfo.len; i++) {
12178 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12179 | continue; /* This is a deregistered protocol or header field */
12180 |
12181 | 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", 12181 , __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", 12181 , "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", 12181, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12182 |
12183 | /*
12184 | * Skip the pseudo-field for "proto_tree_add_text()" since
12185 | * we don't want it in the list of filterable protocols.
12186 | */
12187 | if (hfinfo->id == hf_text_only)
12188 | continue;
12189 |
12190 | if (!proto_registrar_is_protocol(i)) {
12191 | 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", 12191 , __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", 12191 , "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", 12191 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12192 |
12193 | /*
12194 | * Skip the field if filter protocols have been set and this one's
12195 | * parent is not listed.
12196 | */
12197 | if (protos) {
12198 | found = false0;
12199 | j = 0;
12200 | proto = protos[0];
12201 | while(proto) {
12202 | if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12203 | found = true1;
12204 | break;
12205 | }
12206 | j++;
12207 | proto = protos[j];
12208 | }
12209 | if (!found)
12210 | continue;
12211 | }
12212 |
12213 | if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12214 | json_dumper_end_object(&dumper); // 7.properties
12215 | json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12216 | open_object = true1;
12217 | }
12218 |
12219 | prev_proto = parent_hfinfo->abbrev;
12220 |
12221 | if (open_object) {
12222 | json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12223 | json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12224 | json_dumper_set_member_name(&dumper, "properties");
12225 | json_dumper_begin_object(&dumper); // 7.properties
12226 | open_object = false0;
12227 | }
12228 | /* Skip the fields that would map into string. This is the default in elasticsearch. */
12229 | type = ws_type_to_elastic(hfinfo->type);
12230 | /* when type is NULL, we have the default mapping: string */
12231 | if (type) {
12232 | str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo-> abbrev);
12233 | dot_to_underscore(str);
12234 | if (g_strcmp0(prev_item, str)) {
12235 | json_dumper_set_member_name(&dumper, str);
12236 | json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12237 | json_dumper_set_member_name(&dumper, "type");
12238 | json_dumper_value_string(&dumper, type);
12239 | json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12240 | }
12241 | g_free(prev_item);
12242 | prev_item = str;
12243 | }
12244 | }
12245 | }
12246 | g_free(prev_item);
12247 |
12248 | if (prev_proto) {
12249 | json_dumper_end_object(&dumper); // 7.properties
12250 | json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12251 | }
12252 |
12253 | json_dumper_end_object(&dumper); // 5.properties
12254 | json_dumper_end_object(&dumper); // 4.layers
12255 | json_dumper_end_object(&dumper); // 3.properties
12256 | json_dumper_end_object(&dumper); // 2.mappings
12257 | json_dumper_end_object(&dumper); // 1.root
12258 | bool_Bool ret = json_dumper_finish(&dumper);
12259 | DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12259, "ret"))));
12260 |
12261 | g_strfreev(protos);
12262 | }
12263 |
12264 | /* Dumps the contents of the registration database to stdout. An independent
12265 | * program can take this output and format it into nice tables or HTML or
12266 | * whatever.
12267 | *
12268 | * There is one record per line. Each record is either a protocol or a header
12269 | * field, differentiated by the first field. The fields are tab-delimited.
12270 | *
12271 | * Protocols
12272 | * ---------
12273 | * Field 1 = 'P'
12274 | * Field 2 = descriptive protocol name
12275 | * Field 3 = protocol abbreviation
12276 | *
12277 | * Header Fields
12278 | * -------------
12279 | * Field 1 = 'F'
12280 | * Field 2 = descriptive field name
12281 | * Field 3 = field abbreviation
12282 | * Field 4 = type ( textual representation of the ftenum type )
12283 | * Field 5 = parent protocol abbreviation
12284 | * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12285 | * Field 7 = bitmask: format: hex: 0x....
12286 | * Field 8 = blurb describing field
12287 | */
12288 | void
12289 | proto_registrar_dump_fields(void)
12290 | {
12291 | header_field_info *hfinfo, *parent_hfinfo;
12292 | int i, len;
12293 | const char *enum_name;
12294 | const char *base_name;
12295 | const char *blurb;
12296 | char width[5];
12297 |
12298 | len = gpa_hfinfo.len;
12299 | for (i = 0; i < len ; i++) {
12300 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12301 | continue; /* This is a deregistered protocol or header field */
12302 |
12303 | 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", 12303 , __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", 12303 , "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", 12303, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12304 |
12305 | /*
12306 | * Skip the pseudo-field for "proto_tree_add_text()" since
12307 | * we don't want it in the list of filterable fields.
12308 | */
12309 | if (hfinfo->id == hf_text_only)
12310 | continue;
12311 |
12312 | /* format for protocols */
12313 | if (proto_registrar_is_protocol(i)) {
12314 | printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12315 | }
12316 | /* format for header fields */
12317 | else {
12318 | /*
12319 | * If this field isn't at the head of the list of
12320 | * fields with this name, skip this field - all
12321 | * fields with the same name are really just versions
12322 | * of the same field stored in different bits, and
12323 | * should have the same type/radix/value list, and
12324 | * just differ in their bit masks. (If a field isn't
12325 | * a bitfield, but can be, say, 1 or 2 bytes long,
12326 | * it can just be made FT_UINT16, meaning the
12327 | * *maximum* length is 2 bytes, and be used
12328 | * for all lengths.)
12329 | */
12330 | if (hfinfo->same_name_prev_id != -1)
12331 | continue;
12332 |
12333 | 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", 12333 , __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", 12333 , "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", 12333 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12334 |
12335 | enum_name = ftype_name(hfinfo->type);
12336 | base_name = "";
12337 |
12338 | if (hfinfo->type == FT_CHAR ||
12339 | hfinfo->type == FT_UINT8 ||
12340 | hfinfo->type == FT_UINT16 ||
12341 | hfinfo->type == FT_UINT24 ||
12342 | hfinfo->type == FT_UINT32 ||
12343 | hfinfo->type == FT_UINT40 ||
12344 | hfinfo->type == FT_UINT48 ||
12345 | hfinfo->type == FT_UINT56 ||
12346 | hfinfo->type == FT_UINT64 ||
12347 | hfinfo->type == FT_INT8 ||
12348 | hfinfo->type == FT_INT16 ||
12349 | hfinfo->type == FT_INT24 ||
12350 | hfinfo->type == FT_INT32 ||
12351 | hfinfo->type == FT_INT40 ||
12352 | hfinfo->type == FT_INT48 ||
12353 | hfinfo->type == FT_INT56 ||
12354 | hfinfo->type == FT_INT64) {
12355 |
12356 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12357 | case BASE_NONE:
12358 | case BASE_DEC:
12359 | case BASE_HEX:
12360 | case BASE_OCT:
12361 | case BASE_DEC_HEX:
12362 | case BASE_HEX_DEC:
12363 | case BASE_CUSTOM:
12364 | case BASE_PT_UDP:
12365 | case BASE_PT_TCP:
12366 | case BASE_PT_DCCP:
12367 | case BASE_PT_SCTP:
12368 | case BASE_OUI:
12369 | base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12370 | break;
12371 | default:
12372 | base_name = "????";
12373 | break;
12374 | }
12375 | } else if (hfinfo->type == FT_BOOLEAN) {
12376 | /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12377 | snprintf(width, sizeof(width), "%d", hfinfo->display);
12378 | base_name = width;
12379 | }
12380 |
12381 | blurb = hfinfo->blurb;
12382 | if (blurb == NULL((void*)0))
12383 | blurb = "";
12384 | else if (strlen(blurb) == 0)
12385 | blurb = "\"\"";
12386 |
12387 | printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12388 | hfinfo->name, hfinfo->abbrev, enum_name,
12389 | parent_hfinfo->abbrev, base_name,
12390 | hfinfo->bitmask, blurb);
12391 | }
12392 | }
12393 | }
12394 |
12395 | /* Dumps all abbreviated field and protocol completions of the given string to
12396 | * stdout. An independent program may use this for command-line tab completion
12397 | * of fields.
12398 | */
12399 | bool_Bool
12400 | proto_registrar_dump_field_completions(const char *prefix)
12401 | {
12402 | header_field_info *hfinfo;
12403 | int i, len;
12404 | size_t prefix_len;
12405 | bool_Bool matched = false0;
12406 |
12407 | prefix_len = strlen(prefix);
12408 | len = gpa_hfinfo.len;
12409 | for (i = 0; i < len ; i++) {
12410 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12411 | continue; /* This is a deregistered protocol or header field */
12412 |
12413 | 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", 12413 , __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", 12413 , "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", 12413, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12414 |
12415 | /*
12416 | * Skip the pseudo-field for "proto_tree_add_text()" since
12417 | * we don't want it in the list of filterable fields.
12418 | */
12419 | if (hfinfo->id == hf_text_only)
12420 | continue;
12421 |
12422 | /* format for protocols */
12423 | if (proto_registrar_is_protocol(i)) {
12424 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12425 | matched = true1;
12426 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12427 | }
12428 | }
12429 | /* format for header fields */
12430 | else {
12431 | /*
12432 | * If this field isn't at the head of the list of
12433 | * fields with this name, skip this field - all
12434 | * fields with the same name are really just versions
12435 | * of the same field stored in different bits, and
12436 | * should have the same type/radix/value list, and
12437 | * just differ in their bit masks. (If a field isn't
12438 | * a bitfield, but can be, say, 1 or 2 bytes long,
12439 | * it can just be made FT_UINT16, meaning the
12440 | * *maximum* length is 2 bytes, and be used
12441 | * for all lengths.)
12442 | */
12443 | if (hfinfo->same_name_prev_id != -1)
12444 | continue;
12445 |
12446 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12447 | matched = true1;
12448 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12449 | }
12450 | }
12451 | }
12452 | return matched;
12453 | }
12454 |
12455 | /* Dumps field types and descriptive names to stdout. An independent
12456 | * program can take this output and format it into nice tables or HTML or
12457 | * whatever.
12458 | *
12459 | * There is one record per line. The fields are tab-delimited.
12460 | *
12461 | * Field 1 = field type name, e.g. FT_UINT8
12462 | * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12463 | */
12464 | void
12465 | proto_registrar_dump_ftypes(void)
12466 | {
12467 | int fte;
12468 |
12469 | for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12470 | printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12471 | }
12472 | }
12473 |
12474 | /* This function indicates whether it's possible to construct a
12475 | * "match selected" display filter string for the specified field,
12476 | * returns an indication of whether it's possible, and, if it's
12477 | * possible and "filter" is non-null, constructs the filter and
12478 | * sets "*filter" to point to it.
12479 | * You do not need to [g_]free() this string since it will be automatically
12480 | * freed once the next packet is dissected.
12481 | */
12482 | static bool_Bool
12483 | construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12484 | char **filter)
12485 | {
12486 | const header_field_info *hfinfo;
12487 | int start, length, length_remaining;
12488 |
12489 | if (!finfo)
12490 | return false0;
12491 |
12492 | hfinfo = finfo->hfinfo;
12493 | DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12493, "hfinfo"))));
12494 |
12495 | /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12496 | * then "the numeric value ... is not used when preparing
12497 | * filters for the field in question." If it's any other
12498 | * base, we'll generate the filter normally (which will
12499 | * be numeric, even though the human-readable string does
12500 | * work for filtering.)
12501 | *
12502 | * XXX - It might be nice to use fvalue_to_string_repr() in
12503 | * "proto_item_fill_label()" as well, although, there, you'd
12504 | * have to deal with the base *and* with resolved values for
12505 | * addresses.
12506 | *
12507 | * Perhaps in addition to taking the repr type (DISPLAY
12508 | * or DFILTER) and the display (base), fvalue_to_string_repr()
12509 | * should have the the "strings" values in the header_field_info
12510 | * structure for the field as a parameter, so it can have
12511 | * if the field is Boolean or an enumerated integer type,
12512 | * the tables used to generate human-readable values.
12513 | */
12514 | if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12515 | const char *str = NULL((void*)0);
12516 |
12517 | switch (hfinfo->type) {
12518 |
12519 | case FT_INT8:
12520 | case FT_INT16:
12521 | case FT_INT24:
12522 | case FT_INT32:
12523 | str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12524 | break;
12525 |
12526 | case FT_CHAR:
12527 | case FT_UINT8:
12528 | case FT_UINT16:
12529 | case FT_UINT24:
12530 | case FT_UINT32:
12531 | str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12532 | break;
12533 |
12534 | default:
12535 | break;
12536 | }
12537 |
12538 | if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12539 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12540 | return true1;
12541 | }
12542 | }
12543 |
12544 | switch (hfinfo->type) {
12545 |
12546 | case FT_PROTOCOL:
12547 | if (filter != NULL((void*)0))
12548 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12549 | break;
12550 |
12551 | case FT_NONE:
12552 | /*
12553 | * If the length is 0, just match the name of the
12554 | * field.
12555 | *
12556 | * (Also check for negative values, just in case,
12557 | * as we'll cast it to an unsigned value later.)
12558 | */
12559 | length = finfo->length;
12560 | if (length == 0) {
12561 | if (filter != NULL((void*)0))
12562 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12563 | break;
12564 | }
12565 | if (length < 0)
12566 | return false0;
12567 |
12568 | /*
12569 | * This doesn't have a value, so we'd match
12570 | * on the raw bytes at this address.
12571 | *
12572 | * Should we be allowed to access to the raw bytes?
12573 | * If "edt" is NULL, the answer is "no".
12574 | */
12575 | if (edt == NULL((void*)0))
12576 | return false0;
12577 |
12578 | /*
12579 | * Is this field part of the raw frame tvbuff?
12580 | * If not, we can't use "frame[N:M]" to match
12581 | * it.
12582 | *
12583 | * XXX - should this be frame-relative, or
12584 | * protocol-relative?
12585 | *
12586 | * XXX - does this fallback for non-registered
12587 | * fields even make sense?
12588 | */
12589 | if (finfo->ds_tvb != edt->tvb)
12590 | return false0; /* you lose */
12591 |
12592 | /*
12593 | * Don't go past the end of that tvbuff.
12594 | */
12595 | length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12596 | if (length > length_remaining)
12597 | length = length_remaining;
12598 | if (length <= 0)
12599 | return false0;
12600 |
12601 | if (filter != NULL((void*)0)) {
12602 | start = finfo->start;
12603 | char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12604 | *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12605 | wmem_free(NULL((void*)0), str);
12606 | }
12607 | break;
12608 |
12609 | /* By default, use the fvalue's "to_string_repr" method. */
12610 | default:
12611 | if (filter != NULL((void*)0)) {
12612 | char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12613 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12614 | wmem_free(NULL((void*)0), str);
12615 | }
12616 | break;
12617 | }
12618 |
12619 | return true1;
12620 | }
12621 |
12622 | /*
12623 | * Returns true if we can do a "match selected" on the field, false
12624 | * otherwise.
12625 | */
12626 | bool_Bool
12627 | proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12628 | {
12629 | return construct_match_selected_string(finfo, edt, NULL((void*)0));
12630 | }
12631 |
12632 | /* This function attempts to construct a "match selected" display filter
12633 | * string for the specified field; if it can do so, it returns a pointer
12634 | * to the string, otherwise it returns NULL.
12635 | *
12636 | * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12637 | */
12638 | char *
12639 | proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12640 | {
12641 | char *filter = NULL((void*)0);
12642 |
12643 | if (!construct_match_selected_string(finfo, edt, &filter))
12644 | {
12645 | wmem_free(NULL((void*)0), filter);
12646 | return NULL((void*)0);
12647 | }
12648 | return filter;
12649 | }
12650 |
12651 | /* This function is common code for all proto_tree_add_bitmask... functions.
12652 | */
12653 |
12654 | static bool_Bool
12655 | proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12656 | const int len, const int ett, int * const *fields,
12657 | const int flags, bool_Bool first,
12658 | bool_Bool use_parent_tree,
12659 | proto_tree* tree, uint64_t value)
12660 | {
12661 | uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12662 | uint64_t bitmask = 0;
12663 | uint64_t tmpval;
12664 | header_field_info *hf;
12665 | uint32_t integer32;
12666 | int bit_offset;
12667 | int no_of_bits;
12668 |
12669 | if (!*fields)
12670 | 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" );
12671 |
12672 | if (len < 0 || len > 8)
12673 | REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12674 | /**
12675 | * packet-frame.c uses len=0 since the value is taken from the packet
12676 | * metadata, not the packet bytes. In that case, assume that all bits
12677 | * in the provided value are valid.
12678 | */
12679 | if (len > 0) {
12680 | available_bits >>= (8 - (unsigned)len)*8;
12681 | }
12682 |
12683 | if (use_parent_tree == false0)
12684 | tree = proto_item_add_subtree(item, ett);
12685 |
12686 | while (*fields) {
12687 | uint64_t present_bits;
12688 | 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", 12688, __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", 12688 , "**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", 12688, "gpa_hfinfo.hfi[**fields] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];;
12689 | 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", 12689 , "hf->bitmask != 0", hf->abbrev))));
12690 |
12691 | bitmask |= hf->bitmask;
12692 |
12693 | /* Skip fields that aren't fully present */
12694 | present_bits = available_bits & hf->bitmask;
12695 | if (present_bits != hf->bitmask) {
12696 | fields++;
12697 | continue;
12698 | }
12699 |
12700 | switch (hf->type) {
12701 | case FT_CHAR:
12702 | case FT_UINT8:
12703 | case FT_UINT16:
12704 | case FT_UINT24:
12705 | case FT_UINT32:
12706 | proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12707 | break;
12708 |
12709 | case FT_INT8:
12710 | case FT_INT16:
12711 | case FT_INT24:
12712 | case FT_INT32:
12713 | proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12714 | break;
12715 |
12716 | case FT_UINT40:
12717 | case FT_UINT48:
12718 | case FT_UINT56:
12719 | case FT_UINT64:
12720 | proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12721 | break;
12722 |
12723 | case FT_INT40:
12724 | case FT_INT48:
12725 | case FT_INT56:
12726 | case FT_INT64:
12727 | proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12728 | break;
12729 |
12730 | case FT_BOOLEAN:
12731 | proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12732 | break;
12733 |
12734 | default:
12735 | 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))
12736 | 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))
12737 | 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))
12738 | 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));
12739 | break;
12740 | }
12741 | if (flags & BMT_NO_APPEND0x01) {
12742 | fields++;
12743 | continue;
12744 | }
12745 | tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12746 |
12747 | /* XXX: README.developer and the comments have always defined
12748 | * BMT_NO_INT as "only boolean flags are added to the title /
12749 | * don't add non-boolean (integral) fields", but the
12750 | * implementation has always added BASE_CUSTOM and fields with
12751 | * value_strings, though not fields with unit_strings.
12752 | * Possibly this is because some dissectors use a FT_UINT8
12753 | * with a value_string for fields that should be a FT_BOOLEAN.
12754 | */
12755 | switch (hf->type) {
12756 | case FT_CHAR:
12757 | if (hf->display == BASE_CUSTOM) {
12758 | char lbl[ITEM_LABEL_LENGTH240];
12759 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12760 |
12761 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12761, "fmtfunc"))));
12762 | fmtfunc(lbl, (uint32_t) tmpval);
12763 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12764 | hf->name, lbl);
12765 | first = false0;
12766 | }
12767 | else if (hf->strings) {
12768 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12769 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12770 | first = false0;
12771 | }
12772 | else if (!(flags & BMT_NO_INT0x02)) {
12773 | char buf[32];
12774 | const char *out;
12775 |
12776 | if (!first) {
12777 | proto_item_append_text(item, ", ");
12778 | }
12779 |
12780 | out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12781 | proto_item_append_text(item, "%s: %s", hf->name, out);
12782 | first = false0;
12783 | }
12784 |
12785 | break;
12786 |
12787 | case FT_UINT8:
12788 | case FT_UINT16:
12789 | case FT_UINT24:
12790 | case FT_UINT32:
12791 | if (hf->display == BASE_CUSTOM) {
12792 | char lbl[ITEM_LABEL_LENGTH240];
12793 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12794 |
12795 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12795, "fmtfunc"))));
12796 | fmtfunc(lbl, (uint32_t) tmpval);
12797 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12798 | hf->name, lbl);
12799 | first = false0;
12800 | }
12801 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12802 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12803 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12804 | first = false0;
12805 | }
12806 | else if (!(flags & BMT_NO_INT0x02)) {
12807 | char buf[NUMBER_LABEL_LENGTH80];
12808 | const char *out = NULL((void*)0);
12809 |
12810 | if (!first) {
12811 | proto_item_append_text(item, ", ");
12812 | }
12813 |
12814 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12815 | out = hf_try_val_to_str((uint32_t) tmpval, hf);
12816 | }
12817 | if (out == NULL((void*)0)) {
12818 | out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12819 | }
12820 | proto_item_append_text(item, "%s: %s", hf->name, out);
12821 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12822 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12823 | }
12824 | first = false0;
12825 | }
12826 |
12827 | break;
12828 |
12829 | case FT_INT8:
12830 | case FT_INT16:
12831 | case FT_INT24:
12832 | case FT_INT32:
12833 | integer32 = (uint32_t) tmpval;
12834 | if (hf->bitmask) {
12835 | no_of_bits = ws_count_ones(hf->bitmask);
12836 | integer32 = ws_sign_ext32(integer32, no_of_bits);
12837 | }
12838 | if (hf->display == BASE_CUSTOM) {
12839 | char lbl[ITEM_LABEL_LENGTH240];
12840 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12841 |
12842 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12842, "fmtfunc"))));
12843 | fmtfunc(lbl, (int32_t) integer32);
12844 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12845 | hf->name, lbl);
12846 | first = false0;
12847 | }
12848 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12849 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12850 | hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12851 | first = false0;
12852 | }
12853 | else if (!(flags & BMT_NO_INT0x02)) {
12854 | char buf[NUMBER_LABEL_LENGTH80];
12855 | const char *out = NULL((void*)0);
12856 |
12857 | if (!first) {
12858 | proto_item_append_text(item, ", ");
12859 | }
12860 |
12861 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12862 | out = hf_try_val_to_str((int32_t) integer32, hf);
12863 | }
12864 | if (out == NULL((void*)0)) {
12865 | out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12866 | }
12867 | proto_item_append_text(item, "%s: %s", hf->name, out);
12868 | if (hf->display & BASE_UNIT_STRING0x00001000) {
12869 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12870 | }
12871 | first = false0;
12872 | }
12873 |
12874 | break;
12875 |
12876 | case FT_UINT40:
12877 | case FT_UINT48:
12878 | case FT_UINT56:
12879 | case FT_UINT64:
12880 | if (hf->display == BASE_CUSTOM) {
12881 | char lbl[ITEM_LABEL_LENGTH240];
12882 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12883 |
12884 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12884, "fmtfunc"))));
12885 | fmtfunc(lbl, tmpval);
12886 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12887 | hf->name, lbl);
12888 | first = false0;
12889 | }
12890 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12891 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12892 | hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12893 | first = false0;
12894 | }
12895 | else if (!(flags & BMT_NO_INT0x02)) {
12896 | char buf[NUMBER_LABEL_LENGTH80];
12897 | const char *out = NULL((void*)0);
12898 |
12899 | if (!first) {
12900 | proto_item_append_text(item, ", ");
12901 | }
12902 |
12903 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12904 | out = hf_try_val64_to_str(tmpval, hf);
12905 | }
12906 | if (out == NULL((void*)0)) {
12907 | out = hfinfo_number_value_format64(hf, buf, tmpval);
12908 | }
12909 | proto_item_append_text(item, "%s: %s", hf->name, out);
12910 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12911 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12912 | }
12913 | first = false0;
12914 | }
12915 |
12916 | break;
12917 |
12918 | case FT_INT40:
12919 | case FT_INT48:
12920 | case FT_INT56:
12921 | case FT_INT64:
12922 | if (hf->bitmask) {
12923 | no_of_bits = ws_count_ones(hf->bitmask);
12924 | tmpval = ws_sign_ext64(tmpval, no_of_bits);
12925 | }
12926 | if (hf->display == BASE_CUSTOM) {
12927 | char lbl[ITEM_LABEL_LENGTH240];
12928 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12929 |
12930 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12930, "fmtfunc"))));
12931 | fmtfunc(lbl, (int64_t) tmpval);
12932 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12933 | hf->name, lbl);
12934 | first = false0;
12935 | }
12936 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12937 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12938 | hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12939 | first = false0;
12940 | }
12941 | else if (!(flags & BMT_NO_INT0x02)) {
12942 | char buf[NUMBER_LABEL_LENGTH80];
12943 | const char *out = NULL((void*)0);
12944 |
12945 | if (!first) {
12946 | proto_item_append_text(item, ", ");
12947 | }
12948 |
12949 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12950 | out = hf_try_val64_to_str((int64_t) tmpval, hf);
12951 | }
12952 | if (out == NULL((void*)0)) {
12953 | out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12954 | }
12955 | proto_item_append_text(item, "%s: %s", hf->name, out);
12956 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12957 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12958 | }
12959 | first = false0;
12960 | }
12961 |
12962 | break;
12963 |
12964 | case FT_BOOLEAN:
12965 | if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12966 | /* If we have true/false strings, emit full - otherwise messages
12967 | might look weird */
12968 | const struct true_false_string *tfs =
12969 | (const struct true_false_string *)hf->strings;
12970 |
12971 | if (tmpval) {
12972 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12973 | hf->name, tfs->true_string);
12974 | first = false0;
12975 | } else if (!(flags & BMT_NO_FALSE0x04)) {
12976 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12977 | hf->name, tfs->false_string);
12978 | first = false0;
12979 | }
12980 | } else if (hf->bitmask & value) {
12981 | /* If the flag is set, show the name */
12982 | proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12983 | first = false0;
12984 | }
12985 | break;
12986 | default:
12987 | 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))
12988 | 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))
12989 | 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))
12990 | 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));
12991 | break;
12992 | }
12993 |
12994 | fields++;
12995 | }
12996 |
12997 | /* XXX: We don't pass the hfi into this function. Perhaps we should,
12998 | * but then again most dissectors don't set the bitmask field for
12999 | * the higher level bitmask hfi, so calculate the bitmask from the
13000 | * fields present. */
13001 | if (item) {
13002 | bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13003 | no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13004 | 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);
13005 | 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);
13006 | }
13007 | return first;
13008 | }
13009 |
13010 | /* This function will dissect a sequence of bytes that describe a
13011 | * bitmask and supply the value of that sequence through a pointer.
13012 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13013 | * to be dissected.
13014 | * This field will form an expansion under which the individual fields of the
13015 | * bitmask is dissected and displayed.
13016 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13017 | *
13018 | * fields is an array of pointers to int that lists all the fields of the
13019 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13020 | * or another integer of the same type/size as hf_hdr with a mask specified.
13021 | * This array is terminated by a NULL entry.
13022 | *
13023 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13024 | * FT_integer fields that have a value_string attached will have the
13025 | * matched string displayed on the expansion line.
13026 | */
13027 | proto_item *
13028 | proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13029 | const unsigned offset, const int hf_hdr,
13030 | const int ett, int * const *fields,
13031 | const unsigned encoding, uint64_t *retval)
13032 | {
13033 | 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);
13034 | }
13035 |
13036 | /* This function will dissect a sequence of bytes that describe a
13037 | * bitmask.
13038 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13039 | * to be dissected.
13040 | * This field will form an expansion under which the individual fields of the
13041 | * bitmask is dissected and displayed.
13042 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13043 | *
13044 | * fields is an array of pointers to int that lists all the fields of the
13045 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13046 | * or another integer of the same type/size as hf_hdr with a mask specified.
13047 | * This array is terminated by a NULL entry.
13048 | *
13049 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13050 | * FT_integer fields that have a value_string attached will have the
13051 | * matched string displayed on the expansion line.
13052 | */
13053 | proto_item *
13054 | proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13055 | const unsigned offset, const int hf_hdr,
13056 | const int ett, int * const *fields,
13057 | const unsigned encoding)
13058 | {
13059 | return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13060 | }
13061 |
13062 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13063 | * what data is appended to the header.
13064 | */
13065 | proto_item *
13066 | proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13067 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13068 | uint64_t *retval)
13069 | {
13070 | proto_item *item = NULL((void*)0);
13071 | header_field_info *hf;
13072 | int len;
13073 | uint64_t value;
13074 |
13075 | 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", 13075, __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", 13075 , "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", 13075, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13076 | 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", 13076, (hf)->abbrev)));
13077 | len = ftype_wire_size(hf->type);
13078 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13079 |
13080 | if (parent_tree) {
13081 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13082 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13083 | flags, false0, false0, NULL((void*)0), value);
13084 | }
13085 |
13086 | *retval = value;
13087 | if (hf->bitmask) {
13088 | /* Mask out irrelevant portions */
13089 | *retval &= hf->bitmask;
13090 | /* Shift bits */
13091 | *retval >>= hfinfo_bitshift(hf);
13092 | }
13093 |
13094 | return item;
13095 | }
13096 |
13097 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13098 | * what data is appended to the header.
13099 | */
13100 | proto_item *
13101 | proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13102 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13103 | {
13104 | proto_item *item = NULL((void*)0);
13105 | header_field_info *hf;
13106 | int len;
13107 | uint64_t value;
13108 |
13109 | 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", 13109, __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", 13109 , "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", 13109, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13110 | 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", 13110, (hf)->abbrev)));
13111 |
13112 | if (parent_tree) {
13113 | len = ftype_wire_size(hf->type);
13114 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13115 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13116 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13117 | flags, false0, false0, NULL((void*)0), value);
13118 | }
13119 |
13120 | return item;
13121 | }
13122 |
13123 | /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13124 | can't be retrieved directly from tvb) */
13125 | proto_item *
13126 | proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13127 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13128 | {
13129 | return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13130 | hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13131 | }
13132 |
13133 | /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13134 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13135 | proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13136 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13137 | {
13138 | proto_item *item = NULL((void*)0);
13139 | header_field_info *hf;
13140 | int len;
13141 |
13142 | 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", 13142, __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", 13142 , "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", 13142, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13143 | 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", 13143, (hf)->abbrev)));
13144 | /* the proto_tree_add_uint/_uint64() calls below
13145 | will fail if tvb==NULL and len!=0 */
13146 | len = tvb ? ftype_wire_size(hf->type) : 0;
13147 |
13148 | if (parent_tree) {
13149 | if (len <= 4)
13150 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13151 | else
13152 | item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13153 |
13154 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13155 | flags, false0, false0, NULL((void*)0), value);
13156 | }
13157 |
13158 | return item;
13159 | }
13160 |
13161 | /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13162 | void
13163 | proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13164 | const int len, int * const *fields, const unsigned encoding)
13165 | {
13166 | uint64_t value;
13167 |
13168 | if (tree) {
13169 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13170 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13171 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13172 | }
13173 | }
13174 |
13175 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13176 | proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13177 | const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13178 | {
13179 | uint64_t value;
13180 |
13181 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13182 | if (tree) {
13183 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13184 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13185 | }
13186 | if (retval) {
13187 | *retval = value;
13188 | }
13189 | }
13190 |
13191 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13192 | proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13193 | const int len, int * const *fields, const uint64_t value)
13194 | {
13195 | if (tree) {
13196 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13197 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13198 | }
13199 | }
13200 |
13201 |
13202 | /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13203 | * This is intended to support bitmask fields whose lengths can vary, perhaps
13204 | * as the underlying standard evolves over time.
13205 | * With this API there is the possibility of being called to display more or
13206 | * less data than the dissector was coded to support.
13207 | * In such cases, it is assumed that bitmasks are extended on the MSb end.
13208 | * Thus when presented with "too much" or "too little" data, MSbits will be
13209 | * ignored or MSfields sacrificed.
13210 | *
13211 | * Only fields for which all defined bits are available are displayed.
13212 | */
13213 | proto_item *
13214 | proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13215 | const unsigned offset, const unsigned len, const int hf_hdr,
13216 | const int ett, int * const *fields, struct expert_field* exp,
13217 | const unsigned encoding)
13218 | {
13219 | proto_item *item = NULL((void*)0);
13220 | header_field_info *hf;
13221 | unsigned decodable_len;
13222 | unsigned decodable_offset;
13223 | uint32_t decodable_value;
13224 | uint64_t value;
13225 |
13226 | 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", 13226, __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", 13226 , "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", 13226, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13227 | 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", 13227, (hf)->abbrev)));
13228 |
13229 | decodable_offset = offset;
13230 | decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len ) : ((unsigned) ftype_wire_size(hf->type)));
13231 |
13232 | /* If we are ftype_wire_size-limited,
13233 | * make sure we decode as many LSBs as possible.
13234 | */
13235 | if (encoding == ENC_BIG_ENDIAN0x00000000) {
13236 | decodable_offset += (len - decodable_len);
13237 | }
13238 |
13239 | if (parent_tree) {
13240 | decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13241 | decodable_len, encoding);
13242 |
13243 | /* The root item covers all the bytes even if we can't decode them all */
13244 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13245 | decodable_value);
13246 | }
13247 |
13248 | if (decodable_len < len) {
13249 | /* Dissector likely requires updating for new protocol revision */
13250 | expert_add_info_format(NULL((void*)0), item, exp,
13251 | "Only least-significant %d of %d bytes decoded",
13252 | decodable_len, len);
13253 | }
13254 |
13255 | if (item) {
13256 | value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13257 | proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13258 | ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13259 | }
13260 |
13261 | return item;
13262 | }
13263 |
13264 | /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13265 | proto_item *
13266 | proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13267 | const unsigned offset, const unsigned len,
13268 | const char *name, const char *fallback,
13269 | const int ett, int * const *fields,
13270 | const unsigned encoding, const int flags)
13271 | {
13272 | proto_item *item = NULL((void*)0);
13273 | uint64_t value;
13274 |
13275 | if (parent_tree) {
13276 | item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13277 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13278 | if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13279 | flags, true1, false0, NULL((void*)0), value) && fallback) {
13280 | /* Still at first item - append 'fallback' text if any */
13281 | proto_item_append_text(item, "%s", fallback);
13282 | }
13283 | }
13284 |
13285 | return item;
13286 | }
13287 |
13288 | proto_item *
13289 | proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13290 | const unsigned bit_offset, const int no_of_bits,
13291 | const unsigned encoding)
13292 | {
13293 | header_field_info *hfinfo;
13294 | int octet_length;
13295 | int octet_offset;
13296 |
13297 | 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", 13297, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13297 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13297, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13298 |
13299 | if (no_of_bits < 0) {
13300 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13301 | }
13302 | octet_length = (no_of_bits + 7) >> 3;
13303 | octet_offset = bit_offset >> 3;
13304 | test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13305 |
13306 | /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13307 | * but only after doing a bunch more work (which we can, in the common
13308 | * case, shortcut here).
13309 | */
13310 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13311 | 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", 13311 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13311, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13311, "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", 13311, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
13312 |
13313 | return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13314 | }
13315 |
13316 | /*
13317 | * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13318 | * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13319 | * Offset should be given in bits from the start of the tvb.
13320 | */
13321 |
13322 | static proto_item *
13323 | _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13324 | const unsigned bit_offset, const int no_of_bits,
13325 | uint64_t *return_value, const unsigned encoding)
13326 | {
13327 | int offset;
13328 | unsigned length;
13329 | uint8_t tot_no_bits;
13330 | char *bf_str;
13331 | char lbl_str[ITEM_LABEL_LENGTH240];
13332 | uint64_t value = 0;
13333 | uint8_t *bytes = NULL((void*)0);
13334 | size_t bytes_length = 0;
13335 |
13336 | proto_item *pi;
13337 | header_field_info *hf_field;
13338 |
13339 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13340 | 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", 13340, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13340 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13340, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;;
13341 |
13342 | if (hf_field->bitmask != 0) {
13343 | 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)
13344 | " 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)
13345 | 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);
13346 | }
13347 |
13348 | if (no_of_bits < 0) {
13349 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13350 | } else if (no_of_bits == 0) {
13351 | 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)
13352 | 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);
13353 | }
13354 |
13355 | /* Byte align offset */
13356 | offset = bit_offset>>3;
13357 |
13358 | /*
13359 | * Calculate the number of octets used to hold the bits
13360 | */
13361 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13362 | length = (tot_no_bits + 7) >> 3;
13363 |
13364 | if (no_of_bits < 65) {
13365 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13366 | } else if (hf_field->type != FT_BYTES) {
13367 | 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)
13368 | 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);
13369 | return NULL((void*)0);
13370 | }
13371 |
13372 | /* Sign extend for signed types */
13373 | switch (hf_field->type) {
13374 | case FT_INT8:
13375 | case FT_INT16:
13376 | case FT_INT24:
13377 | case FT_INT32:
13378 | case FT_INT40:
13379 | case FT_INT48:
13380 | case FT_INT56:
13381 | case FT_INT64:
13382 | value = ws_sign_ext64(value, no_of_bits);
13383 | break;
13384 |
13385 | default:
13386 | break;
13387 | }
13388 |
13389 | if (return_value) {
13390 | *return_value = value;
13391 | }
13392 |
13393 | /* Coast clear. Try and fake it */
13394 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13395 | 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", 13395 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13395, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13395, "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", 13395, __func__, "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); } } };
13396 |
13397 | bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13398 |
13399 | switch (hf_field->type) {
13400 | case FT_BOOLEAN:
13401 | /* Boolean field */
13402 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13403 | "%s = %s: %s",
13404 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13405 | break;
13406 |
13407 | case FT_CHAR:
13408 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13409 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13410 | break;
13411 |
13412 | case FT_UINT8:
13413 | case FT_UINT16:
13414 | case FT_UINT24:
13415 | case FT_UINT32:
13416 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13417 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13418 | break;
13419 |
13420 | case FT_INT8:
13421 | case FT_INT16:
13422 | case FT_INT24:
13423 | case FT_INT32:
13424 | pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13425 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13426 | break;
13427 |
13428 | case FT_UINT40:
13429 | case FT_UINT48:
13430 | case FT_UINT56:
13431 | case FT_UINT64:
13432 | pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13433 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13434 | break;
13435 |
13436 | case FT_INT40:
13437 | case FT_INT48:
13438 | case FT_INT56:
13439 | case FT_INT64:
13440 | pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13441 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13442 | break;
13443 |
13444 | case FT_BYTES:
13445 | bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13446 | pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13447 | proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13448 | proto_item_set_text(pi, "%s", lbl_str);
13449 | return pi;
13450 |
13451 | /* TODO: should handle FT_UINT_BYTES ? */
13452 |
13453 | default:
13454 | 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))
13455 | 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))
13456 | 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))
13457 | 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));
13458 | return NULL((void*)0);
13459 | }
13460 |
13461 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13462 | return pi;
13463 | }
13464 |
13465 | proto_item *
13466 | proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13467 | const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13468 | uint64_t *return_value)
13469 | {
13470 | proto_item *pi;
13471 | int no_of_bits;
13472 | int octet_offset;
13473 | unsigned mask_initial_bit_offset;
13474 | unsigned mask_greatest_bit_offset;
13475 | unsigned octet_length;
13476 | uint8_t i;
13477 | char bf_str[256];
13478 | char lbl_str[ITEM_LABEL_LENGTH240];
13479 | uint64_t value;
13480 | uint64_t composite_bitmask;
13481 | uint64_t composite_bitmap;
13482 |
13483 | header_field_info *hf_field;
13484 |
13485 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13486 | 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", 13486, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13486 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13486, "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 | →
13487 |
13488 | if (hf_field->bitmask != 0) {
8 | ← | Assuming field 'bitmask' is equal to 0 | →
9 | ← | Taking false branch | →
13489 | 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)
13490 | " 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)
13491 | 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);
13492 | }
13493 |
13494 | mask_initial_bit_offset = bit_offset % 8;
13495 |
13496 | no_of_bits = 0;
13497 | value = 0;
13498 | i = 0;
13499 | mask_greatest_bit_offset = 0;
13500 | composite_bitmask = 0;
13501 | composite_bitmap = 0;
13502 |
13503 | 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 | →
13504 | uint64_t crumb_mask, crumb_value;
13505 | uint8_t crumb_end_bit_offset;
13506 |
13507 | crumb_value = tvb_get_bits64(tvb,
13508 | bit_offset + crumb_spec[i].crumb_bit_offset,
13509 | crumb_spec[i].crumb_bit_length,
13510 | ENC_BIG_ENDIAN0x00000000);
13511 | value += crumb_value;
13512 | no_of_bits += crumb_spec[i].crumb_bit_length;
13513 | 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", 13513 , "no_of_bits <= 64", "a value larger than 64 bits cannot be represented" ))));
12 | ← | Assuming 'no_of_bits' is <= 64 | →
13 | ← | '?' condition is true | →
13514 |
13515 | /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13516 | octet containing the initial offset.
13517 | If the mask is beyond 32 bits, then give up on bit map display.
13518 | This could be improved in future, probably showing a table
13519 | of 32 or 64 bits per row */
13520 | if (mask_greatest_bit_offset
13.1 | 'mask_greatest_bit_offset' is < 32
< 32) {
14 | ← | Taking true branch | →
13521 | crumb_end_bit_offset = mask_initial_bit_offset
13522 | + crumb_spec[i].crumb_bit_offset
13523 | + crumb_spec[i].crumb_bit_length;
13524 | 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' | →
13525 |
13526 | if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17 | ← | Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset' | →
18 | ← | Taking false branch | →
13527 | mask_greatest_bit_offset = crumb_end_bit_offset;
13528 | }
13529 | /* Currently the bitmap of the crumbs are only shown if
13530 | * smaller than 32 bits. Do not bother calculating the
13531 | * mask if it is larger than that. */
13532 | if (crumb_end_bit_offset
18.1 | 'crumb_end_bit_offset' is <= 32
<= 32) {
19 | ← | Taking true branch | →
13533 | 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'
13534 | composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13535 | }
13536 | }
13537 | /* Shift left for the next segment */
13538 | value <<= crumb_spec[++i].crumb_bit_length;
13539 | }
13540 |
13541 | /* Sign extend for signed types */
13542 | switch (hf_field->type) {
13543 | case FT_INT8:
13544 | case FT_INT16:
13545 | case FT_INT24:
13546 | case FT_INT32:
13547 | case FT_INT40:
13548 | case FT_INT48:
13549 | case FT_INT56:
13550 | case FT_INT64:
13551 | value = ws_sign_ext64(value, no_of_bits);
13552 | break;
13553 | default:
13554 | break;
13555 | }
13556 |
13557 | if (return_value) {
13558 | *return_value = value;
13559 | }
13560 |
13561 | /* Coast clear. Try and fake it */
13562 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13563 | 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", 13563 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13563, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13563, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13563, __func__, "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); } } };
13564 |
13565 | /* initialise the format string */
13566 | bf_str[0] = '\0';
13567 |
13568 | octet_offset = bit_offset >> 3;
13569 |
13570 | /* Round up mask length to nearest octet */
13571 | octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13572 | mask_greatest_bit_offset = octet_length << 3;
13573 |
13574 | /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13575 | It would be a useful enhancement to eliminate this restriction. */
13576 | if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13577 | other_decode_bitfield_value(bf_str,
13578 | (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13579 | (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13580 | mask_greatest_bit_offset);
13581 | } else {
13582 | /* If the bitmask is too large, try to describe its contents. */
13583 | snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13584 | }
13585 |
13586 | switch (hf_field->type) {
13587 | case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13588 | /* Boolean field */
13589 | return proto_tree_add_boolean_format(tree, hfindex,
13590 | tvb, octet_offset, octet_length, value,
13591 | "%s = %s: %s",
13592 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13593 | break;
13594 |
13595 | case FT_CHAR:
13596 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13597 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13598 | break;
13599 |
13600 | case FT_UINT8:
13601 | case FT_UINT16:
13602 | case FT_UINT24:
13603 | case FT_UINT32:
13604 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13605 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13606 | break;
13607 |
13608 | case FT_INT8:
13609 | case FT_INT16:
13610 | case FT_INT24:
13611 | case FT_INT32:
13612 | pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13613 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13614 | break;
13615 |
13616 | case FT_UINT40:
13617 | case FT_UINT48:
13618 | case FT_UINT56:
13619 | case FT_UINT64:
13620 | pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13621 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13622 | break;
13623 |
13624 | case FT_INT40:
13625 | case FT_INT48:
13626 | case FT_INT56:
13627 | case FT_INT64:
13628 | pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13629 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13630 | break;
13631 |
13632 | default:
13633 | 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))
13634 | 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))
13635 | 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))
13636 | 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));
13637 | return NULL((void*)0);
13638 | }
13639 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13640 | return pi;
13641 | }
13642 |
13643 | void
13644 | proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13645 | const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13646 | {
13647 | header_field_info *hfinfo;
13648 | int start = bit_offset >> 3;
13649 | int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13650 |
13651 | /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13652 | * so that we can use the tree's memory scope in calculating the string */
13653 | if (length == -1) {
13654 | tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13655 | } else {
13656 | tvb_ensure_bytes_exist(tvb, start, length);
13657 | }
13658 | if (!tree) return;
13659 |
13660 | 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", 13660, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13660 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13660, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13661 | proto_tree_add_text_internal(tree, tvb, start, length,
13662 | "%s crumb %d of %s (decoded above)",
13663 | decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13664 | tvb_get_bits32(tvb,
13665 | bit_offset,
13666 | crumb_spec[crumb_index].crumb_bit_length,
13667 | ENC_BIG_ENDIAN0x00000000),
13668 | ENC_BIG_ENDIAN0x00000000),
13669 | crumb_index,
13670 | hfinfo->name);
13671 | }
13672 |
13673 | proto_item *
13674 | proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13675 | const unsigned bit_offset, const int no_of_bits,
13676 | uint64_t *return_value, const unsigned encoding)
13677 | {
13678 | proto_item *item;
13679 |
13680 | if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13681 | bit_offset, no_of_bits,
13682 | return_value, encoding))) {
13683 | 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);
13684 | 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);
13685 | }
13686 | return item;
13687 | }
13688 |
13689 | static proto_item *
13690 | _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13691 | tvbuff_t *tvb, const unsigned bit_offset,
13692 | const int no_of_bits, void *value_ptr,
13693 | const unsigned encoding, char *value_str)
13694 | {
13695 | int offset;
13696 | unsigned length;
13697 | uint8_t tot_no_bits;
13698 | char *str;
13699 | uint64_t value = 0;
13700 | header_field_info *hf_field;
13701 |
13702 | /* We do not have to return a value, try to fake it as soon as possible */
13703 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13704 | 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", 13704 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13704, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13704, "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", 13704, __func__, "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); } } };
13705 |
13706 | if (hf_field->bitmask != 0) {
13707 | 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)
13708 | " 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)
13709 | 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);
13710 | }
13711 |
13712 | if (no_of_bits < 0) {
13713 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13714 | } else if (no_of_bits == 0) {
13715 | 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)
13716 | 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);
13717 | }
13718 |
13719 | /* Byte align offset */
13720 | offset = bit_offset>>3;
13721 |
13722 | /*
13723 | * Calculate the number of octets used to hold the bits
13724 | */
13725 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13726 | length = tot_no_bits>>3;
13727 | /* If we are using part of the next octet, increase length by 1 */
13728 | if (tot_no_bits & 0x07)
13729 | length++;
13730 |
13731 | if (no_of_bits < 65) {
13732 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13733 | } else {
13734 | 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)
13735 | 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);
13736 | return NULL((void*)0);
13737 | }
13738 |
13739 | str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13740 |
13741 | (void) g_strlcat(str, " = ", 256+64);
13742 | (void) g_strlcat(str, hf_field->name, 256+64);
13743 |
13744 | /*
13745 | * This function does not receive an actual value but a dimensionless pointer to that value.
13746 | * For this reason, the type of the header field is examined in order to determine
13747 | * what kind of value we should read from this address.
13748 | * The caller of this function must make sure that for the specific header field type the address of
13749 | * a compatible value is provided.
13750 | */
13751 | switch (hf_field->type) {
13752 | case FT_BOOLEAN:
13753 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13754 | "%s: %s", str, value_str);
13755 | break;
13756 |
13757 | case FT_CHAR:
13758 | case FT_UINT8:
13759 | case FT_UINT16:
13760 | case FT_UINT24:
13761 | case FT_UINT32:
13762 | return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13763 | "%s: %s", str, value_str);
13764 | break;
13765 |
13766 | case FT_UINT40:
13767 | case FT_UINT48:
13768 | case FT_UINT56:
13769 | case FT_UINT64:
13770 | return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13771 | "%s: %s", str, value_str);
13772 | break;
13773 |
13774 | case FT_INT8:
13775 | case FT_INT16:
13776 | case FT_INT24:
13777 | case FT_INT32:
13778 | return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13779 | "%s: %s", str, value_str);
13780 | break;
13781 |
13782 | case FT_INT40:
13783 | case FT_INT48:
13784 | case FT_INT56:
13785 | case FT_INT64:
13786 | return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13787 | "%s: %s", str, value_str);
13788 | break;
13789 |
13790 | case FT_FLOAT:
13791 | return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13792 | "%s: %s", str, value_str);
13793 | break;
13794 |
13795 | default:
13796 | 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))
13797 | 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))
13798 | 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))
13799 | 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));
13800 | return NULL((void*)0);
13801 | }
13802 | }
13803 |
13804 | static proto_item *
13805 | proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13806 | tvbuff_t *tvb, const unsigned bit_offset,
13807 | const int no_of_bits, void *value_ptr,
13808 | const unsigned encoding, char *value_str)
13809 | {
13810 | proto_item *item;
13811 |
13812 | if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13813 | tvb, bit_offset, no_of_bits,
13814 | value_ptr, encoding, value_str))) {
13815 | 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);
13816 | 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);
13817 | }
13818 | return item;
13819 | }
13820 |
13821 | #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); \
13822 | va_start(ap, format)__builtin_va_start(ap, format); \
13823 | dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13824 | va_end(ap)__builtin_va_end(ap);
13825 |
13826 | proto_item *
13827 | proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13828 | tvbuff_t *tvb, const unsigned bit_offset,
13829 | const int no_of_bits, uint32_t value,
13830 | const unsigned encoding,
13831 | const char *format, ...)
13832 | {
13833 | va_list ap;
13834 | char *dst;
13835 | header_field_info *hf_field;
13836 |
13837 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13838 |
13839 | 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", 13839 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13839, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13839, "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", 13839, __func__, "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); } } };
13840 |
13841 | switch (hf_field->type) {
13842 | case FT_UINT8:
13843 | case FT_UINT16:
13844 | case FT_UINT24:
13845 | case FT_UINT32:
13846 | break;
13847 |
13848 | default:
13849 | 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)
13850 | 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);
13851 | return NULL((void*)0);
13852 | }
13853 |
13854 | 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);;
13855 |
13856 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13857 | }
13858 |
13859 | proto_item *
13860 | proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13861 | tvbuff_t *tvb, const unsigned bit_offset,
13862 | const int no_of_bits, uint64_t value,
13863 | const unsigned encoding,
13864 | const char *format, ...)
13865 | {
13866 | va_list ap;
13867 | char *dst;
13868 | header_field_info *hf_field;
13869 |
13870 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13871 |
13872 | 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", 13872 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13872, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13872, "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", 13872, __func__, "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); } } };
13873 |
13874 | switch (hf_field->type) {
13875 | case FT_UINT40:
13876 | case FT_UINT48:
13877 | case FT_UINT56:
13878 | case FT_UINT64:
13879 | break;
13880 |
13881 | default:
13882 | 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)
13883 | 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);
13884 | return NULL((void*)0);
13885 | }
13886 |
13887 | 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);;
13888 |
13889 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13890 | }
13891 |
13892 | proto_item *
13893 | proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13894 | tvbuff_t *tvb, const unsigned bit_offset,
13895 | const int no_of_bits, float value,
13896 | const unsigned encoding,
13897 | const char *format, ...)
13898 | {
13899 | va_list ap;
13900 | char *dst;
13901 | header_field_info *hf_field;
13902 |
13903 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13904 |
13905 | 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", 13905 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13905, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13905, "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", 13905, __func__, "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); } } };
13906 |
13907 | 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", 13907, ((hf_field))->abbrev))));
13908 |
13909 | 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);;
13910 |
13911 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13912 | }
13913 |
13914 | proto_item *
13915 | proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13916 | tvbuff_t *tvb, const unsigned bit_offset,
13917 | const int no_of_bits, int32_t value,
13918 | const unsigned encoding,
13919 | const char *format, ...)
13920 | {
13921 | va_list ap;
13922 | char *dst;
13923 | header_field_info *hf_field;
13924 |
13925 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13926 |
13927 | 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", 13927 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13927, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13927, "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", 13927, __func__, "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); } } };
13928 |
13929 | switch (hf_field->type) {
13930 | case FT_INT8:
13931 | case FT_INT16:
13932 | case FT_INT24:
13933 | case FT_INT32:
13934 | break;
13935 |
13936 | default:
13937 | 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)
13938 | 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);
13939 | return NULL((void*)0);
13940 | }
13941 |
13942 | 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);;
13943 |
13944 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13945 | }
13946 |
13947 | proto_item *
13948 | proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13949 | tvbuff_t *tvb, const unsigned bit_offset,
13950 | const int no_of_bits, int64_t value,
13951 | const unsigned encoding,
13952 | const char *format, ...)
13953 | {
13954 | va_list ap;
13955 | char *dst;
13956 | header_field_info *hf_field;
13957 |
13958 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13959 |
13960 | 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", 13960 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13960, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13960, "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", 13960, __func__, "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); } } };
13961 |
13962 | switch (hf_field->type) {
13963 | case FT_INT40:
13964 | case FT_INT48:
13965 | case FT_INT56:
13966 | case FT_INT64:
13967 | break;
13968 |
13969 | default:
13970 | 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)
13971 | 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);
13972 | return NULL((void*)0);
13973 | }
13974 |
13975 | 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);;
13976 |
13977 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13978 | }
13979 |
13980 | proto_item *
13981 | proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13982 | tvbuff_t *tvb, const unsigned bit_offset,
13983 | const int no_of_bits, uint64_t value,
13984 | const unsigned encoding,
13985 | const char *format, ...)
13986 | {
13987 | va_list ap;
13988 | char *dst;
13989 | header_field_info *hf_field;
13990 |
13991 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13992 |
13993 | 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", 13993 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13993, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13993, "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", 13993, __func__, "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); } } };
13994 |
13995 | 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" , 13995, ((hf_field))->abbrev))));
13996 |
13997 | 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);;
13998 |
13999 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14000 | }
14001 |
14002 | proto_item *
14003 | proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14004 | const unsigned bit_offset, const int no_of_chars)
14005 | {
14006 | proto_item *pi;
14007 | header_field_info *hfinfo;
14008 | int byte_length;
14009 | int byte_offset;
14010 | char *string;
14011 |
14012 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14013 |
14014 | 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", 14014 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14014, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14014, "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", 14014, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14015 |
14016 | 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" , 14016, ((hfinfo))->abbrev))));
14017 |
14018 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14019 | byte_offset = bit_offset >> 3;
14020 |
14021 | string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14022 |
14023 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14024 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14024, "byte_length >= 0" ))));
14025 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14026 |
14027 | return pi;
14028 | }
14029 |
14030 | proto_item *
14031 | proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14032 | const unsigned bit_offset, const int no_of_chars)
14033 | {
14034 | proto_item *pi;
14035 | header_field_info *hfinfo;
14036 | int byte_length;
14037 | int byte_offset;
14038 | char *string;
14039 |
14040 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14041 |
14042 | 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", 14042 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14042, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14042, "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", 14042, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14043 |
14044 | 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" , 14044, ((hfinfo))->abbrev))));
14045 |
14046 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14047 | byte_offset = bit_offset >> 3;
14048 |
14049 | string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14050 |
14051 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14052 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14052, "byte_length >= 0" ))));
14053 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14054 |
14055 | return pi;
14056 | }
14057 |
14058 | const value_string proto_checksum_vals[] = {
14059 | { PROTO_CHECKSUM_E_BAD, "Bad" },
14060 | { PROTO_CHECKSUM_E_GOOD, "Good" },
14061 | { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14062 | { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14063 | { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14064 |
14065 | { 0, NULL((void*)0) }
14066 | };
14067 |
14068 | proto_item *
14069 | proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14070 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14071 | packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14072 | {
14073 | header_field_info *hfinfo;
14074 | uint32_t checksum;
14075 | uint32_t len;
14076 | proto_item* ti = NULL((void*)0);
14077 | proto_item* ti2;
14078 | bool_Bool incorrect_checksum = true1;
14079 |
14080 | 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", 14080, __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", 14080 , "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", 14080, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14081 |
14082 | switch (hfinfo->type) {
14083 | case FT_UINT8:
14084 | len = 1;
14085 | break;
14086 | case FT_UINT16:
14087 | len = 2;
14088 | break;
14089 | case FT_UINT24:
14090 | len = 3;
14091 | break;
14092 | case FT_UINT32:
14093 | len = 4;
14094 | break;
14095 | default:
14096 | 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)
14097 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32" , hfinfo->abbrev);
14098 | }
14099 |
14100 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14101 | ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14102 | proto_item_set_generated(ti);
14103 | if (hf_checksum_status != -1) {
14104 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14105 | proto_item_set_generated(ti2);
14106 | }
14107 | return ti;
14108 | }
14109 |
14110 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14111 | ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14112 | proto_item_set_generated(ti);
14113 | } else {
14114 | ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14115 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14116 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14117 | if (computed_checksum == 0) {
14118 | proto_item_append_text(ti, " [correct]");
14119 | if (hf_checksum_status != -1) {
14120 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14121 | proto_item_set_generated(ti2);
14122 | }
14123 | incorrect_checksum = false0;
14124 | } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14125 | computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14126 | /* XXX - This can't distinguish between "shouldbe"
14127 | * 0x0000 and 0xFFFF unless we know whether there
14128 | * were any nonzero bits (other than the checksum).
14129 | * Protocols should not use this path if they might
14130 | * have an all zero packet.
14131 | * Some implementations put the wrong zero; maybe
14132 | * we should have a special expert info for that?
14133 | */
14134 | }
14135 | } else {
14136 | if (checksum == computed_checksum) {
14137 | proto_item_append_text(ti, " [correct]");
14138 | if (hf_checksum_status != -1) {
14139 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14140 | proto_item_set_generated(ti2);
14141 | }
14142 | incorrect_checksum = false0;
14143 | }
14144 | }
14145 |
14146 | if (incorrect_checksum) {
14147 | if (hf_checksum_status != -1) {
14148 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14149 | proto_item_set_generated(ti2);
14150 | }
14151 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14152 | proto_item_append_text(ti, " [incorrect]");
14153 | if (bad_checksum_expert != NULL((void*)0))
14154 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14155 | } else {
14156 | proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14157 | if (bad_checksum_expert != NULL((void*)0))
14158 | 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);
14159 | }
14160 | }
14161 | } else {
14162 | if (hf_checksum_status != -1) {
14163 | proto_item_append_text(ti, " [unverified]");
14164 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14165 | proto_item_set_generated(ti2);
14166 | }
14167 | }
14168 | }
14169 |
14170 | return ti;
14171 | }
14172 |
14173 | proto_item *
14174 | proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14175 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14176 | packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14177 | {
14178 | header_field_info *hfinfo;
14179 | uint8_t *checksum = NULL((void*)0);
14180 | proto_item* ti = NULL((void*)0);
14181 | proto_item* ti2;
14182 | bool_Bool incorrect_checksum = true1;
14183 |
14184 | 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", 14184, __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", 14184 , "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", 14184, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14185 |
14186 | if (hfinfo->type != FT_BYTES) {
14187 | REPORT_DISSECTOR_BUG("field %s is not of type FT_BYTES",proto_report_dissector_bug("field %s is not of type FT_BYTES" , hfinfo->abbrev)
14188 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES" , hfinfo->abbrev);
14189 | }
14190 |
14191 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14192 | ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14193 | proto_item_set_generated(ti);
14194 | if (hf_checksum_status != -1) {
14195 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14196 | proto_item_set_generated(ti2);
14197 | }
14198 | return ti;
14199 | }
14200 |
14201 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14202 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14203 | proto_item_set_generated(ti);
14204 | } else {
14205 | checksum = (uint8_t*)wmem_alloc0_array(pinfo->pool, uint8_t, checksum_len)((uint8_t*)wmem_alloc0((pinfo->pool), (((((checksum_len)) <= 0) || ((size_t)sizeof(uint8_t) > (9223372036854775807L / ( size_t)((checksum_len))))) ? 0 : (sizeof(uint8_t) * ((checksum_len ))))));
14206 | tvb_memcpy(tvb, checksum, offset, checksum_len);
14207 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14208 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14209 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14210 | if (computed_checksum == 0) {
14211 | proto_item_append_text(ti, " [correct]");
14212 | if (hf_checksum_status != -1) {
14213 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14214 | proto_item_set_generated(ti2);
14215 | }
14216 | incorrect_checksum = false0;
14217 | }
14218 | } else {
14219 | if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14220 | proto_item_append_text(ti, " [correct]");
14221 | if (hf_checksum_status != -1) {
14222 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14223 | proto_item_set_generated(ti2);
14224 | }
14225 | incorrect_checksum = false0;
14226 | }
14227 | }
14228 |
14229 | if (incorrect_checksum) {
14230 | if (hf_checksum_status != -1) {
14231 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14232 | proto_item_set_generated(ti2);
14233 | }
14234 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14235 | proto_item_append_text(ti, " [incorrect]");
14236 | if (bad_checksum_expert != NULL((void*)0))
14237 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14238 | } else {
14239 | size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14240 | char *computed_checksum_str = (char*)wmem_alloc0_array(pinfo->pool, char, computed_checksum_str_len)((char*)wmem_alloc0((pinfo->pool), (((((computed_checksum_str_len )) <= 0) || ((size_t)sizeof(char) > (9223372036854775807L / (size_t)((computed_checksum_str_len))))) ? 0 : (sizeof(char ) * ((computed_checksum_str_len))))));
14241 | for (size_t counter = 0; counter < checksum_len; ++counter) {
14242 | snprintf(
14243 | /* On ecah iteration inserts two characters */
14244 | (char*)&computed_checksum_str[counter << 1],
14245 | computed_checksum_str_len - (counter << 1),
14246 | "%02x",
14247 | computed_checksum[counter]);
14248 | }
14249 | proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14250 | if (bad_checksum_expert != NULL((void*)0))
14251 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14252 | }
14253 | }
14254 | } else {
14255 | if (hf_checksum_status != -1) {
14256 | proto_item_append_text(ti, " [unverified]");
14257 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14258 | proto_item_set_generated(ti2);
14259 | }
14260 | }
14261 | }
14262 |
14263 | return ti;
14264 | }
14265 |
14266 | unsigned char
14267 | proto_check_field_name(const char *field_name)
14268 | {
14269 | return module_check_valid_name(field_name, false0);
14270 | }
14271 |
14272 | unsigned char
14273 | proto_check_field_name_lower(const char *field_name)
14274 | {
14275 | return module_check_valid_name(field_name, true1);
14276 | }
14277 |
14278 | bool_Bool
14279 | tree_expanded(int tree_type)
14280 | {
14281 | if (tree_type <= 0) {
14282 | return false0;
14283 | }
14284 | 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", 14284, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14285 | return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14286 | }
14287 |
14288 | void
14289 | tree_expanded_set(int tree_type, bool_Bool value)
14290 | {
14291 | 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", 14291, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14292 |
14293 | if (value)
14294 | tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14295 | else
14296 | tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14297 | }
14298 |
14299 | /*
14300 | * Editor modelines - https://www.wireshark.org/tools/modelines.html
14301 | *
14302 | * Local variables:
14303 | * c-basic-offset: 8
14304 | * tab-width: 8
14305 | * indent-tabs-mode: t
14306 | * End:
14307 | *
14308 | * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14309 | * :indentSize=8:tabSize=8:noTabs=false:
14310 | */