### Bug Summary

File: | epan/proto.c
Warning: | line 13549, 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-22-100336-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 |
37 | #include <epan/packet.h>
38 | #include "exceptions.h"
39 | #include "ptvcursor.h"
40 | #include "strutil.h"
41 | #include "addr_resolv.h"
42 | #include "address_types.h"
43 | #include "oids.h"
44 | #include "proto.h"
45 | #include "epan_dissect.h"
46 | #include "dfilter/dfilter.h"
47 | #include "tvbuff.h"
48 | #include "charsets.h"
49 | #include "column-info.h"
50 | #include "to_str.h"
51 | #include "osi-utils.h"
52 | #include "expert.h"
53 | #include "show_exception.h"
54 | #include "in_cksum.h"
55 | #include "register-int.h"
56 |
57 | #include <wsutil/crash_info.h>
58 | #include <wsutil/epochs.h>
59 |
60 | /* Ptvcursor limits */
61 | #define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
62 | #define SUBTREE_MAX_LEVELS256 256
63 |
64 | typedef struct __subtree_lvl {
65 | int cursor_offset;
66 | proto_item *it;
67 | proto_tree *tree;
68 | } subtree_lvl;
69 |
70 | struct ptvcursor {
71 | wmem_allocator_t *scope;
72 | subtree_lvl *pushed_tree;
73 | uint8_t pushed_tree_index;
74 | uint8_t pushed_tree_max;
75 | proto_tree *tree;
76 | tvbuff_t *tvb;
77 | int offset;
78 | };
79 |
80 | #define cVALS(x)(const value_string*)(x) (const value_string*)(x)
81 |
82 | /** See inlined comments.
83 | @param tree the tree to append this item to
84 | @param free_block a code block to call to free resources if this returns
85 | @return NULL if 'tree' is null */
86 | #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
87 | if (!tree) { \
88 | free_block; \
89 | return NULL((void*)0); \
90 | }
91 |
92 | /** See inlined comments.
93 | @param tree the tree to append this item to
94 | @return NULL if 'tree' is null */
95 | #define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
96 | CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
97 |
98 | /** See inlined comments.
99 | @param length the length of this item
100 | @param cleanup_block a code block to call to free resources if this returns
101 | @return NULL if 'length' is lower -1 or equal 0 */
102 | #define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return ( (void*)0); } \
103 | if (length < -1 || length == 0 ) { \
104 | cleanup_block; \
105 | return NULL((void*)0); \
106 | }
107 |
108 | /** See inlined comments.
109 | @param length the length of this item
110 | @return NULL if 'length' is lower -1 or equal 0 */
111 | #define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); } \
112 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); }
113 |
114 | /** See inlined comments.
115 | @param tree the tree to append this item to
116 | @param hfindex field index
117 | @param hfinfo header_field
118 | @param free_block a code block to call to free resources if this returns
119 | @return the header field matching 'hfinfo' */
120 | #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 120, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 120, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 120, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { free_block; return proto_tree_add_fake_node(tree, hfinfo ); } } } \
121 | /* If the tree is not visible and this item is not referenced \
122 | we don't have to do much work at all but we should still \
123 | return a node so that referenced field items below this node \
124 | (think proto_item_add_subtree()) will still have somewhere \
125 | to attach to or else filtering will not work (they would be \
126 | ignored since tree would be NULL). \
127 | DON'T try to fake a node where PTREE_FINFO(tree) is visible \
128 | because that means we can change its length or repr, and we \
129 | don't want to do so with calls intended for this faked new \
130 | item, so this item needs a new (hidden) child node. \
131 | We fake FT_PROTOCOL unless some clients have requested us \
132 | not to do so. \
133 | */ \
134 | PTREE_DATA(tree)((tree)->tree_data)->count++; \
135 | PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 135, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 135, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 135, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; \
136 | if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
137 | free_block; \
138 | if (wireshark_abort_on_too_many_items) \
139 | ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)
140 | hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 140 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); \
141 | /* Let the exception handler add items to the tree */ \
142 | PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
143 | THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)))
144 | wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)))
145 | "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)))
146 | hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); \
147 | } \
148 | if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
149 | if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
150 | if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
151 | && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
152 | && (hfinfo->type != FT_PROTOCOL || \
153 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
154 | free_block; \
155 | /* return fake node with no field info */\
156 | return proto_tree_add_fake_node(tree, hfinfo); \
157 | } \
158 | } \
159 | }
160 |
161 | /** See inlined comments.
162 | @param tree the tree to append this item to
163 | @param hfindex field index
164 | @param hfinfo header_field
165 | @return the header field matching 'hfinfo' */
166 | #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 166, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 166, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 166, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } } \
167 | TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } }
168 |
169 |
170 | /** See inlined comments.
171 | @param pi the created protocol item we're about to return */
172 | #define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 172, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; } \
173 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 173, __func__, "assertion failed: %s", "pi" ); } while (0); \
174 | if (!PITEM_FINFO(pi)((pi)->finfo)) \
175 | return pi; \
176 | if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
177 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
178 | /* If the tree (GUI) or item isn't visible it's pointless for \
179 | * us to generate the protocol item's string representation */ \
180 | return pi; \
181 | }
182 | /* Same as above but returning void */
183 | #define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; } \
184 | if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
185 | return; \
186 | if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
187 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
188 | /* If the tree (GUI) or item isn't visible it's pointless for \
189 | * us to generate the protocol item's string representation */ \
190 | return; \
191 | }
192 | /* Similar to above, but allows a NULL tree */
193 | #define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) || (!(((pi)->tree_data)->visible) && proto_item_is_hidden ((pi)))) { return pi; } \
194 | if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
195 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
196 | /* If the tree (GUI) or item isn't visible it's pointless for \
197 | * us to generate the protocol item's string representation */ \
198 | return pi; \
199 | }
200 |
201 | #ifdef ENABLE_CHECK_FILTER
202 | #define CHECK_HF_VALUE(type, spec, start_values) \
203 | { \
204 | const type *current; \
205 | int n, m; \
206 | current = start_values; \
207 | for (n=0; current; n++, current++) { \
208 | /* Drop out if we reached the end. */ \
209 | if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
210 | break; \
211 | } \
212 | /* Check value against all previous */ \
213 | for (m=0; m < n; m++) { \
214 | /* There are lots of duplicates with the same string, \
215 | so only report if different... */ \
216 | if ((start_values[m].value == current->value) && \
217 | (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
218 | ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr)
219 | " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr)
220 | hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr)
221 | current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 221 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr); \
222 | } \
223 | } \
224 | } \
225 | }
226 | #endif
227 |
228 | /* The longest NUMBER-like field label we have is for BASE_OUI, which
229 | * can have up to 64 bytes for the manufacturer name if resolved plus
230 | * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
231 | */
232 | #define NUMBER_LABEL_LENGTH80 80
233 |
234 | static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
235 | static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
236 | static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
237 | static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
238 | static int hfinfo_bitoffset(const header_field_info *hfinfo);
239 | static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
240 | static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
241 |
242 | #define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
243 | ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
244 |
245 | static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
246 | static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
247 |
248 | static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
249 | static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
250 | static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
251 | static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252 | static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
253 | static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
254 | static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255 |
256 | static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
257 | static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
258 | static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
259 | static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
260 |
261 | static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
262 | static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
263 | static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
264 | static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
265 | static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
266 | static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
267 | static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
268 | static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
269 | static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
270 | static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
271 | static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
272 |
273 | static void proto_cleanup_base(void);
274 |
275 | static proto_item *
276 | proto_tree_add_node(proto_tree *tree, field_info *fi);
277 |
278 | static proto_item *
279 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
280 |
281 | static void
282 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
283 | int *item_length, const unsigned encoding);
284 |
285 | static int
286 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
287 | int length, unsigned item_length, const int encoding);
288 |
289 | static field_info *
290 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
291 | const int start, const int item_length);
292 |
293 | static proto_item *
294 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
295 | int start, int *length);
296 |
297 | static void
298 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
299 | static void
300 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
301 |
302 | static void
303 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
304 | static void
305 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
306 | static void
307 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
308 | static void
309 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
310 | static void
311 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
312 | static void
313 | proto_tree_set_string(field_info *fi, const char* value);
314 | static void
315 | proto_tree_set_ax25(field_info *fi, const uint8_t* value);
316 | static void
317 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
318 | static void
319 | proto_tree_set_vines(field_info *fi, const uint8_t* value);
320 | static void
321 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
322 | static void
323 | proto_tree_set_ether(field_info *fi, const uint8_t* value);
324 | static void
325 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
326 | static void
327 | proto_tree_set_ipxnet(field_info *fi, uint32_t value);
328 | static void
329 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
330 | static void
331 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
332 | static void
333 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
334 | static void
335 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
336 | static void
337 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
338 | static void
339 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
340 | static void
341 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
342 | static void
343 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
344 | static void
345 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
346 | static void
347 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
348 | static void
349 | proto_tree_set_boolean(field_info *fi, uint64_t value);
350 | static void
351 | proto_tree_set_float(field_info *fi, float value);
352 | static void
353 | proto_tree_set_double(field_info *fi, double value);
354 | static void
355 | proto_tree_set_uint(field_info *fi, uint32_t value);
356 | static void
357 | proto_tree_set_int(field_info *fi, int32_t value);
358 | static void
359 | proto_tree_set_uint64(field_info *fi, uint64_t value);
360 | static void
361 | proto_tree_set_int64(field_info *fi, int64_t value);
362 | static void
363 | proto_tree_set_eui64(field_info *fi, const uint64_t value);
364 | static void
365 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
366 |
367 | /* Handle type length mismatch (now filterable) expert info */
368 | static int proto_type_length_mismatch;
369 | static expert_field ei_type_length_mismatch_error;
370 | static expert_field ei_type_length_mismatch_warn;
371 | static void register_type_length_mismatch(void);
372 |
373 | /* Handle byte array string decoding errors with expert info */
374 | static int proto_byte_array_string_decoding_error;
375 | static expert_field ei_byte_array_string_decoding_failed_error;
376 | static void register_byte_array_string_decodinws_error(void);
377 |
378 | /* Handle date and time string decoding errors with expert info */
379 | static int proto_date_time_string_decoding_error;
380 | static expert_field ei_date_time_string_decoding_failed_error;
381 | static void register_date_time_string_decodinws_error(void);
382 |
383 | /* Handle string errors expert info */
384 | static int proto_string_errors;
385 | static expert_field ei_string_trailing_characters;
386 | static void register_string_errors(void);
387 |
388 | static int proto_register_field_init(header_field_info *hfinfo, const int parent);
389 |
390 | /* special-case header field used within proto.c */
391 | static header_field_info hfi_text_only =
392 | { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
393 | int hf_text_only;
394 |
395 | /* Structure for information about a protocol */
396 | struct _protocol {
397 | const char *name; /* long description */
398 | const char *short_name; /* short description */
399 | const char *filter_name; /* name of this protocol in filters */
400 | GPtrArray *fields; /* fields for this protocol */
401 | int proto_id; /* field ID for this protocol */
402 | bool_Bool is_enabled; /* true if protocol is enabled */
403 | bool_Bool enabled_by_default; /* true if protocol is enabled by default */
404 | bool_Bool can_toggle; /* true if is_enabled can be changed */
405 | int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
406 | For dissectors that need a protocol name so they
407 | can be added to a dissector table, but use the
408 | parent_proto_id for things like enable/disable */
409 | GList *heur_list; /* Heuristic dissectors associated with this protocol */
410 | };
411 |
412 | /* List of all protocols */
413 | static GList *protocols;
414 |
415 | /* Structure stored for deregistered g_slice */
416 | struct g_slice_data {
417 | size_t block_size;
418 | void *mem_block;
419 | };
420 |
421 | /* Deregistered fields */
422 | static GPtrArray *deregistered_fields;
423 | static GPtrArray *deregistered_data;
424 | static GPtrArray *deregistered_slice;
425 |
426 | /* indexed by prefix, contains initializers */
427 | static GHashTable* prefixes;
428 |
429 | /* Contains information about a field when a dissector calls
430 | * proto_tree_add_item. */
431 | #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)))
432 | #define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
433 |
434 | /* Contains the space for proto_nodes. */
435 | #define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void *)0); node->next = ((void*)0); \
436 | node->first_child = NULL((void*)0); \
437 | node->last_child = NULL((void*)0); \
438 | node->next = NULL((void*)0);
439 |
440 | #define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
441 | wmem_free(pool, node)
442 |
443 | /* String space for protocol and field items for the GUI */
444 | #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; \
445 | il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
446 | il->value_pos = 0; \
447 | il->value_len = 0;
448 | #define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
449 | wmem_free(pool, il);
450 |
451 | #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", 451, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 451, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 451, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex]; \
452 | if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
453 | ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 453 , __func__, "Unregistered hf! index=%d", hfindex); \
454 | 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", 454, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))); \
455 | 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", 455, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))); \
456 | hfinfo = gpa_hfinfo.hfi[hfindex];
457 |
458 | #define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
459 |
460 | /* List which stores protocols and fields that have been registered */
461 | typedef struct _gpa_hfinfo_t {
462 | uint32_t len;
463 | uint32_t allocated_len;
464 | header_field_info **hfi;
465 | } gpa_hfinfo_t;
466 |
467 | static gpa_hfinfo_t gpa_hfinfo;
468 |
469 | /* Hash table of abbreviations and IDs */
470 | static wmem_map_t *gpa_name_map;
471 | static header_field_info *same_name_hfinfo;
472 |
473 | /* Hash table protocol aliases. const char * -> const char * */
474 | static GHashTable *gpa_protocol_aliases;
475 |
476 | /*
477 | * We're called repeatedly with the same field name when sorting a column.
478 | * Cache our last gpa_name_map hit for faster lookups.
479 | */
480 | static char *last_field_name;
481 | static header_field_info *last_hfinfo;
482 |
483 | /* Points to the first element of an array of bits, indexed by
484 | a subtree item type; that array element is true if subtrees of
485 | an item of that type are to be expanded. */
486 | static uint32_t *tree_is_expanded;
487 |
488 | /* Number of elements in that array. The entry with index 0 is not used. */
489 | int num_tree_types = 1;
490 |
491 | /* Name hashtables for fast detection of duplicate names */
492 | static GHashTable* proto_names;
493 | static GHashTable* proto_short_names;
494 | static GHashTable* proto_filter_names;
495 |
496 | static const char *reserved_filter_names[] = {
497 | /* Display filter keywords. */
498 | "eq",
499 | "ne",
500 | "all_eq",
501 | "any_eq",
502 | "all_ne",
503 | "any_ne",
504 | "gt",
505 | "ge",
506 | "lt",
507 | "le",
508 | "bitand",
509 | "bitwise_and",
510 | "contains",
511 | "matches",
512 | "not",
513 | "and",
514 | "or",
515 | "xor",
516 | "in",
517 | "any",
518 | "all",
519 | "true",
520 | "false",
521 | "nan",
522 | "inf",
523 | "infinity",
524 | NULL((void*)0)
525 | };
526 |
527 | static GHashTable *proto_reserved_filter_names;
528 | static GQueue* saved_dir_queue;
529 |
530 | static int
531 | proto_compare_name(const void *p1_arg, const void *p2_arg)
532 | {
533 | const protocol_t *p1 = (const protocol_t *)p1_arg;
534 | const protocol_t *p2 = (const protocol_t *)p2_arg;
535 |
536 | return g_ascii_strcasecmp(p1->short_name, p2->short_name);
537 | }
538 |
539 | static GSList *dissector_plugins;
540 |
541 | #ifdef HAVE_PLUGINS1
542 | void
543 | proto_register_plugin(const proto_plugin *plug)
544 | {
545 | dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
546 | }
547 | #else /* HAVE_PLUGINS */
548 | void
549 | proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
550 | {
551 | ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 551, __func__, "proto_register_plugin: built without support for binary plugins" ); } } while (0);
552 | }
553 | #endif /* HAVE_PLUGINS */
554 |
555 | static void
556 | call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
557 | {
558 | proto_plugin *plug = (proto_plugin *)data;
559 |
560 | if (plug->register_protoinfo) {
561 | plug->register_protoinfo();
562 | }
563 | }
564 |
565 | static void
566 | call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
567 | {
568 | proto_plugin *plug = (proto_plugin *)data;
569 |
570 | if (plug->register_handoff) {
571 | plug->register_handoff();
572 | }
573 | }
574 |
575 | /* initialize data structures and register protocols and fields */
576 | void
577 | proto_init(GSList *register_all_plugin_protocols_list,
578 | GSList *register_all_plugin_handoffs_list,
579 | register_cb cb,
580 | void *client_data)
581 | {
582 | proto_cleanup_base();
583 | saved_dir_queue = g_queue_new();
584 |
585 | proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
586 | proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
587 | proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
588 |
589 | proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
590 | for (const char **ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
591 | /* GHashTable has no key destructor so the cast is safe. */
592 | g_hash_table_add(proto_reserved_filter_names, *(char **)ptr);
593 | }
594 |
595 | gpa_hfinfo.len = 0;
596 | gpa_hfinfo.allocated_len = 0;
597 | gpa_hfinfo.hfi = NULL((void*)0);
598 | gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
599 | wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
600 | gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
601 | deregistered_fields = g_ptr_array_new();
602 | deregistered_data = g_ptr_array_new();
603 | deregistered_slice = g_ptr_array_new();
604 |
605 | /* Initialize the ftype subsystem */
606 | ftypes_initialize();
607 |
608 | /* Initialize the address type subsystem */
609 | address_types_initialize();
610 |
611 | /* Register one special-case FT_TEXT_ONLY field for use when
612 | converting wireshark to new-style proto_tree. These fields
613 | are merely strings on the GUI tree; they are not filterable */
614 | hf_text_only = proto_register_field_init(&hfi_text_only, -1);
615 |
616 | /* Register the pseudo-protocols used for exceptions. */
617 | register_show_exception();
618 | register_type_length_mismatch();
619 | register_byte_array_string_decodinws_error();
620 | register_date_time_string_decodinws_error();
621 | register_string_errors();
622 | ftypes_register_pseudofields();
623 | col_register_protocol();
624 |
625 | /* Have each built-in dissector register its protocols, fields,
626 | dissector tables, and dissectors to be called through a
627 | handle, and do whatever one-time initialization it needs to
628 | do. */
629 | register_all_protocols(cb, client_data);
630 |
631 | /* Now call the registration routines for all epan plugins. */
632 | for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
633 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
634 | }
635 |
636 | /* Now call the registration routines for all dissector plugins. */
637 | if (cb)
638 | (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
639 | g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
640 |
641 | /* Now call the "handoff registration" routines of all built-in
642 | dissectors; those routines register the dissector in other
643 | dissectors' handoff tables, and fetch any dissector handles
644 | they need. */
645 | register_all_protocol_handoffs(cb, client_data);
646 |
647 | /* Now do the same with epan plugins. */
648 | for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
649 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
650 | }
651 |
652 | /* Now do the same with dissector plugins. */
653 | if (cb)
654 | (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
655 | g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
656 |
657 | /* sort the protocols by protocol name */
658 | protocols = g_list_sort(protocols, proto_compare_name);
659 |
660 | /* sort the dissector handles in dissector tables (for -G reports
661 | * and -d error messages. The GUI sorts the handles itself.) */
662 | packet_all_tables_sort_handles();
663 |
664 | /* We've assigned all the subtree type values; allocate the array
665 | for them, and zero it out. */
666 | 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 )));
667 | }
668 |
669 | static void
670 | proto_cleanup_base(void)
671 | {
672 | protocol_t *protocol;
673 | header_field_info *hfinfo;
674 |
675 | /* Free the abbrev/ID hash table */
676 | if (gpa_name_map) {
677 | // XXX - We don't have a wmem_map_destroy, but
678 | // it does get cleaned up when epan scope is
679 | // destroyed
680 | //g_hash_table_destroy(gpa_name_map);
681 | gpa_name_map = NULL((void*)0);
682 | }
683 | if (gpa_protocol_aliases) {
684 | g_hash_table_destroy(gpa_protocol_aliases);
685 | gpa_protocol_aliases = NULL((void*)0);
686 | }
687 | g_free(last_field_name);
688 | last_field_name = NULL((void*)0);
689 |
690 | while (protocols) {
691 | protocol = (protocol_t *)protocols->data;
692 | 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", 692 , __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", 692, "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", 692, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol-> proto_id];;
693 | 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", 693, "protocol->proto_id == hfinfo->id" ))));
694 |
695 | 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);
696 | if (protocol->parent_proto_id != -1) {
697 | // pino protocol
698 | DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 698, "protocol->fields == ((void*)0)" )))); //helpers should not have any registered fields
699 | 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" , 699, "protocol->heur_list == ((void*)0)")))); //helpers should not have a heuristic list
700 | } else {
701 | if (protocol->fields) {
702 | g_ptr_array_free(protocol->fields, true1);
703 | }
704 | g_list_free(protocol->heur_list);
705 | }
706 | protocols = g_list_remove(protocols, protocol);
707 | g_free(protocol);
708 | }
709 |
710 | if (proto_names) {
711 | g_hash_table_destroy(proto_names);
712 | proto_names = NULL((void*)0);
713 | }
714 |
715 | if (proto_short_names) {
716 | g_hash_table_destroy(proto_short_names);
717 | proto_short_names = NULL((void*)0);
718 | }
719 |
720 | if (proto_filter_names) {
721 | g_hash_table_destroy(proto_filter_names);
722 | proto_filter_names = NULL((void*)0);
723 | }
724 |
725 | if (proto_reserved_filter_names) {
726 | g_hash_table_destroy(proto_reserved_filter_names);
727 | proto_reserved_filter_names = NULL((void*)0);
728 | }
729 |
730 | if (gpa_hfinfo.allocated_len) {
731 | gpa_hfinfo.len = 0;
732 | gpa_hfinfo.allocated_len = 0;
733 | g_free(gpa_hfinfo.hfi);
734 | gpa_hfinfo.hfi = NULL((void*)0);
735 | }
736 |
737 | if (deregistered_fields) {
738 | g_ptr_array_free(deregistered_fields, true1);
739 | deregistered_fields = NULL((void*)0);
740 | }
741 |
742 | if (deregistered_data) {
743 | g_ptr_array_free(deregistered_data, true1);
744 | deregistered_data = NULL((void*)0);
745 | }
746 |
747 | if (deregistered_slice) {
748 | g_ptr_array_free(deregistered_slice, true1);
749 | deregistered_slice = NULL((void*)0);
750 | }
751 |
752 | g_free(tree_is_expanded);
753 | tree_is_expanded = NULL((void*)0);
754 |
755 | if (prefixes)
756 | g_hash_table_destroy(prefixes);
757 |
758 | if (saved_dir_queue != NULL((void*)0)) {
759 | g_queue_clear_full(saved_dir_queue, g_free);
760 | g_queue_free(saved_dir_queue);
761 | saved_dir_queue = NULL((void*)0);
762 | }
763 | }
764 |
765 | void
766 | proto_cleanup(void)
767 | {
768 | proto_free_deregistered_fields();
769 | proto_cleanup_base();
770 |
771 | g_slist_free(dissector_plugins);
772 | dissector_plugins = NULL((void*)0);
773 | }
774 |
775 | static bool_Bool
776 | ws_pushd(const char* dir)
777 | {
778 | //Save the current working directory
779 | const char* save_wd = get_current_working_dir();
780 | if (save_wd != NULL((void*)0))
781 | g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
782 |
783 | //Change to the new one
784 | #ifdef _WIN32
785 | SetCurrentDirectory(utf_8to16(dir));
786 | return true1;
787 | #else
788 | return (chdir(dir) == 0);
789 | #endif
790 | }
791 |
792 | static bool_Bool
793 | ws_popd(void)
794 | {
795 | int ret = 0;
796 | char* saved_wd = g_queue_pop_head(saved_dir_queue);
797 | if (saved_wd == NULL((void*)0))
798 | return false0;
799 |
800 | //Restore the previous one
801 | #ifdef _WIN32
802 | SetCurrentDirectory(utf_8to16(saved_wd));
803 | #else
804 | ret = chdir(saved_wd);
805 | #endif
806 | g_free(saved_wd);
807 | return (ret == 0);
808 | }
809 |
810 | void
811 | proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
812 | {
813 | if (ws_pushd(dir))
814 | {
815 | func(param);
816 | ws_popd();
817 | }
818 | }
819 |
820 | static bool_Bool
821 | // NOLINTNEXTLINE(misc-no-recursion)
822 | proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
823 | void *data)
824 | {
825 | proto_node *pnode = tree;
826 | proto_node *child;
827 | proto_node *current;
828 |
829 | if (func(pnode, data))
830 | return true1;
831 |
832 | child = pnode->first_child;
833 | while (child != NULL((void*)0)) {
834 | /*
835 | * The routine we call might modify the child, e.g. by
836 | * freeing it, so we get the child's successor before
837 | * calling that routine.
838 | */
839 | current = child;
840 | child = current->next;
841 | // We recurse here, but we're limited by prefs.gui_max_tree_depth
842 | if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
843 | return true1;
844 | }
845 |
846 | return false0;
847 | }
848 |
849 | void
850 | proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
851 | void *data)
852 | {
853 | proto_node *node = tree;
854 | proto_node *current;
855 |
856 | if (!node)
857 | return;
858 |
859 | node = node->first_child;
860 | while (node != NULL((void*)0)) {
861 | current = node;
862 | node = current->next;
863 | func((proto_tree *)current, data);
864 | }
865 | }
866 |
867 | static void
868 | free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
869 | {
870 | GPtrArray *ptrs = (GPtrArray *)value;
871 | int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
872 | header_field_info *hfinfo;
873 |
874 | 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", 874, __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", 874, "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", 874, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
875 | if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
876 | /* when a field is referenced by a filter this also
877 | affects the refcount for the parent protocol so we need
878 | to adjust the refcount for the parent as well
879 | */
880 | if (hfinfo->parent != -1) {
881 | header_field_info *parent_hfinfo;
882 | 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", 882 , __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", 882, "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", 882, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)" , "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo ->parent];;
883 | parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
884 | }
885 | hfinfo->ref_type = HF_REF_TYPE_NONE;
886 | }
887 |
888 | g_ptr_array_free(ptrs, true1);
889 | }
890 |
891 | static void
892 | proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
893 | {
894 | field_info *finfo = PNODE_FINFO(node)((node)->finfo);
895 |
896 | proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
897 |
898 | if (finfo) {
899 | fvalue_free(finfo->value);
900 | finfo->value = NULL((void*)0);
901 | }
902 | }
903 |
904 | void
905 | proto_tree_reset(proto_tree *tree)
906 | {
907 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
908 |
909 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
910 |
911 | /* free tree data */
912 | if (tree_data->interesting_hfids) {
913 | /* Free all the GPtrArray's in the interesting_hfids hash. */
914 | g_hash_table_foreach(tree_data->interesting_hfids,
915 | free_GPtrArray_value, NULL((void*)0));
916 |
917 | /* And then remove all values. */
918 | g_hash_table_remove_all(tree_data->interesting_hfids);
919 | }
920 |
921 | /* Reset track of the number of children */
922 | tree_data->count = 0;
923 |
924 | /* Reset our loop checks */
925 | tree_data->idle_count_ds_tvb = NULL((void*)0);
926 | tree_data->max_start = 0;
927 | tree_data->start_idle_count = 0;
928 |
929 | PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void *)0); tree->next = ((void*)0);;
930 | }
931 |
932 | /* frees the resources that the dissection a proto_tree uses */
933 | void
934 | proto_tree_free(proto_tree *tree)
935 | {
936 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
937 |
938 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
939 |
940 | /* free tree data */
941 | if (tree_data->interesting_hfids) {
942 | /* Free all the GPtrArray's in the interesting_hfids hash. */
943 | g_hash_table_foreach(tree_data->interesting_hfids,
944 | free_GPtrArray_value, NULL((void*)0));
945 |
946 | /* And then destroy the hash. */
947 | g_hash_table_destroy(tree_data->interesting_hfids);
948 | }
949 |
950 | 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);
951 |
952 | g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else (void) ((proto_tree*) 0 == (tree)); } while (0);
953 | }
954 |
955 | /* Is the parsing being done for a visible proto_tree or an invisible one?
956 | * By setting this correctly, the proto_tree creation is sped up by not
957 | * having to call vsnprintf and copy strings around.
958 | */
959 | bool_Bool
960 | proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
961 | {
962 | bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
963 |
964 | PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
965 |
966 | return old_visible;
967 | }
968 |
969 | void
970 | proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
971 | {
972 | if (tree)
973 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
974 | }
975 |
976 | /* Assume dissector set only its protocol fields.
977 | This function is called by dissectors and allows the speeding up of filtering
978 | in wireshark; if this function returns false it is safe to reset tree to NULL
979 | and thus skip calling most of the expensive proto_tree_add_...()
980 | functions.
981 | If the tree is visible we implicitly assume the field is referenced.
982 | */
983 | bool_Bool
984 | proto_field_is_referenced(proto_tree *tree, int proto_id)
985 | {
986 | register header_field_info *hfinfo;
987 |
988 |
989 | if (!tree)
990 | return false0;
991 |
992 | if (PTREE_DATA(tree)((tree)->tree_data)->visible)
993 | return true1;
994 |
995 | 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", 995, __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", 995, "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", 995, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
996 | if (hfinfo->ref_type != HF_REF_TYPE_NONE)
997 | return true1;
998 |
999 | if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1000 | return true1;
1001 |
1002 | return false0;
1003 | }
1004 |
1005 |
1006 | /* Finds a record in the hfinfo array by id. */
1007 | header_field_info *
1008 | proto_registrar_get_nth(unsigned hfindex)
1009 | {
1010 | register header_field_info *hfinfo;
1011 |
1012 | 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", 1012, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1012, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1012, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
1013 | return hfinfo;
1014 | }
1015 |
1016 |
1017 | /* Prefix initialization
1018 | * this allows for a dissector to register a display filter name prefix
1019 | * so that it can delay the initialization of the hf array as long as
1020 | * possible.
1021 | */
1022 |
1023 | /* compute a hash for the part before the dot of a display filter */
1024 | static unsigned
1025 | prefix_hash (const void *key) {
1026 | /* end the string at the dot and compute its hash */
1027 | char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1028 | char* c = copy;
1029 | unsigned tmp;
1030 |
1031 | for (; *c; c++) {
1032 | if (*c == '.') {
1033 | *c = 0;
1034 | break;
1035 | }
1036 | }
1037 |
1038 | tmp = wmem_str_hash(copy);
1039 | g_free(copy);
1040 | return tmp;
1041 | }
1042 |
1043 | /* are both strings equal up to the end or the dot? */
1044 | static gboolean
1045 | prefix_equal (const void *ap, const void *bp) {
1046 | const char* a = (const char *)ap;
1047 | const char* b = (const char *)bp;
1048 |
1049 | do {
1050 | char ac = *a++;
1051 | char bc = *b++;
1052 |
1053 | if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1054 |
1055 | if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1056 | if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1057 |
1058 | if (ac != bc) return FALSE(0);
1059 | } while (1);
1060 |
1061 | return FALSE(0);
1062 | }
1063 |
1064 | /* Register a new prefix for "delayed" initialization of field arrays */
1065 | void
1066 | proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1067 | if (! prefixes ) {
1068 | prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1069 | }
1070 |
1071 | g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1072 | }
1073 |
1074 | /* helper to call all prefix initializers */
1075 | static gboolean
1076 | initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1077 | ((prefix_initializer_t)v)((const char *)k);
1078 | return TRUE(!(0));
1079 | }
1080 |
1081 | /** Initialize every remaining uninitialized prefix. */
1082 | void
1083 | proto_initialize_all_prefixes(void) {
1084 | g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1085 | }
1086 |
1087 | /* Finds a record in the hfinfo array by name.
1088 | * If it fails to find it in the already registered fields,
1089 | * it tries to find and call an initializer in the prefixes
1090 | * table and if so it looks again.
1091 | */
1092 |
1093 | header_field_info *
1094 | proto_registrar_get_byname(const char *field_name)
1095 | {
1096 | header_field_info *hfinfo;
1097 | prefix_initializer_t pi;
1098 |
1099 | if (!field_name)
1100 | return NULL((void*)0);
1101 |
1102 | if (g_strcmp0(field_name, last_field_name) == 0) {
1103 | return last_hfinfo;
1104 | }
1105 |
1106 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1107 |
1108 | if (hfinfo) {
1109 | g_free(last_field_name);
1110 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1111 | last_hfinfo = hfinfo;
1112 | return hfinfo;
1113 | }
1114 |
1115 | if (!prefixes)
1116 | return NULL((void*)0);
1117 |
1118 | if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1119 | pi(field_name);
1120 | g_hash_table_remove(prefixes, field_name);
1121 | } else {
1122 | return NULL((void*)0);
1123 | }
1124 |
1125 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1126 |
1127 | if (hfinfo) {
1128 | g_free(last_field_name);
1129 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1130 | last_hfinfo = hfinfo;
1131 | }
1132 | return hfinfo;
1133 | }
1134 |
1135 | header_field_info*
1136 | proto_registrar_get_byalias(const char *alias_name)
1137 | {
1138 | if (!alias_name) {
1139 | return NULL((void*)0);
1140 | }
1141 |
1142 | /* Find our aliased protocol. */
1143 | char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1144 | char *dot = strchr(an_copy, '.');
1145 | if (dot) {
1146 | *dot = '\0';
1147 | }
1148 | const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1149 | if (!proto_pfx) {
1150 | g_free(an_copy);
1151 | return NULL((void*)0);
1152 | }
1153 |
1154 | /* Construct our aliased field and look it up. */
1155 | GString *filter_name = g_string_new(proto_pfx);
1156 | if (dot) {
1157 | g_string_append_printf(filter_name, ".%s", dot+1);
1158 | }
1159 | header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1160 | g_free(an_copy);
1161 | 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)))));
1162 |
1163 | return hfinfo;
1164 | }
1165 |
1166 | int
1167 | proto_registrar_get_id_byname(const char *field_name)
1168 | {
1169 | header_field_info *hfinfo;
1170 |
1171 | hfinfo = proto_registrar_get_byname(field_name);
1172 |
1173 | if (!hfinfo)
1174 | return -1;
1175 |
1176 | return hfinfo->id;
1177 | }
1178 |
1179 | static int
1180 | label_strcat_flags(const header_field_info *hfinfo)
1181 | {
1182 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1183 | return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1184 |
1185 | return 0;
1186 | }
1187 |
1188 | static char *
1189 | format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1190 | const uint8_t *bytes, unsigned length, size_t max_str_len)
1191 | {
1192 | char *str = NULL((void*)0);
1193 | const uint8_t *p;
1194 | bool_Bool is_printable;
1195 |
1196 | if (bytes) {
1197 | if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1198 | /*
1199 | * If all bytes are valid and printable UTF-8, show the
1200 | * bytes as a string - in quotes to indicate that it's
1201 | * a string.
1202 | */
1203 | if (isprint_utf8_string(bytes, length)) {
1204 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1205 | (int)length, bytes);
1206 | return str;
1207 | }
1208 | } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1209 | /*
1210 | * Check whether all bytes are printable.
1211 | */
1212 | is_printable = true1;
1213 | for (p = bytes; p < bytes+length; p++) {
1214 | if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1215 | /* Not printable. */
1216 | is_printable = false0;
1217 | break;
1218 | }
1219 | }
1220 |
1221 | /*
1222 | * If all bytes are printable ASCII, show the bytes
1223 | * as a string - in quotes to indicate that it's
1224 | * a string.
1225 | */
1226 | if (is_printable) {
1227 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1228 | (int)length, bytes);
1229 | return str;
1230 | }
1231 | }
1232 |
1233 | /*
1234 | * Either it's not printable ASCII, or we don't care whether
1235 | * it's printable ASCII; show it as hex bytes.
1236 | */
1237 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1238 | case SEP_DOT:
1239 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1240 | break;
1241 | case SEP_DASH:
1242 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1243 | break;
1244 | case SEP_COLON:
1245 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1246 | break;
1247 | case SEP_SPACE:
1248 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1249 | break;
1250 | case BASE_NONE:
1251 | default:
1252 | if (prefs.display_byte_fields_with_spaces) {
1253 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1254 | } else {
1255 | str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1256 | }
1257 | break;
1258 | }
1259 | }
1260 | else {
1261 | if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1262 | str = wmem_strdup(scope, "<none>");
1263 | } else {
1264 | str = wmem_strdup(scope, "<MISSING>");
1265 | }
1266 | }
1267 | return str;
1268 | }
1269 |
1270 | static char *
1271 | format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1272 | const uint8_t *bytes, unsigned length)
1273 | {
1274 | return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1275 | }
1276 |
1277 | static void
1278 | ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1279 | {
1280 | subtree_lvl *pushed_tree;
1281 |
1282 | 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" , 1282, "ptvc->pushed_tree_max <= 256-8"))));
1283 | ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1284 |
1285 | pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1286 | DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1286, "pushed_tree != ((void*)0)" ))));
1287 | ptvc->pushed_tree = pushed_tree;
1288 | }
1289 |
1290 | static void
1291 | ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1292 | {
1293 | ptvc->pushed_tree = NULL((void*)0);
1294 | ptvc->pushed_tree_max = 0;
1295 | 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", 1295, "ptvc->pushed_tree_index == 0" ))));
1296 | ptvc->pushed_tree_index = 0;
1297 | }
1298 |
1299 | /* Allocates an initializes a ptvcursor_t with 3 variables:
1300 | * proto_tree, tvbuff, and offset. */
1301 | ptvcursor_t *
1302 | ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1303 | {
1304 | ptvcursor_t *ptvc;
1305 |
1306 | ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1307 | ptvc->scope = scope;
1308 | ptvc->tree = tree;
1309 | ptvc->tvb = tvb;
1310 | ptvc->offset = offset;
1311 | ptvc->pushed_tree = NULL((void*)0);
1312 | ptvc->pushed_tree_max = 0;
1313 | ptvc->pushed_tree_index = 0;
1314 | return ptvc;
1315 | }
1316 |
1317 |
1318 | /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1319 | void
1320 | ptvcursor_free(ptvcursor_t *ptvc)
1321 | {
1322 | ptvcursor_free_subtree_levels(ptvc);
1323 | /*g_free(ptvc);*/
1324 | }
1325 |
1326 | /* Returns tvbuff. */
1327 | tvbuff_t *
1328 | ptvcursor_tvbuff(ptvcursor_t *ptvc)
1329 | {
1330 | return ptvc->tvb;
1331 | }
1332 |
1333 | /* Returns current offset. */
1334 | int
1335 | ptvcursor_current_offset(ptvcursor_t *ptvc)
1336 | {
1337 | return ptvc->offset;
1338 | }
1339 |
1340 | proto_tree *
1341 | ptvcursor_tree(ptvcursor_t *ptvc)
1342 | {
1343 | if (!ptvc)
1344 | return NULL((void*)0);
1345 |
1346 | return ptvc->tree;
1347 | }
1348 |
1349 | void
1350 | ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1351 | {
1352 | ptvc->tree = tree;
1353 | }
1354 |
1355 | /* creates a subtree, sets it as the working tree and pushes the old working tree */
1356 | proto_tree *
1357 | ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1358 | {
1359 | subtree_lvl *subtree;
1360 | if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1361 | ptvcursor_new_subtree_levels(ptvc);
1362 |
1363 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1364 | subtree->tree = ptvc->tree;
1365 | subtree->it= NULL((void*)0);
1366 | ptvc->pushed_tree_index++;
1367 | return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1368 | }
1369 |
1370 | /* pops a subtree */
1371 | void
1372 | ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1373 | {
1374 | subtree_lvl *subtree;
1375 |
1376 | if (ptvc->pushed_tree_index <= 0)
1377 | return;
1378 |
1379 | ptvc->pushed_tree_index--;
1380 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1381 | if (subtree->it != NULL((void*)0))
1382 | proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1383 |
1384 | ptvc->tree = subtree->tree;
1385 | }
1386 |
1387 | /* saves the current tvb offset and the item in the current subtree level */
1388 | static void
1389 | ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1390 | {
1391 | subtree_lvl *subtree;
1392 |
1393 | 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", 1393, "ptvc->pushed_tree_index > 0" ))));
1394 |
1395 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1396 | subtree->it = it;
1397 | subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1398 | }
1399 |
1400 | /* Creates a subtree and adds it to the cursor as the working tree but does not
1401 | * save the old working tree */
1402 | proto_tree *
1403 | ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1404 | {
1405 | ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1406 | return ptvc->tree;
1407 | }
1408 |
1409 | static proto_tree *
1410 | ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1411 | {
1412 | ptvcursor_push_subtree(ptvc, it, ett_subtree);
1413 | if (length == SUBTREE_UNDEFINED_LENGTH-1)
1414 | ptvcursor_subtree_set_item(ptvc, it);
1415 | return ptvcursor_tree(ptvc);
1416 | }
1417 |
1418 | /* Add an item to the tree and create a subtree
1419 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1420 | * In this case, when the subtree will be closed, the parent item length will
1421 | * be equal to the advancement of the cursor since the creation of the subtree.
1422 | */
1423 | proto_tree *
1424 | ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1425 | const unsigned encoding, int ett_subtree)
1426 | {
1427 | proto_item *it;
1428 |
1429 | it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1430 | return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1431 | }
1432 |
1433 | static proto_item *
1434 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1435 |
1436 | /* Add a text node to the tree and create a subtree
1437 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1438 | * In this case, when the subtree will be closed, the item length will be equal
1439 | * to the advancement of the cursor since the creation of the subtree.
1440 | */
1441 | proto_tree *
1442 | ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1443 | int ett_subtree, const char *format, ...)
1444 | {
1445 | proto_item *pi;
1446 | va_list ap;
1447 | header_field_info *hfinfo;
1448 | proto_tree *tree;
1449 |
1450 | tree = ptvcursor_tree(ptvc);
1451 |
1452 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1453 |
1454 | 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", 1454 , __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", 1454, "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", 1454, "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", 1454, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1455 |
1456 | pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1457 | ptvcursor_current_offset(ptvc), length);
1458 |
1459 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1459, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1460 |
1461 | va_start(ap, format)__builtin_va_start(ap, format);
1462 | proto_tree_set_representation(pi, format, ap);
1463 | va_end(ap)__builtin_va_end(ap);
1464 |
1465 | return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1466 | }
1467 |
1468 | /* Add a text-only node, leaving it to our caller to fill the text in */
1469 | static proto_item *
1470 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1471 | {
1472 | proto_item *pi;
1473 |
1474 | if (tree == NULL((void*)0))
1475 | return NULL((void*)0);
1476 |
1477 | pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1478 |
1479 | return pi;
1480 | }
1481 |
1482 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1483 | proto_item *
1484 | proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1485 | const char *format, ...)
1486 | {
1487 | proto_item *pi;
1488 | va_list ap;
1489 | header_field_info *hfinfo;
1490 |
1491 | if (length == -1) {
1492 | length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1493 | } else {
1494 | tvb_ensure_bytes_exist(tvb, start, length);
1495 | }
1496 |
1497 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1498 |
1499 | 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", 1499 , __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", 1499, "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", 1499, "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", 1499, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1500 |
1501 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1502 |
1503 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1503, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1504 |
1505 | va_start(ap, format)__builtin_va_start(ap, format);
1506 | proto_tree_set_representation(pi, format, ap);
1507 | va_end(ap)__builtin_va_end(ap);
1508 |
1509 | return pi;
1510 | }
1511 |
1512 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1513 | proto_item *
1514 | proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1515 | int length, const char *format, va_list ap)
1516 | {
1517 | proto_item *pi;
1518 | header_field_info *hfinfo;
1519 |
1520 | /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1521 | * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1522 | * the length to be what's in the tvbuff if length is -1, and the
1523 | * minimum of length and what's in the tvbuff if not.
1524 | */
1525 |
1526 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1527 |
1528 | 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", 1528 , __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", 1528, "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", 1528, "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", 1528, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1529 |
1530 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1531 |
1532 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1532, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1533 |
1534 | proto_tree_set_representation(pi, format, ap);
1535 |
1536 | return pi;
1537 | }
1538 |
1539 | /* Add a text-only node that creates a subtree underneath.
1540 | */
1541 | proto_tree *
1542 | proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1543 | {
1544 | return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1545 | }
1546 |
1547 | /* Add a text-only node that creates a subtree underneath.
1548 | */
1549 | proto_tree *
1550 | proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1551 | {
1552 | proto_tree *pt;
1553 | proto_item *pi;
1554 | va_list ap;
1555 |
1556 | va_start(ap, format)__builtin_va_start(ap, format);
1557 | pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1558 | va_end(ap)__builtin_va_end(ap);
1559 |
1560 | if (tree_item != NULL((void*)0))
1561 | *tree_item = pi;
1562 |
1563 | pt = proto_item_add_subtree(pi, idx);
1564 |
1565 | return pt;
1566 | }
1567 |
1568 | /* Add a text-only node for debugging purposes. The caller doesn't need
1569 | * to worry about tvbuff, start, or length. Debug message gets sent to
1570 | * STDOUT, too */
1571 | proto_item *
1572 | proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1573 | {
1574 | proto_item *pi;
1575 | va_list ap;
1576 |
1577 | pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1578 |
1579 | if (pi) {
1580 | va_start(ap, format)__builtin_va_start(ap, format);
1581 | proto_tree_set_representation(pi, format, ap);
1582 | va_end(ap)__builtin_va_end(ap);
1583 | }
1584 | va_start(ap, format)__builtin_va_start(ap, format);
1585 | vprintf(format, ap);
1586 | va_end(ap)__builtin_va_end(ap);
1587 | printf("\n");
1588 |
1589 | return pi;
1590 | }
1591 |
1592 | proto_item *
1593 | proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1594 | {
1595 | proto_item *pi;
1596 | header_field_info *hfinfo;
1597 |
1598 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1599 |
1600 | 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", 1600 , __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", 1600, "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", 1600, "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", 1600, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1601 |
1602 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1603 |
1604 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1604, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1605 |
1606 | proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1607 |
1608 | return pi;
1609 | }
1610 |
1611 | proto_item *
1612 | proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1613 | {
1614 | proto_item *pi;
1615 | header_field_info *hfinfo;
1616 | char *str;
1617 |
1618 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1619 |
1620 | 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", 1620 , __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", 1620, "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", 1620, "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", 1620, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1621 |
1622 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1623 |
1624 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1624, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1625 |
1626 | str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1627 | proto_item_set_text(pi, "%s", str);
1628 | wmem_free(NULL((void*)0), str);
1629 |
1630 | return pi;
1631 | }
1632 |
1633 | void proto_report_dissector_bug(const char *format, ...)
1634 | {
1635 | va_list args;
1636 |
1637 | if (wireshark_abort_on_dissector_bug) {
1638 | /*
1639 | * Try to have the error message show up in the crash
1640 | * information.
1641 | */
1642 | va_start(args, format)__builtin_va_start(args, format);
1643 | ws_vadd_crash_info(format, args);
1644 | va_end(args)__builtin_va_end(args);
1645 |
1646 | /*
1647 | * Print the error message.
1648 | */
1649 | va_start(args, format)__builtin_va_start(args, format);
1650 | vfprintf(stderrstderr, format, args);
1651 | va_end(args)__builtin_va_end(args);
1652 | putc('\n', stderrstderr);
1653 |
1654 | /*
1655 | * And crash.
1656 | */
1657 | abort();
1658 | } else {
1659 | va_start(args, format)__builtin_va_start(args, format);
1660 | VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1661 | va_end(args)__builtin_va_end(args);
1662 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1662 , __func__, "assertion \"not reached\" failed"); /* GCC 12 with ASAN needs this. */
1663 | }
1664 | }
1665 |
1666 | /* We could probably get away with changing is_error to a minimum length value. */
1667 | static void
1668 | report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1669 | {
1670 | if (is_error) {
1671 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1672 | } else {
1673 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1674 | }
1675 |
1676 | if (is_error) {
1677 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1678 | }
1679 | }
1680 |
1681 | static uint32_t
1682 | get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1683 | {
1684 | uint32_t value;
1685 | bool_Bool length_error;
1686 |
1687 | switch (length) {
1688 |
1689 | case 1:
1690 | value = tvb_get_uint8(tvb, offset);
1691 | if (encoding & ENC_ZIGBEE0x40000000) {
1692 | if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1693 | value = 0;
1694 | }
1695 | }
1696 | break;
1697 |
1698 | case 2:
1699 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1700 | : tvb_get_ntohs(tvb, offset);
1701 | if (encoding & ENC_ZIGBEE0x40000000) {
1702 | if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1703 | value = 0;
1704 | }
1705 | }
1706 | break;
1707 |
1708 | case 3:
1709 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1710 | : tvb_get_ntoh24(tvb, offset);
1711 | break;
1712 |
1713 | case 4:
1714 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1715 | : tvb_get_ntohl(tvb, offset);
1716 | break;
1717 |
1718 | default:
1719 | if (length < 1) {
1720 | length_error = true1;
1721 | value = 0;
1722 | } else {
1723 | length_error = false0;
1724 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1725 | : tvb_get_ntohl(tvb, offset);
1726 | }
1727 | report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1728 | break;
1729 | }
1730 | return value;
1731 | }
1732 |
1733 | static inline uint64_t
1734 | get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1735 | {
1736 | uint64_t value;
1737 |
1738 | value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1739 |
1740 | if (length < 1 || length > 8) {
1741 | report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1742 | }
1743 |
1744 | return value;
1745 | }
1746 |
1747 | static int32_t
1748 | get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1749 | {
1750 | int32_t value;
1751 | bool_Bool length_error;
1752 |
1753 | switch (length) {
1754 |
1755 | case 1:
1756 | value = tvb_get_int8(tvb, offset);
1757 | break;
1758 |
1759 | case 2:
1760 | value = encoding ? tvb_get_letohis(tvb, offset)
1761 | : tvb_get_ntohis(tvb, offset);
1762 | break;
1763 |
1764 | case 3:
1765 | value = encoding ? tvb_get_letohi24(tvb, offset)
1766 | : tvb_get_ntohi24(tvb, offset);
1767 | break;
1768 |
1769 | case 4:
1770 | value = encoding ? tvb_get_letohil(tvb, offset)
1771 | : tvb_get_ntohil(tvb, offset);
1772 | break;
1773 |
1774 | default:
1775 | if (length < 1) {
1776 | length_error = true1;
1777 | value = 0;
1778 | } else {
1779 | length_error = false0;
1780 | value = encoding ? tvb_get_letohil(tvb, offset)
1781 | : tvb_get_ntohil(tvb, offset);
1782 | }
1783 | report_type_length_mismatch(tree, "a signed integer", length, length_error);
1784 | break;
1785 | }
1786 | return value;
1787 | }
1788 |
1789 | /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1790 | * be cast-able as a int64_t. This is weird, but what the code has always done.
1791 | */
1792 | static inline uint64_t
1793 | get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1794 | {
1795 | uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1796 |
1797 | switch (length) {
1798 | case 7:
1799 | value = ws_sign_ext64(value, 56);
1800 | break;
1801 | case 6:
1802 | value = ws_sign_ext64(value, 48);
1803 | break;
1804 | case 5:
1805 | value = ws_sign_ext64(value, 40);
1806 | break;
1807 | case 4:
1808 | value = ws_sign_ext64(value, 32);
1809 | break;
1810 | case 3:
1811 | value = ws_sign_ext64(value, 24);
1812 | break;
1813 | case 2:
1814 | value = ws_sign_ext64(value, 16);
1815 | break;
1816 | case 1:
1817 | value = ws_sign_ext64(value, 8);
1818 | break;
1819 | }
1820 |
1821 | return value;
1822 | }
1823 |
1824 | /* For FT_STRING */
1825 | static inline const uint8_t *
1826 | get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1827 | int length, int *ret_length, const unsigned encoding)
1828 | {
1829 | if (length == -1) {
1830 | length = tvb_ensure_captured_length_remaining(tvb, start);
1831 | }
1832 | *ret_length = length;
1833 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1834 | }
1835 |
1836 | /* For FT_STRINGZ */
1837 | static inline const uint8_t *
1838 | get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1839 | int start, int length, int *ret_length, const unsigned encoding)
1840 | {
1841 | const uint8_t *value;
1842 |
1843 | if (length < -1) {
1844 | report_type_length_mismatch(tree, "a string", length, true1);
1845 | }
1846 | if (length == -1) {
1847 | /* This can throw an exception */
1848 | value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1849 | } else {
1850 | /* In this case, length signifies the length of the string.
1851 | *
1852 | * This could either be a null-padded string, which doesn't
1853 | * necessarily have a '\0' at the end, or a null-terminated
1854 | * string, with a trailing '\0'. (Yes, there are cases
1855 | * where you have a string that's both counted and null-
1856 | * terminated.)
1857 | *
1858 | * In the first case, we must allocate a buffer of length
1859 | * "length+1", to make room for a trailing '\0'.
1860 | *
1861 | * In the second case, we don't assume that there is a
1862 | * trailing '\0' there, as the packet might be malformed.
1863 | * (XXX - should we throw an exception if there's no
1864 | * trailing '\0'?) Therefore, we allocate a buffer of
1865 | * length "length+1", and put in a trailing '\0', just to
1866 | * be safe.
1867 | *
1868 | * (XXX - this would change if we made string values counted
1869 | * rather than null-terminated.)
1870 | */
1871 | value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1872 | }
1873 | *ret_length = length;
1874 | return value;
1875 | }
1876 |
1877 | /* For FT_UINT_STRING */
1878 | static inline const uint8_t *
1879 | get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1880 | tvbuff_t *tvb, int start, int length, int *ret_length,
1881 | const unsigned encoding)
1882 | {
1883 | uint32_t n;
1884 | const uint8_t *value;
1885 |
1886 | /* I believe it's ok if this is called with a NULL tree */
1887 | n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1888 | value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1889 | length += n;
1890 | *ret_length = length;
1891 | return value;
1892 | }
1893 |
1894 | /* For FT_STRINGZPAD */
1895 | static inline const uint8_t *
1896 | get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1897 | int length, int *ret_length, const unsigned encoding)
1898 | {
1899 | /*
1900 | * XXX - currently, string values are null-
1901 | * terminated, so a "zero-padded" string
1902 | * isn't special. If we represent string
1903 | * values as something that includes a counted
1904 | * array of bytes, we'll need to strip the
1905 | * trailing NULs.
1906 | */
1907 | if (length == -1) {
1908 | length = tvb_ensure_captured_length_remaining(tvb, start);
1909 | }
1910 | *ret_length = length;
1911 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1912 | }
1913 |
1914 | /* For FT_STRINGZTRUNC */
1915 | static inline const uint8_t *
1916 | get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1917 | int length, int *ret_length, const unsigned encoding)
1918 | {
1919 | /*
1920 | * XXX - currently, string values are null-
1921 | * terminated, so a "zero-truncated" string
1922 | * isn't special. If we represent string
1923 | * values as something that includes a counted
1924 | * array of bytes, we'll need to strip everything
1925 | * starting with the terminating NUL.
1926 | */
1927 | if (length == -1) {
1928 | length = tvb_ensure_captured_length_remaining(tvb, start);
1929 | }
1930 | *ret_length = length;
1931 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1932 | }
1933 |
1934 | /*
1935 | * Deltas between the epochs for various non-UN*X time stamp formats and
1936 | * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1937 | * stamp format.
1938 | */
1939 |
1940 | /*
1941 | * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1942 | * XXX - if it's OK if this is unsigned, can we just use
1943 | * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1944 | */
1945 | #define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1946 |
1947 | /*
1948 | * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1949 | */
1950 | #define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1951 |
1952 | /* this can be called when there is no tree, so tree may be null */
1953 | static void
1954 | get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1955 | const int length, const unsigned encoding, nstime_t *time_stamp,
1956 | const bool_Bool is_relative)
1957 | {
1958 | uint32_t tmpsecs;
1959 | uint64_t tmp64secs;
1960 | uint64_t todusecs;
1961 |
1962 | switch (encoding) {
1963 |
1964 | case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1965 | /*
1966 | * If the length is 16, 8-byte seconds, followed
1967 | * by 8-byte fractional time in nanoseconds,
1968 | * both big-endian.
1969 | *
1970 | * If the length is 12, 8-byte seconds, followed
1971 | * by 4-byte fractional time in nanoseconds,
1972 | * both big-endian.
1973 | *
1974 | * If the length is 8, 4-byte seconds, followed
1975 | * by 4-byte fractional time in nanoseconds,
1976 | * both big-endian.
1977 | *
1978 | * For absolute times, the seconds are seconds
1979 | * since the UN*X epoch.
1980 | */
1981 | if (length == 16) {
1982 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1983 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1984 | } else if (length == 12) {
1985 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1986 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1987 | } else if (length == 8) {
1988 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1989 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1990 | } else if (length == 4) {
1991 | /*
1992 | * Backwards compatibility.
1993 | * ENC_TIME_SECS_NSECS is 0; using
1994 | * ENC_BIG_ENDIAN by itself with a 4-byte
1995 | * time-in-seconds value was done in the
1996 | * past.
1997 | */
1998 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1999 | time_stamp->nsecs = 0;
2000 | } else {
2001 | time_stamp->secs = 0;
2002 | time_stamp->nsecs = 0;
2003 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2004 | }
2005 | break;
2006 |
2007 | case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2008 | /*
2009 | * If the length is 16, 8-byte seconds, followed
2010 | * by 8-byte fractional time in nanoseconds,
2011 | * both little-endian.
2012 | *
2013 | * If the length is 12, 8-byte seconds, followed
2014 | * by 4-byte fractional time in nanoseconds,
2015 | * both little-endian.
2016 | *
2017 | * If the length is 8, 4-byte seconds, followed
2018 | * by 4-byte fractional time in nanoseconds,
2019 | * both little-endian.
2020 | *
2021 | * For absolute times, the seconds are seconds
2022 | * since the UN*X epoch.
2023 | */
2024 | if (length == 16) {
2025 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2026 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2027 | } else if (length == 12) {
2028 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2029 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2030 | } else if (length == 8) {
2031 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2032 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2033 | } else if (length == 4) {
2034 | /*
2035 | * Backwards compatibility.
2036 | * ENC_TIME_SECS_NSECS is 0; using
2037 | * ENC_LITTLE_ENDIAN by itself with a 4-byte
2038 | * time-in-seconds value was done in the
2039 | * past.
2040 | */
2041 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2042 | time_stamp->nsecs = 0;
2043 | } else {
2044 | time_stamp->secs = 0;
2045 | time_stamp->nsecs = 0;
2046 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2047 | }
2048 | break;
2049 |
2050 | case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2051 | /*
2052 | * NTP time stamp, big-endian.
2053 | * Only supported for absolute times.
2054 | */
2055 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2055, "!is_relative" ))));
2056 |
2057 | /* We need a temporary variable here so the unsigned math
2058 | * works correctly (for years > 2036 according to RFC 2030
2059 | * chapter 3).
2060 | *
2061 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2062 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2063 | * If bit 0 is not set, the time is in the range 2036-2104 and
2064 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2065 | */
2066 | tmpsecs = tvb_get_ntohl(tvb, start);
2067 | if ((tmpsecs & 0x80000000) != 0)
2068 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2069 | else
2070 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2071 |
2072 | if (length == 8) {
2073 | tmp64secs = tvb_get_ntoh64(tvb, start);
2074 | if (tmp64secs == 0) {
2075 | //This is "NULL" time
2076 | time_stamp->secs = 0;
2077 | time_stamp->nsecs = 0;
2078 | } else {
2079 | /*
2080 | * Convert 1/2^32s of a second to
2081 | * nanoseconds.
2082 | */
2083 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2084 | }
2085 | } else if (length == 4) {
2086 | /*
2087 | * Backwards compatibility.
2088 | */
2089 | if (tmpsecs == 0) {
2090 | //This is "NULL" time
2091 | time_stamp->secs = 0;
2092 | }
2093 | time_stamp->nsecs = 0;
2094 | } else {
2095 | time_stamp->secs = 0;
2096 | time_stamp->nsecs = 0;
2097 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2098 | }
2099 | break;
2100 |
2101 | case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2102 | /*
2103 | * NTP time stamp, little-endian.
2104 | * Only supported for absolute times.
2105 | *
2106 | * NTP doesn't use this, because it's an Internet format
2107 | * and hence big-endian. Any implementation must decide
2108 | * whether the NTP timestamp is a 64-bit unsigned fixed
2109 | * point number (RFC 1305, RFC 4330) or a 64-bit struct
2110 | * with a 32-bit unsigned seconds field followed by a
2111 | * 32-bit fraction field (cf. RFC 5905, which obsoletes
2112 | * the previous two).
2113 | *
2114 | * XXX: We do the latter, but no dissector uses this format.
2115 | * OTOH, ERF timestamps do the former, so perhaps we
2116 | * should switch the interpretation so that packet-erf.c
2117 | * could use this directly?
2118 | */
2119 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2119, "!is_relative" ))));
2120 |
2121 | /* We need a temporary variable here so the unsigned math
2122 | * works correctly (for years > 2036 according to RFC 2030
2123 | * chapter 3).
2124 | *
2125 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2126 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2127 | * If bit 0 is not set, the time is in the range 2036-2104 and
2128 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2129 | */
2130 | tmpsecs = tvb_get_letohl(tvb, start);
2131 | if ((tmpsecs & 0x80000000) != 0)
2132 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2133 | else
2134 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2135 |
2136 | if (length == 8) {
2137 | tmp64secs = tvb_get_letoh64(tvb, start);
2138 | if (tmp64secs == 0) {
2139 | //This is "NULL" time
2140 | time_stamp->secs = 0;
2141 | time_stamp->nsecs = 0;
2142 | } else {
2143 | /*
2144 | * Convert 1/2^32s of a second to
2145 | * nanoseconds.
2146 | */
2147 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2148 | }
2149 | } else if (length == 4) {
2150 | /*
2151 | * Backwards compatibility.
2152 | */
2153 | if (tmpsecs == 0) {
2154 | //This is "NULL" time
2155 | time_stamp->secs = 0;
2156 | }
2157 | time_stamp->nsecs = 0;
2158 | } else {
2159 | time_stamp->secs = 0;
2160 | time_stamp->nsecs = 0;
2161 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2162 | }
2163 | break;
2164 |
2165 | case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2166 | /*
2167 | * S/3x0 and z/Architecture TOD clock time stamp,
2168 | * big-endian. The epoch is January 1, 1900,
2169 | * 00:00:00 (proleptic?) UTC.
2170 | *
2171 | * Only supported for absolute times.
2172 | */
2173 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2173, "!is_relative" ))));
2174 | DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2174, "length == 8" ))));
2175 |
2176 | if (length == 8) {
2177 | todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2178 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2179 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2180 | } else {
2181 | time_stamp->secs = 0;
2182 | time_stamp->nsecs = 0;
2183 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2184 | }
2185 | break;
2186 |
2187 | case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2188 | /*
2189 | * S/3x0 and z/Architecture TOD clock time stamp,
2190 | * little-endian. The epoch is January 1, 1900,
2191 | * 00:00:00 (proleptic?) UTC.
2192 | *
2193 | * Only supported for absolute times.
2194 | */
2195 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2195, "!is_relative" ))));
2196 |
2197 | if (length == 8) {
2198 | todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2199 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2200 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2201 | } else {
2202 | time_stamp->secs = 0;
2203 | time_stamp->nsecs = 0;
2204 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2205 | }
2206 | break;
2207 |
2208 | case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2209 | /*
2210 | * Time stamp using the same seconds/fraction format
2211 | * as NTP, but with the origin of the time stamp being
2212 | * the UNIX epoch rather than the NTP epoch; big-
2213 | * endian.
2214 | *
2215 | * Only supported for absolute times.
2216 | */
2217 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2217, "!is_relative" ))));
2218 |
2219 | if (length == 8) {
2220 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2221 | /*
2222 | * Convert 1/2^32s of a second to nanoseconds.
2223 | */
2224 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2225 | } else {
2226 | time_stamp->secs = 0;
2227 | time_stamp->nsecs = 0;
2228 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2229 | }
2230 | break;
2231 |
2232 | case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2233 | /*
2234 | * Time stamp using the same seconds/fraction format
2235 | * as NTP, but with the origin of the time stamp being
2236 | * the UNIX epoch rather than the NTP epoch; little-
2237 | * endian.
2238 | *
2239 | * Only supported for absolute times.
2240 | *
2241 | * The RTPS specification explicitly supports Little
2242 | * Endian encoding. In one place, it states that its
2243 | * Time_t representation "is the one defined by ...
2244 | * RFC 1305", but in another explicitly defines it as
2245 | * a struct consisting of an 32 bit unsigned seconds
2246 | * field and a 32 bit unsigned fraction field, not a 64
2247 | * bit fixed point, so we do that here.
2248 | * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2249 | */
2250 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2250, "!is_relative" ))));
2251 |
2252 | if (length == 8) {
2253 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2254 | /*
2255 | * Convert 1/2^32s of a second to nanoseconds.
2256 | */
2257 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2258 | } else {
2259 | time_stamp->secs = 0;
2260 | time_stamp->nsecs = 0;
2261 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2262 | }
2263 | break;
2264 |
2265 | case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2266 | /*
2267 | * MIP6 time stamp, big-endian.
2268 | * A 64-bit unsigned integer field containing a timestamp. The
2269 | * value indicates the number of seconds since January 1, 1970,
2270 | * 00:00 UTC, by using a fixed point format. In this format, the
2271 | * integer number of seconds is contained in the first 48 bits of
2272 | * the field, and the remaining 16 bits indicate the number of
2273 | * 1/65536 fractions of a second.
2274 |
2275 | * Only supported for absolute times.
2276 | */
2277 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2277, "!is_relative" ))));
2278 |
2279 | if (length == 8) {
2280 | /* We need a temporary variable here so the casting and fractions
2281 | * of a second work correctly.
2282 | */
2283 | tmp64secs = tvb_get_ntoh48(tvb, start);
2284 | tmpsecs = tvb_get_ntohs(tvb, start + 6);
2285 | tmpsecs <<= 16;
2286 |
2287 | if ((tmp64secs == 0) && (tmpsecs == 0)) {
2288 | //This is "NULL" time
2289 | time_stamp->secs = 0;
2290 | time_stamp->nsecs = 0;
2291 | } else {
2292 | time_stamp->secs = (time_t)tmp64secs;
2293 | time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2294 | }
2295 | } else {
2296 | time_stamp->secs = 0;
2297 | time_stamp->nsecs = 0;
2298 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2299 | }
2300 | break;
2301 |
2302 | case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2303 | /*
2304 | * If the length is 16, 8-byte seconds, followed
2305 | * by 8-byte fractional time in microseconds,
2306 | * both big-endian.
2307 | *
2308 | * If the length is 12, 8-byte seconds, followed
2309 | * by 4-byte fractional time in microseconds,
2310 | * both big-endian.
2311 | *
2312 | * If the length is 8, 4-byte seconds, followed
2313 | * by 4-byte fractional time in microseconds,
2314 | * both big-endian.
2315 | *
2316 | * For absolute times, the seconds are seconds
2317 | * since the UN*X epoch.
2318 | */
2319 | if (length == 16) {
2320 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2321 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2322 | } else if (length == 12) {
2323 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2324 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2325 | } else if (length == 8) {
2326 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2327 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2328 | } else {
2329 | time_stamp->secs = 0;
2330 | time_stamp->nsecs = 0;
2331 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2332 | }
2333 | break;
2334 |
2335 | case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2336 | /*
2337 | * If the length is 16, 8-byte seconds, followed
2338 | * by 8-byte fractional time in microseconds,
2339 | * both little-endian.
2340 | *
2341 | * If the length is 12, 8-byte seconds, followed
2342 | * by 4-byte fractional time in microseconds,
2343 | * both little-endian.
2344 | *
2345 | * If the length is 8, 4-byte seconds, followed
2346 | * by 4-byte fractional time in microseconds,
2347 | * both little-endian.
2348 | *
2349 | * For absolute times, the seconds are seconds
2350 | * since the UN*X epoch.
2351 | */
2352 | if (length == 16) {
2353 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2354 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2355 | } else if (length == 12) {
2356 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2357 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2358 | } else if (length == 8) {
2359 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2360 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2361 | } else {
2362 | time_stamp->secs = 0;
2363 | time_stamp->nsecs = 0;
2364 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2365 | }
2366 | break;
2367 |
2368 | case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2369 | case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2370 | /*
2371 | * Seconds, 1 to 8 bytes.
2372 | * For absolute times, it's seconds since the
2373 | * UN*X epoch.
2374 | */
2375 | if (length >= 1 && length <= 8) {
2376 | time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2377 | time_stamp->nsecs = 0;
2378 | } else {
2379 | time_stamp->secs = 0;
2380 | time_stamp->nsecs = 0;
2381 | report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2382 | }
2383 | break;
2384 |
2385 | case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2386 | case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2387 | /*
2388 | * Milliseconds, 1 to 8 bytes.
2389 | * For absolute times, it's milliseconds since the
2390 | * UN*X epoch.
2391 | */
2392 | if (length >= 1 && length <= 8) {
2393 | uint64_t msecs;
2394 |
2395 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2396 | time_stamp->secs = (time_t)(msecs / 1000);
2397 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2398 | } else {
2399 | time_stamp->secs = 0;
2400 | time_stamp->nsecs = 0;
2401 | report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2402 | }
2403 | break;
2404 |
2405 | case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2406 | case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2407 | /*
2408 | * Microseconds, 1 to 8 bytes.
2409 | * For absolute times, it's microseconds since the
2410 | * UN*X epoch.
2411 | */
2412 | if (length >= 1 && length <= 8) {
2413 | uint64_t usecs;
2414 |
2415 | usecs = get_uint64_value(tree, tvb, start, length, encoding);
2416 | time_stamp->secs = (time_t)(usecs / 1000000);
2417 | time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2418 | } else {
2419 | time_stamp->secs = 0;
2420 | time_stamp->nsecs = 0;
2421 | report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2422 | }
2423 | break;
2424 |
2425 | case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2426 | case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2427 | /*
2428 | * nanoseconds, 1 to 8 bytes.
2429 | * For absolute times, it's nanoseconds since the
2430 | * UN*X epoch.
2431 | */
2432 |
2433 | if (length >= 1 && length <= 8) {
2434 | uint64_t nsecs;
2435 |
2436 | nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2437 | time_stamp->secs = (time_t)(nsecs / 1000000000);
2438 | time_stamp->nsecs = (int)(nsecs % 1000000000);
2439 | } else {
2440 | time_stamp->secs = 0;
2441 | time_stamp->nsecs = 0;
2442 | report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2443 | }
2444 | break;
2445 |
2446 | case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2447 | /*
2448 | * 1/64ths of a second since the UN*X epoch,
2449 | * big-endian.
2450 | *
2451 | * Only supported for absolute times.
2452 | */
2453 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2453, "!is_relative" ))));
2454 |
2455 | if (length == 8) {
2456 | /*
2457 | * The upper 48 bits are seconds since the
2458 | * UN*X epoch.
2459 | */
2460 | time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2461 | /*
2462 | * The lower 16 bits are 1/2^16s of a second;
2463 | * convert them to nanoseconds.
2464 | *
2465 | * XXX - this may give the impression of higher
2466 | * precision than you actually get.
2467 | */
2468 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2469 | } else {
2470 | time_stamp->secs = 0;
2471 | time_stamp->nsecs = 0;
2472 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2473 | }
2474 | break;
2475 |
2476 | case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2477 | /*
2478 | * 1/64ths of a second since the UN*X epoch,
2479 | * little-endian.
2480 | *
2481 | * Only supported for absolute times.
2482 | */
2483 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2483, "!is_relative" ))));
2484 |
2485 | if (length == 8) {
2486 | /*
2487 | * XXX - this is assuming that, if anybody
2488 | * were ever to use this format - RFC 3971
2489 | * doesn't, because that's an Internet
2490 | * protocol, and those use network byte
2491 | * order, i.e. big-endian - they'd treat it
2492 | * as a 64-bit count of 1/2^16s of a second,
2493 | * putting the upper 48 bits at the end.
2494 | *
2495 | * The lower 48 bits are seconds since the
2496 | * UN*X epoch.
2497 | */
2498 | time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2499 | /*
2500 | * The upper 16 bits are 1/2^16s of a second;
2501 | * convert them to nanoseconds.
2502 | *
2503 | * XXX - this may give the impression of higher
2504 | * precision than you actually get.
2505 | */
2506 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2507 | } else {
2508 | time_stamp->secs = 0;
2509 | time_stamp->nsecs = 0;
2510 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2511 | }
2512 | break;
2513 |
2514 | case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2515 | /*
2516 | * NTP time stamp, with 1-second resolution (i.e.,
2517 | * seconds since the NTP epoch), big-endian.
2518 | * Only supported for absolute times.
2519 | */
2520 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2520, "!is_relative" ))));
2521 |
2522 | if (length == 4) {
2523 | /*
2524 | * We need a temporary variable here so the unsigned math
2525 | * works correctly (for years > 2036 according to RFC 2030
2526 | * chapter 3).
2527 | *
2528 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2529 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2530 | * If bit 0 is not set, the time is in the range 2036-2104 and
2531 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2532 | */
2533 | tmpsecs = tvb_get_ntohl(tvb, start);
2534 | if ((tmpsecs & 0x80000000) != 0)
2535 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2536 | else
2537 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2538 | time_stamp->nsecs = 0;
2539 | } else {
2540 | time_stamp->secs = 0;
2541 | time_stamp->nsecs = 0;
2542 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2543 | }
2544 | break;
2545 |
2546 | case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2547 | /*
2548 | * NTP time stamp, with 1-second resolution (i.e.,
2549 | * seconds since the NTP epoch), little-endian.
2550 | * Only supported for absolute times.
2551 | */
2552 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2552, "!is_relative" ))));
2553 |
2554 | /*
2555 | * We need a temporary variable here so the unsigned math
2556 | * works correctly (for years > 2036 according to RFC 2030
2557 | * chapter 3).
2558 | *
2559 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2560 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2561 | * If bit 0 is not set, the time is in the range 2036-2104 and
2562 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2563 | */
2564 | if (length == 4) {
2565 | tmpsecs = tvb_get_letohl(tvb, start);
2566 | if ((tmpsecs & 0x80000000) != 0)
2567 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2568 | else
2569 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2570 | time_stamp->nsecs = 0;
2571 | } else {
2572 | time_stamp->secs = 0;
2573 | time_stamp->nsecs = 0;
2574 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2575 | }
2576 | break;
2577 |
2578 | case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2579 | /*
2580 | * Milliseconds, 6 to 8 bytes.
2581 | * For absolute times, it's milliseconds since the
2582 | * NTP epoch.
2583 | *
2584 | * ETSI TS 129.274 8.119 defines this as:
2585 | * "a 48 bit unsigned integer in network order format
2586 | * ...encoded as the number of milliseconds since
2587 | * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2588 | * rounded value of 1000 x the value of the 64-bit
2589 | * timestamp (Seconds + (Fraction / (1<<32))) defined
2590 | * in clause 6 of IETF RFC 5905."
2591 | *
2592 | * Taken literally, the part after "i.e." would
2593 | * mean that the value rolls over before reaching
2594 | * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2595 | * when the 64 bit timestamp rolls over, and we have
2596 | * to pick an NTP Era equivalence class to support
2597 | * (such as 1968-01-20 to 2104-02-06).
2598 | *
2599 | * OTOH, the extra room might be used to store Era
2600 | * information instead, in which case times until
2601 | * 10819-08-03 can be represented with 6 bytes without
2602 | * ambiguity. We handle both implementations, and assume
2603 | * that times before 1968-01-20 are not represented.
2604 | *
2605 | * Only 6 bytes or more makes sense as an absolute
2606 | * time. 5 bytes or fewer could express a span of
2607 | * less than 35 years, either 1900-1934 or 2036-2070.
2608 | */
2609 | if (length >= 6 && length <= 8) {
2610 | uint64_t msecs;
2611 |
2612 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2613 | tmp64secs = (msecs / 1000);
2614 | /*
2615 | * Assume that times in the first half of NTP
2616 | * Era 0 really represent times in the NTP
2617 | * Era 1.
2618 | */
2619 | if (tmp64secs >= 0x80000000)
2620 | time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2621 | else
2622 | time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2623 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2624 | }
2625 | else {
2626 | time_stamp->secs = 0;
2627 | time_stamp->nsecs = 0;
2628 | report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2629 | }
2630 | break;
2631 |
2632 | case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2633 | /*
2634 | * MP4 file time stamps, big-endian.
2635 | * Only supported for absolute times.
2636 | */
2637 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2637, "!is_relative" ))));
2638 |
2639 | if (length == 8) {
2640 | tmp64secs = tvb_get_ntoh64(tvb, start);
2641 | time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2642 | time_stamp->nsecs = 0;
2643 | } else if (length == 4) {
2644 | tmpsecs = tvb_get_ntohl(tvb, start);
2645 | time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2646 | time_stamp->nsecs = 0;
2647 | } else {
2648 | time_stamp->secs = 0;
2649 | time_stamp->nsecs = 0;
2650 | report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2651 | }
2652 | break;
2653 |
2654 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2655 | /*
2656 | * Zigbee ZCL time stamps, big-endian.
2657 | * Only supported for absolute times.
2658 | */
2659 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2659, "!is_relative" ))));
2660 |
2661 | if (length == 8) {
2662 | tmp64secs = tvb_get_ntoh64(tvb, start);
2663 | 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);
2664 | time_stamp->nsecs = 0;
2665 | } else if (length == 4) {
2666 | tmpsecs = tvb_get_ntohl(tvb, start);
2667 | time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2668 | time_stamp->nsecs = 0;
2669 | } else {
2670 | time_stamp->secs = 0;
2671 | time_stamp->nsecs = 0;
2672 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2673 | }
2674 | break;
2675 |
2676 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2677 | /*
2678 | * Zigbee ZCL time stamps, little-endian.
2679 | * Only supported for absolute times.
2680 | */
2681 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2681, "!is_relative" ))));
2682 |
2683 | if (length == 8) {
2684 | tmp64secs = tvb_get_letoh64(tvb, start);
2685 | 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);
2686 | time_stamp->nsecs = 0;
2687 | } else if (length == 4) {
2688 | tmpsecs = tvb_get_letohl(tvb, start);
2689 | time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2690 | time_stamp->nsecs = 0;
2691 | } else {
2692 | time_stamp->secs = 0;
2693 | time_stamp->nsecs = 0;
2694 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2695 | }
2696 | break;
2697 |
2698 | default:
2699 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 2699));
2700 | break;
2701 | }
2702 | }
2703 |
2704 | static void
2705 | tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2706 | {
2707 | const header_field_info *hfinfo = fi->hfinfo;
2708 |
2709 | if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2710 | GPtrArray *ptrs = NULL((void*)0);
2711 |
2712 | if (tree_data->interesting_hfids == NULL((void*)0)) {
2713 | /* Initialize the hash because we now know that it is needed */
2714 | tree_data->interesting_hfids =
2715 | g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2716 | } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2717 | ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2718 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2719 | }
2720 |
2721 | if (!ptrs) {
2722 | /* First element triggers the creation of pointer array */
2723 | ptrs = g_ptr_array_new();
2724 | g_hash_table_insert(tree_data->interesting_hfids,
2725 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2726 | }
2727 |
2728 | g_ptr_array_add(ptrs, fi);
2729 | }
2730 | }
2731 |
2732 |
2733 | /*
2734 | * Validates that field length bytes are available starting from
2735 | * start (pos/neg). Throws an exception if they aren't.
2736 | */
2737 | static void
2738 | test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2739 | int start, int length, const unsigned encoding)
2740 | {
2741 | int size = length;
2742 |
2743 | if (!tvb)
2744 | return;
2745 |
2746 | if ((hfinfo->type == FT_STRINGZ) ||
2747 | ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2748 | (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 ))))) {
2749 | /* If we're fetching until the end of the TVB, only validate
2750 | * that the offset is within range.
2751 | */
2752 | if (length == -1)
2753 | size = 0;
2754 | }
2755 |
2756 | tvb_ensure_bytes_exist(tvb, start, size);
2757 | }
2758 |
2759 | static void
2760 | detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2761 | {
2762 | bool_Bool found_stray_character = false0;
2763 |
2764 | if (!string)
2765 | return;
2766 |
2767 | switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2768 | case ENC_ASCII0x00000000:
2769 | case ENC_UTF_80x00000002:
2770 | for (int i = (int)strlen(string); i < length; i++) {
2771 | if (string[i] != '\0') {
2772 | found_stray_character = true1;
2773 | break;
2774 | }
2775 | }
2776 | break;
2777 |
2778 | default:
2779 | break;
2780 | }
2781 |
2782 | if (found_stray_character) {
2783 | expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2784 | }
2785 | }
2786 |
2787 | static void
2788 | free_fvalue_cb(void *data)
2789 | {
2790 | fvalue_t *fv = (fvalue_t*)data;
2791 | fvalue_free(fv);
2792 | }
2793 |
2794 | /* Add an item to a proto_tree, using the text label registered to that item;
2795 | the item is extracted from the tvbuff handed to it. */
2796 | static proto_item *
2797 | proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2798 | tvbuff_t *tvb, int start, int length,
2799 | unsigned encoding)
2800 | {
2801 | proto_item *pi;
2802 | uint32_t value, n;
2803 | uint64_t value64;
2804 | ws_in4_addr ipv4_value;
2805 | float floatval;
2806 | double doubleval;
2807 | const char *stringval = NULL((void*)0);
2808 | nstime_t time_stamp;
2809 | bool_Bool length_error;
2810 |
2811 | /* Ensure that the newly created fvalue_t is freed if we throw an
2812 | * exception before adding it to the tree. (gcc creates clobbering
2813 | * when it optimizes the equivalent TRY..EXCEPT implementation.)
2814 | * XXX: Move the new_field_info() call inside here?
2815 | */
2816 | 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));
2817 |
2818 | switch (new_fi->hfinfo->type) {
2819 | case FT_NONE:
2820 | /* no value to set for FT_NONE */
2821 | break;
2822 |
2823 | case FT_PROTOCOL:
2824 | proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2825 | break;
2826 |
2827 | case FT_BYTES:
2828 | proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2829 | break;
2830 |
2831 | case FT_UINT_BYTES:
2832 | n = get_uint_value(tree, tvb, start, length, encoding);
2833 | proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2834 |
2835 | /* Instead of calling proto_item_set_len(), since we don't yet
2836 | * have a proto_item, we set the field_info's length ourselves. */
2837 | new_fi->length = n + length;
2838 | break;
2839 |
2840 | case FT_BOOLEAN:
2841 | /*
2842 | * Map all non-zero values to little-endian for
2843 | * backwards compatibility.
2844 | */
2845 | if (encoding)
2846 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2847 | proto_tree_set_boolean(new_fi,
2848 | get_uint64_value(tree, tvb, start, length, encoding));
2849 | break;
2850 |
2851 | case FT_CHAR:
2852 | /* XXX - make these just FT_UINT? */
2853 | case FT_UINT8:
2854 | case FT_UINT16:
2855 | case FT_UINT24:
2856 | case FT_UINT32:
2857 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2858 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2859 | value = (uint32_t)value64;
2860 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2861 | new_fi->flags |= FI_VARINT0x00040000;
2862 | }
2863 | }
2864 | else {
2865 | /*
2866 | * Map all non-zero values to little-endian for
2867 | * backwards compatibility.
2868 | */
2869 | if (encoding)
2870 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2871 |
2872 | value = get_uint_value(tree, tvb, start, length, encoding);
2873 | }
2874 | proto_tree_set_uint(new_fi, value);
2875 | break;
2876 |
2877 | case FT_UINT40:
2878 | case FT_UINT48:
2879 | case FT_UINT56:
2880 | case FT_UINT64:
2881 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2882 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2883 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2884 | new_fi->flags |= FI_VARINT0x00040000;
2885 | }
2886 | }
2887 | else {
2888 | /*
2889 | * Map all other non-zero values to little-endian for
2890 | * backwards compatibility.
2891 | */
2892 | if (encoding)
2893 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2894 |
2895 | value64 = get_uint64_value(tree, tvb, start, length, encoding);
2896 | }
2897 | proto_tree_set_uint64(new_fi, value64);
2898 | break;
2899 |
2900 | /* XXX - make these just FT_INT? */
2901 | case FT_INT8:
2902 | case FT_INT16:
2903 | case FT_INT24:
2904 | case FT_INT32:
2905 | /*
2906 | * Map all non-zero values to little-endian for
2907 | * backwards compatibility.
2908 | */
2909 | if (encoding)
2910 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2911 | proto_tree_set_int(new_fi,
2912 | get_int_value(tree, tvb, start, length, encoding));
2913 | break;
2914 |
2915 | case FT_INT40:
2916 | case FT_INT48:
2917 | case FT_INT56:
2918 | case FT_INT64:
2919 | /*
2920 | * Map all non-zero values to little-endian for
2921 | * backwards compatibility.
2922 | */
2923 | if (encoding)
2924 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2925 | proto_tree_set_int64(new_fi,
2926 | get_int64_value(tree, tvb, start, length, encoding));
2927 | break;
2928 |
2929 | case FT_IPv4:
2930 | /*
2931 | * Map all non-zero values to little-endian for
2932 | * backwards compatibility.
2933 | */
2934 | if (encoding)
2935 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2936 | if (length != FT_IPv4_LEN4) {
2937 | length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2938 | report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2939 | }
2940 | ipv4_value = tvb_get_ipv4(tvb, start);
2941 | /*
2942 | * NOTE: to support code written when
2943 | * proto_tree_add_item() took a bool as its
2944 | * last argument, with false meaning "big-endian"
2945 | * and true meaning "little-endian", we treat any
2946 | * non-zero value of "encoding" as meaning
2947 | * "little-endian".
2948 | */
2949 | 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);
2950 | break;
2951 |
2952 | case FT_IPXNET:
2953 | if (length != FT_IPXNET_LEN4) {
2954 | length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2955 | report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2956 | }
2957 | proto_tree_set_ipxnet(new_fi,
2958 | get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2959 | break;
2960 |
2961 | case FT_IPv6:
2962 | if (length != FT_IPv6_LEN16) {
2963 | length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2964 | report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2965 | }
2966 | proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2967 | break;
2968 |
2969 | case FT_FCWWN:
2970 | if (length != FT_FCWWN_LEN8) {
2971 | length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2972 | report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2973 | }
2974 | proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2975 | break;
2976 |
2977 | case FT_AX25:
2978 | if (length != 7) {
2979 | length_error = length < 7 ? true1 : false0;
2980 | report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2981 | }
2982 | proto_tree_set_ax25_tvb(new_fi, tvb, start);
2983 | break;
2984 |
2985 | case FT_VINES:
2986 | if (length != VINES_ADDR_LEN6) {
2987 | length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2988 | report_type_length_mismatch(tree, "a Vines address", length, length_error);
2989 | }
2990 | proto_tree_set_vines_tvb(new_fi, tvb, start);
2991 | break;
2992 |
2993 | case FT_ETHER:
2994 | if (length != FT_ETHER_LEN6) {
2995 | length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2996 | report_type_length_mismatch(tree, "a MAC address", length, length_error);
2997 | }
2998 | proto_tree_set_ether_tvb(new_fi, tvb, start);
2999 | break;
3000 |
3001 | case FT_EUI64:
3002 | /*
3003 | * Map all non-zero values to little-endian for
3004 | * backwards compatibility.
3005 | */
3006 | if (encoding)
3007 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3008 | if (length != FT_EUI64_LEN8) {
3009 | length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3010 | report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3011 | }
3012 | proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3013 | break;
3014 | case FT_GUID:
3015 | /*
3016 | * Map all non-zero values to little-endian for
3017 | * backwards compatibility.
3018 | */
3019 | if (encoding)
3020 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3021 | if (length != FT_GUID_LEN16) {
3022 | length_error = length < FT_GUID_LEN16 ? true1 : false0;
3023 | report_type_length_mismatch(tree, "a GUID", length, length_error);
3024 | }
3025 | proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3026 | break;
3027 |
3028 | case FT_OID:
3029 | case FT_REL_OID:
3030 | proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3031 | break;
3032 |
3033 | case FT_SYSTEM_ID:
3034 | proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3035 | break;
3036 |
3037 | case FT_FLOAT:
3038 | /*
3039 | * NOTE: to support code written when
3040 | * proto_tree_add_item() took a bool as its
3041 | * last argument, with false meaning "big-endian"
3042 | * and true meaning "little-endian", we treat any
3043 | * non-zero value of "encoding" as meaning
3044 | * "little-endian".
3045 | *
3046 | * At some point in the future, we might
3047 | * support non-IEEE-binary floating-point
3048 | * formats in the encoding as well
3049 | * (IEEE decimal, System/3x0, VAX).
3050 | */
3051 | if (encoding)
3052 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3053 | if (length != 4) {
3054 | length_error = length < 4 ? true1 : false0;
3055 | report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3056 | }
3057 | if (encoding)
3058 | floatval = tvb_get_letohieee_float(tvb, start);
3059 | else
3060 | floatval = tvb_get_ntohieee_float(tvb, start);
3061 | proto_tree_set_float(new_fi, floatval);
3062 | break;
3063 |
3064 | case FT_DOUBLE:
3065 | /*
3066 | * NOTE: to support code written when
3067 | * proto_tree_add_item() took a bool as its
3068 | * last argument, with false meaning "big-endian"
3069 | * and true meaning "little-endian", we treat any
3070 | * non-zero value of "encoding" as meaning
3071 | * "little-endian".
3072 | *
3073 | * At some point in the future, we might
3074 | * support non-IEEE-binary floating-point
3075 | * formats in the encoding as well
3076 | * (IEEE decimal, System/3x0, VAX).
3077 | */
3078 | if (encoding == true1)
3079 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3080 | if (length != 8) {
3081 | length_error = length < 8 ? true1 : false0;
3082 | report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3083 | }
3084 | if (encoding)
3085 | doubleval = tvb_get_letohieee_double(tvb, start);
3086 | else
3087 | doubleval = tvb_get_ntohieee_double(tvb, start);
3088 | proto_tree_set_double(new_fi, doubleval);
3089 | break;
3090 |
3091 | case FT_STRING:
3092 | stringval = get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3093 | tvb, start, length, &length, encoding);
3094 | proto_tree_set_string(new_fi, stringval);
3095 |
3096 | /* Instead of calling proto_item_set_len(), since we
3097 | * don't yet have a proto_item, we set the
3098 | * field_info's length ourselves.
3099 | *
3100 | * XXX - our caller can't use that length to
3101 | * advance an offset unless they arrange that
3102 | * there always be a protocol tree into which
3103 | * we're putting this item.
3104 | */
3105 | new_fi->length = length;
3106 | break;
3107 |
3108 | case FT_STRINGZ:
3109 | stringval = get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3110 | tree, tvb, start, length, &length, encoding);
3111 | proto_tree_set_string(new_fi, stringval);
3112 |
3113 | /* Instead of calling proto_item_set_len(),
3114 | * since we don't yet have a proto_item, we
3115 | * set the field_info's length ourselves.
3116 | *
3117 | * XXX - our caller can't use that length to
3118 | * advance an offset unless they arrange that
3119 | * there always be a protocol tree into which
3120 | * we're putting this item.
3121 | */
3122 | new_fi->length = length;
3123 | break;
3124 |
3125 | case FT_UINT_STRING:
3126 | /*
3127 | * NOTE: to support code written when
3128 | * proto_tree_add_item() took a bool as its
3129 | * last argument, with false meaning "big-endian"
3130 | * and true meaning "little-endian", if the
3131 | * encoding value is true, treat that as
3132 | * ASCII with a little-endian length.
3133 | *
3134 | * This won't work for code that passes
3135 | * arbitrary non-zero values; that code
3136 | * will need to be fixed.
3137 | */
3138 | if (encoding == true1)
3139 | encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3140 | stringval = get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3141 | tree, tvb, start, length, &length, encoding);
3142 | proto_tree_set_string(new_fi, stringval);
3143 |
3144 | /* Instead of calling proto_item_set_len(), since we
3145 | * don't yet have a proto_item, we set the
3146 | * field_info's length ourselves.
3147 | *
3148 | * XXX - our caller can't use that length to
3149 | * advance an offset unless they arrange that
3150 | * there always be a protocol tree into which
3151 | * we're putting this item.
3152 | */
3153 | new_fi->length = length;
3154 | break;
3155 |
3156 | case FT_STRINGZPAD:
3157 | stringval = get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3158 | tvb, start, length, &length, encoding);
3159 | proto_tree_set_string(new_fi, stringval);
3160 |
3161 | /* Instead of calling proto_item_set_len(), since we
3162 | * don't yet have a proto_item, we set the
3163 | * field_info's length ourselves.
3164 | *
3165 | * XXX - our caller can't use that length to
3166 | * advance an offset unless they arrange that
3167 | * there always be a protocol tree into which
3168 | * we're putting this item.
3169 | */
3170 | new_fi->length = length;
3171 | break;
3172 |
3173 | case FT_STRINGZTRUNC:
3174 | stringval = get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3175 | tvb, start, length, &length, encoding);
3176 | proto_tree_set_string(new_fi, stringval);
3177 |
3178 | /* Instead of calling proto_item_set_len(), since we
3179 | * don't yet have a proto_item, we set the
3180 | * field_info's length ourselves.
3181 | *
3182 | * XXX - our caller can't use that length to
3183 | * advance an offset unless they arrange that
3184 | * there always be a protocol tree into which
3185 | * we're putting this item.
3186 | */
3187 | new_fi->length = length;
3188 | break;
3189 |
3190 | case FT_ABSOLUTE_TIME:
3191 | /*
3192 | * Absolute times can be in any of a number of
3193 | * formats, and they can be big-endian or
3194 | * little-endian.
3195 | *
3196 | * Historically FT_TIMEs were only timespecs;
3197 | * the only question was whether they were stored
3198 | * in big- or little-endian format.
3199 | *
3200 | * For backwards compatibility, we interpret an
3201 | * encoding of 1 as meaning "little-endian timespec",
3202 | * so that passing true is interpreted as that.
3203 | */
3204 | if (encoding == true1)
3205 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3206 |
3207 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3208 |
3209 | proto_tree_set_time(new_fi, &time_stamp);
3210 | break;
3211 |
3212 | case FT_RELATIVE_TIME:
3213 | /*
3214 | * Relative times can be in any of a number of
3215 | * formats, and they can be big-endian or
3216 | * little-endian.
3217 | *
3218 | * Historically FT_TIMEs were only timespecs;
3219 | * the only question was whether they were stored
3220 | * in big- or little-endian format.
3221 | *
3222 | * For backwards compatibility, we interpret an
3223 | * encoding of 1 as meaning "little-endian timespec",
3224 | * so that passing true is interpreted as that.
3225 | */
3226 | if (encoding == true1)
3227 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3228 |
3229 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3230 |
3231 | proto_tree_set_time(new_fi, &time_stamp);
3232 | break;
3233 | case FT_IEEE_11073_SFLOAT:
3234 | if (encoding)
3235 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3236 | if (length != 2) {
3237 | length_error = length < 2 ? true1 : false0;
3238 | report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3239 | }
3240 |
3241 | fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3242 |
3243 | break;
3244 | case FT_IEEE_11073_FLOAT:
3245 | if (encoding)
3246 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3247 | if (length != 4) {
3248 | length_error = length < 4 ? true1 : false0;
3249 | report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3250 | }
3251 | fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3252 |
3253 | break;
3254 | default:
3255 | 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))
3256 | 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))
3257 | 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))
3258 | 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));
3259 | break;
3260 | }
3261 | 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);
3262 |
3263 | /* Don't add new node to proto_tree until now so that any exceptions
3264 | * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3265 | /* XXX. wouldn't be better to add this item to tree, with some special
3266 | * flag (FI_EXCEPTION?) to know which item caused exception? For
3267 | * strings and bytes, we would have to set new_fi->value to something
3268 | * non-NULL, or otherwise ensure that proto_item_fill_display_label
3269 | * could handle NULL values. */
3270 | CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context ); }
3271 | pi = proto_tree_add_node(tree, new_fi);
3272 |
3273 | switch (new_fi->hfinfo->type) {
3274 |
3275 | case FT_STRING:
3276 | /* XXX: trailing stray character detection should be done
3277 | * _before_ conversion to UTF-8, because conversion can change
3278 | * the length, or else get_string_length should return a value
3279 | * for the "length in bytes of the string after conversion
3280 | * including internal nulls." (Noting that we do, for other
3281 | * reasons, still need the "length in bytes in the field",
3282 | * especially for FT_STRINGZ.)
3283 | *
3284 | * This is true even for ASCII and UTF-8, because
3285 | * substituting REPLACEMENT CHARACTERS for illegal characters
3286 | * can also do so (and for UTF-8 possibly even make the
3287 | * string _shorter_).
3288 | */
3289 | detect_trailing_stray_characters(encoding, stringval, length, pi);
3290 | break;
3291 |
3292 | default:
3293 | break;
3294 | }
3295 |
3296 | return pi;
3297 | }
3298 |
3299 | proto_item *
3300 | proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3301 | const int start, int length,
3302 | const unsigned encoding, int32_t *retval)
3303 | {
3304 | header_field_info *hfinfo;
3305 | field_info *new_fi;
3306 | int32_t value;
3307 |
3308 | 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", 3308, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3308, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3308, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3309 |
3310 | switch (hfinfo->type) {
3311 | case FT_INT8:
3312 | case FT_INT16:
3313 | case FT_INT24:
3314 | case FT_INT32:
3315 | break;
3316 | case FT_INT64:
3317 | 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)
3318 | hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3319 | default:
3320 | 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)
3321 | hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3322 | }
3323 |
3324 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3325 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3326 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3327 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3328 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3329 | }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 |
3332 | if (encoding & ENC_STRING0x03000000) {
3333 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3334 | }
3335 | /* I believe it's ok if this is called with a NULL tree */
3336 | value = get_int_value(tree, tvb, start, length, encoding);
3337 |
3338 | if (retval) {
3339 | int no_of_bits;
3340 | *retval = value;
3341 | if (hfinfo->bitmask) {
3342 | /* Mask out irrelevant portions */
3343 | *retval &= (uint32_t)(hfinfo->bitmask);
3344 | /* Shift bits */
3345 | *retval >>= hfinfo_bitshift(hfinfo);
3346 | }
3347 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3348 | *retval = ws_sign_ext32(*retval, no_of_bits);
3349 | }
3350 |
3351 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3352 |
3353 | 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", 3353 , __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", 3353, "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", 3353, "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", 3353, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3354 |
3355 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3356 |
3357 | proto_tree_set_int(new_fi, value);
3358 |
3359 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3360 |
3361 | return proto_tree_add_node(tree, new_fi);
3362 | }
3363 |
3364 | proto_item *
3365 | proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3366 | const int start, int length,
3367 | const unsigned encoding, uint32_t *retval)
3368 | {
3369 | header_field_info *hfinfo;
3370 | field_info *new_fi;
3371 | uint32_t value;
3372 |
3373 | 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", 3373, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3373, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3373, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3374 |
3375 | switch (hfinfo->type) {
3376 | case FT_CHAR:
3377 | case FT_UINT8:
3378 | case FT_UINT16:
3379 | case FT_UINT24:
3380 | case FT_UINT32:
3381 | break;
3382 | default:
3383 | 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)
3384 | 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);
3385 | }
3386 |
3387 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3388 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3389 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3390 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3391 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3392 | }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 |
3395 | if (encoding & ENC_STRING0x03000000) {
3396 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3397 | }
3398 | /* I believe it's ok if this is called with a NULL tree */
3399 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3400 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3401 | uint64_t temp64;
3402 | tvb_get_varint(tvb, start, length, &temp64, encoding);
3403 | value = (uint32_t)temp64;
3404 | } else {
3405 | value = get_uint_value(tree, tvb, start, length, encoding);
3406 | }
3407 |
3408 | if (retval) {
3409 | *retval = value;
3410 | if (hfinfo->bitmask) {
3411 | /* Mask out irrelevant portions */
3412 | *retval &= (uint32_t)(hfinfo->bitmask);
3413 | /* Shift bits */
3414 | *retval >>= hfinfo_bitshift(hfinfo);
3415 | }
3416 | }
3417 |
3418 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3419 |
3420 | 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", 3420 , __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", 3420, "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", 3420, "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", 3420, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3421 |
3422 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3423 |
3424 | proto_tree_set_uint(new_fi, value);
3425 |
3426 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3427 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3428 | new_fi->flags |= FI_VARINT0x00040000;
3429 | }
3430 | return proto_tree_add_node(tree, new_fi);
3431 | }
3432 |
3433 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3434 | * and returns proto_item* and uint value retrieved*/
3435 | proto_item *
3436 | ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3437 | const unsigned encoding, uint32_t *retval)
3438 | {
3439 | field_info *new_fi;
3440 | header_field_info *hfinfo;
3441 | int item_length;
3442 | int offset;
3443 | uint32_t value;
3444 |
3445 | offset = ptvc->offset;
3446 | 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", 3446, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3446, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3446, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3447 |
3448 | switch (hfinfo->type) {
3449 | case FT_CHAR:
3450 | case FT_UINT8:
3451 | case FT_UINT16:
3452 | case FT_UINT24:
3453 | case FT_UINT32:
3454 | break;
3455 | default:
3456 | 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)
3457 | 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);
3458 | }
3459 |
3460 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3461 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3462 |
3463 | /* I believe it's ok if this is called with a NULL tree */
3464 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3465 | value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3466 |
3467 | if (retval) {
3468 | *retval = value;
3469 | if (hfinfo->bitmask) {
3470 | /* Mask out irrelevant portions */
3471 | *retval &= (uint32_t)(hfinfo->bitmask);
3472 | /* Shift bits */
3473 | *retval >>= hfinfo_bitshift(hfinfo);
3474 | }
3475 | }
3476 |
3477 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3478 |
3479 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3480 |
3481 | /* Coast clear. Try and fake it */
3482 | 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", 3482 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3482, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3482, "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", 3482, __func__, "Adding %s would put more than %d 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); } } };
3483 |
3484 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3485 |
3486 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3487 | offset, length, encoding);
3488 | }
3489 |
3490 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3491 | * and returns proto_item* and int value retrieved*/
3492 | proto_item *
3493 | ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3494 | const unsigned encoding, int32_t *retval)
3495 | {
3496 | field_info *new_fi;
3497 | header_field_info *hfinfo;
3498 | int item_length;
3499 | int offset;
3500 | uint32_t value;
3501 |
3502 | offset = ptvc->offset;
3503 | 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", 3503, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3503, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3503, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3504 |
3505 | switch (hfinfo->type) {
3506 | case FT_INT8:
3507 | case FT_INT16:
3508 | case FT_INT24:
3509 | case FT_INT32:
3510 | break;
3511 | default:
3512 | 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)
3513 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
3514 | }
3515 |
3516 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3517 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3518 |
3519 | /* I believe it's ok if this is called with a NULL tree */
3520 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3521 | value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3522 |
3523 | if (retval) {
3524 | int no_of_bits;
3525 | *retval = value;
3526 | if (hfinfo->bitmask) {
3527 | /* Mask out irrelevant portions */
3528 | *retval &= (uint32_t)(hfinfo->bitmask);
3529 | /* Shift bits */
3530 | *retval >>= hfinfo_bitshift(hfinfo);
3531 | }
3532 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3533 | *retval = ws_sign_ext32(*retval, no_of_bits);
3534 | }
3535 |
3536 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3537 |
3538 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3539 |
3540 | /* Coast clear. Try and fake it */
3541 | 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", 3541 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3541, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3541, "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", 3541, __func__, "Adding %s would put more than %d 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); } } };
3542 |
3543 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3544 |
3545 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3546 | offset, length, encoding);
3547 | }
3548 |
3549 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3550 | * and returns proto_item* and string value retrieved */
3551 | proto_item*
3552 | ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3553 | {
3554 | header_field_info *hfinfo;
3555 | field_info *new_fi;
3556 | const uint8_t *value;
3557 | int item_length;
3558 | int offset;
3559 |
3560 | offset = ptvc->offset;
3561 |
3562 | 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", 3562 , __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", 3562, "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", 3562, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hf];;
3563 |
3564 | switch (hfinfo->type) {
3565 | case FT_STRING:
3566 | value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3567 | break;
3568 | case FT_STRINGZ:
3569 | value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3570 | break;
3571 | case FT_UINT_STRING:
3572 | value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3573 | break;
3574 | case FT_STRINGZPAD:
3575 | value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3576 | break;
3577 | case FT_STRINGZTRUNC:
3578 | value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3579 | break;
3580 | default:
3581 | 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)
3582 | 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);
3583 | }
3584 |
3585 | if (retval)
3586 | *retval = value;
3587 |
3588 | ptvcursor_advance(ptvc, item_length);
3589 |
3590 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3591 |
3592 | 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", 3592, __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", 3592, "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", 3592, "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", 3592 , __func__, "Adding %s would put more than %d 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); } } };
3593 |
3594 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3595 |
3596 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3597 | offset, length, encoding);
3598 | }
3599 |
3600 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3601 | * and returns proto_item* and boolean value retrieved */
3602 | proto_item*
3603 | ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3604 | {
3605 | header_field_info *hfinfo;
3606 | field_info *new_fi;
3607 | int item_length;
3608 | int offset;
3609 | uint64_t value, bitval;
3610 |
3611 | offset = ptvc->offset;
3612 | 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", 3612, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3612, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3612, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3613 |
3614 | if (hfinfo->type != FT_BOOLEAN) {
3615 | 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)
3616 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3617 | }
3618 |
3619 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3620 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3621 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3622 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3623 | *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3624 | }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 |
3627 | if (encoding & ENC_STRING0x03000000) {
3628 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3629 | }
3630 |
3631 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3632 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3633 |
3634 | /* I believe it's ok if this is called with a NULL tree */
3635 | value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3636 |
3637 | if (retval) {
3638 | bitval = value;
3639 | if (hfinfo->bitmask) {
3640 | /* Mask out irrelevant portions */
3641 | bitval &= hfinfo->bitmask;
3642 | }
3643 | *retval = (bitval != 0);
3644 | }
3645 |
3646 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3647 |
3648 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3649 |
3650 | 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", 3650, __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", 3650, "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", 3650, "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", 3650 , __func__, "Adding %s would put more than %d 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); } } };
3651 |
3652 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3653 |
3654 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3655 | offset, length, encoding);
3656 | }
3657 |
3658 | proto_item *
3659 | proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3660 | const int start, int length, const unsigned encoding, uint64_t *retval)
3661 | {
3662 | header_field_info *hfinfo;
3663 | field_info *new_fi;
3664 | uint64_t value;
3665 |
3666 | 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", 3666, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3666, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3666, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3667 |
3668 | switch (hfinfo->type) {
3669 | case FT_UINT40:
3670 | case FT_UINT48:
3671 | case FT_UINT56:
3672 | case FT_UINT64:
3673 | break;
3674 | default:
3675 | 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)
3676 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64" , hfinfo->abbrev);
3677 | }
3678 |
3679 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3680 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3681 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3682 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3683 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3684 | }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 |
3687 | if (encoding & ENC_STRING0x03000000) {
3688 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3689 | }
3690 | /* I believe it's ok if this is called with a NULL tree */
3691 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3692 | tvb_get_varint(tvb, start, length, &value, encoding);
3693 | } else {
3694 | value = get_uint64_value(tree, tvb, start, length, encoding);
3695 | }
3696 |
3697 | if (retval) {
3698 | *retval = value;
3699 | if (hfinfo->bitmask) {
3700 | /* Mask out irrelevant portions */
3701 | *retval &= hfinfo->bitmask;
3702 | /* Shift bits */
3703 | *retval >>= hfinfo_bitshift(hfinfo);
3704 | }
3705 | }
3706 |
3707 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3708 |
3709 | 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", 3709 , __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", 3709, "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", 3709, "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", 3709, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3710 |
3711 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3712 |
3713 | proto_tree_set_uint64(new_fi, value);
3714 |
3715 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3716 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3717 | new_fi->flags |= FI_VARINT0x00040000;
3718 | }
3719 |
3720 | return proto_tree_add_node(tree, new_fi);
3721 | }
3722 |
3723 | proto_item *
3724 | proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3725 | const int start, int length, const unsigned encoding, int64_t *retval)
3726 | {
3727 | header_field_info *hfinfo;
3728 | field_info *new_fi;
3729 | int64_t value;
3730 |
3731 | 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", 3731, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3731, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3731, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3732 |
3733 | switch (hfinfo->type) {
3734 | case FT_INT40:
3735 | case FT_INT48:
3736 | case FT_INT56:
3737 | case FT_INT64:
3738 | break;
3739 | default:
3740 | 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)
3741 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
3742 | }
3743 |
3744 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3745 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3746 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3747 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3748 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3749 | }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 |
3752 | if (encoding & ENC_STRING0x03000000) {
3753 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3754 | }
3755 | /* I believe it's ok if this is called with a NULL tree */
3756 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3757 | tvb_get_varint(tvb, start, length, &value, encoding);
3758 | }
3759 | else {
3760 | value = get_int64_value(tree, tvb, start, length, encoding);
3761 | }
3762 |
3763 | if (retval) {
3764 | *retval = value;
3765 | }
3766 |
3767 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3768 |
3769 | 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", 3769 , __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", 3769, "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", 3769, "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", 3769, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3770 |
3771 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3772 |
3773 | proto_tree_set_int64(new_fi, value);
3774 |
3775 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3776 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3777 | new_fi->flags |= FI_VARINT0x00040000;
3778 | }
3779 |
3780 | return proto_tree_add_node(tree, new_fi);
3781 | }
3782 |
3783 | proto_item *
3784 | proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3785 | const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3786 | {
3787 | header_field_info *hfinfo;
3788 | field_info *new_fi;
3789 | uint64_t value;
3790 |
3791 | 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", 3791, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3791, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3791, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3792 |
3793 | 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 )))) {
3794 | 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)
3795 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT" , hfinfo->abbrev);
3796 | }
3797 |
3798 | /* length validation for native number encoding caught by get_uint64_value() */
3799 | /* length has to be -1 or > 0 regardless of encoding */
3800 | if (length == 0)
3801 | 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)
3802 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint" , length);
3803 |
3804 | if (encoding & ENC_STRING0x03000000) {
3805 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3806 | }
3807 |
3808 | length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3809 |
3810 | if (retval) {
3811 | *retval = value;
3812 | if (hfinfo->bitmask) {
3813 | /* Mask out irrelevant portions */
3814 | *retval &= hfinfo->bitmask;
3815 | /* Shift bits */
3816 | *retval >>= hfinfo_bitshift(hfinfo);
3817 | }
3818 | }
3819 |
3820 | if (lenretval) {
3821 | *lenretval = length;
3822 | }
3823 |
3824 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3825 |
3826 | 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", 3826 , __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", 3826, "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", 3826, "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", 3826, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3827 |
3828 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3829 |
3830 | proto_tree_set_uint64(new_fi, value);
3831 |
3832 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3833 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3834 | new_fi->flags |= FI_VARINT0x00040000;
3835 | }
3836 |
3837 | return proto_tree_add_node(tree, new_fi);
3838 |
3839 | }
3840 |
3841 | proto_item *
3842 | proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3843 | const int start, int length,
3844 | const unsigned encoding, bool_Bool *retval)
3845 | {
3846 | header_field_info *hfinfo;
3847 | field_info *new_fi;
3848 | uint64_t value, bitval;
3849 |
3850 | 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", 3850, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3850, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3850, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3851 |
3852 | if (hfinfo->type != FT_BOOLEAN) {
3853 | 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)
3854 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3855 | }
3856 |
3857 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3858 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3859 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3860 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3861 | *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3862 | }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 |
3865 | if (encoding & ENC_STRING0x03000000) {
3866 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3867 | }
3868 | /* I believe it's ok if this is called with a NULL tree */
3869 | value = get_uint64_value(tree, tvb, start, length, encoding);
3870 |
3871 | if (retval) {
3872 | bitval = value;
3873 | if (hfinfo->bitmask) {
3874 | /* Mask out irrelevant portions */
3875 | bitval &= hfinfo->bitmask;
3876 | }
3877 | *retval = (bitval != 0);
3878 | }
3879 |
3880 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3881 |
3882 | 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", 3882 , __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", 3882, "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", 3882, "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", 3882, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3883 |
3884 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3885 |
3886 | proto_tree_set_boolean(new_fi, value);
3887 |
3888 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3889 |
3890 | return proto_tree_add_node(tree, new_fi);
3891 | }
3892 |
3893 | proto_item *
3894 | proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3895 | const int start, int length,
3896 | const unsigned encoding, float *retval)
3897 | {
3898 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3899 | field_info *new_fi;
3900 | float value;
3901 |
3902 | 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", 3902, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3903 |
3904 | if (hfinfo->type != FT_FLOAT) {
3905 | 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);
3906 | }
3907 |
3908 | if (length != 4) {
3909 | report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3910 | }
3911 |
3912 | /* treat any nonzero encoding as little endian for backwards compatibility */
3913 | value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3914 | if (retval) {
3915 | *retval = value;
3916 | }
3917 |
3918 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3919 |
3920 | 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", 3920 , __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", 3920, "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", 3920, "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", 3920, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3921 |
3922 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3923 | if (encoding) {
3924 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3925 | }
3926 |
3927 | proto_tree_set_float(new_fi, value);
3928 |
3929 | return proto_tree_add_node(tree, new_fi);
3930 | }
3931 |
3932 | proto_item *
3933 | proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3934 | const int start, int length,
3935 | const unsigned encoding, double *retval)
3936 | {
3937 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3938 | field_info *new_fi;
3939 | double value;
3940 |
3941 | 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", 3941, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3942 |
3943 | if (hfinfo->type != FT_DOUBLE) {
3944 | 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);
3945 | }
3946 |
3947 | if (length != 8) {
3948 | report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3949 | }
3950 |
3951 | /* treat any nonzero encoding as little endian for backwards compatibility */
3952 | value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3953 | if (retval) {
3954 | *retval = value;
3955 | }
3956 |
3957 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3958 |
3959 | 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", 3959 , __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", 3959, "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", 3959, "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", 3959, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3960 |
3961 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3962 | if (encoding) {
3963 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3964 | }
3965 |
3966 | proto_tree_set_double(new_fi, value);
3967 |
3968 | return proto_tree_add_node(tree, new_fi);
3969 | }
3970 |
3971 | proto_item *
3972 | proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3973 | const int start, int length,
3974 | const unsigned encoding, ws_in4_addr *retval)
3975 | {
3976 | header_field_info *hfinfo;
3977 | field_info *new_fi;
3978 | ws_in4_addr value;
3979 |
3980 | 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", 3980, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3980, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3980, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3981 |
3982 | switch (hfinfo->type) {
3983 | case FT_IPv4:
3984 | break;
3985 | default:
3986 | 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)
3987 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4", hfinfo->abbrev);
3988 | }
3989 |
3990 | if (length != FT_IPv4_LEN4)
3991 | 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)
3992 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4" , length);
3993 |
3994 | if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3995 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3996 | }
3997 |
3998 | /*
3999 | * NOTE: to support code written when proto_tree_add_item() took
4000 | * a bool as its last argument, with false meaning "big-endian"
4001 | * and true meaning "little-endian", we treat any non-zero value
4002 | * of "encoding" as meaning "little-endian".
4003 | */
4004 | value = tvb_get_ipv4(tvb, start);
4005 | if (encoding)
4006 | 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))));
4007 |
4008 | if (retval) {
4009 | *retval = value;
4010 | }
4011 |
4012 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4013 |
4014 | 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", 4014 , __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", 4014, "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", 4014, "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", 4014, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4015 |
4016 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4017 |
4018 | proto_tree_set_ipv4(new_fi, value);
4019 |
4020 | new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4021 | return proto_tree_add_node(tree, new_fi);
4022 | }
4023 |
4024 | proto_item *
4025 | proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4026 | const int start, int length,
4027 | const unsigned encoding, ws_in6_addr *addr)
4028 | {
4029 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4030 | field_info *new_fi;
4031 |
4032 | 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", 4032, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4033 |
4034 | switch (hfinfo->type) {
4035 | case FT_IPv6:
4036 | break;
4037 | default:
4038 | 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)
4039 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6", hfinfo->abbrev);
4040 | }
4041 |
4042 | if (length != FT_IPv6_LEN16)
4043 | 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)
4044 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6" , length);
4045 |
4046 | if (encoding) {
4047 | 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" );
4048 | }
4049 |
4050 | tvb_get_ipv6(tvb, start, addr);
4051 |
4052 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4053 |
4054 | 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", 4054 , __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", 4054, "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", 4054, "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", 4054, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4055 |
4056 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4057 |
4058 | proto_tree_set_ipv6(new_fi, addr);
4059 |
4060 | return proto_tree_add_node(tree, new_fi);
4061 | }
4062 |
4063 | proto_item *
4064 | proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4065 | const int start, int length, const unsigned encoding, uint8_t *retval) {
4066 |
4067 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4068 | field_info *new_fi;
4069 |
4070 | 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", 4070, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4071 |
4072 | switch (hfinfo->type) {
4073 | case FT_ETHER:
4074 | break;
4075 | default:
4076 | 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)
4077 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER" , hfinfo->abbrev);
4078 | }
4079 |
4080 | if (length != FT_ETHER_LEN6)
4081 | 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)
4082 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether" , length);
4083 |
4084 | if (encoding) {
4085 | 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" );
4086 | }
4087 |
4088 | tvb_memcpy(tvb, retval, start, length);
4089 |
4090 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4091 |
4092 | 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", 4092 , __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", 4092, "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", 4092, "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", 4092, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4093 |
4094 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4095 |
4096 | proto_tree_set_ether(new_fi, retval);
4097 |
4098 | return proto_tree_add_node(tree, new_fi);
4099 | }
4100 |
4101 |
4102 | proto_item *
4103 | proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4104 | tvbuff_t *tvb,
4105 | const int start, int length,
4106 | const unsigned encoding,
4107 | wmem_allocator_t *scope,
4108 | const uint8_t **retval,
4109 | int *lenretval)
4110 | {
4111 | proto_item *pi;
4112 | header_field_info *hfinfo;
4113 | field_info *new_fi;
4114 | const uint8_t *value;
4115 |
4116 | 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", 4116, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4116, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4116, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4117 |
4118 | switch (hfinfo->type) {
4119 | case FT_STRING:
4120 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4121 | break;
4122 | case FT_STRINGZ:
4123 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4124 | break;
4125 | case FT_UINT_STRING:
4126 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4127 | break;
4128 | case FT_STRINGZPAD:
4129 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4130 | break;
4131 | case FT_STRINGZTRUNC:
4132 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4133 | break;
4134 | default:
4135 | 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)
4136 | 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);
4137 | }
4138 |
4139 | if (retval)
4140 | *retval = value;
4141 |
4142 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4143 |
4144 | 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", 4144 , __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", 4144, "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", 4144, "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", 4144, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4145 |
4146 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4147 |
4148 | proto_tree_set_string(new_fi, value);
4149 |
4150 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4151 |
4152 | pi = proto_tree_add_node(tree, new_fi);
4153 |
4154 | switch (hfinfo->type) {
4155 |
4156 | case FT_STRINGZ:
4157 | case FT_STRINGZPAD:
4158 | case FT_STRINGZTRUNC:
4159 | case FT_UINT_STRING:
4160 | break;
4161 |
4162 | case FT_STRING:
4163 | detect_trailing_stray_characters(encoding, value, length, pi);
4164 | break;
4165 |
4166 | default:
4167 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4167 , __func__, "assertion \"not reached\" failed");
4168 | }
4169 |
4170 | return pi;
4171 | }
4172 |
4173 | proto_item *
4174 | proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4175 | const int start, int length,
4176 | const unsigned encoding, wmem_allocator_t *scope,
4177 | const uint8_t **retval)
4178 | {
4179 | return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4180 | tvb, start, length, encoding, scope, retval, &length);
4181 | }
4182 |
4183 | proto_item *
4184 | proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4185 | tvbuff_t *tvb,
4186 | const int start, int length,
4187 | const unsigned encoding,
4188 | wmem_allocator_t *scope,
4189 | char **retval,
4190 | int *lenretval)
4191 | {
4192 | proto_item *pi;
4193 | header_field_info *hfinfo;
4194 | field_info *new_fi;
4195 | const uint8_t *value;
4196 | uint32_t n = 0;
4197 |
4198 | 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", 4198, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4198, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4198, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4199 |
4200 | switch (hfinfo->type) {
4201 | case FT_STRING:
4202 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4203 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4204 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4205 | break;
4206 | case FT_STRINGZ:
4207 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4208 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4209 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4210 | break;
4211 | case FT_UINT_STRING:
4212 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4213 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4214 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4215 | break;
4216 | case FT_STRINGZPAD:
4217 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4218 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4219 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4220 | break;
4221 | case FT_STRINGZTRUNC:
4222 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4223 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4224 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4225 | break;
4226 | case FT_BYTES:
4227 | tvb_ensure_bytes_exist(tvb, start, length);
4228 | value = tvb_get_ptr(tvb, start, length);
4229 | *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4230 | *lenretval = length;
4231 | break;
4232 | case FT_UINT_BYTES:
4233 | n = get_uint_value(tree, tvb, start, length, encoding);
4234 | tvb_ensure_bytes_exist(tvb, start + length, n);
4235 | value = tvb_get_ptr(tvb, start + length, n);
4236 | *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4237 | *lenretval = length + n;
4238 | break;
4239 | default:
4240 | 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)
4241 | 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);
4242 | }
4243 |
4244 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4245 |
4246 | TRY_TO_FAKE_THIS_ITEM(tree, hfinfo->id, hfinfo)((tree)->tree_data)->count++; if((hfinfo->id == 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4246 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4246, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4246, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4246, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4247 |
4248 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4249 |
4250 | switch (hfinfo->type) {
4251 |
4252 | case FT_STRING:
4253 | case FT_STRINGZ:
4254 | case FT_UINT_STRING:
4255 | case FT_STRINGZPAD:
4256 | case FT_STRINGZTRUNC:
4257 | proto_tree_set_string(new_fi, value);
4258 | break;
4259 |
4260 | case FT_BYTES:
4261 | proto_tree_set_bytes(new_fi, value, length);
4262 | break;
4263 |
4264 | case FT_UINT_BYTES:
4265 | proto_tree_set_bytes(new_fi, value, n);
4266 | break;
4267 |
4268 | default:
4269 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4269 , __func__, "assertion \"not reached\" failed");
4270 | }
4271 |
4272 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4273 |
4274 | pi = proto_tree_add_node(tree, new_fi);
4275 |
4276 | switch (hfinfo->type) {
4277 |
4278 | case FT_STRINGZ:
4279 | case FT_STRINGZPAD:
4280 | case FT_STRINGZTRUNC:
4281 | case FT_UINT_STRING:
4282 | break;
4283 |
4284 | case FT_STRING:
4285 | detect_trailing_stray_characters(encoding, value, length, pi);
4286 | break;
4287 |
4288 | case FT_BYTES:
4289 | case FT_UINT_BYTES:
4290 | break;
4291 |
4292 | default:
4293 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4293 , __func__, "assertion \"not reached\" failed");
4294 | }
4295 |
4296 | return pi;
4297 | }
4298 |
4299 | proto_item *
4300 | proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4301 | tvbuff_t *tvb,
4302 | const int start, int length,
4303 | const unsigned encoding,
4304 | wmem_allocator_t *scope,
4305 | char **retval)
4306 | {
4307 | return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4308 | tvb, start, length, encoding, scope, retval, &length);
4309 | }
4310 |
4311 | proto_item *
4312 | proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4313 | tvbuff_t *tvb,
4314 | const int start, int length, const unsigned encoding,
4315 | wmem_allocator_t *scope, char **retval)
4316 | {
4317 | header_field_info *hfinfo;
4318 | field_info *new_fi;
4319 | nstime_t time_stamp;
4320 | int flags;
4321 |
4322 | 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", 4322, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4322, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4322, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4323 |
4324 | switch (hfinfo->type) {
4325 | case FT_ABSOLUTE_TIME:
4326 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4327 | flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4328 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4329 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4330 | }
4331 | *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4332 | break;
4333 | case FT_RELATIVE_TIME:
4334 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4335 | *retval = rel_time_to_secs_str(scope, &time_stamp);
4336 | break;
4337 | default:
4338 | 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)
4339 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME" , hfinfo->abbrev);
4340 | }
4341 |
4342 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4343 |
4344 | 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", 4344 , __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", 4344, "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", 4344, "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", 4344, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4345 |
4346 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4347 |
4348 | switch (hfinfo->type) {
4349 |
4350 | case FT_ABSOLUTE_TIME:
4351 | case FT_RELATIVE_TIME:
4352 | proto_tree_set_time(new_fi, &time_stamp);
4353 | break;
4354 | default:
4355 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4355 , __func__, "assertion \"not reached\" failed");
4356 | }
4357 |
4358 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4359 |
4360 | return proto_tree_add_node(tree, new_fi);
4361 | }
4362 |
4363 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
4364 | and returns proto_item* */
4365 | proto_item *
4366 | ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4367 | const unsigned encoding)
4368 | {
4369 | field_info *new_fi;
4370 | header_field_info *hfinfo;
4371 | int item_length;
4372 | int offset;
4373 |
4374 | offset = ptvc->offset;
4375 | 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", 4375, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4375, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4375, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4376 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4377 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4378 |
4379 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4380 |
4381 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4382 |
4383 | /* Coast clear. Try and fake it */
4384 | 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", 4384 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4384, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4384, "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", 4384, __func__, "Adding %s would put more than %d 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); } } };
4385 |
4386 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4387 |
4388 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4389 | offset, length, encoding);
4390 | }
4391 |
4392 | /* Add an item to a proto_tree, using the text label registered to that item;
4393 | the item is extracted from the tvbuff handed to it. */
4394 | proto_item *
4395 | proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4396 | const int start, int length, const unsigned encoding)
4397 | {
4398 | field_info *new_fi;
4399 | int item_length;
4400 |
4401 | 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", 4401, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4402 |
4403 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4404 | test_length(hfinfo, tvb, start, item_length, encoding);
4405 |
4406 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4407 |
4408 | 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", 4408 , __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", 4408, "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", 4408, "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", 4408, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4409 |
4410 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4411 |
4412 | return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4413 | }
4414 |
4415 | proto_item *
4416 | proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4417 | const int start, int length, const unsigned encoding)
4418 | {
4419 | register header_field_info *hfinfo;
4420 |
4421 | 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", 4421, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4421, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4421, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4422 | return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4423 | }
4424 |
4425 | /* Add an item to a proto_tree, using the text label registered to that item;
4426 | the item is extracted from the tvbuff handed to it.
4427 |
4428 | Return the length of the item through the pointer. */
4429 | proto_item *
4430 | proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4431 | tvbuff_t *tvb, const int start,
4432 | int length, const unsigned encoding,
4433 | int *lenretval)
4434 | {
4435 | field_info *new_fi;
4436 | int item_length;
4437 | proto_item *item;
4438 |
4439 | 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", 4439, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4440 |
4441 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4442 | test_length(hfinfo, tvb, start, item_length, encoding);
4443 |
4444 | if (!tree) {
4445 | /*
4446 | * We need to get the correct item length here.
4447 | * That's normally done by proto_tree_new_item(),
4448 | * but we won't be calling it.
4449 | */
4450 | *lenretval = get_full_length(hfinfo, tvb, start, length,
4451 | item_length, encoding);
4452 | return NULL((void*)0);
4453 | }
4454 |
4455 | 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", 4462 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { { *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", 4462 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4456 | /*((tree)->tree_data)->count++; if((hfinfo->id == 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4462 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { { *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", 4462 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4457 | * 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", 4462 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { { *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", 4462 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4458 | * 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", 4462 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { { *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", 4462 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4459 | */((tree)->tree_data)->count++; if((hfinfo->id == 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4462 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { { *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", 4462 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4460 | *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", 4462 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { { *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", 4462 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4461 | 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", 4462 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { { *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", 4462 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4462 | })((tree)->tree_data)->count++; if((hfinfo->id == 0 || (unsigned)hfinfo->id > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4462 , __func__, "Unregistered hf! index=%d", hfinfo->id); ((void ) ((hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "hfinfo->id > 0 && (unsigned)hfinfo->id < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfinfo-> id] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4462, "gpa_hfinfo.hfi[hfinfo->id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> id];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { { *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", 4462 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } };
4463 |
4464 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4465 |
4466 | item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4467 | *lenretval = new_fi->length;
4468 | return item;
4469 | }
4470 |
4471 | proto_item *
4472 | proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4473 | const int start, int length,
4474 | const unsigned encoding, int *lenretval)
4475 | {
4476 | register header_field_info *hfinfo;
4477 |
4478 | PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4478, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4478, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4478, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4479 | return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4480 | }
4481 |
4482 | /* which FT_ types can use proto_tree_add_bytes_item() */
4483 | static inline bool_Bool
4484 | validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4485 | {
4486 | return (type == FT_BYTES ||
4487 | type == FT_UINT_BYTES ||
4488 | type == FT_OID ||
4489 | type == FT_REL_OID ||
4490 | type == FT_SYSTEM_ID );
4491 | }
4492 |
4493 | /* Note: this does no validation that the byte array of an FT_OID or
4494 | FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4495 | so I think it's ok to continue not validating it?
4496 | */
4497 | proto_item *
4498 | proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4499 | const int start, int length, const unsigned encoding,
4500 | GByteArray *retval, int *endoff, int *err)
4501 | {
4502 | field_info *new_fi;
4503 | GByteArray *bytes = retval;
4504 | GByteArray *created_bytes = NULL((void*)0);
4505 | bool_Bool failed = false0;
4506 | uint32_t n = 0;
4507 | header_field_info *hfinfo;
4508 | bool_Bool generate = (bytes || tree) ? true1 : false0;
4509 |
4510 | 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", 4510, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4510, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4510, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4511 |
4512 | 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", 4512, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4513 |
4514 | 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", 4515, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))))
4515 | "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", 4515, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))));
4516 |
4517 | CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); };
4518 |
4519 | if (encoding & ENC_STR_NUM0x01000000) {
4520 | 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" );
4521 | }
4522 |
4523 | if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4524 | if (hfinfo->type == FT_UINT_BYTES) {
4525 | /* can't decode FT_UINT_BYTES from strings */
4526 | 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")
4527 | "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");
4528 | }
4529 |
4530 | unsigned hex_encoding = encoding;
4531 | if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4532 | /* If none of the separator values are used,
4533 | * assume no separator (the common case). */
4534 | hex_encoding |= ENC_SEP_NONE0x00010000;
4535 | #if 0
4536 | 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")
4537 | "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");
4538 | #endif
4539 | }
4540 |
4541 | if (!bytes) {
4542 | /* caller doesn't care about return value, but we need it to
4543 | call tvb_get_string_bytes() and set the tree later */
4544 | bytes = created_bytes = g_byte_array_new();
4545 | }
4546 |
4547 | /*
4548 | * bytes might be NULL after this, but can't add expert
4549 | * error until later; if it's NULL, just note that
4550 | * it failed.
4551 | */
4552 | bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4553 | if (bytes == NULL((void*)0))
4554 | failed = true1;
4555 | }
4556 | else if (generate) {
4557 | tvb_ensure_bytes_exist(tvb, start, length);
4558 |
4559 | if (hfinfo->type == FT_UINT_BYTES) {
4560 | n = length; /* n is now the "header" length */
4561 | length = get_uint_value(tree, tvb, start, n, encoding);
4562 | /* length is now the value's length; only store the value in the array */
4563 | tvb_ensure_bytes_exist(tvb, start + n, length);
4564 | if (!bytes) {
4565 | /* caller doesn't care about return value, but
4566 | * we may need it to set the tree later */
4567 | bytes = created_bytes = g_byte_array_new();
4568 | }
4569 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4570 | }
4571 | else if (length > 0) {
4572 | if (!bytes) {
4573 | /* caller doesn't care about return value, but
4574 | * we may need it to set the tree later */
4575 | bytes = created_bytes = g_byte_array_new();
4576 | }
4577 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4578 | }
4579 |
4580 | if (endoff)
4581 | *endoff = start + n + length;
4582 | }
4583 |
4584 | if (err)
4585 | *err = failed ? EINVAL22 : 0;
4586 |
4587 | 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); }
4588 | {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4589 | 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); }
4590 | 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); }
4591 | 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); }
4592 | 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 | } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); };
4594 |
4595 | 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", 4601 , __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", 4601, "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", 4601, "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", 4601 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4596 | {((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", 4601 , __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", 4601, "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", 4601, "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", 4601 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 | 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", 4601 , __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", 4601, "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", 4601, "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", 4601 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 | 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", 4601 , __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", 4601, "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", 4601, "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", 4601 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 | 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", 4601 , __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", 4601, "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", 4601, "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", 4601 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 | 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", 4601 , __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", 4601, "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", 4601, "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", 4601 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 | } )((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", 4601 , __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", 4601, "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", 4601, "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", 4601 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 |
4603 | /* n will be zero except when it's a FT_UINT_BYTES */
4604 | new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4605 |
4606 | if (encoding & ENC_STRING0x03000000) {
4607 | if (failed)
4608 | expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4609 |
4610 | if (bytes)
4611 | proto_tree_set_bytes_gbytearray(new_fi, bytes);
4612 | else
4613 | proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4614 |
4615 | if (created_bytes)
4616 | g_byte_array_free(created_bytes, true1);
4617 | }
4618 | else {
4619 | /* n will be zero except when it's a FT_UINT_BYTES */
4620 | proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4621 |
4622 | /* XXX: If we have a non-NULL tree but NULL retval, we don't
4623 | * use the byte array created above in this case.
4624 | */
4625 | if (created_bytes)
4626 | g_byte_array_free(created_bytes, true1);
4627 |
4628 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4629 | (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);
4630 | }
4631 |
4632 | return proto_tree_add_node(tree, new_fi);
4633 | }
4634 |
4635 |
4636 | proto_item *
4637 | proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4638 | const int start, int length, const unsigned encoding,
4639 | nstime_t *retval, int *endoff, int *err)
4640 | {
4641 | field_info *new_fi;
4642 | nstime_t time_stamp;
4643 | int saved_err = 0;
4644 | header_field_info *hfinfo;
4645 |
4646 | PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4646, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4646, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4646, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4647 |
4648 | 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", 4648, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4649 |
4650 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4651 | {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4652 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4653 | {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4654 | nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4655 | }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 |
4658 | nstime_set_zero(&time_stamp);
4659 |
4660 | if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4661 | 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", 4661, ((hfinfo))->abbrev))));
4662 | /* The only string format that could be a relative time is
4663 | * ENC_ISO_8601_TIME, and that is treated as an absolute time
4664 | * relative to "now" currently.
4665 | */
4666 | if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4667 | saved_err = EINVAL22;
4668 | }
4669 | else {
4670 | 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", 4670, ((hfinfo))->abbrev))));
4671 | const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4672 |
4673 | tvb_ensure_bytes_exist(tvb, start, length);
4674 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4675 | if (endoff) *endoff = start + length;
4676 | }
4677 |
4678 | if (err) *err = saved_err;
4679 |
4680 | if (retval) {
4681 | retval->secs = time_stamp.secs;
4682 | retval->nsecs = time_stamp.nsecs;
4683 | }
4684 |
4685 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4686 |
4687 | 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", 4687 , __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", 4687, "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", 4687, "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", 4687, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4688 |
4689 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4690 |
4691 | proto_tree_set_time(new_fi, &time_stamp);
4692 |
4693 | if (encoding & ENC_STRING0x03000000) {
4694 | if (saved_err)
4695 | expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4696 | }
4697 | else {
4698 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4699 | (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);
4700 | }
4701 |
4702 | return proto_tree_add_node(tree, new_fi);
4703 | }
4704 |
4705 | /* Add a FT_NONE to a proto_tree */
4706 | proto_item *
4707 | proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4708 | const int start, int length, const char *format,
4709 | ...)
4710 | {
4711 | proto_item *pi;
4712 | va_list ap;
4713 | header_field_info *hfinfo;
4714 |
4715 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4716 |
4717 | 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", 4717 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4717, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4717, "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", 4717, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4718 |
4719 | 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", 4719 , ((hfinfo))->abbrev))));
4720 |
4721 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4722 |
4723 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4723, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4724 |
4725 | va_start(ap, format)__builtin_va_start(ap, format);
4726 | proto_tree_set_representation(pi, format, ap);
4727 | va_end(ap)__builtin_va_end(ap);
4728 |
4729 | /* no value to set for FT_NONE */
4730 | return pi;
4731 | }
4732 |
4733 | /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4734 | * offset, and returns proto_item* */
4735 | proto_item *
4736 | ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4737 | const unsigned encoding)
4738 | {
4739 | proto_item *item;
4740 |
4741 | item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4742 | length, encoding);
4743 |
4744 | return item;
4745 | }
4746 |
4747 | /* Advance the ptvcursor's offset within its tvbuff without
4748 | * adding anything to the proto_tree. */
4749 | void
4750 | ptvcursor_advance(ptvcursor_t* ptvc, int length)
4751 | {
4752 | if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc ->offset))) {
4753 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4754 | }
4755 | }
4756 |
4757 |
4758 | static void
4759 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4760 | {
4761 | fvalue_set_protocol(fi->value, tvb, field_data, length);
4762 | }
4763 |
4764 | /* Add a FT_PROTOCOL to a proto_tree */
4765 | proto_item *
4766 | proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4767 | int start, int length, const char *format, ...)
4768 | {
4769 | proto_item *pi;
4770 | tvbuff_t *protocol_tvb;
4771 | va_list ap;
4772 | header_field_info *hfinfo;
4773 | char* protocol_rep;
4774 |
4775 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4776 |
4777 | 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", 4777 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4777, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4777, "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", 4777, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4778 |
4779 | 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" , 4779, ((hfinfo))->abbrev))));
4780 |
4781 | /*
4782 | * This can throw an exception, so do it before we allocate anything.
4783 | */
4784 | protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4785 |
4786 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4787 |
4788 | va_start(ap, format)__builtin_va_start(ap, format);
4789 | protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4790 | proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4791 | g_free(protocol_rep);
4792 | va_end(ap)__builtin_va_end(ap);
4793 |
4794 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4794, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4795 |
4796 | va_start(ap, format)__builtin_va_start(ap, format);
4797 | proto_tree_set_representation(pi, format, ap);
4798 | va_end(ap)__builtin_va_end(ap);
4799 |
4800 | return pi;
4801 | }
4802 |
4803 | /* Add a FT_BYTES to a proto_tree */
4804 | proto_item *
4805 | proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4806 | int length, const uint8_t *start_ptr)
4807 | {
4808 | proto_item *pi;
4809 | header_field_info *hfinfo;
4810 | int item_length;
4811 |
4812 | 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", 4812, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4812, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4812, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4813 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4814 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4815 |
4816 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4817 |
4818 | 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", 4818 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4818, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4818, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4818, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4819 |
4820 | 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", 4820, ((hfinfo))->abbrev))));
4821 |
4822 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4823 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4824 |
4825 | return pi;
4826 | }
4827 |
4828 | /* Add a FT_BYTES to a proto_tree */
4829 | proto_item *
4830 | proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4831 | int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4832 | {
4833 | proto_item *pi;
4834 | header_field_info *hfinfo;
4835 | int item_length;
4836 |
4837 | 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", 4837, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4837, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4837, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4838 | get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4839 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4840 |
4841 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4842 |
4843 | 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", 4843 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4843, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4843, "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", 4843, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4844 |
4845 | 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", 4845, ((hfinfo))->abbrev))));
4846 |
4847 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4848 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4849 |
4850 | return pi;
4851 | }
4852 |
4853 | proto_item *
4854 | proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4855 | int start, int length,
4856 | const uint8_t *start_ptr,
4857 | const char *format, ...)
4858 | {
4859 | proto_item *pi;
4860 | va_list ap;
4861 |
4862 | if (start_ptr == NULL((void*)0))
4863 | start_ptr = tvb_get_ptr(tvb, start, length);
4864 |
4865 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4866 |
4867 | 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; };
4868 |
4869 | va_start(ap, format)__builtin_va_start(ap, format);
4870 | proto_tree_set_representation_value(pi, format, ap);
4871 | va_end(ap)__builtin_va_end(ap);
4872 |
4873 | return pi;
4874 | }
4875 |
4876 | proto_item *
4877 | proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4878 | int start, int length, const uint8_t *start_ptr,
4879 | const char *format, ...)
4880 | {
4881 | proto_item *pi;
4882 | va_list ap;
4883 |
4884 | if (start_ptr == NULL((void*)0))
4885 | start_ptr = tvb_get_ptr(tvb, start, length);
4886 |
4887 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4888 |
4889 | 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; };
4890 |
4891 | va_start(ap, format)__builtin_va_start(ap, format);
4892 | proto_tree_set_representation(pi, format, ap);
4893 | va_end(ap)__builtin_va_end(ap);
4894 |
4895 | return pi;
4896 | }
4897 |
4898 | static void
4899 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4900 | {
4901 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4901, "length >= 0" ))));
4902 | 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", 4902, "start_ptr != ((void*)0) || length == 0" ))));
4903 |
4904 | fvalue_set_bytes_data(fi->value, start_ptr, length);
4905 | }
4906 |
4907 |
4908 | static void
4909 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4910 | {
4911 | tvb_ensure_bytes_exist(tvb, offset, length);
4912 | proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4913 | }
4914 |
4915 | static void
4916 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4917 | {
4918 | GByteArray *bytes;
4919 |
4920 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4920, "value != ((void*)0)" ))));
4921 |
4922 | bytes = byte_array_dup(value);
4923 |
4924 | fvalue_set_byte_array(fi->value, bytes);
4925 | }
4926 |
4927 | /* Add a FT_*TIME to a proto_tree */
4928 | proto_item *
4929 | proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4930 | int length, const nstime_t *value_ptr)
4931 | {
4932 | proto_item *pi;
4933 | header_field_info *hfinfo;
4934 |
4935 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4936 |
4937 | TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4937 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4937, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4937, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4937, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
4938 |
4939 | DISSECTOR_ASSERT_FIELD_TYPE_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", 4939, ((hfinfo))->abbrev))));
4940 |
4941 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4942 | proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4943 |
4944 | return pi;
4945 | }
4946 |
4947 | proto_item *
4948 | proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4949 | int start, int length, nstime_t *value_ptr,
4950 | const char *format, ...)
4951 | {
4952 | proto_item *pi;
4953 | va_list ap;
4954 |
4955 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4956 | if (pi != tree) {
4957 | va_start(ap, format)__builtin_va_start(ap, format);
4958 | proto_tree_set_representation_value(pi, format, ap);
4959 | va_end(ap)__builtin_va_end(ap);
4960 | }
4961 |
4962 | return pi;
4963 | }
4964 |
4965 | proto_item *
4966 | proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4967 | int start, int length, nstime_t *value_ptr,
4968 | const char *format, ...)
4969 | {
4970 | proto_item *pi;
4971 | va_list ap;
4972 |
4973 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4974 | if (pi != tree) {
4975 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4975, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4976 |
4977 | va_start(ap, format)__builtin_va_start(ap, format);
4978 | proto_tree_set_representation(pi, format, ap);
4979 | va_end(ap)__builtin_va_end(ap);
4980 | }
4981 |
4982 | return pi;
4983 | }
4984 |
4985 | /* Set the FT_*TIME value */
4986 | static void
4987 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4988 | {
4989 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4989, "value_ptr != ((void*)0)" ))));
4990 |
4991 | fvalue_set_time(fi->value, value_ptr);
4992 | }
4993 |
4994 | /* Add a FT_IPXNET to a proto_tree */
4995 | proto_item *
4996 | proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4997 | int length, uint32_t value)
4998 | {
4999 | proto_item *pi;
5000 | header_field_info *hfinfo;
5001 |
5002 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5003 |
5004 | 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", 5004 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5004, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5004, "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", 5004, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5005 |
5006 | 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" , 5006, ((hfinfo))->abbrev))));
5007 |
5008 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5009 | proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5010 |
5011 | return pi;
5012 | }
5013 |
5014 | proto_item *
5015 | proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5016 | int start, int length, uint32_t value,
5017 | const char *format, ...)
5018 | {
5019 | proto_item *pi;
5020 | va_list ap;
5021 |
5022 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5023 | if (pi != tree) {
5024 | va_start(ap, format)__builtin_va_start(ap, format);
5025 | proto_tree_set_representation_value(pi, format, ap);
5026 | va_end(ap)__builtin_va_end(ap);
5027 | }
5028 |
5029 | return pi;
5030 | }
5031 |
5032 | proto_item *
5033 | proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5034 | int start, int length, uint32_t value,
5035 | const char *format, ...)
5036 | {
5037 | proto_item *pi;
5038 | va_list ap;
5039 |
5040 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5041 | if (pi != tree) {
5042 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5042, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5043 |
5044 | va_start(ap, format)__builtin_va_start(ap, format);
5045 | proto_tree_set_representation(pi, format, ap);
5046 | va_end(ap)__builtin_va_end(ap);
5047 | }
5048 |
5049 | return pi;
5050 | }
5051 |
5052 | /* Set the FT_IPXNET value */
5053 | static void
5054 | proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5055 | {
5056 | fvalue_set_uinteger(fi->value, value);
5057 | }
5058 |
5059 | /* Add a FT_IPv4 to a proto_tree */
5060 | proto_item *
5061 | proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5062 | int length, ws_in4_addr value)
5063 | {
5064 | proto_item *pi;
5065 | header_field_info *hfinfo;
5066 |
5067 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5068 |
5069 | 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", 5069 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5069, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5069, "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", 5069, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5070 |
5071 | 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", 5071 , ((hfinfo))->abbrev))));
5072 |
5073 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5074 | proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5075 |
5076 | return pi;
5077 | }
5078 |
5079 | proto_item *
5080 | proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5081 | int start, int length, ws_in4_addr value,
5082 | const char *format, ...)
5083 | {
5084 | proto_item *pi;
5085 | va_list ap;
5086 |
5087 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5088 | if (pi != tree) {
5089 | va_start(ap, format)__builtin_va_start(ap, format);
5090 | proto_tree_set_representation_value(pi, format, ap);
5091 | va_end(ap)__builtin_va_end(ap);
5092 | }
5093 |
5094 | return pi;
5095 | }
5096 |
5097 | proto_item *
5098 | proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5099 | int start, int length, ws_in4_addr value,
5100 | const char *format, ...)
5101 | {
5102 | proto_item *pi;
5103 | va_list ap;
5104 |
5105 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5106 | if (pi != tree) {
5107 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5107, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5108 |
5109 | va_start(ap, format)__builtin_va_start(ap, format);
5110 | proto_tree_set_representation(pi, format, ap);
5111 | va_end(ap)__builtin_va_end(ap);
5112 | }
5113 |
5114 | return pi;
5115 | }
5116 |
5117 | /* Set the FT_IPv4 value */
5118 | static void
5119 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5120 | {
5121 | ipv4_addr_and_mask ipv4;
5122 | ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5123 | fvalue_set_ipv4(fi->value, &ipv4);
5124 | }
5125 |
5126 | /* Add a FT_IPv6 to a proto_tree */
5127 | proto_item *
5128 | proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5129 | int length, const ws_in6_addr *value)
5130 | {
5131 | proto_item *pi;
5132 | header_field_info *hfinfo;
5133 |
5134 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5135 |
5136 | 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", 5136 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5136, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5136, "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", 5136, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5137 |
5138 | 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", 5138 , ((hfinfo))->abbrev))));
5139 |
5140 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5141 | proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5142 |
5143 | return pi;
5144 | }
5145 |
5146 | proto_item *
5147 | proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5148 | int start, int length,
5149 | const ws_in6_addr *value_ptr,
5150 | const char *format, ...)
5151 | {
5152 | proto_item *pi;
5153 | va_list ap;
5154 |
5155 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5156 | if (pi != tree) {
5157 | va_start(ap, format)__builtin_va_start(ap, format);
5158 | proto_tree_set_representation_value(pi, format, ap);
5159 | va_end(ap)__builtin_va_end(ap);
5160 | }
5161 |
5162 | return pi;
5163 | }
5164 |
5165 | proto_item *
5166 | proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5167 | int start, int length,
5168 | const ws_in6_addr *value_ptr,
5169 | const char *format, ...)
5170 | {
5171 | proto_item *pi;
5172 | va_list ap;
5173 |
5174 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5175 | if (pi != tree) {
5176 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5176, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5177 |
5178 | va_start(ap, format)__builtin_va_start(ap, format);
5179 | proto_tree_set_representation(pi, format, ap);
5180 | va_end(ap)__builtin_va_end(ap);
5181 | }
5182 |
5183 | return pi;
5184 | }
5185 |
5186 | /* Set the FT_IPv6 value */
5187 | static void
5188 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5189 | {
5190 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5190, "value != ((void*)0)" ))));
5191 | ipv6_addr_and_prefix ipv6;
5192 | ipv6.addr = *value;
5193 | ipv6.prefix = 128;
5194 | fvalue_set_ipv6(fi->value, &ipv6);
5195 | }
5196 |
5197 | static void
5198 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5199 | {
5200 | proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5201 | }
5202 |
5203 | /* Set the FT_FCWWN value */
5204 | static void
5205 | proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5206 | {
5207 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5207, "value_ptr != ((void*)0)" ))));
5208 | fvalue_set_fcwwn(fi->value, value_ptr);
5209 | }
5210 |
5211 | static void
5212 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5213 | {
5214 | proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5215 | }
5216 |
5217 | /* Add a FT_GUID to a proto_tree */
5218 | proto_item *
5219 | proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5220 | int length, const e_guid_t *value_ptr)
5221 | {
5222 | proto_item *pi;
5223 | header_field_info *hfinfo;
5224 |
5225 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5226 |
5227 | 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", 5227 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5227, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5227, "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", 5227, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5228 |
5229 | 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", 5229 , ((hfinfo))->abbrev))));
5230 |
5231 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5232 | proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5233 |
5234 | return pi;
5235 | }
5236 |
5237 | proto_item *
5238 | proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5239 | int start, int length,
5240 | const e_guid_t *value_ptr,
5241 | const char *format, ...)
5242 | {
5243 | proto_item *pi;
5244 | va_list ap;
5245 |
5246 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5247 | if (pi != tree) {
5248 | va_start(ap, format)__builtin_va_start(ap, format);
5249 | proto_tree_set_representation_value(pi, format, ap);
5250 | va_end(ap)__builtin_va_end(ap);
5251 | }
5252 |
5253 | return pi;
5254 | }
5255 |
5256 | proto_item *
5257 | proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5258 | int start, int length, const e_guid_t *value_ptr,
5259 | const char *format, ...)
5260 | {
5261 | proto_item *pi;
5262 | va_list ap;
5263 |
5264 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5265 | if (pi != tree) {
5266 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5266, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5267 |
5268 | va_start(ap, format)__builtin_va_start(ap, format);
5269 | proto_tree_set_representation(pi, format, ap);
5270 | va_end(ap)__builtin_va_end(ap);
5271 | }
5272 |
5273 | return pi;
5274 | }
5275 |
5276 | /* Set the FT_GUID value */
5277 | static void
5278 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5279 | {
5280 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5280, "value_ptr != ((void*)0)" ))));
5281 | fvalue_set_guid(fi->value, value_ptr);
5282 | }
5283 |
5284 | static void
5285 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5286 | const unsigned encoding)
5287 | {
5288 | e_guid_t guid;
5289 |
5290 | tvb_get_guid(tvb, start, &guid, encoding);
5291 | proto_tree_set_guid(fi, &guid);
5292 | }
5293 |
5294 | /* Add a FT_OID to a proto_tree */
5295 | proto_item *
5296 | proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5297 | int length, const uint8_t* value_ptr)
5298 | {
5299 | proto_item *pi;
5300 | header_field_info *hfinfo;
5301 |
5302 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5303 |
5304 | 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", 5304 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5304, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5304, "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", 5304, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5305 |
5306 | 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", 5306 , ((hfinfo))->abbrev))));
5307 |
5308 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5309 | proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5310 |
5311 | return pi;
5312 | }
5313 |
5314 | proto_item *
5315 | proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5316 | int start, int length,
5317 | const uint8_t* value_ptr,
5318 | const char *format, ...)
5319 | {
5320 | proto_item *pi;
5321 | va_list ap;
5322 |
5323 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5324 | if (pi != tree) {
5325 | va_start(ap, format)__builtin_va_start(ap, format);
5326 | proto_tree_set_representation_value(pi, format, ap);
5327 | va_end(ap)__builtin_va_end(ap);
5328 | }
5329 |
5330 | return pi;
5331 | }
5332 |
5333 | proto_item *
5334 | proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5335 | int start, int length, const uint8_t* value_ptr,
5336 | const char *format, ...)
5337 | {
5338 | proto_item *pi;
5339 | va_list ap;
5340 |
5341 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5342 | if (pi != tree) {
5343 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5343, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5344 |
5345 | va_start(ap, format)__builtin_va_start(ap, format);
5346 | proto_tree_set_representation(pi, format, ap);
5347 | va_end(ap)__builtin_va_end(ap);
5348 | }
5349 |
5350 | return pi;
5351 | }
5352 |
5353 | /* Set the FT_OID value */
5354 | static void
5355 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5356 | {
5357 | GByteArray *bytes;
5358 |
5359 | 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", 5359, "value_ptr != ((void*)0) || length == 0" ))));
5360 |
5361 | bytes = g_byte_array_new();
5362 | if (length > 0) {
5363 | g_byte_array_append(bytes, value_ptr, length);
5364 | }
5365 | fvalue_set_byte_array(fi->value, bytes);
5366 | }
5367 |
5368 | static void
5369 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5370 | {
5371 | proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5372 | }
5373 |
5374 | /* Set the FT_SYSTEM_ID value */
5375 | static void
5376 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5377 | {
5378 | GByteArray *bytes;
5379 |
5380 | 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", 5380, "value_ptr != ((void*)0) || length == 0" ))));
5381 |
5382 | bytes = g_byte_array_new();
5383 | if (length > 0) {
5384 | g_byte_array_append(bytes, value_ptr, length);
5385 | }
5386 | fvalue_set_byte_array(fi->value, bytes);
5387 | }
5388 |
5389 | static void
5390 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5391 | {
5392 | proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5393 | }
5394 |
5395 | /* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5396 | * proto_tree. Creates own copy of string, and frees it when the proto_tree
5397 | * is destroyed. */
5398 | proto_item *
5399 | proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5400 | int length, const char* value)
5401 | {
5402 | proto_item *pi;
5403 | header_field_info *hfinfo;
5404 | int item_length;
5405 |
5406 | 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", 5406, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5406, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5406, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
5407 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5408 | /*
5409 | * Special case - if the length is 0, skip the test, so that
5410 | * we can have an empty string right after the end of the
5411 | * packet. (This handles URL-encoded forms where the last field
5412 | * has no value so the form ends right after the =.)
5413 | */
5414 | if (item_length != 0)
5415 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5416 |
5417 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5418 |
5419 | 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", 5419 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5419, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5419, "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", 5419, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5420 |
5421 | 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", 5421, ((hfinfo))->abbrev))));
5422 |
5423 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5424 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5424, "length >= 0" ))));
5425 |
5426 | 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", 5426, __func__, value, -1, __uni_endptr); } } while (0); } } while (0);
5427 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5428 |
5429 | return pi;
5430 | }
5431 |
5432 | proto_item *
5433 | proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5434 | int start, int length, const char* value,
5435 | const char *format,
5436 | ...)
5437 | {
5438 | proto_item *pi;
5439 | va_list ap;
5440 |
5441 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5442 | if (pi != tree) {
5443 | va_start(ap, format)__builtin_va_start(ap, format);
5444 | proto_tree_set_representation_value(pi, format, ap);
5445 | va_end(ap)__builtin_va_end(ap);
5446 | }
5447 |
5448 | return pi;
5449 | }
5450 |
5451 | proto_item *
5452 | proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5453 | int start, int length, const char* value,
5454 | const char *format, ...)
5455 | {
5456 | proto_item *pi;
5457 | va_list ap;
5458 |
5459 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5460 | if (pi != tree) {
5461 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5461, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5462 |
5463 | va_start(ap, format)__builtin_va_start(ap, format);
5464 | proto_tree_set_representation(pi, format, ap);
5465 | va_end(ap)__builtin_va_end(ap);
5466 | }
5467 |
5468 | return pi;
5469 | }
5470 |
5471 | /* Set the FT_STRING value */
5472 | static void
5473 | proto_tree_set_string(field_info *fi, const char* value)
5474 | {
5475 | if (value) {
5476 | fvalue_set_string(fi->value, value);
5477 | } else {
5478 | /*
5479 | * XXX - why is a null value for a string field
5480 | * considered valid?
5481 | */
5482 | fvalue_set_string(fi->value, "[ Null ]");
5483 | }
5484 | }
5485 |
5486 | /* Set the FT_AX25 value */
5487 | static void
5488 | proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5489 | {
5490 | fvalue_set_ax25(fi->value, value);
5491 | }
5492 |
5493 | static void
5494 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5495 | {
5496 | proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5497 | }
5498 |
5499 | /* Set the FT_VINES value */
5500 | static void
5501 | proto_tree_set_vines(field_info *fi, const uint8_t* value)
5502 | {
5503 | fvalue_set_vines(fi->value, value);
5504 | }
5505 |
5506 | static void
5507 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5508 | {
5509 | proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5510 | }
5511 |
5512 | /* Add a FT_ETHER to a proto_tree */
5513 | proto_item *
5514 | proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5515 | int length, const uint8_t* value)
5516 | {
5517 | proto_item *pi;
5518 | header_field_info *hfinfo;
5519 |
5520 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5521 |
5522 | 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", 5522 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5522, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5522, "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", 5522, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5523 |
5524 | 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", 5524, ((hfinfo))->abbrev))));
5525 |
5526 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5527 | proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5528 |
5529 | return pi;
5530 | }
5531 |
5532 | proto_item *
5533 | proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5534 | int start, int length, const uint8_t* value,
5535 | const char *format, ...)
5536 | {
5537 | proto_item *pi;
5538 | va_list ap;
5539 |
5540 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5541 | if (pi != tree) {
5542 | va_start(ap, format)__builtin_va_start(ap, format);
5543 | proto_tree_set_representation_value(pi, format, ap);
5544 | va_end(ap)__builtin_va_end(ap);
5545 | }
5546 |
5547 | return pi;
5548 | }
5549 |
5550 | proto_item *
5551 | proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5552 | int start, int length, const uint8_t* value,
5553 | const char *format, ...)
5554 | {
5555 | proto_item *pi;
5556 | va_list ap;
5557 |
5558 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5559 | if (pi != tree) {
5560 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5560, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5561 |
5562 | va_start(ap, format)__builtin_va_start(ap, format);
5563 | proto_tree_set_representation(pi, format, ap);
5564 | va_end(ap)__builtin_va_end(ap);
5565 | }
5566 |
5567 | return pi;
5568 | }
5569 |
5570 | /* Set the FT_ETHER value */
5571 | static void
5572 | proto_tree_set_ether(field_info *fi, const uint8_t* value)
5573 | {
5574 | fvalue_set_ether(fi->value, value);
5575 | }
5576 |
5577 | static void
5578 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5579 | {
5580 | proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5581 | }
5582 |
5583 | /* Add a FT_BOOLEAN to a proto_tree */
5584 | proto_item *
5585 | proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5586 | int length, uint64_t value)
5587 | {
5588 | proto_item *pi;
5589 | header_field_info *hfinfo;
5590 |
5591 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5592 |
5593 | 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", 5593 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5593, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5593, "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", 5593, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5594 |
5595 | 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" , 5595, ((hfinfo))->abbrev))));
5596 |
5597 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5598 | proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5599 |
5600 | return pi;
5601 | }
5602 |
5603 | proto_item *
5604 | proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5605 | tvbuff_t *tvb, int start, int length,
5606 | uint64_t value, const char *format, ...)
5607 | {
5608 | proto_item *pi;
5609 | va_list ap;
5610 |
5611 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5612 | if (pi != tree) {
5613 | va_start(ap, format)__builtin_va_start(ap, format);
5614 | proto_tree_set_representation_value(pi, format, ap);
5615 | va_end(ap)__builtin_va_end(ap);
5616 | }
5617 |
5618 | return pi;
5619 | }
5620 |
5621 | proto_item *
5622 | proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5623 | int start, int length, uint64_t value,
5624 | const char *format, ...)
5625 | {
5626 | proto_item *pi;
5627 | va_list ap;
5628 |
5629 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5630 | if (pi != tree) {
5631 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5631, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5632 |
5633 | va_start(ap, format)__builtin_va_start(ap, format);
5634 | proto_tree_set_representation(pi, format, ap);
5635 | va_end(ap)__builtin_va_end(ap);
5636 | }
5637 |
5638 | return pi;
5639 | }
5640 |
5641 | /* Set the FT_BOOLEAN value */
5642 | static void
5643 | proto_tree_set_boolean(field_info *fi, uint64_t value)
5644 | {
5645 | proto_tree_set_uint64(fi, value);
5646 | }
5647 |
5648 | /* Generate, into "buf", a string showing the bits of a bitfield.
5649 | Return a pointer to the character after that string. */
5650 | static char *
5651 | other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5652 | {
5653 | int i = 0;
5654 | uint64_t bit;
5655 | char *p;
5656 |
5657 | p = buf;
5658 |
5659 | /* This is a devel error. It is safer to stop here. */
5660 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5660, "width >= 1" ))));
5661 |
5662 | bit = UINT64_C(1)1UL << (width - 1);
5663 | for (;;) {
5664 | if (mask & bit) {
5665 | /* This bit is part of the field. Show its value. */
5666 | if (val & bit)
5667 | *p++ = '1';
5668 | else
5669 | *p++ = '0';
5670 | } else {
5671 | /* This bit is not part of the field. */
5672 | *p++ = '.';
5673 | }
5674 | bit >>= 1;
5675 | i++;
5676 | if (i >= width)
5677 | break;
5678 | if (i % 4 == 0)
5679 | *p++ = ' ';
5680 | }
5681 | *p = '\0';
5682 | return p;
5683 | }
5684 |
5685 | static char *
5686 | decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5687 | {
5688 | char *p;
5689 |
5690 | p = other_decode_bitfield_value(buf, val, mask, width);
5691 | p = g_stpcpy(p, " = ");
5692 |
5693 | return p;
5694 | }
5695 |
5696 | static char *
5697 | other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5698 | {
5699 | int i = 0;
5700 | uint64_t bit;
5701 | char *p;
5702 |
5703 | p = buf;
5704 |
5705 | /* This is a devel error. It is safer to stop here. */
5706 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5706, "width >= 1" ))));
5707 |
5708 | bit = UINT64_C(1)1UL << (width - 1);
5709 | for (;;) {
5710 | if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5711 | (mask & bit)) {
5712 | /* This bit is part of the field. Show its value. */
5713 | if (val & bit)
5714 | *p++ = '1';
5715 | else
5716 | *p++ = '0';
5717 | } else {
5718 | /* This bit is not part of the field. */
5719 | *p++ = '.';
5720 | }
5721 | bit >>= 1;
5722 | i++;
5723 | if (i >= width)
5724 | break;
5725 | if (i % 4 == 0)
5726 | *p++ = ' ';
5727 | }
5728 |
5729 | *p = '\0';
5730 | return p;
5731 | }
5732 |
5733 | static char *
5734 | decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5735 | {
5736 | char *p;
5737 |
5738 | p = other_decode_bitfield_varint_value(buf, val, mask, width);
5739 | p = g_stpcpy(p, " = ");
5740 |
5741 | return p;
5742 | }
5743 |
5744 | /* Add a FT_FLOAT to a proto_tree */
5745 | proto_item *
5746 | proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5747 | int length, float value)
5748 | {
5749 | proto_item *pi;
5750 | header_field_info *hfinfo;
5751 |
5752 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5753 |
5754 | 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", 5754 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5754, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5754, "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", 5754, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5755 |
5756 | 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", 5756, ((hfinfo))->abbrev))));
5757 |
5758 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5759 | proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5760 |
5761 | return pi;
5762 | }
5763 |
5764 | proto_item *
5765 | proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5766 | int start, int length, float value,
5767 | const char *format, ...)
5768 | {
5769 | proto_item *pi;
5770 | va_list ap;
5771 |
5772 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5773 | if (pi != tree) {
5774 | va_start(ap, format)__builtin_va_start(ap, format);
5775 | proto_tree_set_representation_value(pi, format, ap);
5776 | va_end(ap)__builtin_va_end(ap);
5777 | }
5778 |
5779 | return pi;
5780 | }
5781 |
5782 | proto_item *
5783 | proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5784 | int start, int length, float value,
5785 | const char *format, ...)
5786 | {
5787 | proto_item *pi;
5788 | va_list ap;
5789 |
5790 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5791 | if (pi != tree) {
5792 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5792, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5793 |
5794 | va_start(ap, format)__builtin_va_start(ap, format);
5795 | proto_tree_set_representation(pi, format, ap);
5796 | va_end(ap)__builtin_va_end(ap);
5797 | }
5798 |
5799 | return pi;
5800 | }
5801 |
5802 | /* Set the FT_FLOAT value */
5803 | static void
5804 | proto_tree_set_float(field_info *fi, float value)
5805 | {
5806 | fvalue_set_floating(fi->value, value);
5807 | }
5808 |
5809 | /* Add a FT_DOUBLE to a proto_tree */
5810 | proto_item *
5811 | proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5812 | int length, double value)
5813 | {
5814 | proto_item *pi;
5815 | header_field_info *hfinfo;
5816 |
5817 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5818 |
5819 | 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", 5819 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5819, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5819, "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", 5819, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5820 |
5821 | 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" , 5821, ((hfinfo))->abbrev))));
5822 |
5823 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5824 | proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5825 |
5826 | return pi;
5827 | }
5828 |
5829 | proto_item *
5830 | proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5831 | int start, int length, double value,
5832 | const char *format, ...)
5833 | {
5834 | proto_item *pi;
5835 | va_list ap;
5836 |
5837 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5838 | if (pi != tree) {
5839 | va_start(ap, format)__builtin_va_start(ap, format);
5840 | proto_tree_set_representation_value(pi, format, ap);
5841 | va_end(ap)__builtin_va_end(ap);
5842 | }
5843 |
5844 | return pi;
5845 | }
5846 |
5847 | proto_item *
5848 | proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5849 | int start, int length, double value,
5850 | const char *format, ...)
5851 | {
5852 | proto_item *pi;
5853 | va_list ap;
5854 |
5855 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5856 | if (pi != tree) {
5857 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5857, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5858 |
5859 | va_start(ap, format)__builtin_va_start(ap, format);
5860 | proto_tree_set_representation(pi, format, ap);
5861 | va_end(ap)__builtin_va_end(ap);
5862 | }
5863 |
5864 | return pi;
5865 | }
5866 |
5867 | /* Set the FT_DOUBLE value */
5868 | static void
5869 | proto_tree_set_double(field_info *fi, double value)
5870 | {
5871 | fvalue_set_floating(fi->value, value);
5872 | }
5873 |
5874 | /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5875 | proto_item *
5876 | proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5877 | int length, uint32_t value)
5878 | {
5879 | proto_item *pi = NULL((void*)0);
5880 | header_field_info *hfinfo;
5881 |
5882 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5883 |
5884 | 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", 5884 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5884, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5884, "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", 5884, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5885 |
5886 | switch (hfinfo->type) {
5887 | case FT_CHAR:
5888 | case FT_UINT8:
5889 | case FT_UINT16:
5890 | case FT_UINT24:
5891 | case FT_UINT32:
5892 | case FT_FRAMENUM:
5893 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5894 | proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5895 | break;
5896 |
5897 | default:
5898 | 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)
5899 | 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);
5900 | }
5901 |
5902 | return pi;
5903 | }
5904 |
5905 | proto_item *
5906 | proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5907 | int start, int length, uint32_t value,
5908 | const char *format, ...)
5909 | {
5910 | proto_item *pi;
5911 | va_list ap;
5912 |
5913 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5914 | if (pi != tree) {
5915 | va_start(ap, format)__builtin_va_start(ap, format);
5916 | proto_tree_set_representation_value(pi, format, ap);
5917 | va_end(ap)__builtin_va_end(ap);
5918 | }
5919 |
5920 | return pi;
5921 | }
5922 |
5923 | proto_item *
5924 | proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5925 | int start, int length, uint32_t value,
5926 | const char *format, ...)
5927 | {
5928 | proto_item *pi;
5929 | va_list ap;
5930 |
5931 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5932 | if (pi != tree) {
5933 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5933, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5934 |
5935 | va_start(ap, format)__builtin_va_start(ap, format);
5936 | proto_tree_set_representation(pi, format, ap);
5937 | va_end(ap)__builtin_va_end(ap);
5938 | }
5939 |
5940 | return pi;
5941 | }
5942 |
5943 | /* Set the FT_UINT{8,16,24,32} value */
5944 | static void
5945 | proto_tree_set_uint(field_info *fi, uint32_t value)
5946 | {
5947 | const header_field_info *hfinfo;
5948 | uint32_t integer;
5949 |
5950 | hfinfo = fi->hfinfo;
5951 | integer = value;
5952 |
5953 | if (hfinfo->bitmask) {
5954 | /* Mask out irrelevant portions */
5955 | integer &= (uint32_t)(hfinfo->bitmask);
5956 |
5957 | /* Shift bits */
5958 | integer >>= hfinfo_bitshift(hfinfo);
5959 |
5960 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
5961 | 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);
5962 | }
5963 |
5964 | fvalue_set_uinteger(fi->value, integer);
5965 | }
5966 |
5967 | /* Add FT_UINT{40,48,56,64} to a proto_tree */
5968 | proto_item *
5969 | proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5970 | int length, uint64_t value)
5971 | {
5972 | proto_item *pi = NULL((void*)0);
5973 | header_field_info *hfinfo;
5974 |
5975 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5976 |
5977 | TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5977 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5977, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5977, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 5977, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } };
5978 |
5979 | switch (hfinfo->type) {
5980 | case FT_UINT40:
5981 | case FT_UINT48:
5982 | case FT_UINT56:
5983 | case FT_UINT64:
5984 | case FT_FRAMENUM:
5985 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5986 | proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5987 | break;
5988 |
5989 | default:
5990 | 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)
5991 | 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);
5992 | }
5993 |
5994 | return pi;
5995 | }
5996 |
5997 | proto_item *
5998 | proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5999 | int start, int length, uint64_t value,
6000 | const char *format, ...)
6001 | {
6002 | proto_item *pi;
6003 | va_list ap;
6004 |
6005 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6006 | if (pi != tree) {
6007 | va_start(ap, format)__builtin_va_start(ap, format);
6008 | proto_tree_set_representation_value(pi, format, ap);
6009 | va_end(ap)__builtin_va_end(ap);
6010 | }
6011 |
6012 | return pi;
6013 | }
6014 |
6015 | proto_item *
6016 | proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6017 | int start, int length, uint64_t value,
6018 | const char *format, ...)
6019 | {
6020 | proto_item *pi;
6021 | va_list ap;
6022 |
6023 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6024 | if (pi != tree) {
6025 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6025, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6026 |
6027 | va_start(ap, format)__builtin_va_start(ap, format);
6028 | proto_tree_set_representation(pi, format, ap);
6029 | va_end(ap)__builtin_va_end(ap);
6030 | }
6031 |
6032 | return pi;
6033 | }
6034 |
6035 | /* Set the FT_UINT{40,48,56,64} value */
6036 | static void
6037 | proto_tree_set_uint64(field_info *fi, uint64_t value)
6038 | {
6039 | const header_field_info *hfinfo;
6040 | uint64_t integer;
6041 |
6042 | hfinfo = fi->hfinfo;
6043 | integer = value;
6044 |
6045 | if (hfinfo->bitmask) {
6046 | /* Mask out irrelevant portions */
6047 | integer &= hfinfo->bitmask;
6048 |
6049 | /* Shift bits */
6050 | integer >>= hfinfo_bitshift(hfinfo);
6051 |
6052 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6053 | 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);
6054 | }
6055 |
6056 | fvalue_set_uinteger64(fi->value, integer);
6057 | }
6058 |
6059 | /* Add FT_INT{8,16,24,32} to a proto_tree */
6060 | proto_item *
6061 | proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6062 | int length, int32_t value)
6063 | {
6064 | proto_item *pi = NULL((void*)0);
6065 | header_field_info *hfinfo;
6066 |
6067 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6068 |
6069 | 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", 6069 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6069, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6069, "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", 6069, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6070 |
6071 | switch (hfinfo->type) {
6072 | case FT_INT8:
6073 | case FT_INT16:
6074 | case FT_INT24:
6075 | case FT_INT32:
6076 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6077 | proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6078 | break;
6079 |
6080 | default:
6081 | 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)
6082 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
6083 | }
6084 |
6085 | return pi;
6086 | }
6087 |
6088 | proto_item *
6089 | proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6090 | int start, int length, int32_t value,
6091 | const char *format, ...)
6092 | {
6093 | proto_item *pi;
6094 | va_list ap;
6095 |
6096 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6097 | if (pi != tree) {
6098 | va_start(ap, format)__builtin_va_start(ap, format);
6099 | proto_tree_set_representation_value(pi, format, ap);
6100 | va_end(ap)__builtin_va_end(ap);
6101 | }
6102 |
6103 | return pi;
6104 | }
6105 |
6106 | proto_item *
6107 | proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6108 | int start, int length, int32_t value,
6109 | const char *format, ...)
6110 | {
6111 | proto_item *pi;
6112 | va_list ap;
6113 |
6114 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6115 | if (pi != tree) {
6116 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6116, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6117 |
6118 | va_start(ap, format)__builtin_va_start(ap, format);
6119 | proto_tree_set_representation(pi, format, ap);
6120 | va_end(ap)__builtin_va_end(ap);
6121 | }
6122 |
6123 | return pi;
6124 | }
6125 |
6126 | /* Set the FT_INT{8,16,24,32} value */
6127 | static void
6128 | proto_tree_set_int(field_info *fi, int32_t value)
6129 | {
6130 | const header_field_info *hfinfo;
6131 | uint32_t integer;
6132 | int no_of_bits;
6133 |
6134 | hfinfo = fi->hfinfo;
6135 | integer = (uint32_t) value;
6136 |
6137 | if (hfinfo->bitmask) {
6138 | /* Mask out irrelevant portions */
6139 | integer &= (uint32_t)(hfinfo->bitmask);
6140 |
6141 | /* Shift bits */
6142 | integer >>= hfinfo_bitshift(hfinfo);
6143 |
6144 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6145 | integer = ws_sign_ext32(integer, no_of_bits);
6146 |
6147 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6148 | 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);
6149 | }
6150 |
6151 | fvalue_set_sinteger(fi->value, integer);
6152 | }
6153 |
6154 | /* Add FT_INT{40,48,56,64} to a proto_tree */
6155 | proto_item *
6156 | proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6157 | int length, int64_t value)
6158 | {
6159 | proto_item *pi = NULL((void*)0);
6160 | header_field_info *hfinfo;
6161 |
6162 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6163 |
6164 | 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", 6164 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6164, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6164, "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", 6164, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6165 |
6166 | switch (hfinfo->type) {
6167 | case FT_INT40:
6168 | case FT_INT48:
6169 | case FT_INT56:
6170 | case FT_INT64:
6171 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6172 | proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6173 | break;
6174 |
6175 | default:
6176 | 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)
6177 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
6178 | }
6179 |
6180 | return pi;
6181 | }
6182 |
6183 | proto_item *
6184 | proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6185 | int start, int length, int64_t value,
6186 | const char *format, ...)
6187 | {
6188 | proto_item *pi;
6189 | va_list ap;
6190 |
6191 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6192 | if (pi != tree) {
6193 | va_start(ap, format)__builtin_va_start(ap, format);
6194 | proto_tree_set_representation_value(pi, format, ap);
6195 | va_end(ap)__builtin_va_end(ap);
6196 | }
6197 |
6198 | return pi;
6199 | }
6200 |
6201 | /* Set the FT_INT{40,48,56,64} value */
6202 | static void
6203 | proto_tree_set_int64(field_info *fi, int64_t value)
6204 | {
6205 | const header_field_info *hfinfo;
6206 | uint64_t integer;
6207 | int no_of_bits;
6208 |
6209 | hfinfo = fi->hfinfo;
6210 | integer = value;
6211 |
6212 | if (hfinfo->bitmask) {
6213 | /* Mask out irrelevant portions */
6214 | integer &= hfinfo->bitmask;
6215 |
6216 | /* Shift bits */
6217 | integer >>= hfinfo_bitshift(hfinfo);
6218 |
6219 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6220 | integer = ws_sign_ext64(integer, no_of_bits);
6221 |
6222 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6223 | 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);
6224 | }
6225 |
6226 | fvalue_set_sinteger64(fi->value, integer);
6227 | }
6228 |
6229 | proto_item *
6230 | proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6231 | int start, int length, int64_t value,
6232 | const char *format, ...)
6233 | {
6234 | proto_item *pi;
6235 | va_list ap;
6236 |
6237 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6238 | if (pi != tree) {
6239 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6239, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6240 |
6241 | va_start(ap, format)__builtin_va_start(ap, format);
6242 | proto_tree_set_representation(pi, format, ap);
6243 | va_end(ap)__builtin_va_end(ap);
6244 | }
6245 |
6246 | return pi;
6247 | }
6248 |
6249 | /* Add a FT_EUI64 to a proto_tree */
6250 | proto_item *
6251 | proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6252 | int length, const uint64_t value)
6253 | {
6254 | proto_item *pi;
6255 | header_field_info *hfinfo;
6256 |
6257 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6258 |
6259 | 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", 6259 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6259, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6259, "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", 6259, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6260 |
6261 | 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", 6261, ((hfinfo))->abbrev))));
6262 |
6263 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6264 | proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6265 |
6266 | return pi;
6267 | }
6268 |
6269 | proto_item *
6270 | proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6271 | int start, int length, const uint64_t value,
6272 | const char *format, ...)
6273 | {
6274 | proto_item *pi;
6275 | va_list ap;
6276 |
6277 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6278 | if (pi != tree) {
6279 | va_start(ap, format)__builtin_va_start(ap, format);
6280 | proto_tree_set_representation_value(pi, format, ap);
6281 | va_end(ap)__builtin_va_end(ap);
6282 | }
6283 |
6284 | return pi;
6285 | }
6286 |
6287 | proto_item *
6288 | proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6289 | int start, int length, const uint64_t value,
6290 | const char *format, ...)
6291 | {
6292 | proto_item *pi;
6293 | va_list ap;
6294 |
6295 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6296 | if (pi != tree) {
6297 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6297, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6298 |
6299 | va_start(ap, format)__builtin_va_start(ap, format);
6300 | proto_tree_set_representation(pi, format, ap);
6301 | va_end(ap)__builtin_va_end(ap);
6302 | }
6303 |
6304 | return pi;
6305 | }
6306 |
6307 | /* Set the FT_EUI64 value */
6308 | static void
6309 | proto_tree_set_eui64(field_info *fi, const uint64_t value)
6310 | {
6311 | uint8_t v[FT_EUI64_LEN8];
6312 | phtonu64(v, value);
6313 | fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6314 | }
6315 |
6316 | static void
6317 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6318 | {
6319 | if (encoding)
6320 | {
6321 | proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6322 | } else {
6323 | proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6324 | }
6325 | }
6326 |
6327 | proto_item *
6328 | proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6329 | const mac_hf_list_t *list_generic,
6330 | int idx, tvbuff_t *tvb,
6331 | proto_tree *tree, int offset)
6332 | {
6333 | uint8_t addr[6];
6334 | const char *addr_name = NULL((void*)0);
6335 | const char *oui_name = NULL((void*)0);
6336 | proto_item *addr_item = NULL((void*)0);
6337 | proto_tree *addr_tree = NULL((void*)0);
6338 | proto_item *ret_val = NULL((void*)0);
6339 |
6340 | if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6341 | return NULL((void*)0);
6342 | }
6343 |
6344 | /* Resolve what we can of the address */
6345 | tvb_memcpy(tvb, addr, offset, sizeof addr);
6346 | if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6347 | addr_name = get_ether_name(addr);
6348 | }
6349 | if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6350 | oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6351 | }
6352 |
6353 | /* Add the item for the specific address type */
6354 | ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6355 | if (idx >= 0) {
6356 | addr_tree = proto_item_add_subtree(ret_val, idx);
6357 | }
6358 | else {
6359 | addr_tree = tree;
6360 | }
6361 |
6362 | if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6363 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6364 | tvb, offset, 6, addr_name);
6365 | proto_item_set_generated(addr_item);
6366 | proto_item_set_hidden(addr_item);
6367 | }
6368 |
6369 | if (list_specific->hf_oui != NULL((void*)0)) {
6370 | addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6371 | proto_item_set_generated(addr_item);
6372 | proto_item_set_hidden(addr_item);
6373 |
6374 | if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6375 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6376 | proto_item_set_generated(addr_item);
6377 | proto_item_set_hidden(addr_item);
6378 | }
6379 | }
6380 |
6381 | if (list_specific->hf_lg != NULL((void*)0)) {
6382 | proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6383 | }
6384 | if (list_specific->hf_ig != NULL((void*)0)) {
6385 | proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6386 | }
6387 |
6388 | /* Were we given a list for generic address fields? If not, stop here */
6389 | if (list_generic == NULL((void*)0)) {
6390 | return ret_val;
6391 | }
6392 |
6393 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6394 | proto_item_set_hidden(addr_item);
6395 |
6396 | if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6397 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6398 | tvb, offset, 6, addr_name);
6399 | proto_item_set_generated(addr_item);
6400 | proto_item_set_hidden(addr_item);
6401 | }
6402 |
6403 | if (list_generic->hf_oui != NULL((void*)0)) {
6404 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6405 | proto_item_set_generated(addr_item);
6406 | proto_item_set_hidden(addr_item);
6407 |
6408 | if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6409 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6410 | proto_item_set_generated(addr_item);
6411 | proto_item_set_hidden(addr_item);
6412 | }
6413 | }
6414 |
6415 | if (list_generic->hf_lg != NULL((void*)0)) {
6416 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6417 | proto_item_set_hidden(addr_item);
6418 | }
6419 | if (list_generic->hf_ig != NULL((void*)0)) {
6420 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6421 | proto_item_set_hidden(addr_item);
6422 | }
6423 | return ret_val;
6424 | }
6425 |
6426 | static proto_item *
6427 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6428 | {
6429 | proto_node *pnode, *tnode, *sibling;
6430 | field_info *tfi;
6431 | unsigned depth = 1;
6432 |
6433 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6433, __func__, "assertion failed: %s", "tree" ); } while (0);
6434 |
6435 | /*
6436 | * Restrict our depth. proto_tree_traverse_pre_order and
6437 | * proto_tree_traverse_post_order (and possibly others) are recursive
6438 | * so we need to be mindful of our stack size.
6439 | */
6440 | if (tree->first_child == NULL((void*)0)) {
6441 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6442 | depth++;
6443 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6444 | 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__)), 6447)))
6445 | "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__)), 6447)))
6446 | 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__)), 6447)))
6447 | 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__)), 6447)));
6448 | }
6449 | }
6450 | }
6451 |
6452 | /*
6453 | * Make sure "tree" is ready to have subtrees under it, by
6454 | * checking whether it's been given an ett_ value.
6455 | *
6456 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6457 | * node of the protocol tree. That node is not displayed,
6458 | * so it doesn't need an ett_ value to remember whether it
6459 | * was expanded.
6460 | */
6461 | tnode = tree;
6462 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6463 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6464 | 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" , 6465)
6465 | 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" , 6465);
6466 | /* XXX - is it safe to continue here? */
6467 | }
6468 |
6469 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6470 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6471 | pnode->parent = tnode;
6472 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6473 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6474 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6475 |
6476 | if (tnode->last_child != NULL((void*)0)) {
6477 | sibling = tnode->last_child;
6478 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6478, "sibling->next == ((void*)0)" ))));
6479 | sibling->next = pnode;
6480 | } else
6481 | tnode->first_child = pnode;
6482 | tnode->last_child = pnode;
6483 |
6484 | /* We should not be adding a fake node for an interesting field */
6485 | 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", 6485, __func__, "assertion failed: %s" , "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT" ); } while (0);
6486 |
6487 | /* XXX - Should the proto_item have a header_field_info member, at least
6488 | * for faked items, to know what hfi was faked? (Some dissectors look at
6489 | * the tree items directly.)
6490 | */
6491 | return (proto_item *)pnode;
6492 | }
6493 |
6494 | /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6495 | static proto_item *
6496 | proto_tree_add_node(proto_tree *tree, field_info *fi)
6497 | {
6498 | proto_node *pnode, *tnode, *sibling;
6499 | field_info *tfi;
6500 | unsigned depth = 1;
6501 |
6502 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6502, __func__, "assertion failed: %s", "tree" ); } while (0);
6503 |
6504 | /*
6505 | * Restrict our depth. proto_tree_traverse_pre_order and
6506 | * proto_tree_traverse_post_order (and possibly others) are recursive
6507 | * so we need to be mindful of our stack size.
6508 | */
6509 | if (tree->first_child == NULL((void*)0)) {
6510 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6511 | depth++;
6512 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6513 | fvalue_free(fi->value);
6514 | fi->value = NULL((void*)0);
6515 | 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__)), 6518)))
6516 | "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__)), 6518)))
6517 | 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__)), 6518)))
6518 | 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__)), 6518)));
6519 | }
6520 | }
6521 | }
6522 |
6523 | /*
6524 | * Make sure "tree" is ready to have subtrees under it, by
6525 | * checking whether it's been given an ett_ value.
6526 | *
6527 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6528 | * node of the protocol tree. That node is not displayed,
6529 | * so it doesn't need an ett_ value to remember whether it
6530 | * was expanded.
6531 | */
6532 | tnode = tree;
6533 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6534 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6535 | /* Since we are not adding fi to a node, its fvalue won't get
6536 | * freed by proto_tree_free_node(), so free it now.
6537 | */
6538 | fvalue_free(fi->value);
6539 | fi->value = NULL((void*)0);
6540 | 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", 6541)
6541 | 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", 6541);
6542 | /* XXX - is it safe to continue here? */
6543 | }
6544 |
6545 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6546 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6547 | pnode->parent = tnode;
6548 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6549 | PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6550 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6551 |
6552 | if (tnode->last_child != NULL((void*)0)) {
6553 | sibling = tnode->last_child;
6554 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6554, "sibling->next == ((void*)0)" ))));
6555 | sibling->next = pnode;
6556 | } else
6557 | tnode->first_child = pnode;
6558 | tnode->last_child = pnode;
6559 |
6560 | tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6561 |
6562 | return (proto_item *)pnode;
6563 | }
6564 |
6565 |
6566 | /* Generic way to allocate field_info and add to proto_tree.
6567 | * Sets *pfi to address of newly-allocated field_info struct */
6568 | static proto_item *
6569 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6570 | int *length)
6571 | {
6572 | proto_item *pi;
6573 | field_info *fi;
6574 | int item_length;
6575 |
6576 | get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6577 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6578 | pi = proto_tree_add_node(tree, fi);
6579 |
6580 | return pi;
6581 | }
6582 |
6583 |
6584 | static void
6585 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6586 | int *item_length, const unsigned encoding)
6587 | {
6588 | int length_remaining;
6589 |
6590 | /*
6591 | * We only allow a null tvbuff if the item has a zero length,
6592 | * i.e. if there's no data backing it.
6593 | */
6594 | 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", 6594, "tvb != ((void*)0) || *length == 0" ))));
6595 |
6596 | /*
6597 | * XXX - in some protocols, there are 32-bit unsigned length
6598 | * fields, so lengths in protocol tree and tvbuff routines
6599 | * should really be unsigned. We should have, for those
6600 | * field types for which "to the end of the tvbuff" makes sense,
6601 | * additional routines that take no length argument and
6602 | * add fields that run to the end of the tvbuff.
6603 | */
6604 | if (*length == -1) {
6605 | /*
6606 | * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6607 | * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6608 | * of -1 means "set the length to what remains in the
6609 | * tvbuff".
6610 | *
6611 | * The assumption is either that
6612 | *
6613 | * 1) the length of the item can only be determined
6614 | * by dissection (typically true of items with
6615 | * subitems, which are probably FT_NONE or
6616 | * FT_PROTOCOL)
6617 | *
6618 | * or
6619 | *
6620 | * 2) if the tvbuff is "short" (either due to a short
6621 | * snapshot length or due to lack of reassembly of
6622 | * fragments/segments/whatever), we want to display
6623 | * what's available in the field (probably FT_BYTES
6624 | * or FT_STRING) and then throw an exception later
6625 | *
6626 | * or
6627 | *
6628 | * 3) the field is defined to be "what's left in the
6629 | * packet"
6630 | *
6631 | * so we set the length to what remains in the tvbuff so
6632 | * that, if we throw an exception while dissecting, it
6633 | * has what is probably the right value.
6634 | *
6635 | * For FT_STRINGZ, it means "the string is null-terminated,
6636 | * not null-padded; set the length to the actual length
6637 | * of the string", and if the tvbuff if short, we just
6638 | * throw an exception.
6639 | *
6640 | * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6641 | * it means "find the end of the string",
6642 | * and if the tvbuff if short, we just throw an exception.
6643 | *
6644 | * It's not valid for any other type of field. For those
6645 | * fields, we treat -1 the same way we treat other
6646 | * negative values - we assume the length is a Really
6647 | * Big Positive Number, and throw a ReportedBoundsError
6648 | * exception, under the assumption that the Really Big
6649 | * Length would run past the end of the packet.
6650 | */
6651 | 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 )))) {
6652 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6653 | /*
6654 | * Leave the length as -1, so our caller knows
6655 | * it was -1.
6656 | */
6657 | *item_length = *length;
6658 | return;
6659 | } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6660 | switch (tvb_get_uint8(tvb, start) >> 6)
6661 | {
6662 | case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6663 | *item_length = 1;
6664 | break;
6665 | case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6666 | *item_length = 2;
6667 | break;
6668 | case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6669 | *item_length = 4;
6670 | break;
6671 | case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6672 | *item_length = 8;
6673 | break;
6674 | }
6675 | }
6676 | }
6677 |
6678 | switch (hfinfo->type) {
6679 |
6680 | case FT_PROTOCOL:
6681 | case FT_NONE:
6682 | case FT_BYTES:
6683 | case FT_STRING:
6684 | case FT_STRINGZPAD:
6685 | case FT_STRINGZTRUNC:
6686 | /*
6687 | * We allow FT_PROTOCOLs to be zero-length -
6688 | * for example, an ONC RPC NULL procedure has
6689 | * neither arguments nor reply, so the
6690 | * payload for that protocol is empty.
6691 | *
6692 | * We also allow the others to be zero-length -
6693 | * because that's the way the code has been for a
6694 | * long, long time.
6695 | *
6696 | * However, we want to ensure that the start
6697 | * offset is not *past* the byte past the end
6698 | * of the tvbuff: we throw an exception in that
6699 | * case.
6700 | */
6701 | *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6702 | DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6702, "*length >= 0" ))));
6703 | break;
6704 |
6705 | case FT_STRINGZ:
6706 | /*
6707 | * Leave the length as -1, so our caller knows
6708 | * it was -1.
6709 | */
6710 | break;
6711 |
6712 | default:
6713 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6714 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 6714));
6715 | }
6716 | *item_length = *length;
6717 | } else {
6718 | *item_length = *length;
6719 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6720 | /*
6721 | * These types are for interior nodes of the
6722 | * tree, and don't have data associated with
6723 | * them; if the length is negative (XXX - see
6724 | * above) or goes past the end of the tvbuff,
6725 | * cut it short at the end of the tvbuff.
6726 | * That way, if this field is selected in
6727 | * Wireshark, we don't highlight stuff past
6728 | * the end of the data.
6729 | */
6730 | /* XXX - what to do, if we don't have a tvb? */
6731 | if (tvb) {
6732 | length_remaining = tvb_captured_length_remaining(tvb, start);
6733 | if (*item_length < 0 ||
6734 | (*item_length > 0 &&
6735 | (length_remaining < *item_length)))
6736 | *item_length = length_remaining;
6737 | }
6738 | }
6739 | if (*item_length < 0) {
6740 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6741 | }
6742 | }
6743 | }
6744 |
6745 | static int
6746 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6747 | int length, unsigned item_length, const int encoding)
6748 | {
6749 | uint32_t n;
6750 |
6751 | /*
6752 | * We need to get the correct item length here.
6753 | * That's normally done by proto_tree_new_item(),
6754 | * but we won't be calling it.
6755 | */
6756 | switch (hfinfo->type) {
6757 |
6758 | case FT_NONE:
6759 | case FT_PROTOCOL:
6760 | case FT_BYTES:
6761 | /*
6762 | * The length is the specified length.
6763 | */
6764 | break;
6765 |
6766 | case FT_UINT_BYTES:
6767 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6768 | item_length += n;
6769 | if ((int)item_length < length) {
6770 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6771 | }
6772 | break;
6773 |
6774 | /* XXX - make these just FT_UINT? */
6775 | case FT_UINT8:
6776 | case FT_UINT16:
6777 | case FT_UINT24:
6778 | case FT_UINT32:
6779 | case FT_UINT40:
6780 | case FT_UINT48:
6781 | case FT_UINT56:
6782 | case FT_UINT64:
6783 | /* XXX - make these just FT_INT? */
6784 | case FT_INT8:
6785 | case FT_INT16:
6786 | case FT_INT24:
6787 | case FT_INT32:
6788 | case FT_INT40:
6789 | case FT_INT48:
6790 | case FT_INT56:
6791 | case FT_INT64:
6792 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6793 | if (length < -1) {
6794 | report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6795 | }
6796 | if (length == -1) {
6797 | uint64_t dummy;
6798 | /* This can throw an exception */
6799 | /* XXX - do this without fetching the varint? */
6800 | length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6801 | if (length == 0) {
6802 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6803 | }
6804 | }
6805 | item_length = length;
6806 | break;
6807 | }
6808 |
6809 | /*
6810 | * The length is the specified length.
6811 | */
6812 | break;
6813 |
6814 | case FT_BOOLEAN:
6815 | case FT_CHAR:
6816 | case FT_IPv4:
6817 | case FT_IPXNET:
6818 | case FT_IPv6:
6819 | case FT_FCWWN:
6820 | case FT_AX25:
6821 | case FT_VINES:
6822 | case FT_ETHER:
6823 | case FT_EUI64:
6824 | case FT_GUID:
6825 | case FT_OID:
6826 | case FT_REL_OID:
6827 | case FT_SYSTEM_ID:
6828 | case FT_FLOAT:
6829 | case FT_DOUBLE:
6830 | case FT_STRING:
6831 | /*
6832 | * The length is the specified length.
6833 | */
6834 | break;
6835 |
6836 | case FT_STRINGZ:
6837 | if (length < -1) {
6838 | report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6839 | }
6840 | if (length == -1) {
6841 | /* This can throw an exception */
6842 | /* XXX - do this without fetching the string? */
6843 | wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6844 | }
6845 | item_length = length;
6846 | break;
6847 |
6848 | case FT_UINT_STRING:
6849 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6850 | item_length += n;
6851 | if ((int)item_length < length) {
6852 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6853 | }
6854 | break;
6855 |
6856 | case FT_STRINGZPAD:
6857 | case FT_STRINGZTRUNC:
6858 | case FT_ABSOLUTE_TIME:
6859 | case FT_RELATIVE_TIME:
6860 | case FT_IEEE_11073_SFLOAT:
6861 | case FT_IEEE_11073_FLOAT:
6862 | /*
6863 | * The length is the specified length.
6864 | */
6865 | break;
6866 |
6867 | default:
6868 | 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 ))
6869 | 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 ))
6870 | 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 ))
6871 | 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 ));
6872 | break;
6873 | }
6874 | return item_length;
6875 | }
6876 |
6877 | // This was arbitrarily chosen, but if you're adding 50K items to the tree
6878 | // without advancing the offset you should probably take a long, hard look
6879 | // at what you're doing.
6880 | // We *could* make this a configurable option, but I (Gerald) would like to
6881 | // avoid adding yet another nerd knob.
6882 | # define PROTO_TREE_MAX_IDLE50000 50000
6883 | static field_info *
6884 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6885 | const int start, const int item_length)
6886 | {
6887 | field_info *fi;
6888 |
6889 | FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo ->pool)), sizeof(field_info)));
6890 |
6891 | fi->hfinfo = hfinfo;
6892 | fi->start = start;
6893 | fi->start += (tvb)?tvb_raw_offset(tvb):0;
6894 | /* add the data source tvbuff */
6895 | fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6896 |
6897 | // If our start offset hasn't advanced after adding many items it probably
6898 | // means we're in a large or infinite loop.
6899 | if (fi->start > 0) {
6900 | if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6901 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6902 | 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", 6902, "((tree)->tree_data)->start_idle_count < 50000" , fi->hfinfo->abbrev))));
6903 | } else {
6904 | PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6905 | PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6906 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6907 | }
6908 | }
6909 | fi->length = item_length;
6910 | fi->tree_type = -1;
6911 | fi->flags = 0;
6912 | if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6913 | /* If the tree is not visible, set the item hidden, unless we
6914 | * need the representation or length and can't fake them.
6915 | */
6916 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6917 | FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); } while(0);
6918 | }
6919 | }
6920 | fi->value = fvalue_new(fi->hfinfo->type);
6921 | fi->rep = NULL((void*)0);
6922 |
6923 | fi->appendix_start = 0;
6924 | fi->appendix_length = 0;
6925 |
6926 | fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6927 | fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6928 |
6929 | return fi;
6930 | }
6931 |
6932 | static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6933 | {
6934 | if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6935 | return 0;
6936 | }
6937 |
6938 | /* Search for field name */
6939 | char *ptr = strstr(representation, hfinfo->name);
6940 | if (!ptr) {
6941 | return 0;
6942 | }
6943 |
6944 | /* Check if field name ends with the ": " delimiter */
6945 | ptr += strlen(hfinfo->name);
6946 | if (strncmp(ptr, ": ", 2) == 0) {
6947 | ptr += 2;
6948 | }
6949 |
6950 | /* Return offset to after field name */
6951 | return ptr - representation;
6952 | }
6953 |
6954 | static size_t label_find_name_pos(const item_label_t *rep)
6955 | {
6956 | size_t name_pos = 0;
6957 |
6958 | /* If the value_pos is too small or too large, we can't find the expected format */
6959 | if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6960 | return 0;
6961 | }
6962 |
6963 | /* Check if the format looks like "label: value", then set name_pos before ':'. */
6964 | if (rep->representation[rep->value_pos-2] == ':') {
6965 | name_pos = rep->value_pos - 2;
6966 | }
6967 |
6968 | return name_pos;
6969 | }
6970 |
6971 | /* If the protocol tree is to be visible, set the representation of a
6972 | proto_tree entry with the name of the field for the item and with
6973 | the value formatted with the supplied printf-style format and
6974 | argument list. */
6975 | static void
6976 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6977 | {
6978 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6978, __func__, "assertion failed: %s", "pi" ); } while (0);
6979 |
6980 | /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6981 | * items string representation */
6982 | if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6983 | size_t name_pos, ret = 0;
6984 | char *str;
6985 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6986 | const header_field_info *hf;
6987 |
6988 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 6988, "fi"))));
6989 |
6990 | hf = fi->hfinfo;
6991 |
6992 | 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;;
6993 | 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)))) {
6994 | uint64_t val;
6995 | char *p;
6996 |
6997 | 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))
6998 | val = fvalue_get_uinteger(fi->value);
6999 | else
7000 | val = fvalue_get_uinteger64(fi->value);
7001 |
7002 | val <<= hfinfo_bitshift(hf);
7003 |
7004 | p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7005 | ret = (p - fi->rep->representation);
7006 | }
7007 |
7008 | /* put in the hf name */
7009 | name_pos = ret = label_concat(fi->rep->representation, ret, hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, hf-> name, 0);
7010 |
7011 | ret = label_concat(fi->rep->representation, ret, ": ")ws_label_strcpy(fi->rep->representation, 240, ret, ": " , 0);
7012 | /* If possible, Put in the value of the string */
7013 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7014 | 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" , 7014, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7015 | fi->rep->value_pos = ret;
7016 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, str, 0);
7017 | if (ret >= ITEM_LABEL_LENGTH240) {
7018 | /* Uh oh, we don't have enough room. Tell the user
7019 | * that the field is truncated.
7020 | */
7021 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7022 | }
7023 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7024 | }
7025 | }
7026 |
7027 | /* If the protocol tree is to be visible, set the representation of a
7028 | proto_tree entry with the representation formatted with the supplied
7029 | printf-style format and argument list. */
7030 | static void
7031 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7032 | {
7033 | size_t ret; /*tmp return value */
7034 | char *str;
7035 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7036 |
7037 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7037, "fi"))));
7038 |
7039 | if (!proto_item_is_hidden(pi)) {
7040 | 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;;
7041 |
7042 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7043 | 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" , 7043, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7044 | fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7045 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7046 | if (ret >= ITEM_LABEL_LENGTH240) {
7047 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7048 | size_t name_pos = label_find_name_pos(fi->rep);
7049 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7050 | }
7051 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7052 | }
7053 | }
7054 |
7055 | static int
7056 | proto_strlcpy(char *dest, const char *src, size_t dest_size)
7057 | {
7058 | if (dest_size == 0) return 0;
7059 |
7060 | size_t res = g_strlcpy(dest, src, dest_size);
7061 |
7062 | /* At most dest_size - 1 characters will be copied
7063 | * (unless dest_size is 0). */
7064 | if (res >= dest_size)
7065 | res = dest_size - 1;
7066 | return (int) res;
7067 | }
7068 |
7069 | static header_field_info *
7070 | hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7071 | {
7072 | header_field_info *dup_hfinfo;
7073 |
7074 | if (hfinfo->same_name_prev_id == -1)
7075 | return NULL((void*)0);
7076 | 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", 7076 , __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", 7076, "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", 7076, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo ->same_name_prev_id];;
7077 | return dup_hfinfo;
7078 | }
7079 |
7080 | static void
7081 | hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7082 | {
7083 | g_free(last_field_name);
7084 | last_field_name = NULL((void*)0);
7085 |
7086 | if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7087 | /* No hfinfo with the same name */
7088 | wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7089 | return;
7090 | }
7091 |
7092 | if (hfinfo->same_name_next) {
7093 | hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7094 | }
7095 |
7096 | if (hfinfo->same_name_prev_id != -1) {
7097 | header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7098 | same_name_prev->same_name_next = hfinfo->same_name_next;
7099 | if (!hfinfo->same_name_next) {
7100 | /* It's always the latest added hfinfo which is stored in gpa_name_map */
7101 | wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7102 | }
7103 | }
7104 | }
7105 |
7106 | int
7107 | proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7108 | {
7109 | const header_field_info *hfinfo = finfo->hfinfo;
7110 | int label_len = 0;
7111 | char *tmp_str;
7112 | const char *str;
7113 | const uint8_t *bytes;
7114 | uint32_t number;
7115 | uint64_t number64;
7116 | const char *hf_str_val;
7117 | char number_buf[NUMBER_LABEL_LENGTH80];
7118 | const char *number_out;
7119 | address addr;
7120 | const ipv4_addr_and_mask *ipv4;
7121 | const ipv6_addr_and_prefix *ipv6;
7122 |
7123 | switch (hfinfo->type) {
7124 |
7125 | case FT_NONE:
7126 | case FT_PROTOCOL:
7127 | return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7128 |
7129 | case FT_UINT_BYTES:
7130 | case FT_BYTES:
7131 | tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7132 | hfinfo,
7133 | fvalue_get_bytes_data(finfo->value),
7134 | (unsigned)fvalue_length2(finfo->value),
7135 | label_str_size);
7136 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7137 | wmem_free(NULL((void*)0), tmp_str);
7138 | break;
7139 |
7140 | case FT_ABSOLUTE_TIME:
7141 | {
7142 | const nstime_t *value = fvalue_get_time(finfo->value);
7143 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7144 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7145 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7146 | }
7147 | if (hfinfo->strings) {
7148 | const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7149 | if (time_string != NULL((void*)0)) {
7150 | label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7151 | break;
7152 | }
7153 | }
7154 | tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7155 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7156 | wmem_free(NULL((void*)0), tmp_str);
7157 | break;
7158 | }
7159 |
7160 | case FT_RELATIVE_TIME:
7161 | tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7162 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7163 | wmem_free(NULL((void*)0), tmp_str);
7164 | break;
7165 |
7166 | case FT_BOOLEAN:
7167 | number64 = fvalue_get_uinteger64(finfo->value);
7168 | label_len = proto_strlcpy(display_label_str,
7169 | tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7170 | break;
7171 |
7172 | case FT_CHAR:
7173 | number = fvalue_get_uinteger(finfo->value);
7174 |
7175 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7176 | char tmp[ITEM_LABEL_LENGTH240];
7177 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7178 |
7179 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7179, "fmtfunc"))));
7180 | fmtfunc(tmp, number);
7181 |
7182 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7183 |
7184 | } else if (hfinfo->strings) {
7185 | number_out = hf_try_val_to_str(number, hfinfo);
7186 |
7187 | if (!number_out) {
7188 | number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7189 | }
7190 |
7191 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7192 |
7193 | } else {
7194 | number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7195 |
7196 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7197 | }
7198 |
7199 | break;
7200 |
7201 | /* XXX - make these just FT_NUMBER? */
7202 | case FT_INT8:
7203 | case FT_INT16:
7204 | case FT_INT24:
7205 | case FT_INT32:
7206 | case FT_UINT8:
7207 | case FT_UINT16:
7208 | case FT_UINT24:
7209 | case FT_UINT32:
7210 | case FT_FRAMENUM:
7211 | hf_str_val = NULL((void*)0);
7212 | 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 )) ?
7213 | (uint32_t) fvalue_get_sinteger(finfo->value) :
7214 | fvalue_get_uinteger(finfo->value);
7215 |
7216 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7217 | char tmp[ITEM_LABEL_LENGTH240];
7218 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7219 |
7220 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7220, "fmtfunc"))));
7221 | fmtfunc(tmp, number);
7222 |
7223 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7224 |
7225 | } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7226 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7227 | number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7228 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7229 | hf_str_val = hf_try_val_to_str(number, hfinfo);
7230 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7231 | } else {
7232 | number_out = hf_try_val_to_str(number, hfinfo);
7233 |
7234 | if (!number_out) {
7235 | number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7236 | }
7237 |
7238 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7239 | }
7240 | } else {
7241 | number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7242 |
7243 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7244 | }
7245 |
7246 | break;
7247 |
7248 | case FT_INT40:
7249 | case FT_INT48:
7250 | case FT_INT56:
7251 | case FT_INT64:
7252 | case FT_UINT40:
7253 | case FT_UINT48:
7254 | case FT_UINT56:
7255 | case FT_UINT64:
7256 | hf_str_val = NULL((void*)0);
7257 | 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 )) ?
7258 | (uint64_t) fvalue_get_sinteger64(finfo->value) :
7259 | fvalue_get_uinteger64(finfo->value);
7260 |
7261 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7262 | char tmp[ITEM_LABEL_LENGTH240];
7263 | custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7264 |
7265 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 7265, "fmtfunc64" ))));
7266 | fmtfunc64(tmp, number64);
7267 |
7268 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7269 | } else if (hfinfo->strings) {
7270 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7271 | number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7272 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7273 | hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7274 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7275 | } else {
7276 | number_out = hf_try_val64_to_str(number64, hfinfo);
7277 |
7278 | if (!number_out)
7279 | number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7280 |
7281 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7282 | }
7283 | } else {
7284 | number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7285 |
7286 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7287 | }
7288 |
7289 | break;
7290 |
7291 | case FT_EUI64:
7292 | set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7293 | tmp_str = address_to_display(NULL((void*)0), &addr);
7294 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7295 | wmem_free(NULL((void*)0), tmp_str);
7296 | break;
7297 |
7298 | case FT_IPv4:
7299 | ipv4 = fvalue_get_ipv4(finfo->value);
7300 | //XXX: Should we ignore the mask?
7301 | set_address_ipv4(&addr, ipv4);
7302 | tmp_str = address_to_display(NULL((void*)0), &addr);
7303 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7304 | wmem_free(NULL((void*)0), tmp_str);
7305 | free_address(&addr);
7306 | break;
7307 |
7308 | case FT_IPv6:
7309 | ipv6 = fvalue_get_ipv6(finfo->value);
7310 | set_address_ipv6(&addr, ipv6);
7311 | tmp_str = address_to_display(NULL((void*)0), &addr);
7312 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7313 | wmem_free(NULL((void*)0), tmp_str);
7314 | free_address(&addr);
7315 | break;
7316 |
7317 | case FT_FCWWN:
7318 | set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7319 | tmp_str = address_to_display(NULL((void*)0), &addr);
7320 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7321 | wmem_free(NULL((void*)0), tmp_str);
7322 | break;
7323 |
7324 | case FT_ETHER:
7325 | set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7326 | tmp_str = address_to_display(NULL((void*)0), &addr);
7327 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7328 | wmem_free(NULL((void*)0), tmp_str);
7329 | break;
7330 |
7331 | case FT_GUID:
7332 | tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7333 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7334 | wmem_free(NULL((void*)0), tmp_str);
7335 | break;
7336 |
7337 | case FT_REL_OID:
7338 | bytes = fvalue_get_bytes_data(finfo->value);
7339 | tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7340 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7341 | wmem_free(NULL((void*)0), tmp_str);
7342 | break;
7343 |
7344 | case FT_OID:
7345 | bytes = fvalue_get_bytes_data(finfo->value);
7346 | tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7347 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7348 | wmem_free(NULL((void*)0), tmp_str);
7349 | break;
7350 |
7351 | case FT_SYSTEM_ID:
7352 | bytes = fvalue_get_bytes_data(finfo->value);
7353 | tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7354 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7355 | wmem_free(NULL((void*)0), tmp_str);
7356 | break;
7357 |
7358 | case FT_FLOAT:
7359 | case FT_DOUBLE:
7360 | label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7361 | break;
7362 |
7363 | case FT_IEEE_11073_SFLOAT:
7364 | case FT_IEEE_11073_FLOAT:
7365 | label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7366 | break;
7367 |
7368 | case FT_STRING:
7369 | case FT_STRINGZ:
7370 | case FT_UINT_STRING:
7371 | case FT_STRINGZPAD:
7372 | case FT_STRINGZTRUNC:
7373 | str = fvalue_get_string(finfo->value);
7374 | label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, str, label_strcat_flags(hfinfo));
7375 | if (label_len >= label_str_size) {
7376 | /* Truncation occurred. Get the real length
7377 | * copied (not including '\0') */
7378 | label_len = label_str_size ? label_str_size - 1 : 0;
7379 | }
7380 | break;
7381 |
7382 | default:
7383 | /* First try ftype string representation */
7384 | tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7385 | if (!tmp_str) {
7386 | /* Default to show as bytes */
7387 | bytes = fvalue_get_bytes_data(finfo->value);
7388 | tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo-> value), 36);
7389 | }
7390 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7391 | wmem_free(NULL((void*)0), tmp_str);
7392 | break;
7393 | }
7394 | return label_len;
7395 | }
7396 |
7397 | const char *
7398 | proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7399 | char *result, char *expr, const int size)
7400 | {
7401 | int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7402 | GPtrArray *finfos;
7403 | field_info *finfo = NULL((void*)0);
7404 | header_field_info* hfinfo;
7405 | const char *abbrev = NULL((void*)0);
7406 |
7407 | char *str;
7408 | col_custom_t *field_idx;
7409 | int field_id;
7410 | int ii = 0;
7411 |
7412 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7412, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7413 | while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7414 | field_id = field_idx->field_id;
7415 | if (field_id == 0) {
7416 | GPtrArray *fvals = NULL((void*)0);
7417 | bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7418 | if (fvals != NULL((void*)0)) {
7419 |
7420 | // XXX - Handling occurrences is unusual when more
7421 | // than one field is involved, e.g. there's four
7422 | // results for tcp.port + tcp.port. We may really
7423 | // want to apply it to the operands, not the output.
7424 | // Note that occurrences are not quite the same as
7425 | // the layer operator (should the grammar support
7426 | // both?)
7427 | /* Calculate single index or set outer boundaries */
7428 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7429 | if (occurrence < 0) {
7430 | i = occurrence + len;
7431 | last = i;
7432 | } else if (occurrence > 0) {
7433 | i = occurrence - 1;
7434 | last = i;
7435 | } else {
7436 | i = 0;
7437 | last = len - 1;
7438 | }
7439 | if (i < 0 || i >= len) {
7440 | g_ptr_array_unref(fvals);
7441 | continue;
7442 | }
7443 | for (; i <= last; i++) {
7444 | /* XXX - We could have a "resolved" result
7445 | * for types where the value depends only
7446 | * on the type, e.g. FT_IPv4, and not on
7447 | * hfinfo->strings. Supporting the latter
7448 | * requires knowing which hfinfo matched
7449 | * if there are multiple with the same
7450 | * abbreviation. In any case, we need to
7451 | * know the expected return type of the
7452 | * field expression.
7453 | */
7454 | str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7455 | if (offset_r && (offset_r < (size - 1)))
7456 | result[offset_r++] = ',';
7457 | if (offset_e && (offset_e < (size - 1)))
7458 | expr[offset_e++] = ',';
7459 | offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7460 | // col_{add,append,set}_* calls ws_label_strcpy
7461 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7462 |
7463 | g_free(str);
7464 | }
7465 | g_ptr_array_unref(fvals);
7466 | } else if (passed) {
7467 | // XXX - Occurrence doesn't make sense for a test
7468 | // output, it should be applied to the operands.
7469 | if (offset_r && (offset_r < (size - 1)))
7470 | result[offset_r++] = ',';
7471 | if (offset_e && (offset_e < (size - 1)))
7472 | expr[offset_e++] = ',';
7473 | /* Prevent multiple check marks */
7474 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7475 | offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7476 | } else {
7477 | result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7478 | }
7479 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7480 | offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7481 | } else {
7482 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7483 | }
7484 | }
7485 | continue;
7486 | }
7487 | 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", 7487 , __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", 7487, "(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", 7487, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7488 |
7489 | /* do we need to rewind ? */
7490 | if (!hfinfo)
7491 | return "";
7492 |
7493 | if (occurrence < 0) {
7494 | /* Search other direction */
7495 | while (hfinfo->same_name_prev_id != -1) {
7496 | 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", 7496 , __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", 7496, "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", 7496, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7497 | }
7498 | }
7499 |
7500 | prev_len = 0; /* Reset handled occurrences */
7501 |
7502 | while (hfinfo) {
7503 | finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7504 |
7505 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7506 | if (occurrence < 0) {
7507 | hfinfo = hfinfo->same_name_next;
7508 | } else {
7509 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7510 | }
7511 | continue;
7512 | }
7513 |
7514 | /* Are there enough occurrences of the field? */
7515 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7516 | if (occurrence < 0) {
7517 | hfinfo = hfinfo->same_name_next;
7518 | } else {
7519 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7520 | }
7521 | prev_len += len;
7522 | continue;
7523 | }
7524 |
7525 | /* Calculate single index or set outer boundaries */
7526 | if (occurrence < 0) {
7527 | i = occurrence + len + prev_len;
7528 | last = i;
7529 | } else if (occurrence > 0) {
7530 | i = occurrence - 1 - prev_len;
7531 | last = i;
7532 | } else {
7533 | i = 0;
7534 | last = len - 1;
7535 | }
7536 |
7537 | prev_len += len; /* Count handled occurrences */
7538 |
7539 | while (i <= last) {
7540 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7541 |
7542 | if (offset_r && (offset_r < (size - 1)))
7543 | result[offset_r++] = ',';
7544 |
7545 | if (display_details) {
7546 | char representation[ITEM_LABEL_LENGTH240];
7547 | size_t offset = 0;
7548 |
7549 | if (finfo->rep && finfo->rep->value_len) {
7550 | g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7551 | MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo-> rep->value_len + 1) : (240)));
7552 | } else {
7553 | proto_item_fill_label(finfo, representation, &offset);
7554 | }
7555 | offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7556 | } else {
7557 | switch (hfinfo->type) {
7558 |
7559 | case FT_NONE:
7560 | case FT_PROTOCOL:
7561 | /* Prevent multiple check marks */
7562 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7563 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7564 | } else {
7565 | result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7566 | }
7567 | break;
7568 |
7569 | default:
7570 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7571 | break;
7572 | }
7573 | }
7574 |
7575 | if (offset_e && (offset_e < (size - 1)))
7576 | expr[offset_e++] = ',';
7577 |
7578 | 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 )))) {
7579 | const char *hf_str_val;
7580 | /* Integer types with BASE_NONE never get the numeric value. */
7581 | if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16 || (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32 )) {
7582 | hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7583 | } 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 )) {
7584 | hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7585 | } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48 || (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64 )) {
7586 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7587 | } else { // if (FT_IS_UINT64(hfinfo->type)) {
7588 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7589 | }
7590 | snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7591 | offset_e = (int)strlen(expr);
7592 | } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7593 | /* Prevent multiple check marks */
7594 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7595 | offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7596 | } else {
7597 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7598 | }
7599 | } else {
7600 | str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7601 | // col_{add,append,set}_* calls ws_label_strcpy
7602 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, str, 0);
7603 | wmem_free(NULL((void*)0), str);
7604 | }
7605 | i++;
7606 | }
7607 |
7608 | /* XXX: Why is only the first abbreviation returned for a multifield
7609 | * custom column? */
7610 | if (!abbrev) {
7611 | /* Store abbrev for return value */
7612 | abbrev = hfinfo->abbrev;
7613 | }
7614 |
7615 | if (occurrence == 0) {
7616 | /* Fetch next hfinfo with same name (abbrev) */
7617 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7618 | } else {
7619 | hfinfo = NULL((void*)0);
7620 | }
7621 | }
7622 | }
7623 |
7624 | if (offset_r >= (size - 1)) {
7625 | mark_truncated(result, 0, size, NULL((void*)0));
7626 | }
7627 | if (offset_e >= (size - 1)) {
7628 | mark_truncated(expr, 0, size, NULL((void*)0));
7629 | }
7630 | return abbrev ? abbrev : "";
7631 | }
7632 |
7633 | char *
7634 | proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7635 | {
7636 | int len, prev_len, last, i;
7637 | GPtrArray *finfos;
7638 | field_info *finfo = NULL((void*)0);
7639 | header_field_info* hfinfo;
7640 |
7641 | char *filter = NULL((void*)0);
7642 | GPtrArray *filter_array;
7643 |
7644 | col_custom_t *col_custom;
7645 | int field_id;
7646 |
7647 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7647, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7648 | filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7649 | for (GSList *iter = field_ids; iter; iter = iter->next) {
7650 | col_custom = (col_custom_t*)iter->data;
7651 | field_id = col_custom->field_id;
7652 | if (field_id == 0) {
7653 | GPtrArray *fvals = NULL((void*)0);
7654 | bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7655 | if (fvals != NULL((void*)0)) {
7656 | // XXX - Handling occurrences is unusual when more
7657 | // than one field is involved, e.g. there's four
7658 | // results for tcp.port + tcp.port. We really
7659 | // want to apply it to the operands, not the output.
7660 | /* Calculate single index or set outer boundaries */
7661 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7662 | if (occurrence < 0) {
7663 | i = occurrence + len;
7664 | last = i;
7665 | } else if (occurrence > 0) {
7666 | i = occurrence - 1;
7667 | last = i;
7668 | } else {
7669 | i = 0;
7670 | last = len - 1;
7671 | }
7672 | if (i < 0 || i >= len) {
7673 | g_ptr_array_unref(fvals);
7674 | continue;
7675 | }
7676 | for (; i <= last; i++) {
7677 | /* XXX - Should multiple values for one
7678 | * field use set membership to reduce
7679 | * verbosity, here and below? */
7680 | char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7681 | filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7682 | wmem_free(NULL((void*)0), str);
7683 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7684 | g_ptr_array_add(filter_array, filter);
7685 | }
7686 | }
7687 | g_ptr_array_unref(fvals);
7688 | } else if (passed) {
7689 | filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7690 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7691 | g_ptr_array_add(filter_array, filter);
7692 | }
7693 | } else {
7694 | filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7695 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7696 | g_ptr_array_add(filter_array, filter);
7697 | }
7698 | }
7699 | continue;
7700 | }
7701 |
7702 | 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", 7702 , __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", 7702, "(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", 7702, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7703 |
7704 | /* do we need to rewind ? */
7705 | if (!hfinfo)
7706 | return NULL((void*)0);
7707 |
7708 | if (occurrence < 0) {
7709 | /* Search other direction */
7710 | while (hfinfo->same_name_prev_id != -1) {
7711 | 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", 7711 , __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", 7711, "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", 7711, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7712 | }
7713 | }
7714 |
7715 | prev_len = 0; /* Reset handled occurrences */
7716 |
7717 | while (hfinfo) {
7718 | finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7719 |
7720 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7721 | if (occurrence < 0) {
7722 | hfinfo = hfinfo->same_name_next;
7723 | } else {
7724 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7725 | }
7726 | continue;
7727 | }
7728 |
7729 | /* Are there enough occurrences of the field? */
7730 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7731 | if (occurrence < 0) {
7732 | hfinfo = hfinfo->same_name_next;
7733 | } else {
7734 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7735 | }
7736 | prev_len += len;
7737 | continue;
7738 | }
7739 |
7740 | /* Calculate single index or set outer boundaries */
7741 | if (occurrence < 0) {
7742 | i = occurrence + len + prev_len;
7743 | last = i;
7744 | } else if (occurrence > 0) {
7745 | i = occurrence - 1 - prev_len;
7746 | last = i;
7747 | } else {
7748 | i = 0;
7749 | last = len - 1;
7750 | }
7751 |
7752 | prev_len += len; /* Count handled occurrences */
7753 |
7754 | while (i <= last) {
7755 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7756 |
7757 | filter = proto_construct_match_selected_string(finfo, edt);
7758 | if (filter) {
7759 | /* Only add the same expression once (especially for FT_PROTOCOL).
7760 | * The ptr array doesn't have NULL entries so g_str_equal is fine.
7761 | */
7762 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7763 | g_ptr_array_add(filter_array, filter);
7764 | }
7765 | }
7766 | i++;
7767 | }
7768 |
7769 | if (occurrence == 0) {
7770 | /* Fetch next hfinfo with same name (abbrev) */
7771 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7772 | } else {
7773 | hfinfo = NULL((void*)0);
7774 | }
7775 | }
7776 | }
7777 |
7778 | g_ptr_array_add(filter_array, NULL((void*)0));
7779 |
7780 | /* XXX: Should this be || or && ? */
7781 | char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7782 |
7783 | g_ptr_array_free(filter_array, true1);
7784 |
7785 | return output;
7786 | }
7787 |
7788 | /* Set text of proto_item after having already been created. */
7789 | void
7790 | proto_item_set_text(proto_item *pi, const char *format, ...)
7791 | {
7792 | field_info *fi = NULL((void*)0);
7793 | va_list ap;
7794 |
7795 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7796 |
7797 | fi = PITEM_FINFO(pi)((pi)->finfo);
7798 | if (fi == NULL((void*)0))
7799 | return;
7800 |
7801 | if (fi->rep) {
7802 | ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep );;
7803 | fi->rep = NULL((void*)0);
7804 | }
7805 |
7806 | va_start(ap, format)__builtin_va_start(ap, format);
7807 | proto_tree_set_representation(pi, format, ap);
7808 | va_end(ap)__builtin_va_end(ap);
7809 | }
7810 |
7811 | /* Append to text of proto_item after having already been created. */
7812 | void
7813 | proto_item_append_text(proto_item *pi, const char *format, ...)
7814 | {
7815 | field_info *fi = NULL((void*)0);
7816 | size_t curlen;
7817 | char *str;
7818 | va_list ap;
7819 |
7820 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7821 |
7822 | fi = PITEM_FINFO(pi)((pi)->finfo);
7823 | if (fi == NULL((void*)0)) {
7824 | return;
7825 | }
7826 |
7827 | if (!proto_item_is_hidden(pi)) {
7828 | /*
7829 | * If we don't already have a representation,
7830 | * generate the default representation.
7831 | */
7832 | if (fi->rep == NULL((void*)0)) {
7833 | 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;;
7834 | proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7835 | /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7836 | if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7837 | (strncmp(format, ": ", 2) == 0)) {
7838 | fi->rep->value_pos += 2;
7839 | }
7840 | }
7841 | if (fi->rep) {
7842 | curlen = strlen(fi->rep->representation);
7843 | /* curlen doesn't include the \0 byte.
7844 | * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7845 | * the representation has already been truncated (of an up
7846 | * to 4 byte UTF-8 character) or is just at the maximum length
7847 | * unless we search for " [truncated]" (which may not be
7848 | * at the start.)
7849 | * It's safer to do nothing.
7850 | */
7851 | if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7852 | va_start(ap, format)__builtin_va_start(ap, format);
7853 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7854 | va_end(ap)__builtin_va_end(ap);
7855 | 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" , 7855, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7856 | /* Keep fi->rep->value_pos */
7857 | curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, str, 0);
7858 | if (curlen >= ITEM_LABEL_LENGTH240) {
7859 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7860 | size_t name_pos = label_find_name_pos(fi->rep);
7861 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7862 | }
7863 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7864 | }
7865 | }
7866 | }
7867 | }
7868 |
7869 | /* Prepend to text of proto_item after having already been created. */
7870 | void
7871 | proto_item_prepend_text(proto_item *pi, const char *format, ...)
7872 | {
7873 | field_info *fi = NULL((void*)0);
7874 | size_t pos;
7875 | char representation[ITEM_LABEL_LENGTH240];
7876 | char *str;
7877 | va_list ap;
7878 |
7879 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7880 |
7881 | fi = PITEM_FINFO(pi)((pi)->finfo);
7882 | if (fi == NULL((void*)0)) {
7883 | return;
7884 | }
7885 |
7886 | if (!proto_item_is_hidden(pi)) {
7887 | /*
7888 | * If we don't already have a representation,
7889 | * generate the default representation.
7890 | */
7891 | if (fi->rep == NULL((void*)0)) {
7892 | 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;;
7893 | proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7894 | } else
7895 | (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7896 |
7897 | va_start(ap, format)__builtin_va_start(ap, format);
7898 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7899 | va_end(ap)__builtin_va_end(ap);
7900 | 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" , 7900, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7901 | fi->rep->value_pos += strlen(str);
7902 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, str, 0);
7903 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, representation, 0);
7904 | /* XXX: As above, if the old representation is close to the label
7905 | * length, it might already be marked as truncated. */
7906 | if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7907 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7908 | size_t name_pos = label_find_name_pos(fi->rep);
7909 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7910 | }
7911 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7912 | }
7913 | }
7914 |
7915 | static void
7916 | finfo_set_len(field_info *fi, const int length)
7917 | {
7918 | int length_remaining;
7919 |
7920 | 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", 7920, "length >= 0", fi->hfinfo->abbrev))));
7921 | length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7922 | if (length > length_remaining)
7923 | fi->length = length_remaining;
7924 | else
7925 | fi->length = length;
7926 |
7927 | /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7928 | if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7929 | fvalue_set_protocol_length(fi->value, fi->length);
7930 | }
7931 |
7932 | /*
7933 | * You cannot just make the "len" field of a GByteArray
7934 | * larger, if there's no data to back that length;
7935 | * you can only make it smaller.
7936 | */
7937 | if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7938 | GBytes *bytes = fvalue_get_bytes(fi->value);
7939 | size_t size;
7940 | const void *data = g_bytes_get_data(bytes, &size);
7941 | if ((size_t)fi->length <= size) {
7942 | fvalue_set_bytes_data(fi->value, data, fi->length);
7943 | }
7944 | g_bytes_unref(bytes);
7945 | }
7946 | }
7947 |
7948 | void
7949 | proto_item_set_len(proto_item *pi, const int length)
7950 | {
7951 | field_info *fi;
7952 |
7953 | if (pi == NULL((void*)0))
7954 | return;
7955 |
7956 | fi = PITEM_FINFO(pi)((pi)->finfo);
7957 | if (fi == NULL((void*)0))
7958 | return;
7959 |
7960 | finfo_set_len(fi, length);
7961 | }
7962 |
7963 | /*
7964 | * Sets the length of the item based on its start and on the specified
7965 | * offset, which is the offset past the end of the item; as the start
7966 | * in the item is relative to the beginning of the data source tvbuff,
7967 | * we need to pass in a tvbuff - the end offset is relative to the beginning
7968 | * of that tvbuff.
7969 | */
7970 | void
7971 | proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7972 | {
7973 | field_info *fi;
7974 | int length;
7975 |
7976 | if (pi == NULL((void*)0))
7977 | return;
7978 |
7979 | fi = PITEM_FINFO(pi)((pi)->finfo);
7980 | if (fi == NULL((void*)0))
7981 | return;
7982 |
7983 | end += tvb_raw_offset(tvb);
7984 | DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7984, "end >= fi->start" ))));
7985 | length = end - fi->start;
7986 |
7987 | finfo_set_len(fi, length);
7988 | }
7989 |
7990 | int
7991 | proto_item_get_len(const proto_item *pi)
7992 | {
7993 | field_info *fi;
7994 |
7995 | if (!pi)
7996 | return -1;
7997 | fi = PITEM_FINFO(pi)((pi)->finfo);
7998 | return fi ? fi->length : -1;
7999 | }
8000 |
8001 | void
8002 | proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8003 | if (!ti) {
8004 | return;
8005 | }
8006 | 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);
8007 | 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);
8008 | }
8009 |
8010 | char *
8011 | proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8012 | {
8013 | field_info *fi;
8014 |
8015 | if (!pi)
8016 | return wmem_strdup(scope, "");
8017 | fi = PITEM_FINFO(pi)((pi)->finfo);
8018 | if (!fi)
8019 | return wmem_strdup(scope, "");
8020 | DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8020, "fi->hfinfo != ((void*)0)" ))));
8021 | return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8022 | }
8023 |
8024 | proto_tree *
8025 | proto_tree_create_root(packet_info *pinfo)
8026 | {
8027 | proto_node *pnode;
8028 |
8029 | /* Initialize the proto_node */
8030 | pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8031 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
8032 | pnode->parent = NULL((void*)0);
8033 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8034 | pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8035 |
8036 | /* Make sure we can access pinfo everywhere */
8037 | pnode->tree_data->pinfo = pinfo;
8038 |
8039 | /* Don't initialize the tree_data_t. Wait until we know we need it */
8040 | pnode->tree_data->interesting_hfids = NULL((void*)0);
8041 |
8042 | /* Set the default to false so it's easier to
8043 | * find errors; if we expect to see the protocol tree
8044 | * but for some reason the default 'visible' is not
8045 | * changed, then we'll find out very quickly. */
8046 | pnode->tree_data->visible = false0;
8047 |
8048 | /* Make sure that we fake protocols (if possible) */
8049 | pnode->tree_data->fake_protocols = true1;
8050 |
8051 | /* Keep track of the number of children */
8052 | pnode->tree_data->count = 0;
8053 |
8054 | /* Initialize our loop checks */
8055 | pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8056 | pnode->tree_data->max_start = 0;
8057 | pnode->tree_data->start_idle_count = 0;
8058 |
8059 | return (proto_tree *)pnode;
8060 | }
8061 |
8062 |
8063 | /* "prime" a proto_tree with a single hfid that a dfilter
8064 | * is interested in. */
8065 | void
8066 | proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8067 | {
8068 | header_field_info *hfinfo;
8069 |
8070 | 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", 8070, __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", 8070, "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", 8070, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8071 | /* this field is referenced by a filter so increase the refcount.
8072 | also increase the refcount for the parent, i.e the protocol.
8073 | Don't increase the refcount if we're already printing the
8074 | type, as that is a superset of direct reference.
8075 | */
8076 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8077 | hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8078 | }
8079 | /* only increase the refcount if there is a parent.
8080 | if this is a protocol and not a field then parent will be -1
8081 | and there is no parent to add any refcounting for.
8082 | */
8083 | if (hfinfo->parent != -1) {
8084 | header_field_info *parent_hfinfo;
8085 | 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", 8085 , __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", 8085, "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", 8085, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8086 |
8087 | /* Mark parent as indirectly referenced unless it is already directly
8088 | * referenced, i.e. the user has specified the parent in a filter.
8089 | */
8090 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8091 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8092 | }
8093 | }
8094 |
8095 | /* "prime" a proto_tree with a single hfid that a dfilter
8096 | * is interested in. */
8097 | void
8098 | proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8099 | {
8100 | header_field_info *hfinfo;
8101 |
8102 | 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", 8102, __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", 8102, "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", 8102, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8103 | /* this field is referenced by an (output) filter so increase the refcount.
8104 | also increase the refcount for the parent, i.e the protocol.
8105 | */
8106 | hfinfo->ref_type = HF_REF_TYPE_PRINT;
8107 | /* only increase the refcount if there is a parent.
8108 | if this is a protocol and not a field then parent will be -1
8109 | and there is no parent to add any refcounting for.
8110 | */
8111 | if (hfinfo->parent != -1) {
8112 | header_field_info *parent_hfinfo;
8113 | 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", 8113 , __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", 8113, "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", 8113, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8114 |
8115 | /* Mark parent as indirectly referenced unless it is already directly
8116 | * referenced, i.e. the user has specified the parent in a filter.
8117 | */
8118 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8119 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8120 | }
8121 | }
8122 |
8123 | proto_tree *
8124 | proto_item_add_subtree(proto_item *pi, const int idx) {
8125 | field_info *fi;
8126 |
8127 | if (!pi)
8128 | return NULL((void*)0);
8129 |
8130 | 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", 8130, "idx >= 0 && idx < num_tree_types" ))));
8131 |
8132 | fi = PITEM_FINFO(pi)((pi)->finfo);
8133 | if (!fi)
8134 | return (proto_tree *)pi;
8135 |
8136 | fi->tree_type = idx;
8137 |
8138 | return (proto_tree *)pi;
8139 | }
8140 |
8141 | proto_tree *
8142 | proto_item_get_subtree(proto_item *pi) {
8143 | field_info *fi;
8144 |
8145 | if (!pi)
8146 | return NULL((void*)0);
8147 | fi = PITEM_FINFO(pi)((pi)->finfo);
8148 | if ( (fi) && (fi->tree_type == -1) )
8149 | return NULL((void*)0);
8150 | return (proto_tree *)pi;
8151 | }
8152 |
8153 | proto_item *
8154 | proto_item_get_parent(const proto_item *ti) {
8155 | if (!ti)
8156 | return NULL((void*)0);
8157 | return ti->parent;
8158 | }
8159 |
8160 | proto_item *
8161 | proto_item_get_parent_nth(proto_item *ti, int gen) {
8162 | if (!ti)
8163 | return NULL((void*)0);
8164 | while (gen--) {
8165 | ti = ti->parent;
8166 | if (!ti)
8167 | return NULL((void*)0);
8168 | }
8169 | return ti;
8170 | }
8171 |
8172 |
8173 | proto_item *
8174 | proto_tree_get_parent(proto_tree *tree) {
8175 | if (!tree)
8176 | return NULL((void*)0);
8177 | return (proto_item *)tree;
8178 | }
8179 |
8180 | proto_tree *
8181 | proto_tree_get_parent_tree(proto_tree *tree) {
8182 | if (!tree)
8183 | return NULL((void*)0);
8184 |
8185 | /* we're the root tree, there's no parent
8186 | return ourselves so the caller has at least a tree to attach to */
8187 | if (!tree->parent)
8188 | return tree;
8189 |
8190 | return (proto_tree *)tree->parent;
8191 | }
8192 |
8193 | proto_tree *
8194 | proto_tree_get_root(proto_tree *tree) {
8195 | if (!tree)
8196 | return NULL((void*)0);
8197 | while (tree->parent) {
8198 | tree = tree->parent;
8199 | }
8200 | return tree;
8201 | }
8202 |
8203 | void
8204 | proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8205 | proto_item *item_to_move)
8206 | {
8207 | /* This function doesn't generate any values. It only reorganizes the protocol tree
8208 | * so we can bail out immediately if it isn't visible. */
8209 | if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8210 | return;
8211 |
8212 | 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", 8212, "item_to_move->parent == tree" ))));
8213 | 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", 8213, "fixed_item->parent == tree" ))));
8214 |
8215 | /*** cut item_to_move out ***/
8216 |
8217 | /* is item_to_move the first? */
8218 | if (tree->first_child == item_to_move) {
8219 | /* simply change first child to next */
8220 | tree->first_child = item_to_move->next;
8221 |
8222 | 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", 8222, "tree->last_child != item_to_move" ))));
8223 | } else {
8224 | proto_item *curr_item;
8225 | /* find previous and change it's next */
8226 | for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8227 | if (curr_item->next == item_to_move) {
8228 | break;
8229 | }
8230 | }
8231 |
8232 | DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 8232, "curr_item" ))));
8233 |
8234 | curr_item->next = item_to_move->next;
8235 |
8236 | /* fix last_child if required */
8237 | if (tree->last_child == item_to_move) {
8238 | tree->last_child = curr_item;
8239 | }
8240 | }
8241 |
8242 | /*** insert to_move after fixed ***/
8243 | item_to_move->next = fixed_item->next;
8244 | fixed_item->next = item_to_move;
8245 | if (tree->last_child == fixed_item) {
8246 | tree->last_child = item_to_move;
8247 | }
8248 | }
8249 |
8250 | void
8251 | proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8252 | const int length)
8253 | {
8254 | field_info *fi;
8255 |
8256 | if (tree == NULL((void*)0))
8257 | return;
8258 |
8259 | fi = PTREE_FINFO(tree)((tree)->finfo);
8260 | if (fi == NULL((void*)0))
8261 | return;
8262 |
8263 | start += tvb_raw_offset(tvb);
8264 | DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8264, "start >= 0" ))));
8265 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8265, "length >= 0" ))));
8266 |
8267 | fi->appendix_start = start;
8268 | fi->appendix_length = length;
8269 | }
8270 |
8271 | static void
8272 | check_protocol_filter_name_or_fail(const char *filter_name)
8273 | {
8274 | /* Require at least two characters. */
8275 | if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8276 | 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);
8277 | }
8278 |
8279 | if (proto_check_field_name(filter_name) != '\0') {
8280 | 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)
8281 | " 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)
8282 | " 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);
8283 | }
8284 |
8285 | /* Check that it doesn't match some very common numeric forms. */
8286 | if (filter_name[0] == '0' &&
8287 | (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8288 | filter_name[1] == 'b' || filter_name[1] == 'B')) {
8289 | 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])
8290 | 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]);
8291 | }
8292 |
8293 | /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8294 |
8295 | /* Check that it contains at least one letter. */
8296 | bool_Bool have_letter = false0;
8297 | for (const char *s = filter_name; *s != '\0'; s++) {
8298 | if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8299 | have_letter = true1;
8300 | break;
8301 | }
8302 | }
8303 | if (!have_letter) {
8304 | 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)
8305 | filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z." , filter_name);
8306 | }
8307 |
8308 | /* Check for reserved keywords. */
8309 | if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8310 | 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)
8311 | " 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);
8312 | }
8313 | }
8314 |
8315 | int
8316 | proto_register_protocol(const char *name, const char *short_name,
8317 | const char *filter_name)
8318 | {
8319 | protocol_t *protocol;
8320 | header_field_info *hfinfo;
8321 |
8322 | check_protocol_filter_name_or_fail(filter_name);
8323 |
8324 | /*
8325 | * Add this protocol to the list of known protocols;
8326 | * the list is sorted by protocol short name.
8327 | */
8328 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8329 | protocol->name = name;
8330 | protocol->short_name = short_name;
8331 | protocol->filter_name = filter_name;
8332 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8333 | protocol->is_enabled = true1; /* protocol is enabled by default */
8334 | protocol->enabled_by_default = true1; /* see previous comment */
8335 | protocol->can_toggle = true1;
8336 | protocol->parent_proto_id = -1;
8337 | protocol->heur_list = NULL((void*)0);
8338 |
8339 | /* List will be sorted later by name, when all protocols completed registering */
8340 | protocols = g_list_prepend(protocols, protocol);
8341 | /*
8342 | * Make sure there's not already a protocol with any of those
8343 | * names. Crash if there is, as that's an error in the code
8344 | * or an inappropriate plugin.
8345 | * This situation has to be fixed to not register more than one
8346 | * protocol with the same name.
8347 | */
8348 | if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8349 | /* ws_error will terminate the program */
8350 | 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)
8351 | " 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);
8352 | }
8353 | if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8354 | 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)
8355 | " 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);
8356 | }
8357 | if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8358 | 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)
8359 | " 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);
8360 | }
8361 |
8362 | /* Here we allocate a new header_field_info struct */
8363 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info )));
8364 | hfinfo->name = name;
8365 | hfinfo->abbrev = filter_name;
8366 | hfinfo->type = FT_PROTOCOL;
8367 | hfinfo->display = BASE_NONE;
8368 | hfinfo->strings = protocol;
8369 | hfinfo->bitmask = 0;
8370 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8371 | hfinfo->blurb = NULL((void*)0);
8372 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8373 |
8374 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8375 | return protocol->proto_id;
8376 | }
8377 |
8378 | int
8379 | proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8380 | {
8381 | protocol_t *protocol;
8382 | header_field_info *hfinfo;
8383 |
8384 | /*
8385 | * Helper protocols don't need the strict rules as a "regular" protocol
8386 | * Just register it in a list and make a hf_ field from it
8387 | */
8388 | if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8389 | 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);
8390 | }
8391 |
8392 | if (parent_proto <= 0) {
8393 | 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)
8394 | " 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);
8395 | }
8396 |
8397 | check_protocol_filter_name_or_fail(filter_name);
8398 |
8399 | /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8400 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8401 | protocol->name = name;
8402 | protocol->short_name = short_name;
8403 | protocol->filter_name = filter_name;
8404 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8405 |
8406 | /* Enabling and toggling is really determined by parent protocol,
8407 | but provide default values here */
8408 | protocol->is_enabled = true1;
8409 | protocol->enabled_by_default = true1;
8410 | protocol->can_toggle = true1;
8411 |
8412 | protocol->parent_proto_id = parent_proto;
8413 | protocol->heur_list = NULL((void*)0);
8414 |
8415 | /* List will be sorted later by name, when all protocols completed registering */
8416 | protocols = g_list_prepend(protocols, protocol);
8417 |
8418 | /* Here we allocate a new header_field_info struct */
8419 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info )));
8420 | hfinfo->name = name;
8421 | hfinfo->abbrev = filter_name;
8422 | hfinfo->type = field_type;
8423 | hfinfo->display = BASE_NONE;
8424 | if (field_type == FT_BYTES) {
8425 | hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8426 | }
8427 | hfinfo->strings = protocol;
8428 | hfinfo->bitmask = 0;
8429 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8430 | hfinfo->blurb = NULL((void*)0);
8431 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8432 |
8433 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8434 | return protocol->proto_id;
8435 | }
8436 |
8437 | bool_Bool
8438 | proto_deregister_protocol(const char *short_name)
8439 | {
8440 | protocol_t *protocol;
8441 | header_field_info *hfinfo;
8442 | int proto_id;
8443 | unsigned i;
8444 |
8445 | proto_id = proto_get_id_by_short_name(short_name);
8446 | protocol = find_protocol_by_id(proto_id);
8447 | if (protocol == NULL((void*)0))
8448 | return false0;
8449 |
8450 | g_hash_table_remove(proto_names, protocol->name);
8451 | g_hash_table_remove(proto_short_names, (void *)short_name);
8452 | g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8453 |
8454 | if (protocol->fields) {
8455 | for (i = 0; i < protocol->fields->len; i++) {
8456 | hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8457 | hfinfo_remove_from_gpa_name_map(hfinfo);
8458 | expert_deregister_expertinfo(hfinfo->abbrev);
8459 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8460 | }
8461 | g_ptr_array_free(protocol->fields, true1);
8462 | protocol->fields = NULL((void*)0);
8463 | }
8464 |
8465 | g_list_free(protocol->heur_list);
8466 |
8467 | /* Remove this protocol from the list of known protocols */
8468 | protocols = g_list_remove(protocols, protocol);
8469 |
8470 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8471 | wmem_map_remove(gpa_name_map, protocol->filter_name);
8472 |
8473 | g_free(last_field_name);
8474 | last_field_name = NULL((void*)0);
8475 |
8476 | return true1;
8477 | }
8478 |
8479 | void
8480 | proto_register_alias(const int proto_id, const char *alias_name)
8481 | {
8482 | protocol_t *protocol;
8483 |
8484 | protocol = find_protocol_by_id(proto_id);
8485 | if (alias_name && protocol) {
8486 | g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8487 | }
8488 | }
8489 |
8490 | /*
8491 | * Routines to use to iterate over the protocols.
8492 | * The argument passed to the iterator routines is an opaque cookie to
8493 | * their callers; it's the GList pointer for the current element in
8494 | * the list.
8495 | * The ID of the protocol is returned, or -1 if there is no protocol.
8496 | */
8497 | int
8498 | proto_get_first_protocol(void **cookie)
8499 | {
8500 | protocol_t *protocol;
8501 |
8502 | if (protocols == NULL((void*)0))
8503 | return -1;
8504 | *cookie = protocols;
8505 | protocol = (protocol_t *)protocols->data;
8506 | return protocol->proto_id;
8507 | }
8508 |
8509 | int
8510 | proto_get_data_protocol(void *cookie)
8511 | {
8512 | GList *list_item = (GList *)cookie;
8513 |
8514 | protocol_t *protocol = (protocol_t *)list_item->data;
8515 | return protocol->proto_id;
8516 | }
8517 |
8518 | int
8519 | proto_get_next_protocol(void **cookie)
8520 | {
8521 | GList *list_item = (GList *)*cookie;
8522 | protocol_t *protocol;
8523 |
8524 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8525 | if (list_item == NULL((void*)0))
8526 | return -1;
8527 | *cookie = list_item;
8528 | protocol = (protocol_t *)list_item->data;
8529 | return protocol->proto_id;
8530 | }
8531 |
8532 | header_field_info *
8533 | proto_get_first_protocol_field(const int proto_id, void **cookie)
8534 | {
8535 | protocol_t *protocol = find_protocol_by_id(proto_id);
8536 |
8537 | if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8538 | return NULL((void*)0);
8539 |
8540 | *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8541 | return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8542 | }
8543 |
8544 | header_field_info *
8545 | proto_get_next_protocol_field(const int proto_id, void **cookie)
8546 | {
8547 | protocol_t *protocol = find_protocol_by_id(proto_id);
8548 | unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8549 |
8550 | i++;
8551 |
8552 | if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8553 | return NULL((void*)0);
8554 |
8555 | *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8556 | return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8557 | }
8558 |
8559 | protocol_t *
8560 | find_protocol_by_id(const int proto_id)
8561 | {
8562 | header_field_info *hfinfo;
8563 |
8564 | if (proto_id <= 0)
8565 | return NULL((void*)0);
8566 |
8567 | 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", 8567, __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", 8567, "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", 8567, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
8568 | if (hfinfo->type != FT_PROTOCOL) {
8569 | 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", 8569, "hfinfo->display & 0x00004000" ))));
8570 | }
8571 | return (protocol_t *)hfinfo->strings;
8572 | }
8573 |
8574 | int
8575 | proto_get_id(const protocol_t *protocol)
8576 | {
8577 | return protocol->proto_id;
8578 | }
8579 |
8580 | bool_Bool
8581 | proto_name_already_registered(const char *name)
8582 | {
8583 | DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 8583, "name", "No name present"))));
8584 |
8585 | if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8586 | return true1;
8587 | return false0;
8588 | }
8589 |
8590 | int
8591 | proto_get_id_by_filter_name(const char *filter_name)
8592 | {
8593 | const protocol_t *protocol = NULL((void*)0);
8594 |
8595 | 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", 8595, "filter_name", "No filter name present"))));
8596 |
8597 | protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8598 |
8599 | if (protocol == NULL((void*)0))
8600 | return -1;
8601 | return protocol->proto_id;
8602 | }
8603 |
8604 | int
8605 | proto_get_id_by_short_name(const char *short_name)
8606 | {
8607 | const protocol_t *protocol = NULL((void*)0);
8608 |
8609 | 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", 8609, "short_name", "No short name present"))));
8610 |
8611 | protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8612 |
8613 | if (protocol == NULL((void*)0))
8614 | return -1;
8615 | return protocol->proto_id;
8616 | }
8617 |
8618 | const char *
8619 | proto_get_protocol_name(const int proto_id)
8620 | {
8621 | protocol_t *protocol;
8622 |
8623 | protocol = find_protocol_by_id(proto_id);
8624 |
8625 | if (protocol == NULL((void*)0))
8626 | return NULL((void*)0);
8627 | return protocol->name;
8628 | }
8629 |
8630 | const char *
8631 | proto_get_protocol_short_name(const protocol_t *protocol)
8632 | {
8633 | if (protocol == NULL((void*)0))
8634 | return "(none)";
8635 | return protocol->short_name;
8636 | }
8637 |
8638 | const char *
8639 | proto_get_protocol_long_name(const protocol_t *protocol)
8640 | {
8641 | if (protocol == NULL((void*)0))
8642 | return "(none)";
8643 | return protocol->name;
8644 | }
8645 |
8646 | const char *
8647 | proto_get_protocol_filter_name(const int proto_id)
8648 | {
8649 | protocol_t *protocol;
8650 |
8651 | protocol = find_protocol_by_id(proto_id);
8652 | if (protocol == NULL((void*)0))
8653 | return "(none)";
8654 | return protocol->filter_name;
8655 | }
8656 |
8657 | void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8658 | {
8659 | heur_dtbl_entry_t* heuristic_dissector;
8660 |
8661 | if (protocol == NULL((void*)0))
8662 | return;
8663 |
8664 | heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8665 | if (heuristic_dissector != NULL((void*)0))
8666 | {
8667 | protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8668 | }
8669 | }
8670 |
8671 | void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8672 | {
8673 | if (protocol == NULL((void*)0))
8674 | return;
8675 |
8676 | g_list_foreach(protocol->heur_list, func, user_data);
8677 | }
8678 |
8679 | void
8680 | proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8681 | bool_Bool *is_tcp, bool_Bool *is_udp,
8682 | bool_Bool *is_sctp, bool_Bool *is_tls,
8683 | bool_Bool *is_rtp,
8684 | bool_Bool *is_lte_rlc)
8685 | {
8686 | wmem_list_frame_t *protos = wmem_list_head(layers);
8687 | int proto_id;
8688 | const char *proto_name;
8689 |
8690 | /* Walk the list of a available protocols in the packet and
8691 | attempt to find "major" ones. */
8692 | /* It might make more sense to assemble and return a bitfield. */
8693 | while (protos != NULL((void*)0))
8694 | {
8695 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8696 | proto_name = proto_get_protocol_filter_name(proto_id);
8697 |
8698 | if (is_ip && ((!strcmp(proto_name, "ip")) ||
8699 | (!strcmp(proto_name, "ipv6")))) {
8700 | *is_ip = true1;
8701 | } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8702 | *is_tcp = true1;
8703 | } else if (is_udp && !strcmp(proto_name, "udp")) {
8704 | *is_udp = true1;
8705 | } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8706 | *is_sctp = true1;
8707 | } else if (is_tls && !strcmp(proto_name, "tls")) {
8708 | *is_tls = true1;
8709 | } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8710 | *is_rtp = true1;
8711 | } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8712 | *is_lte_rlc = true1;
8713 | }
8714 |
8715 | protos = wmem_list_frame_next(protos);
8716 | }
8717 | }
8718 |
8719 | bool_Bool
8720 | proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8721 | {
8722 | wmem_list_frame_t *protos = wmem_list_head(layers);
8723 | int proto_id;
8724 | const char *name;
8725 |
8726 | /* Walk the list of a available protocols in the packet and
8727 | attempt to find the specified protocol. */
8728 | while (protos != NULL((void*)0))
8729 | {
8730 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8731 | name = proto_get_protocol_filter_name(proto_id);
8732 |
8733 | if (!strcmp(name, proto_name))
8734 | {
8735 | return true1;
8736 | }
8737 |
8738 | protos = wmem_list_frame_next(protos);
8739 | }
8740 |
8741 | return false0;
8742 | }
8743 |
8744 | char *
8745 | proto_list_layers(const packet_info *pinfo)
8746 | {
8747 | wmem_strbuf_t *buf;
8748 | wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8749 |
8750 | buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8751 |
8752 | /* Walk the list of layers in the packet and
8753 | return a string of all entries. */
8754 | while (layers != NULL((void*)0))
8755 | {
8756 | wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8757 |
8758 | layers = wmem_list_frame_next(layers);
8759 | if (layers != NULL((void*)0)) {
8760 | wmem_strbuf_append_c(buf, ':');
8761 | }
8762 | }
8763 |
8764 | return wmem_strbuf_finalize(buf);
8765 | }
8766 |
8767 | uint8_t
8768 | proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8769 | {
8770 | int *proto_layer_num_ptr;
8771 |
8772 | proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8773 | if (proto_layer_num_ptr == NULL((void*)0)) {
8774 | return 0;
8775 | }
8776 |
8777 | return (uint8_t)*proto_layer_num_ptr;
8778 | }
8779 |
8780 | bool_Bool
8781 | proto_is_pino(const protocol_t *protocol)
8782 | {
8783 | return (protocol->parent_proto_id != -1);
8784 | }
8785 |
8786 | bool_Bool
8787 | // NOLINTNEXTLINE(misc-no-recursion)
8788 | proto_is_protocol_enabled(const protocol_t *protocol)
8789 | {
8790 | if (protocol == NULL((void*)0))
8791 | return false0;
8792 |
8793 | //parent protocol determines enable/disable for helper dissectors
8794 | if (proto_is_pino(protocol))
8795 | return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8796 |
8797 | return protocol->is_enabled;
8798 | }
8799 |
8800 | bool_Bool
8801 | // NOLINTNEXTLINE(misc-no-recursion)
8802 | proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8803 | {
8804 | //parent protocol determines enable/disable for helper dissectors
8805 | if (proto_is_pino(protocol))
8806 | return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8807 |
8808 | return protocol->enabled_by_default;
8809 | }
8810 |
8811 | bool_Bool
8812 | // NOLINTNEXTLINE(misc-no-recursion)
8813 | proto_can_toggle_protocol(const int proto_id)
8814 | {
8815 | protocol_t *protocol;
8816 |
8817 | protocol = find_protocol_by_id(proto_id);
8818 | //parent protocol determines toggling for helper dissectors
8819 | if (proto_is_pino(protocol))
8820 | return proto_can_toggle_protocol(protocol->parent_proto_id);
8821 |
8822 | return protocol->can_toggle;
8823 | }
8824 |
8825 | void
8826 | proto_disable_by_default(const int proto_id)
8827 | {
8828 | protocol_t *protocol;
8829 |
8830 | protocol = find_protocol_by_id(proto_id);
8831 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8831, "protocol->can_toggle" ))));
8832 | 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", 8832, "proto_is_pino(protocol) == 0" ))));
8833 | protocol->is_enabled = false0;
8834 | protocol->enabled_by_default = false0;
8835 | }
8836 |
8837 | void
8838 | proto_set_decoding(const int proto_id, const bool_Bool enabled)
8839 | {
8840 | protocol_t *protocol;
8841 |
8842 | protocol = find_protocol_by_id(proto_id);
8843 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8843, "protocol->can_toggle" ))));
8844 | 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", 8844, "proto_is_pino(protocol) == 0" ))));
8845 | protocol->is_enabled = enabled;
8846 | }
8847 |
8848 | void
8849 | proto_disable_all(void)
8850 | {
8851 | /* This doesn't explicitly disable heuristic protocols,
8852 | * but the heuristic doesn't get called if the parent
8853 | * protocol isn't enabled.
8854 | */
8855 | protocol_t *protocol;
8856 | GList *list_item = protocols;
8857 |
8858 | if (protocols == NULL((void*)0))
8859 | return;
8860 |
8861 | while (list_item) {
8862 | protocol = (protocol_t *)list_item->data;
8863 | if (protocol->can_toggle) {
8864 | protocol->is_enabled = false0;
8865 | }
8866 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8867 | }
8868 | }
8869 |
8870 | static void
8871 | heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8872 | {
8873 | heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8874 |
8875 | heur->enabled = heur->enabled_by_default;
8876 | }
8877 |
8878 | void
8879 | proto_reenable_all(void)
8880 | {
8881 | protocol_t *protocol;
8882 | GList *list_item = protocols;
8883 |
8884 | if (protocols == NULL((void*)0))
8885 | return;
8886 |
8887 | while (list_item) {
8888 | protocol = (protocol_t *)list_item->data;
8889 | if (protocol->can_toggle)
8890 | protocol->is_enabled = protocol->enabled_by_default;
8891 | proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8892 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8893 | }
8894 | }
8895 |
8896 | void
8897 | proto_set_cant_toggle(const int proto_id)
8898 | {
8899 | protocol_t *protocol;
8900 |
8901 | protocol = find_protocol_by_id(proto_id);
8902 | protocol->can_toggle = false0;
8903 | }
8904 |
8905 | static int
8906 | proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8907 | {
8908 | g_ptr_array_add(proto->fields, hfi);
8909 |
8910 | return proto_register_field_init(hfi, parent);
8911 | }
8912 |
8913 | /* for use with static arrays only, since we don't allocate our own copies
8914 | of the header_field_info struct contained within the hf_register_info struct */
8915 | void
8916 | proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8917 | {
8918 | hf_register_info *ptr = hf;
8919 | protocol_t *proto;
8920 | int i;
8921 |
8922 | proto = find_protocol_by_id(parent);
8923 |
8924 | /* if (proto == NULL) - error or return? */
8925 |
8926 | if (proto->fields == NULL((void*)0)) {
8927 | /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8928 | * GLib introduced g_ptr_array_new_from_array, which might have
8929 | * given a reason to actually use it. (#17774)
8930 | */
8931 | proto->fields = g_ptr_array_sized_new(num_records);
8932 | }
8933 |
8934 | for (i = 0; i < num_records; i++, ptr++) {
8935 | /*
8936 | * Make sure we haven't registered this yet.
8937 | * Most fields have variables associated with them that
8938 | * are initialized to 0; some are initialized to -1 (which
8939 | * was the standard before 4.4).
8940 | *
8941 | * XXX - Since this is called almost 300000 times at startup,
8942 | * it might be nice to compare to only 0 and require
8943 | * dissectors to pass in zero for unregistered fields.
8944 | */
8945 | if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8946 | REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev)
8947 | "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)
8948 | ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev);
8949 | return;
8950 | }
8951 |
8952 | *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8953 | }
8954 | }
8955 |
8956 | /* deregister already registered fields */
8957 | void
8958 | proto_deregister_field (const int parent, int hf_id)
8959 | {
8960 | header_field_info *hfi;
8961 | protocol_t *proto;
8962 | unsigned i;
8963 |
8964 | g_free(last_field_name);
8965 | last_field_name = NULL((void*)0);
8966 |
8967 | if (hf_id == -1 || hf_id == 0)
8968 | return;
8969 |
8970 | proto = find_protocol_by_id (parent);
8971 | if (!proto || proto->fields == NULL((void*)0)) {
8972 | return;
8973 | }
8974 |
8975 | for (i = 0; i < proto->fields->len; i++) {
8976 | hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8977 | if (hfi->id == hf_id) {
8978 | /* Found the hf_id in this protocol */
8979 | wmem_map_remove(gpa_name_map, hfi->abbrev);
8980 | g_ptr_array_remove_index_fast(proto->fields, i);
8981 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8982 | return;
8983 | }
8984 | }
8985 | }
8986 |
8987 | /* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8988 | void
8989 | proto_deregister_all_fields_with_prefix(const int parent, const gchar *prefix)
8990 | {
8991 | header_field_info *hfinfo;
8992 | protocol_t *proto;
8993 |
8994 | g_free(last_field_name);
8995 | last_field_name = NULL((void*)0);
8996 |
8997 | proto = find_protocol_by_id(parent);
8998 | if (proto && proto->fields && proto->fields->len > 0) {
8999 | guint i = proto->fields->len;
9000 | do {
9001 | i--;
9002 |
9003 | hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9004 | 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) )) {
9005 | hfinfo_remove_from_gpa_name_map(hfinfo);
9006 | expert_deregister_expertinfo(hfinfo->abbrev);
9007 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9008 | g_ptr_array_remove_index_fast(proto->fields, i);
9009 | }
9010 | } while (i > 0);
9011 | }
9012 | }
9013 |
9014 | void
9015 | proto_add_deregistered_data (void *data)
9016 | {
9017 | g_ptr_array_add(deregistered_data, data);
9018 | }
9019 |
9020 | void
9021 | proto_add_deregistered_slice (size_t block_size, void *mem_block)
9022 | {
9023 | 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 )));
9024 |
9025 | slice_data->block_size = block_size;
9026 | slice_data->mem_block = mem_block;
9027 |
9028 | g_ptr_array_add(deregistered_slice, slice_data);
9029 | }
9030 |
9031 | void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9032 | {
9033 | if (field_strings == NULL((void*)0)) {
9034 | return;
9035 | }
9036 |
9037 | switch (field_type) {
9038 | case FT_FRAMENUM:
9039 | /* This is just an integer represented as a pointer */
9040 | break;
9041 | case FT_PROTOCOL: {
9042 | protocol_t *protocol = (protocol_t *)field_strings;
9043 | g_free((char *)protocol->short_name);
9044 | break;
9045 | }
9046 | case FT_BOOLEAN: {
9047 | true_false_string *tf = (true_false_string *)field_strings;
9048 | g_free((char *)tf->true_string);
9049 | g_free((char *)tf->false_string);
9050 | break;
9051 | }
9052 | case FT_UINT40:
9053 | case FT_INT40:
9054 | case FT_UINT48:
9055 | case FT_INT48:
9056 | case FT_UINT56:
9057 | case FT_INT56:
9058 | case FT_UINT64:
9059 | case FT_INT64: {
9060 | if (field_display & BASE_UNIT_STRING0x00001000) {
9061 | unit_name_string *unit = (unit_name_string *)field_strings;
9062 | g_free((char *)unit->singular);
9063 | g_free((char *)unit->plural);
9064 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9065 | range_string *rs = (range_string *)field_strings;
9066 | while (rs->strptr) {
9067 | g_free((char *)rs->strptr);
9068 | rs++;
9069 | }
9070 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9071 | val64_string_ext *vse = (val64_string_ext *)field_strings;
9072 | val64_string *vs = (val64_string *)vse->_vs_p;
9073 | while (vs->strptr) {
9074 | g_free((char *)vs->strptr);
9075 | vs++;
9076 | }
9077 | val64_string_ext_free(vse);
9078 | field_strings = NULL((void*)0);
9079 | } else if (field_display == BASE_CUSTOM) {
9080 | /* this will be a pointer to a function, don't free that */
9081 | field_strings = NULL((void*)0);
9082 | } else {
9083 | val64_string *vs64 = (val64_string *)field_strings;
9084 | while (vs64->strptr) {
9085 | g_free((char *)vs64->strptr);
9086 | vs64++;
9087 | }
9088 | }
9089 | break;
9090 | }
9091 | case FT_CHAR:
9092 | case FT_UINT8:
9093 | case FT_INT8:
9094 | case FT_UINT16:
9095 | case FT_INT16:
9096 | case FT_UINT24:
9097 | case FT_INT24:
9098 | case FT_UINT32:
9099 | case FT_INT32:
9100 | case FT_FLOAT:
9101 | case FT_DOUBLE: {
9102 | if (field_display & BASE_UNIT_STRING0x00001000) {
9103 | unit_name_string *unit = (unit_name_string *)field_strings;
9104 | g_free((char *)unit->singular);
9105 | g_free((char *)unit->plural);
9106 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9107 | range_string *rs = (range_string *)field_strings;
9108 | while (rs->strptr) {
9109 | g_free((char *)rs->strptr);
9110 | rs++;
9111 | }
9112 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9113 | value_string_ext *vse = (value_string_ext *)field_strings;
9114 | value_string *vs = (value_string *)vse->_vs_p;
9115 | while (vs->strptr) {
9116 | g_free((char *)vs->strptr);
9117 | vs++;
9118 | }
9119 | value_string_ext_free(vse);
9120 | field_strings = NULL((void*)0);
9121 | } else if (field_display == BASE_CUSTOM) {
9122 | /* this will be a pointer to a function, don't free that */
9123 | field_strings = NULL((void*)0);
9124 | } else {
9125 | value_string *vs = (value_string *)field_strings;
9126 | while (vs->strptr) {
9127 | g_free((char *)vs->strptr);
9128 | vs++;
9129 | }
9130 | }
9131 | break;
9132 | default:
9133 | break;
9134 | }
9135 | }
9136 |
9137 | if (field_type != FT_FRAMENUM) {
9138 | g_free((void *)field_strings);
9139 | }
9140 | }
9141 |
9142 | static void
9143 | free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9144 | {
9145 | header_field_info *hfi = (header_field_info *) data;
9146 | int hf_id = hfi->id;
9147 |
9148 | g_free((char *)hfi->name);
9149 | g_free((char *)hfi->abbrev);
9150 | g_free((char *)hfi->blurb);
9151 |
9152 | proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9153 |
9154 | if (hfi->parent == -1)
9155 | 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);
9156 |
9157 | gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9158 | }
9159 |
9160 | static void
9161 | free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9162 | {
9163 | g_free (data);
9164 | }
9165 |
9166 | static void
9167 | free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9168 | {
9169 | struct g_slice_data *slice_data = (struct g_slice_data *)data;
9170 |
9171 | g_slice_free1(slice_data->block_size, slice_data->mem_block);
9172 | 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);
9173 | }
9174 |
9175 | /* free deregistered fields and data */
9176 | void
9177 | proto_free_deregistered_fields (void)
9178 | {
9179 | expert_free_deregistered_expertinfos();
9180 |
9181 | g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9182 | g_ptr_array_free(deregistered_fields, true1);
9183 | deregistered_fields = g_ptr_array_new();
9184 |
9185 | g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9186 | g_ptr_array_free(deregistered_data, true1);
9187 | deregistered_data = g_ptr_array_new();
9188 |
9189 | g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9190 | g_ptr_array_free(deregistered_slice, true1);
9191 | deregistered_slice = g_ptr_array_new();
9192 | }
9193 |
9194 | static const value_string hf_display[] = {
9195 | { BASE_NONE, "BASE_NONE" },
9196 | { BASE_DEC, "BASE_DEC" },
9197 | { BASE_HEX, "BASE_HEX" },
9198 | { BASE_OCT, "BASE_OCT" },
9199 | { BASE_DEC_HEX, "BASE_DEC_HEX" },
9200 | { BASE_HEX_DEC, "BASE_HEX_DEC" },
9201 | { BASE_CUSTOM, "BASE_CUSTOM" },
9202 | { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9203 | { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9204 | { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9205 | { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9206 | { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9207 | { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9208 | { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9209 | { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9210 | { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9211 | { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9212 | { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9213 | { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9214 | { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9215 | { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9216 | { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9217 | { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9218 | { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9219 | { BASE_PT_UDP, "BASE_PT_UDP" },
9220 | { BASE_PT_TCP, "BASE_PT_TCP" },
9221 | { BASE_PT_DCCP, "BASE_PT_DCCP" },
9222 | { BASE_PT_SCTP, "BASE_PT_SCTP" },
9223 | { BASE_OUI, "BASE_OUI" },
9224 | { 0, NULL((void*)0) } };
9225 |
9226 | const char* proto_field_display_to_string(int field_display)
9227 | {
9228 | return val_to_str_const(field_display, hf_display, "Unknown");
9229 | }
9230 |
9231 | static inline port_type
9232 | display_to_port_type(field_display_e e)
9233 | {
9234 | switch (e) {
9235 | case BASE_PT_UDP:
9236 | return PT_UDP;
9237 | case BASE_PT_TCP:
9238 | return PT_TCP;
9239 | case BASE_PT_DCCP:
9240 | return PT_DCCP;
9241 | case BASE_PT_SCTP:
9242 | return PT_SCTP;
9243 | default:
9244 | break;
9245 | }
9246 | return PT_NONE;
9247 | }
9248 |
9249 | /* temporary function containing assert part for easier profiling */
9250 | static void
9251 | tmp_fld_check_assert(header_field_info *hfinfo)
9252 | {
9253 | char* tmp_str;
9254 |
9255 | /* The field must have a name (with length > 0) */
9256 | if (!hfinfo->name || !hfinfo->name[0]) {
9257 | if (hfinfo->abbrev)
9258 | /* Try to identify the field */
9259 | 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)
9260 | hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name" , hfinfo->abbrev);
9261 | else
9262 | /* Hum, no luck */
9263 | 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)" );
9264 | }
9265 |
9266 | /* fields with an empty string for an abbreviation aren't filterable */
9267 | if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9268 | 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);
9269 |
9270 | /* TODO: This check is a significant percentage of startup time (~10%),
9271 | although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9272 | It might be nice to have a way to disable this check when, e.g.,
9273 | running TShark many times with the same configuration. */
9274 | /* Check that the filter name (abbreviation) is legal;
9275 | * it must contain only alphanumerics, '-', "_", and ".". */
9276 | unsigned char c;
9277 | c = module_check_valid_name(hfinfo->abbrev, false0);
9278 | if (c) {
9279 | if (c == '.') {
9280 | 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);
9281 | } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9282 | 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);
9283 | } else {
9284 | 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);
9285 | }
9286 | }
9287 |
9288 | /* These types of fields are allowed to have value_strings,
9289 | * true_false_strings or a protocol_t struct
9290 | */
9291 | if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9292 | switch (hfinfo->type) {
9293 |
9294 | /*
9295 | * These types are allowed to support display value_strings,
9296 | * value64_strings, the extended versions of the previous
9297 | * two, range strings, or unit strings.
9298 | */
9299 | case FT_CHAR:
9300 | case FT_UINT8:
9301 | case FT_UINT16:
9302 | case FT_UINT24:
9303 | case FT_UINT32:
9304 | case FT_UINT40:
9305 | case FT_UINT48:
9306 | case FT_UINT56:
9307 | case FT_UINT64:
9308 | case FT_INT8:
9309 | case FT_INT16:
9310 | case FT_INT24:
9311 | case FT_INT32:
9312 | case FT_INT40:
9313 | case FT_INT48:
9314 | case FT_INT56:
9315 | case FT_INT64:
9316 | case FT_BOOLEAN:
9317 | case FT_PROTOCOL:
9318 | break;
9319 |
9320 | /*
9321 | * This is allowed to have a value of type
9322 | * enum ft_framenum_type to indicate what relationship
9323 | * the frame in question has to the frame in which
9324 | * the field is put.
9325 | */
9326 | case FT_FRAMENUM:
9327 | break;
9328 |
9329 | /*
9330 | * These types are allowed to support only unit strings.
9331 | */
9332 | case FT_FLOAT:
9333 | case FT_DOUBLE:
9334 | case FT_IEEE_11073_SFLOAT:
9335 | case FT_IEEE_11073_FLOAT:
9336 | if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9337 | 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))
9338 | " (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))
9339 | 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));
9340 | }
9341 | break;
9342 |
9343 | /*
9344 | * These types are allowed to support display
9345 | * time_value_strings.
9346 | */
9347 | case FT_ABSOLUTE_TIME:
9348 | if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9349 | hfinfo->display & BASE_EXT_STRING0x00000200 ||
9350 | hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9351 | hfinfo->display & BASE_UNIT_STRING0x00001000) {
9352 | 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))
9353 | " (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))
9354 | 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));
9355 | }
9356 | break;
9357 |
9358 | /*
9359 | * This type is only allowed to support a string if it's
9360 | * a protocol (for pinos).
9361 | */
9362 | case FT_BYTES:
9363 | if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9364 | 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))
9365 | " (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))
9366 | 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));
9367 | }
9368 | break;
9369 |
9370 | default:
9371 | 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))
9372 | " (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))
9373 | 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));
9374 | }
9375 | }
9376 |
9377 | /* TODO: This check may slow down startup, and output quite a few warnings.
9378 | It would be good to be able to enable this (and possibly other checks?)
9379 | in non-release builds. */
9380 | #ifdef ENABLE_CHECK_FILTER
9381 | /* Check for duplicate value_string values.
9382 | There are lots that have the same value *and* string, so for now only
9383 | report those that have same value but different string. */
9384 | if ((hfinfo->strings != NULL((void*)0)) &&
9385 | !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9386 | !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9387 | !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9388 | (
9389 | (hfinfo->type == FT_CHAR) ||
9390 | (hfinfo->type == FT_UINT8) ||
9391 | (hfinfo->type == FT_UINT16) ||
9392 | (hfinfo->type == FT_UINT24) ||
9393 | (hfinfo->type == FT_UINT32) ||
9394 | (hfinfo->type == FT_INT8) ||
9395 | (hfinfo->type == FT_INT16) ||
9396 | (hfinfo->type == FT_INT24) ||
9397 | (hfinfo->type == FT_INT32) )) {
9398 |
9399 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9400 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9401 | const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9402 | CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9403 | } else {
9404 | const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9405 | CHECK_HF_VALUE(value_string, "u", start_values);
9406 | }
9407 | } else {
9408 | const value_string *start_values = (const value_string*)hfinfo->strings;
9409 | CHECK_HF_VALUE(value_string, "u", start_values);
9410 | }
9411 | }
9412 |
9413 | if (hfinfo->type == FT_BOOLEAN) {
9414 | const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9415 | if (tfs) {
9416 | if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9417 | 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" , 9419, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string); } } while (0)
9418 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9419, __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 | tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9419, __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 | }
9421 | }
9422 | }
9423 |
9424 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9425 | const range_string *rs = (const range_string*)(hfinfo->strings);
9426 | if (rs) {
9427 | const range_string *this_it = rs;
9428 |
9429 | do {
9430 | if (this_it->value_max < this_it->value_min) {
9431 | 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" , 9435, __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)
9432 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9435, __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 | this_it->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9435, __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->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9435, __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_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9435, __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;
9437 | continue;
9438 | }
9439 |
9440 | for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9441 | /* Not OK if this one is completely hidden by an earlier one! */
9442 | if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9443 | 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" , 9449, __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)
9444 | "(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" , 9449, __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 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9449, __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 | prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9449, __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->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9449, __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 | this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9449, __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->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9449, __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 | }
9451 | }
9452 | ++this_it;
9453 | } while (this_it->strptr);
9454 | }
9455 | }
9456 | #endif
9457 |
9458 | switch (hfinfo->type) {
9459 |
9460 | case FT_CHAR:
9461 | /* Require the char type to have BASE_HEX, BASE_OCT,
9462 | * BASE_CUSTOM, or BASE_NONE as its base.
9463 | *
9464 | * If the display value is BASE_NONE and there is a
9465 | * strings conversion then the dissector writer is
9466 | * telling us that the field's numerical value is
9467 | * meaningless; we'll avoid showing the value to the
9468 | * user.
9469 | */
9470 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9471 | case BASE_HEX:
9472 | case BASE_OCT:
9473 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9474 | break;
9475 | case BASE_NONE:
9476 | if (hfinfo->strings == NULL((void*)0))
9477 | 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 ))
9478 | " 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 ))
9479 | " 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 ))
9480 | 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 ))
9481 | 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 ));
9482 | break;
9483 | default:
9484 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9485 | 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)
9486 | " 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)
9487 | 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)
9488 | 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);
9489 | //wmem_free(NULL, tmp_str);
9490 | }
9491 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9492 | 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 ))
9493 | 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 ))
9494 | 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 ));
9495 | }
9496 | break;
9497 | case FT_INT8:
9498 | case FT_INT16:
9499 | case FT_INT24:
9500 | case FT_INT32:
9501 | case FT_INT40:
9502 | case FT_INT48:
9503 | case FT_INT56:
9504 | case FT_INT64:
9505 | /* Hexadecimal and octal are, in printf() and everywhere
9506 | * else, unsigned so don't allow dissectors to register a
9507 | * signed field to be displayed unsigned. (Else how would
9508 | * we display negative values?)
9509 | */
9510 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9511 | case BASE_HEX:
9512 | case BASE_OCT:
9513 | case BASE_DEC_HEX:
9514 | case BASE_HEX_DEC:
9515 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9516 | 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)
9517 | 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)
9518 | 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);
9519 | //wmem_free(NULL, tmp_str);
9520 | }
9521 | /* FALL THROUGH */
9522 | case FT_UINT8:
9523 | case FT_UINT16:
9524 | case FT_UINT24:
9525 | case FT_UINT32:
9526 | case FT_UINT40:
9527 | case FT_UINT48:
9528 | case FT_UINT56:
9529 | case FT_UINT64:
9530 | 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 ))) {
9531 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9532 | if (hfinfo->type != FT_UINT16) {
9533 | 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))
9534 | 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))
9535 | 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));
9536 | }
9537 | if (hfinfo->strings != NULL((void*)0)) {
9538 | 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)
9539 | 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)
9540 | 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);
9541 | }
9542 | if (hfinfo->bitmask != 0) {
9543 | 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)
9544 | 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)
9545 | 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);
9546 | }
9547 | wmem_free(NULL((void*)0), tmp_str);
9548 | break;
9549 | }
9550 |
9551 | if (hfinfo->display == BASE_OUI) {
9552 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9553 | if (hfinfo->type != FT_UINT24) {
9554 | 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))
9555 | 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))
9556 | 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));
9557 | }
9558 | if (hfinfo->strings != NULL((void*)0)) {
9559 | 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)
9560 | 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)
9561 | 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);
9562 | }
9563 | if (hfinfo->bitmask != 0) {
9564 | 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)
9565 | 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)
9566 | 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);
9567 | }
9568 | wmem_free(NULL((void*)0), tmp_str);
9569 | break;
9570 | }
9571 |
9572 | /* Require integral types (other than frame number,
9573 | * which is always displayed in decimal) to have a
9574 | * number base.
9575 | *
9576 | * If the display value is BASE_NONE and there is a
9577 | * strings conversion then the dissector writer is
9578 | * telling us that the field's numerical value is
9579 | * meaningless; we'll avoid showing the value to the
9580 | * user.
9581 | */
9582 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9583 | case BASE_DEC:
9584 | case BASE_HEX:
9585 | case BASE_OCT:
9586 | case BASE_DEC_HEX:
9587 | case BASE_HEX_DEC:
9588 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9589 | break;
9590 | case BASE_NONE:
9591 | if (hfinfo->strings == NULL((void*)0)) {
9592 | 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 ))
9593 | " 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 ))
9594 | " 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 ))
9595 | 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 ))
9596 | 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 ));
9597 | }
9598 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9599 | 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 ))
9600 | " 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 ))
9601 | " 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 ))
9602 | 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 ))
9603 | 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 ));
9604 | }
9605 | break;
9606 |
9607 | default:
9608 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9609 | 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)
9610 | " 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)
9611 | 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)
9612 | 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);
9613 | //wmem_free(NULL, tmp_str);
9614 | }
9615 | break;
9616 | case FT_BYTES:
9617 | case FT_UINT_BYTES:
9618 | /* Require bytes to have a "display type" that could
9619 | * add a character between displayed bytes.
9620 | */
9621 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9622 | case BASE_NONE:
9623 | case SEP_DOT:
9624 | case SEP_DASH:
9625 | case SEP_COLON:
9626 | case SEP_SPACE:
9627 | break;
9628 | default:
9629 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9630 | 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)
9631 | 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);
9632 | //wmem_free(NULL, tmp_str);
9633 | }
9634 | if (hfinfo->bitmask != 0)
9635 | 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 ))
9636 | 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 ))
9637 | 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 ));
9638 | //allowed to support string if its a protocol (for pinos)
9639 | if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9640 | 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 ))
9641 | 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 ))
9642 | 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 ));
9643 | break;
9644 |
9645 | case FT_PROTOCOL:
9646 | case FT_FRAMENUM:
9647 | if (hfinfo->display != BASE_NONE) {
9648 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9649 | 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)
9650 | 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)
9651 | 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);
9652 | //wmem_free(NULL, tmp_str);
9653 | }
9654 | if (hfinfo->bitmask != 0)
9655 | 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 ))
9656 | 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 ))
9657 | 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 ));
9658 | break;
9659 |
9660 | case FT_BOOLEAN:
9661 | break;
9662 |
9663 | case FT_ABSOLUTE_TIME:
9664 | if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL && ((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)) {
9665 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9666 | 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)
9667 | 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);
9668 | //wmem_free(NULL, tmp_str);
9669 | }
9670 | if (hfinfo->bitmask != 0)
9671 | 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 ))
9672 | 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 ))
9673 | 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 ));
9674 | break;
9675 |
9676 | case FT_STRING:
9677 | case FT_STRINGZ:
9678 | case FT_UINT_STRING:
9679 | case FT_STRINGZPAD:
9680 | case FT_STRINGZTRUNC:
9681 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9682 | case BASE_NONE:
9683 | case BASE_STR_WSP:
9684 | break;
9685 |
9686 | default:
9687 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9688 | 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)
9689 | " 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)
9690 | 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)
9691 | 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);
9692 | //wmem_free(NULL, tmp_str);
9693 | }
9694 |
9695 | if (hfinfo->bitmask != 0)
9696 | 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 ))
9697 | 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 ))
9698 | 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 ));
9699 | if (hfinfo->strings != NULL((void*)0))
9700 | 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 ))
9701 | 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 ))
9702 | 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 ));
9703 | break;
9704 |
9705 | case FT_IPv4:
9706 | switch (hfinfo->display) {
9707 | case BASE_NONE:
9708 | case BASE_NETMASK:
9709 | break;
9710 |
9711 | default:
9712 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9713 | 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)
9714 | " 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)
9715 | 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)
9716 | 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);
9717 | //wmem_free(NULL, tmp_str);
9718 | break;
9719 | }
9720 | break;
9721 | case FT_FLOAT:
9722 | case FT_DOUBLE:
9723 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9724 | case BASE_NONE:
9725 | case BASE_DEC:
9726 | case BASE_HEX:
9727 | case BASE_EXP:
9728 | case BASE_CUSTOM:
9729 | break;
9730 | default:
9731 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9732 | 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)
9733 | " 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)
9734 | 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)
9735 | 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);
9736 | //wmem_free(NULL, tmp_str);
9737 | }
9738 | if (hfinfo->bitmask != 0)
9739 | 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 ))
9740 | 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 ))
9741 | 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 ));
9742 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9743 | 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 ))
9744 | 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 ))
9745 | 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 ));
9746 | break;
9747 | case FT_IEEE_11073_SFLOAT:
9748 | case FT_IEEE_11073_FLOAT:
9749 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9750 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9751 | 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)
9752 | 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)
9753 | 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)
9754 | 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);
9755 | //wmem_free(NULL, tmp_str);
9756 | }
9757 | if (hfinfo->bitmask != 0)
9758 | 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 ))
9759 | 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 ))
9760 | 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 ));
9761 | if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9762 | 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 ))
9763 | 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 ))
9764 | 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 ));
9765 | break;
9766 | default:
9767 | if (hfinfo->display != BASE_NONE) {
9768 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9769 | 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)
9770 | 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)
9771 | 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)
9772 | 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);
9773 | //wmem_free(NULL, tmp_str);
9774 | }
9775 | if (hfinfo->bitmask != 0)
9776 | 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 ))
9777 | 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 ))
9778 | 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 ));
9779 | if (hfinfo->strings != NULL((void*)0))
9780 | 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 ))
9781 | 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 ))
9782 | 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 ));
9783 | break;
9784 | }
9785 | }
9786 |
9787 | static void
9788 | register_type_length_mismatch(void)
9789 | {
9790 | static ei_register_info ei[] = {
9791 | { &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)}} }},
9792 | { &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)}} }},
9793 | };
9794 |
9795 | expert_module_t* expert_type_length_mismatch;
9796 |
9797 | proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9798 |
9799 | expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9800 | expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9801 |
9802 | /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9803 | disabling them makes no sense. */
9804 | proto_set_cant_toggle(proto_type_length_mismatch);
9805 | }
9806 |
9807 | static void
9808 | register_byte_array_string_decodinws_error(void)
9809 | {
9810 | static ei_register_info ei[] = {
9811 | { &ei_byte_array_string_decoding_failed_error,
9812 | { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9813 | "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)}}
9814 | }
9815 | },
9816 | };
9817 |
9818 | expert_module_t* expert_byte_array_string_decoding_error;
9819 |
9820 | proto_byte_array_string_decoding_error =
9821 | proto_register_protocol("Byte Array-String Decoding Error",
9822 | "Byte Array-string decoding error",
9823 | "_ws.byte_array_string.decoding_error");
9824 |
9825 | expert_byte_array_string_decoding_error =
9826 | expert_register_protocol(proto_byte_array_string_decoding_error);
9827 | expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9828 |
9829 | /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9830 | disabling them makes no sense. */
9831 | proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9832 | }
9833 |
9834 | static void
9835 | register_date_time_string_decodinws_error(void)
9836 | {
9837 | static ei_register_info ei[] = {
9838 | { &ei_date_time_string_decoding_failed_error,
9839 | { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9840 | "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)}}
9841 | }
9842 | },
9843 | };
9844 |
9845 | expert_module_t* expert_date_time_string_decoding_error;
9846 |
9847 | proto_date_time_string_decoding_error =
9848 | proto_register_protocol("Date and Time-String Decoding Error",
9849 | "Date and Time-string decoding error",
9850 | "_ws.date_time_string.decoding_error");
9851 |
9852 | expert_date_time_string_decoding_error =
9853 | expert_register_protocol(proto_date_time_string_decoding_error);
9854 | expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9855 |
9856 | /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9857 | disabling them makes no sense. */
9858 | proto_set_cant_toggle(proto_date_time_string_decoding_error);
9859 | }
9860 |
9861 | static void
9862 | register_string_errors(void)
9863 | {
9864 | static ei_register_info ei[] = {
9865 | { &ei_string_trailing_characters,
9866 | { "_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)}} }
9867 | },
9868 | };
9869 |
9870 | expert_module_t* expert_string_errors;
9871 |
9872 | proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9873 |
9874 | expert_string_errors = expert_register_protocol(proto_string_errors);
9875 | expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9876 |
9877 | /* "String Errors" isn't really a protocol, it's an error indication;
9878 | disabling them makes no sense. */
9879 | proto_set_cant_toggle(proto_string_errors);
9880 | }
9881 |
9882 | static int
9883 | proto_register_field_init(header_field_info *hfinfo, const int parent)
9884 | {
9885 |
9886 | tmp_fld_check_assert(hfinfo);
9887 |
9888 | hfinfo->parent = parent;
9889 | hfinfo->same_name_next = NULL((void*)0);
9890 | hfinfo->same_name_prev_id = -1;
9891 |
9892 | /* if we always add and never delete, then id == len - 1 is correct */
9893 | if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9894 | if (!gpa_hfinfo.hfi) {
9895 | gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9896 | gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9897 | /* The entry with index 0 is not used. */
9898 | gpa_hfinfo.hfi[0] = NULL((void*)0);
9899 | gpa_hfinfo.len = 1;
9900 | } else {
9901 | gpa_hfinfo.allocated_len += 1000;
9902 | gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9903 | sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9904 | /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9905 | }
9906 | }
9907 | gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9908 | gpa_hfinfo.len++;
9909 | hfinfo->id = gpa_hfinfo.len - 1;
9910 |
9911 | /* if we have real names, enter this field in the name tree */
9912 | /* Already checked in tmp_fld_check_assert */
9913 | /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9914 | {
9915 |
9916 | header_field_info *same_name_next_hfinfo;
9917 |
9918 | /* We allow multiple hfinfo's to be registered under the same
9919 | * abbreviation. This was done for X.25, as, depending
9920 | * on whether it's modulo-8 or modulo-128 operation,
9921 | * some bitfield fields may be in different bits of
9922 | * a byte, and we want to be able to refer to that field
9923 | * with one name regardless of whether the packets
9924 | * are modulo-8 or modulo-128 packets. */
9925 |
9926 | /* wmem_map_insert - if key is already present the previous
9927 | * hfinfo with the same key/name is returned, otherwise NULL */
9928 | same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9929 | if (same_name_hfinfo) {
9930 | /* There's already a field with this name.
9931 | * Put the current field *before* that field
9932 | * in the list of fields with this name, Thus,
9933 | * we end up with an effectively
9934 | * doubly-linked-list of same-named hfinfo's,
9935 | * with the head of the list (stored in the
9936 | * hash) being the last seen hfinfo.
9937 | */
9938 | same_name_next_hfinfo =
9939 | same_name_hfinfo->same_name_next;
9940 |
9941 | hfinfo->same_name_next = same_name_next_hfinfo;
9942 | if (same_name_next_hfinfo)
9943 | same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9944 |
9945 | same_name_hfinfo->same_name_next = hfinfo;
9946 | hfinfo->same_name_prev_id = same_name_hfinfo->id;
9947 | #ifdef ENABLE_CHECK_FILTER
9948 | while (same_name_hfinfo) {
9949 | if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9950 | 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" , 9950, __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);
9951 | same_name_hfinfo = same_name_hfinfo->same_name_next;
9952 | }
9953 | #endif
9954 | }
9955 | }
9956 |
9957 | return hfinfo->id;
9958 | }
9959 |
9960 | void
9961 | proto_register_subtree_array(int * const *indices, const int num_indices)
9962 | {
9963 | int i;
9964 | int *const *ptr = indices;
9965 |
9966 | /*
9967 | * If we've already allocated the array of tree types, expand
9968 | * it; this lets plugins such as mate add tree types after
9969 | * the initial startup. (If we haven't already allocated it,
9970 | * we don't allocate it; on the first pass, we just assign
9971 | * ett values and keep track of how many we've assigned, and
9972 | * when we're finished registering all dissectors we allocate
9973 | * the array, so that we do only one allocation rather than
9974 | * wasting CPU time and memory by growing the array for each
9975 | * dissector that registers ett values.)
9976 | */
9977 | if (tree_is_expanded != NULL((void*)0)) {
9978 | tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9979 |
9980 | /* set new items to 0 */
9981 | /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9982 | for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9983 | tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9984 | }
9985 |
9986 | /*
9987 | * Assign "num_indices" subtree numbers starting at "num_tree_types",
9988 | * returning the indices through the pointers in the array whose
9989 | * first element is pointed to by "indices", and update
9990 | * "num_tree_types" appropriately.
9991 | */
9992 | for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9993 | if (**ptr != -1 && **ptr != 0) {
9994 | 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.")
9995 | " 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.")
9996 | " 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.")
9997 | " 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.");
9998 | }
9999 | **ptr = num_tree_types;
10000 | }
10001 | }
10002 |
10003 | static void
10004 | mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10005 | {
10006 | static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10007 | const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10008 | char *last_char;
10009 |
10010 | /* ..... field_name: dataaaaaaaaaaaaa
10011 | * |
10012 | * ^^^^^ name_pos
10013 | *
10014 | * ..... field_name […]: dataaaaaaaaaaaaa
10015 | *
10016 | * name_pos==0 means that we have only data or only a field_name
10017 | */
10018 |
10019 | ws_assert(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10019, __func__, "assertion failed: %s" , "size > trunc_len"); } while (0);
10020 |
10021 | if (name_pos >= size - trunc_len) {
10022 | /* No room for trunc_str after the field_name, put it first. */
10023 | name_pos = 0;
10024 | }
10025 |
10026 | memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10027 | if (name_pos == 0) {
10028 | /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10029 | memcpy(label_str, trunc_str + 1, trunc_len);
10030 | } else {
10031 | memcpy(label_str + name_pos, trunc_str, trunc_len);
10032 | }
10033 | /* in general, label_str is UTF-8
10034 | we can truncate it only at the beginning of a new character
10035 | we go backwards from the byte right after our buffer and
10036 | find the next starting byte of a UTF-8 character, this is
10037 | where we cut
10038 | there's no need to use g_utf8_find_prev_char(), the search
10039 | will always succeed since we copied trunc_str into the
10040 | buffer */
10041 | /* g_utf8_prev_char does not deference the memory address
10042 | * passed in (until after decrementing it, so it is perfectly
10043 | * legal to pass in a pointer one past the last element.
10044 | */
10045 | last_char = g_utf8_prev_char(label_str + size);
10046 | *last_char = '\0';
10047 |
10048 | if (value_pos && *value_pos > 0) {
10049 | if (name_pos == 0) {
10050 | *value_pos += trunc_len;
10051 | } else {
10052 | /* Move one back to include trunc_str in the value. */
10053 | *value_pos -= 1;
10054 | }
10055 | }
10056 |
10057 | /* Check if value_pos is past label_str. */
10058 | if (value_pos && *value_pos >= size) {
10059 | *value_pos = size - 1;
10060 | }
10061 | }
10062 |
10063 | static void
10064 | label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10065 | {
10066 | mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10067 | }
10068 |
10069 | static size_t
10070 | label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10071 | {
10072 | size_t name_pos;
10073 |
10074 | /* "%s: %s", hfinfo->name, text */
10075 | name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10076 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10077 | pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10078 | if (value_pos) {
10079 | *value_pos = pos;
10080 | }
10081 | pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, text ? text : "(null)", label_strcat_flags(hfinfo));
10082 | }
10083 |
10084 | if (pos >= ITEM_LABEL_LENGTH240) {
10085 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10086 | label_mark_truncated(label_str, name_pos, value_pos);
10087 | }
10088 |
10089 | return pos;
10090 | }
10091 |
10092 | static size_t
10093 | label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10094 | {
10095 | size_t name_pos;
10096 |
10097 | /* "%s: %s (%s)", hfinfo->name, text, descr */
10098 | name_pos = pos = label_concat(label_str, pos, hfinfo->name)ws_label_strcpy(label_str, 240, pos, hfinfo->name, 0);
10099 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10100 | pos = label_concat(label_str, pos, ": ")ws_label_strcpy(label_str, 240, pos, ": ", 0);
10101 | if (value_pos) {
10102 | *value_pos = pos;
10103 | }
10104 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10105 | pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)" , 0);
10106 | pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0 );
10107 | } else {
10108 | pos = label_concat(label_str, pos, text ? text : "(null)")ws_label_strcpy(label_str, 240, pos, text ? text : "(null)", 0 );
10109 | pos = label_concat(label_str, pos, " (")ws_label_strcpy(label_str, 240, pos, " (", 0);
10110 | pos = label_concat(label_str, pos, descr ? descr : "(null)")ws_label_strcpy(label_str, 240, pos, descr ? descr : "(null)" , 0);
10111 | pos = label_concat(label_str, pos, ")")ws_label_strcpy(label_str, 240, pos, ")", 0);
10112 | }
10113 | }
10114 |
10115 | if (pos >= ITEM_LABEL_LENGTH240) {
10116 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10117 | label_mark_truncated(label_str, name_pos, value_pos);
10118 | }
10119 |
10120 | return pos;
10121 | }
10122 |
10123 | void
10124 | proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10125 | {
10126 | const header_field_info *hfinfo;
10127 | const char *str;
10128 | const uint8_t *bytes;
10129 | uint32_t integer;
10130 | const ipv4_addr_and_mask *ipv4;
10131 | const ipv6_addr_and_prefix *ipv6;
10132 | const e_guid_t *guid;
10133 | char *name;
10134 | address addr;
10135 | char *addr_str;
10136 | char *tmp;
10137 |
10138 | if (!label_str) {
10139 | ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10139, __func__, "NULL label_str passed to proto_item_fill_label." ); } } while (0);
10140 | return;
10141 | }
10142 |
10143 | label_str[0]= '\0';
10144 |
10145 | if (!fi) {
10146 | return;
10147 | }
10148 |
10149 | hfinfo = fi->hfinfo;
10150 |
10151 | switch (hfinfo->type) {
10152 | case FT_NONE:
10153 | case FT_PROTOCOL:
10154 | (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10155 | if (value_pos) {
10156 | *value_pos = strlen(hfinfo->name);
10157 | }
10158 | break;
10159 |
10160 | case FT_BOOLEAN:
10161 | fill_label_boolean(fi, label_str, value_pos);
10162 | break;
10163 |
10164 | case FT_BYTES:
10165 | case FT_UINT_BYTES:
10166 | tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10167 | fvalue_get_bytes_data(fi->value),
10168 | (unsigned)fvalue_length2(fi->value));
10169 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10170 | wmem_free(NULL((void*)0), tmp);
10171 | break;
10172 |
10173 | case FT_CHAR:
10174 | if (hfinfo->bitmask) {
10175 | fill_label_bitfield_char(fi, label_str, value_pos);
10176 | } else {
10177 | fill_label_char(fi, label_str, value_pos);
10178 | }
10179 | break;
10180 |
10181 | /* Four types of integers to take care of:
10182 | * Bitfield, with val_string
10183 | * Bitfield, w/o val_string
10184 | * Non-bitfield, with val_string
10185 | * Non-bitfield, w/o val_string
10186 | */
10187 | case FT_UINT8:
10188 | case FT_UINT16:
10189 | case FT_UINT24:
10190 | case FT_UINT32:
10191 | if (hfinfo->bitmask) {
10192 | fill_label_bitfield(fi, label_str, value_pos, false0);
10193 | } else {
10194 | fill_label_number(fi, label_str, value_pos, false0);
10195 | }
10196 | break;
10197 |
10198 | case FT_FRAMENUM:
10199 | fill_label_number(fi, label_str, value_pos, false0);
10200 | break;
10201 |
10202 | case FT_UINT40:
10203 | case FT_UINT48:
10204 | case FT_UINT56:
10205 | case FT_UINT64:
10206 | if (hfinfo->bitmask) {
10207 | fill_label_bitfield64(fi, label_str, value_pos, false0);
10208 | } else {
10209 | fill_label_number64(fi, label_str, value_pos, false0);
10210 | }
10211 | break;
10212 |
10213 | case FT_INT8:
10214 | case FT_INT16:
10215 | case FT_INT24:
10216 | case FT_INT32:
10217 | if (hfinfo->bitmask) {
10218 | fill_label_bitfield(fi, label_str, value_pos, true1);
10219 | } else {
10220 | fill_label_number(fi, label_str, value_pos, true1);
10221 | }
10222 | break;
10223 |
10224 | case FT_INT40:
10225 | case FT_INT48:
10226 | case FT_INT56:
10227 | case FT_INT64:
10228 | if (hfinfo->bitmask) {
10229 | fill_label_bitfield64(fi, label_str, value_pos, true1);
10230 | } else {
10231 | fill_label_number64(fi, label_str, value_pos, true1);
10232 | }
10233 | break;
10234 |
10235 | case FT_FLOAT:
10236 | case FT_DOUBLE:
10237 | fill_label_float(fi, label_str, value_pos);
10238 | break;
10239 |
10240 | case FT_ABSOLUTE_TIME:
10241 | {
10242 | const nstime_t *value = fvalue_get_time(fi->value);
10243 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10244 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10245 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10246 | }
10247 | if (hfinfo->strings) {
10248 | /*
10249 | * Table of time valus to be displayed
10250 | * specially.
10251 | */
10252 | const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10253 | if (time_string != NULL((void*)0)) {
10254 | label_fill(label_str, 0, hfinfo, time_string, value_pos);
10255 | break;
10256 | }
10257 | }
10258 | tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10259 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10260 | wmem_free(NULL((void*)0), tmp);
10261 | break;
10262 | }
10263 | case FT_RELATIVE_TIME:
10264 | tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10265 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10266 | wmem_free(NULL((void*)0), tmp);
10267 | break;
10268 |
10269 | case FT_IPXNET:
10270 | integer = fvalue_get_uinteger(fi->value);
10271 | tmp = get_ipxnet_name(NULL((void*)0), integer);
10272 | addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10273 | label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10274 | wmem_free(NULL((void*)0), tmp);
10275 | wmem_free(NULL((void*)0), addr_str);
10276 | break;
10277 |
10278 | case FT_VINES:
10279 | addr.type = AT_VINES;
10280 | addr.len = VINES_ADDR_LEN6;
10281 | addr.data = fvalue_get_bytes_data(fi->value);
10282 |
10283 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10284 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10285 | wmem_free(NULL((void*)0), addr_str);
10286 | break;
10287 |
10288 | case FT_ETHER:
10289 | bytes = fvalue_get_bytes_data(fi->value);
10290 |
10291 | addr.type = AT_ETHER;
10292 | addr.len = 6;
10293 | addr.data = bytes;
10294 |
10295 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10296 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10297 | wmem_free(NULL((void*)0), addr_str);
10298 | break;
10299 |
10300 | case FT_IPv4:
10301 | ipv4 = fvalue_get_ipv4(fi->value);
10302 | set_address_ipv4(&addr, ipv4);
10303 |
10304 | if (hfinfo->display == BASE_NETMASK) {
10305 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10306 | } else {
10307 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10308 | }
10309 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10310 | wmem_free(NULL((void*)0), addr_str);
10311 | free_address(&addr);
10312 | break;
10313 |
10314 | case FT_IPv6:
10315 | ipv6 = fvalue_get_ipv6(fi->value);
10316 | set_address_ipv6(&addr, ipv6);
10317 |
10318 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10319 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10320 | wmem_free(NULL((void*)0), addr_str);
10321 | free_address(&addr);
10322 | break;
10323 |
10324 | case FT_FCWWN:
10325 | bytes = fvalue_get_bytes_data(fi->value);
10326 | addr.type = AT_FCWWN;
10327 | addr.len = FCWWN_ADDR_LEN8;
10328 | addr.data = bytes;
10329 |
10330 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10331 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10332 | wmem_free(NULL((void*)0), addr_str);
10333 | break;
10334 |
10335 | case FT_GUID:
10336 | guid = fvalue_get_guid(fi->value);
10337 | tmp = guid_to_str(NULL((void*)0), guid);
10338 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10339 | wmem_free(NULL((void*)0), tmp);
10340 | break;
10341 |
10342 | case FT_OID:
10343 | bytes = fvalue_get_bytes_data(fi->value);
10344 | name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10345 | tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10346 | if (name) {
10347 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10348 | wmem_free(NULL((void*)0), name);
10349 | } else {
10350 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10351 | }
10352 | wmem_free(NULL((void*)0), tmp);
10353 | break;
10354 |
10355 | case FT_REL_OID:
10356 | bytes = fvalue_get_bytes_data(fi->value);
10357 | name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10358 | tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10359 | if (name) {
10360 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10361 | wmem_free(NULL((void*)0), name);
10362 | } else {
10363 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10364 | }
10365 | wmem_free(NULL((void*)0), tmp);
10366 | break;
10367 |
10368 | case FT_SYSTEM_ID:
10369 | bytes = fvalue_get_bytes_data(fi->value);
10370 | tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10371 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10372 | wmem_free(NULL((void*)0), tmp);
10373 | break;
10374 |
10375 | case FT_EUI64:
10376 | bytes = fvalue_get_bytes_data(fi->value);
10377 | addr.type = AT_EUI64;
10378 | addr.len = EUI64_ADDR_LEN8;
10379 | addr.data = bytes;
10380 |
10381 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10382 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10383 | wmem_free(NULL((void*)0), addr_str);
10384 | break;
10385 | case FT_STRING:
10386 | case FT_STRINGZ:
10387 | case FT_UINT_STRING:
10388 | case FT_STRINGZPAD:
10389 | case FT_STRINGZTRUNC:
10390 | case FT_AX25:
10391 | str = fvalue_get_string(fi->value);
10392 | label_fill(label_str, 0, hfinfo, str, value_pos);
10393 | break;
10394 |
10395 | case FT_IEEE_11073_SFLOAT:
10396 | case FT_IEEE_11073_FLOAT:
10397 | fill_label_ieee_11073_float(fi, label_str, value_pos);
10398 | break;
10399 |
10400 | default:
10401 | 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 ))
10402 | 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 ))
10403 | 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 ))
10404 | 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 ));
10405 | break;
10406 | }
10407 | }
10408 |
10409 | static void
10410 | fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10411 | {
10412 | char *p;
10413 | int bitfield_byte_length = 0, bitwidth;
10414 | uint64_t unshifted_value;
10415 | uint64_t value;
10416 |
10417 | const header_field_info *hfinfo = fi->hfinfo;
10418 |
10419 | value = fvalue_get_uinteger64(fi->value);
10420 | if (hfinfo->bitmask) {
10421 | /* Figure out the bit width */
10422 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10423 |
10424 | /* Un-shift bits */
10425 | unshifted_value = value;
10426 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10427 |
10428 | /* Create the bitfield first */
10429 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10430 | bitfield_byte_length = (int) (p - label_str);
10431 | }
10432 |
10433 | /* Fill in the textual info */
10434 | label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10435 | }
10436 |
10437 | static const char *
10438 | hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10439 | {
10440 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10441 | return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10442 |
10443 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10444 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10445 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10446 | else
10447 | return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10448 | }
10449 |
10450 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10451 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10452 |
10453 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10454 | return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10455 |
10456 | return try_val_to_str(value, (const value_string *) hfinfo->strings);
10457 | }
10458 |
10459 | static const char *
10460 | hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10461 | {
10462 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10463 | if (hfinfo->display & BASE_EXT_STRING0x00000200)
10464 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10465 | else
10466 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10467 | }
10468 |
10469 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10470 | return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10471 |
10472 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10473 | return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10474 |
10475 | /* If this is reached somebody registered a 64-bit field with a 32-bit
10476 | * value-string, which isn't right. */
10477 | 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)
10478 | hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string" , hfinfo->abbrev);
10479 |
10480 | /* This is necessary to squelch MSVC errors; is there
10481 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10482 | never returns? */
10483 | return NULL((void*)0);
10484 | }
10485 |
10486 | static const char *
10487 | hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10488 | {
10489 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10490 | return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10491 |
10492 | 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);
10493 |
10494 | /* This is necessary to squelch MSVC errors; is there
10495 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10496 | never returns? */
10497 | return NULL((void*)0);
10498 | }
10499 |
10500 | static const char *
10501 | hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10502 | {
10503 | const char *str = hf_try_val_to_str(value, hfinfo);
10504 |
10505 | return (str) ? str : unknown_str;
10506 | }
10507 |
10508 | static const char *
10509 | hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10510 | {
10511 | const char *str = hf_try_val64_to_str(value, hfinfo);
10512 |
10513 | return (str) ? str : unknown_str;
10514 | }
10515 |
10516 | /* Fills data for bitfield chars with val_strings */
10517 | static void
10518 | fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10519 | {
10520 | char *p;
10521 | int bitfield_byte_length, bitwidth;
10522 | uint32_t unshifted_value;
10523 | uint32_t value;
10524 |
10525 | char buf[32];
10526 | const char *out;
10527 |
10528 | const header_field_info *hfinfo = fi->hfinfo;
10529 |
10530 | /* Figure out the bit width */
10531 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10532 |
10533 | /* Un-shift bits */
10534 | value = fvalue_get_uinteger(fi->value);
10535 |
10536 | unshifted_value = value;
10537 | if (hfinfo->bitmask) {
10538 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10539 | }
10540 |
10541 | /* Create the bitfield first */
10542 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10543 | bitfield_byte_length = (int) (p - label_str);
10544 |
10545 | /* Fill in the textual info using stored (shifted) value */
10546 | if (hfinfo->display == BASE_CUSTOM) {
10547 | char tmp[ITEM_LABEL_LENGTH240];
10548 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10549 |
10550 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10550, "fmtfunc"))));
10551 | fmtfunc(tmp, value);
10552 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10553 | }
10554 | else if (hfinfo->strings) {
10555 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10556 |
10557 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10558 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10559 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10560 | else
10561 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10562 | }
10563 | else {
10564 | out = hfinfo_char_value_format(hfinfo, buf, value);
10565 |
10566 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10567 | }
10568 | }
10569 |
10570 | /* Fills data for bitfield ints with val_strings */
10571 | static void
10572 | fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10573 | {
10574 | char *p;
10575 | int bitfield_byte_length, bitwidth;
10576 | uint32_t value, unshifted_value;
10577 | char buf[NUMBER_LABEL_LENGTH80];
10578 | const char *out;
10579 |
10580 | const header_field_info *hfinfo = fi->hfinfo;
10581 |
10582 | /* Figure out the bit width */
10583 | if (fi->flags & FI_VARINT0x00040000)
10584 | bitwidth = fi->length*8;
10585 | else
10586 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10587 |
10588 | /* Un-shift bits */
10589 | if (is_signed)
10590 | value = fvalue_get_sinteger(fi->value);
10591 | else
10592 | value = fvalue_get_uinteger(fi->value);
10593 |
10594 | unshifted_value = value;
10595 | if (hfinfo->bitmask) {
10596 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10597 | }
10598 |
10599 | /* Create the bitfield first */
10600 | if (fi->flags & FI_VARINT0x00040000)
10601 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10602 | else
10603 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10604 | bitfield_byte_length = (int) (p - label_str);
10605 |
10606 | /* Fill in the textual info using stored (shifted) value */
10607 | if (hfinfo->display == BASE_CUSTOM) {
10608 | char tmp[ITEM_LABEL_LENGTH240];
10609 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10610 |
10611 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10611, "fmtfunc"))));
10612 | fmtfunc(tmp, value);
10613 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10614 | }
10615 | else if (hfinfo->strings) {
10616 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10617 |
10618 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10619 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10620 | /*
10621 | * Unique values only display value_string string
10622 | * if there is a match. Otherwise it's just a number
10623 | */
10624 | if (val_str) {
10625 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10626 | } else {
10627 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10628 | }
10629 | } else {
10630 | if (val_str == NULL((void*)0))
10631 | val_str = "Unknown";
10632 |
10633 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10634 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10635 | else
10636 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10637 | }
10638 | }
10639 | else {
10640 | out = hfinfo_number_value_format(hfinfo, buf, value);
10641 |
10642 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10643 | }
10644 | }
10645 |
10646 | static void
10647 | fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10648 | {
10649 | char *p;
10650 | int bitfield_byte_length, bitwidth;
10651 | uint64_t value, unshifted_value;
10652 | char buf[NUMBER_LABEL_LENGTH80];
10653 | const char *out;
10654 |
10655 | const header_field_info *hfinfo = fi->hfinfo;
10656 |
10657 | /* Figure out the bit width */
10658 | if (fi->flags & FI_VARINT0x00040000)
10659 | bitwidth = fi->length*8;
10660 | else
10661 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10662 |
10663 | /* Un-shift bits */
10664 | if (is_signed)
10665 | value = fvalue_get_sinteger64(fi->value);
10666 | else
10667 | value = fvalue_get_uinteger64(fi->value);
10668 |
10669 | unshifted_value = value;
10670 | if (hfinfo->bitmask) {
10671 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10672 | }
10673 |
10674 | /* Create the bitfield first */
10675 | if (fi->flags & FI_VARINT0x00040000)
10676 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10677 | else
10678 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10679 | bitfield_byte_length = (int) (p - label_str);
10680 |
10681 | /* Fill in the textual info using stored (shifted) value */
10682 | if (hfinfo->display == BASE_CUSTOM) {
10683 | char tmp[ITEM_LABEL_LENGTH240];
10684 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10685 |
10686 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 10686, "fmtfunc64" ))));
10687 | fmtfunc64(tmp, value);
10688 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10689 | }
10690 | else if (hfinfo->strings) {
10691 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
10692 |
10693 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
10694 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10695 | /*
10696 | * Unique values only display value_string string
10697 | * if there is a match. Otherwise it's just a number
10698 | */
10699 | if (val_str) {
10700 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10701 | } else {
10702 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10703 | }
10704 | } else {
10705 | if (val_str == NULL((void*)0))
10706 | val_str = "Unknown";
10707 |
10708 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10709 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10710 | else
10711 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10712 | }
10713 | }
10714 | else {
10715 | out = hfinfo_number_value_format64(hfinfo, buf, value);
10716 |
10717 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10718 | }
10719 | }
10720 |
10721 | static void
10722 | fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10723 | {
10724 | const header_field_info *hfinfo = fi->hfinfo;
10725 | uint32_t value;
10726 |
10727 | char buf[32];
10728 | const char *out;
10729 |
10730 | value = fvalue_get_uinteger(fi->value);
10731 |
10732 | /* Fill in the textual info */
10733 | if (hfinfo->display == BASE_CUSTOM) {
10734 | char tmp[ITEM_LABEL_LENGTH240];
10735 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10736 |
10737 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10737, "fmtfunc"))));
10738 | fmtfunc(tmp, value);
10739 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10740 | }
10741 | else if (hfinfo->strings) {
10742 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10743 |
10744 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10745 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10746 | }
10747 | else {
10748 | out = hfinfo_char_value_format(hfinfo, buf, value);
10749 |
10750 | label_fill(label_str, 0, hfinfo, out, value_pos);
10751 | }
10752 | }
10753 |
10754 | static void
10755 | fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10756 | {
10757 | const header_field_info *hfinfo = fi->hfinfo;
10758 | uint32_t value;
10759 |
10760 | char buf[NUMBER_LABEL_LENGTH80];
10761 | const char *out;
10762 |
10763 | if (is_signed)
10764 | value = fvalue_get_sinteger(fi->value);
10765 | else
10766 | value = fvalue_get_uinteger(fi->value);
10767 |
10768 | /* Fill in the textual info */
10769 | if (hfinfo->display == BASE_CUSTOM) {
10770 | char tmp[ITEM_LABEL_LENGTH240];
10771 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10772 |
10773 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10773, "fmtfunc"))));
10774 | fmtfunc(tmp, value);
10775 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10776 | }
10777 | else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10778 | /*
10779 | * It makes no sense to have a value-string table for a
10780 | * frame-number field - they're just integers giving
10781 | * the ordinal frame number.
10782 | */
10783 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10784 |
10785 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10786 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10787 | /*
10788 | * Unique values only display value_string string
10789 | * if there is a match. Otherwise it's just a number
10790 | */
10791 | if (val_str) {
10792 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10793 | } else {
10794 | label_fill(label_str, 0, hfinfo, out, value_pos);
10795 | }
10796 | } else {
10797 | if (val_str == NULL((void*)0))
10798 | val_str = "Unknown";
10799 |
10800 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10801 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
10802 | else
10803 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10804 | }
10805 | }
10806 | 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 ))) {
10807 | char tmp[ITEM_LABEL_LENGTH240];
10808 |
10809 | port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10810 | display_to_port_type((field_display_e)hfinfo->display), value);
10811 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10812 | }
10813 | else {
10814 | out = hfinfo_number_value_format(hfinfo, buf, value);
10815 |
10816 | label_fill(label_str, 0, hfinfo, out, value_pos);
10817 | }
10818 | }
10819 |
10820 | static void
10821 | fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10822 | {
10823 | const header_field_info *hfinfo = fi->hfinfo;
10824 | uint64_t value;
10825 |
10826 | char buf[NUMBER_LABEL_LENGTH80];
10827 | const char *out;
10828 |
10829 | if (is_signed)
10830 | value = fvalue_get_sinteger64(fi->value);
10831 | else
10832 | value = fvalue_get_uinteger64(fi->value);
10833 |
10834 | /* Fill in the textual info */
10835 | if (hfinfo->display == BASE_CUSTOM) {
10836 | char tmp[ITEM_LABEL_LENGTH240];
10837 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10838 |
10839 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 10839, "fmtfunc64" ))));
10840 | fmtfunc64(tmp, value);
10841 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10842 | }
10843 | else if (hfinfo->strings) {
10844 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
10845 |
10846 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
10847 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10848 | /*
10849 | * Unique values only display value_string string
10850 | * if there is a match. Otherwise it's just a number
10851 | */
10852 | if (val_str) {
10853 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10854 | } else {
10855 | label_fill(label_str, 0, hfinfo, out, value_pos);
10856 | }
10857 | } else {
10858 | if (val_str == NULL((void*)0))
10859 | val_str = "Unknown";
10860 |
10861 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10862 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
10863 | else
10864 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10865 | }
10866 | }
10867 | else {
10868 | out = hfinfo_number_value_format64(hfinfo, buf, value);
10869 |
10870 | label_fill(label_str, 0, hfinfo, out, value_pos);
10871 | }
10872 | }
10873 |
10874 | static size_t
10875 | fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10876 | {
10877 | int display;
10878 | int n;
10879 | double value;
10880 |
10881 | if (label_str_size < 12) {
10882 | /* Not enough room to write an entire floating point value. */
10883 | return 0;
10884 | }
10885 |
10886 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10887 | value = fvalue_get_floating(fi->value);
10888 |
10889 | if (display == BASE_CUSTOM) {
10890 | const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10891 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10891, "fmtfunc"))));
10892 | fmtfunc(label_str, value);
10893 | return strlen(label_str);
10894 | }
10895 |
10896 | switch (display) {
10897 | case BASE_NONE:
10898 | if (fi->hfinfo->type == FT_FLOAT) {
10899 | n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10900 | } else {
10901 | n = (int)strlen(dtoa_g_fmt(label_str, value));
10902 | }
10903 | break;
10904 | case BASE_DEC:
10905 | n = snprintf(label_str, label_str_size, "%f", value);
10906 | break;
10907 | case BASE_HEX:
10908 | n = snprintf(label_str, label_str_size, "%a", value);
10909 | break;
10910 | case BASE_EXP:
10911 | n = snprintf(label_str, label_str_size, "%e", value);
10912 | break;
10913 | default:
10914 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10914 , __func__, "assertion \"not reached\" failed");
10915 | }
10916 | if (n < 0) {
10917 | return 0; /* error */
10918 | }
10919 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10920 | const char *hf_str_val;
10921 | hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10922 | n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10923 | }
10924 | if (n > label_str_size) {
10925 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10925, __func__, "label length too small"); } } while (0);
10926 | return strlen(label_str);
10927 | }
10928 |
10929 | return n;
10930 | }
10931 |
10932 | void
10933 | fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10934 | {
10935 | char tmp[ITEM_LABEL_LENGTH240];
10936 |
10937 | fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10938 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10939 | }
10940 |
10941 | static size_t
10942 | fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10943 | {
10944 | int display;
10945 | size_t pos = 0;
10946 | double value;
10947 | char* tmp_str;
10948 |
10949 | if (label_str_size < 12) {
10950 | /* Not enough room to write an entire floating point value. */
10951 | return 0;
10952 | }
10953 |
10954 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10955 | tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10956 | pos = label_concat(label_str, pos, tmp_str)ws_label_strcpy(label_str, 240, pos, tmp_str, 0);
10957 | wmem_free(NULL((void*)0), tmp_str);
10958 |
10959 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10960 | const char *hf_str_val;
10961 | fvalue_to_double(fi->value, &value);
10962 | hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10963 | pos = label_concat(label_str, pos, hf_str_val)ws_label_strcpy(label_str, 240, pos, hf_str_val, 0);
10964 | }
10965 | if ((int)pos > label_str_size) {
10966 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10966, __func__, "label length too small"); } } while (0);
10967 | return strlen(label_str);
10968 | }
10969 |
10970 | return pos;
10971 | }
10972 |
10973 | void
10974 | fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10975 | {
10976 | char tmp[ITEM_LABEL_LENGTH240];
10977 |
10978 | fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10979 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10980 | }
10981 |
10982 | int
10983 | hfinfo_bitshift(const header_field_info *hfinfo)
10984 | {
10985 | return ws_ctz(hfinfo->bitmask);
10986 | }
10987 |
10988 |
10989 | static int
10990 | hfinfo_bitoffset(const header_field_info *hfinfo)
10991 | {
10992 | if (!hfinfo->bitmask) {
10993 | return 0;
10994 | }
10995 |
10996 | /* ilog2 = first set bit, counting 0 as the last bit; we want 0
10997 | * as the first bit */
10998 | return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
10999 | }
11000 |
11001 | static int
11002 | hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11003 | {
11004 | if (!hfinfo->bitmask) {
11005 | return 0;
11006 | }
11007 |
11008 | /* ilog2 = first set bit, ctz = last set bit */
11009 | return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11010 | }
11011 |
11012 | static int
11013 | hfinfo_type_bitwidth(enum ftenum type)
11014 | {
11015 | int bitwidth = 0;
11016 |
11017 | switch (type) {
11018 | case FT_CHAR:
11019 | case FT_UINT8:
11020 | case FT_INT8:
11021 | bitwidth = 8;
11022 | break;
11023 | case FT_UINT16:
11024 | case FT_INT16:
11025 | bitwidth = 16;
11026 | break;
11027 | case FT_UINT24:
11028 | case FT_INT24:
11029 | bitwidth = 24;
11030 | break;
11031 | case FT_UINT32:
11032 | case FT_INT32:
11033 | bitwidth = 32;
11034 | break;
11035 | case FT_UINT40:
11036 | case FT_INT40:
11037 | bitwidth = 40;
11038 | break;
11039 | case FT_UINT48:
11040 | case FT_INT48:
11041 | bitwidth = 48;
11042 | break;
11043 | case FT_UINT56:
11044 | case FT_INT56:
11045 | bitwidth = 56;
11046 | break;
11047 | case FT_UINT64:
11048 | case FT_INT64:
11049 | bitwidth = 64;
11050 | break;
11051 | default:
11052 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 11052));
11053 | ;
11054 | }
11055 | return bitwidth;
11056 | }
11057 |
11058 |
11059 | static int
11060 | hfinfo_container_bitwidth(const header_field_info *hfinfo)
11061 | {
11062 | if (!hfinfo->bitmask) {
11063 | return 0;
11064 | }
11065 |
11066 | if (hfinfo->type == FT_BOOLEAN) {
11067 | return hfinfo->display; /* hacky? :) */
11068 | }
11069 |
11070 | return hfinfo_type_bitwidth(hfinfo->type);
11071 | }
11072 |
11073 | static int
11074 | hfinfo_hex_digits(const header_field_info *hfinfo)
11075 | {
11076 | int bitwidth;
11077 |
11078 | /* If we have a bitmask, hfinfo->type is the width of the container, so not
11079 | * appropriate to determine the number of hex digits for the field.
11080 | * So instead, we compute it from the bitmask.
11081 | */
11082 | if (hfinfo->bitmask != 0) {
11083 | bitwidth = hfinfo_mask_bitwidth(hfinfo);
11084 | } else {
11085 | bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11086 | }
11087 |
11088 | /* Divide by 4, rounding up, to get number of hex digits. */
11089 | return (bitwidth + 3) / 4;
11090 | }
11091 |
11092 | const char *
11093 | hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11094 | {
11095 | char *ptr = &buf[6];
11096 | static const char hex_digits[16] =
11097 | { '0', '1', '2', '3', '4', '5', '6', '7',
11098 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11099 |
11100 | *ptr = '\0';
11101 | *(--ptr) = '\'';
11102 | /* Properly format value */
11103 | if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11104 | /*
11105 | * Printable, so just show the character, and, if it needs
11106 | * to be escaped, escape it.
11107 | */
11108 | *(--ptr) = value;
11109 | if (value == '\\' || value == '\'')
11110 | *(--ptr) = '\\';
11111 | } else {
11112 | /*
11113 | * Non-printable; show it as an escape sequence.
11114 | */
11115 | switch (value) {
11116 |
11117 | case '\0':
11118 | /*
11119 | * Show a NUL with only one digit.
11120 | */
11121 | *(--ptr) = '0';
11122 | break;
11123 |
11124 | case '\a':
11125 | case '\b':
11126 | case '\f':
11127 | case '\n':
11128 | case '\r':
11129 | case '\t':
11130 | case '\v':
11131 | *(--ptr) = value - '\a' + 'a';
11132 | break;
11133 |
11134 | default:
11135 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11136 |
11137 | case BASE_OCT:
11138 | *(--ptr) = (value & 0x7) + '0';
11139 | value >>= 3;
11140 | *(--ptr) = (value & 0x7) + '0';
11141 | value >>= 3;
11142 | *(--ptr) = (value & 0x7) + '0';
11143 | break;
11144 |
11145 | case BASE_HEX:
11146 | *(--ptr) = hex_digits[value & 0x0F];
11147 | value >>= 4;
11148 | *(--ptr) = hex_digits[value & 0x0F];
11149 | *(--ptr) = 'x';
11150 | break;
11151 |
11152 | default:
11153 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11154 | }
11155 | }
11156 | *(--ptr) = '\\';
11157 | }
11158 | *(--ptr) = '\'';
11159 | return ptr;
11160 | }
11161 |
11162 | static const char *
11163 | hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11164 | {
11165 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11166 | 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 ));
11167 |
11168 | *ptr = '\0';
11169 | /* Properly format value */
11170 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11171 | case BASE_DEC:
11172 | return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11173 |
11174 | case BASE_DEC_HEX:
11175 | *(--ptr) = ')';
11176 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11177 | *(--ptr) = '(';
11178 | *(--ptr) = ' ';
11179 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11180 | return ptr;
11181 |
11182 | case BASE_OCT:
11183 | return oct_to_str_back(ptr, value);
11184 |
11185 | case BASE_HEX:
11186 | return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11187 |
11188 | case BASE_HEX_DEC:
11189 | *(--ptr) = ')';
11190 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11191 | *(--ptr) = '(';
11192 | *(--ptr) = ' ';
11193 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11194 | return ptr;
11195 |
11196 | case BASE_PT_UDP:
11197 | case BASE_PT_TCP:
11198 | case BASE_PT_DCCP:
11199 | case BASE_PT_SCTP:
11200 | port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11201 | display_to_port_type((field_display_e)display), value);
11202 | return buf;
11203 | case BASE_OUI:
11204 | {
11205 | uint8_t p_oui[3];
11206 | const char *manuf_name;
11207 |
11208 | p_oui[0] = value >> 16 & 0xFF;
11209 | p_oui[1] = value >> 8 & 0xFF;
11210 | p_oui[2] = value & 0xFF;
11211 |
11212 | /* Attempt an OUI lookup. */
11213 | manuf_name = uint_get_manuf_name_if_known(value);
11214 | if (manuf_name == NULL((void*)0)) {
11215 | /* Could not find an OUI. */
11216 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11217 | }
11218 | else {
11219 | /* Found an address string. */
11220 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11221 | }
11222 | return buf;
11223 | }
11224 |
11225 | default:
11226 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11227 | }
11228 | return ptr;
11229 | }
11230 |
11231 | static const char *
11232 | hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11233 | {
11234 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11235 | 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 ));
11236 |
11237 | *ptr = '\0';
11238 | /* Properly format value */
11239 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11240 | case BASE_DEC:
11241 | return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11242 |
11243 | case BASE_DEC_HEX:
11244 | *(--ptr) = ')';
11245 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11246 | *(--ptr) = '(';
11247 | *(--ptr) = ' ';
11248 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11249 | return ptr;
11250 |
11251 | case BASE_OCT:
11252 | return oct64_to_str_back(ptr, value);
11253 |
11254 | case BASE_HEX:
11255 | return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11256 |
11257 | case BASE_HEX_DEC:
11258 | *(--ptr) = ')';
11259 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11260 | *(--ptr) = '(';
11261 | *(--ptr) = ' ';
11262 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11263 | return ptr;
11264 |
11265 | default:
11266 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11267 | }
11268 |
11269 | return ptr;
11270 | }
11271 |
11272 | static const char *
11273 | hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11274 | {
11275 | int display = hfinfo->display;
11276 |
11277 | if (hfinfo->type == FT_FRAMENUM) {
11278 | /*
11279 | * Frame numbers are always displayed in decimal.
11280 | */
11281 | display = BASE_DEC;
11282 | }
11283 |
11284 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11285 | }
11286 |
11287 | static const char *
11288 | hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11289 | {
11290 | int display = hfinfo->display;
11291 |
11292 | if (hfinfo->type == FT_FRAMENUM) {
11293 | /*
11294 | * Frame numbers are always displayed in decimal.
11295 | */
11296 | display = BASE_DEC;
11297 | }
11298 |
11299 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11300 | }
11301 |
11302 | static const char *
11303 | hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11304 | {
11305 | /* Get the underlying BASE_ value */
11306 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11307 |
11308 | return hfinfo_char_value_format_display(display, buf, value);
11309 | }
11310 |
11311 | static const char *
11312 | hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11313 | {
11314 | /* Get the underlying BASE_ value */
11315 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11316 |
11317 | if (hfinfo->type == FT_FRAMENUM) {
11318 | /*
11319 | * Frame numbers are always displayed in decimal.
11320 | */
11321 | display = BASE_DEC;
11322 | }
11323 |
11324 | if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)== BASE_PT_DCCP||(display)==BASE_PT_SCTP))) {
11325 | display = BASE_DEC;
11326 | } else if (display == BASE_OUI) {
11327 | display = BASE_HEX;
11328 | }
11329 |
11330 | switch (display) {
11331 | case BASE_NONE:
11332 | /* case BASE_DEC: */
11333 | case BASE_DEC_HEX:
11334 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11335 | case BASE_CUSTOM:
11336 | display = BASE_DEC;
11337 | break;
11338 |
11339 | /* case BASE_HEX: */
11340 | case BASE_HEX_DEC:
11341 | display = BASE_HEX;
11342 | break;
11343 | }
11344 |
11345 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11346 | }
11347 |
11348 | static const char *
11349 | hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11350 | {
11351 | /* Get the underlying BASE_ value */
11352 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11353 |
11354 | if (hfinfo->type == FT_FRAMENUM) {
11355 | /*
11356 | * Frame numbers are always displayed in decimal.
11357 | */
11358 | display = BASE_DEC;
11359 | }
11360 |
11361 | switch (display) {
11362 | case BASE_NONE:
11363 | /* case BASE_DEC: */
11364 | case BASE_DEC_HEX:
11365 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11366 | case BASE_CUSTOM:
11367 | display = BASE_DEC;
11368 | break;
11369 |
11370 | /* case BASE_HEX: */
11371 | case BASE_HEX_DEC:
11372 | display = BASE_HEX;
11373 | break;
11374 | }
11375 |
11376 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11377 | }
11378 |
11379 | static const char *
11380 | hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11381 | {
11382 | /* Get the underlying BASE_ value */
11383 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11384 |
11385 | return hfinfo_char_value_format_display(display, buf, value);
11386 | }
11387 |
11388 | static const char *
11389 | hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11390 | {
11391 | /* Get the underlying BASE_ value */
11392 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11393 |
11394 | if (display == BASE_NONE)
11395 | return NULL((void*)0);
11396 |
11397 | if (display == BASE_DEC_HEX)
11398 | display = BASE_DEC;
11399 | if (display == BASE_HEX_DEC)
11400 | display = BASE_HEX;
11401 |
11402 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11403 | }
11404 |
11405 | static const char *
11406 | hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11407 | {
11408 | /* Get the underlying BASE_ value */
11409 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11410 |
11411 | if (display == BASE_NONE)
11412 | return NULL((void*)0);
11413 |
11414 | if (display == BASE_DEC_HEX)
11415 | display = BASE_DEC;
11416 | if (display == BASE_HEX_DEC)
11417 | display = BASE_HEX;
11418 |
11419 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11420 | }
11421 |
11422 | const char *
11423 | proto_registrar_get_name(const int n)
11424 | {
11425 | header_field_info *hfinfo;
11426 |
11427 | 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", 11427 , __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", 11427 , "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", 11427, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11428 | return hfinfo->name;
11429 | }
11430 |
11431 | const char *
11432 | proto_registrar_get_abbrev(const int n)
11433 | {
11434 | header_field_info *hfinfo;
11435 |
11436 | 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", 11436 , __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", 11436 , "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", 11436, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11437 | return hfinfo->abbrev;
11438 | }
11439 |
11440 | enum ftenum
11441 | proto_registrar_get_ftype(const int n)
11442 | {
11443 | header_field_info *hfinfo;
11444 |
11445 | 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", 11445 , __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", 11445 , "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", 11445, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11446 | return hfinfo->type;
11447 | }
11448 |
11449 | int
11450 | proto_registrar_get_parent(const int n)
11451 | {
11452 | header_field_info *hfinfo;
11453 |
11454 | 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", 11454 , __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", 11454 , "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", 11454, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11455 | return hfinfo->parent;
11456 | }
11457 |
11458 | bool_Bool
11459 | proto_registrar_is_protocol(const int n)
11460 | {
11461 | header_field_info *hfinfo;
11462 |
11463 | 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", 11463 , __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", 11463 , "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", 11463, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11464 | return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11465 | }
11466 |
11467 | /* Returns length of field in packet (not necessarily the length
11468 | * in our internal representation, as in the case of IPv4).
11469 | * 0 means undeterminable at time of registration
11470 | * -1 means the field is not registered. */
11471 | int
11472 | proto_registrar_get_length(const int n)
11473 | {
11474 | header_field_info *hfinfo;
11475 |
11476 | 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", 11476 , __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", 11476 , "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", 11476, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11477 | return ftype_wire_size(hfinfo->type);
11478 | }
11479 |
11480 | /* Looks for a protocol or a field in a proto_tree. Returns true if
11481 | * it exists anywhere, or false if it exists nowhere. */
11482 | bool_Bool
11483 | proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11484 | {
11485 | GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11486 |
11487 | if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11488 | return true1;
11489 | }
11490 | else {
11491 | return false0;
11492 | }
11493 | }
11494 |
11495 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11496 | * This only works if the hfindex was "primed" before the dissection
11497 | * took place, as we just pass back the already-created GPtrArray*.
11498 | * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11499 | * handles that. */
11500 | GPtrArray *
11501 | proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11502 | {
11503 | if (!tree)
11504 | return NULL((void*)0);
11505 |
11506 | if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11507 | return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11508 | GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11509 | else
11510 | return NULL((void*)0);
11511 | }
11512 |
11513 | bool_Bool
11514 | proto_tracking_interesting_fields(const proto_tree *tree)
11515 | {
11516 | GHashTable *interesting_hfids;
11517 |
11518 | if (!tree)
11519 | return false0;
11520 |
11521 | interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11522 |
11523 | return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11524 | }
11525 |
11526 | /* Helper struct for proto_find_info() and proto_all_finfos() */
11527 | typedef struct {
11528 | GPtrArray *array;
11529 | int id;
11530 | } ffdata_t;
11531 |
11532 | /* Helper function for proto_find_info() */
11533 | static bool_Bool
11534 | find_finfo(proto_node *node, void * data)
11535 | {
11536 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11537 | if (fi && fi->hfinfo) {
11538 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11539 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11540 | }
11541 | }
11542 |
11543 | /* Don't stop traversing. */
11544 | return false0;
11545 | }
11546 |
11547 | /* Helper function for proto_find_first_info() */
11548 | static bool_Bool
11549 | find_first_finfo(proto_node *node, void *data)
11550 | {
11551 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11552 | if (fi && fi->hfinfo) {
11553 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11554 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11555 |
11556 | /* Stop traversing. */
11557 | return true1;
11558 | }
11559 | }
11560 |
11561 | /* Continue traversing. */
11562 | return false0;
11563 | }
11564 |
11565 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11566 | * This works on any proto_tree, primed or unprimed, but actually searches
11567 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11568 | * The caller does need to free the returned GPtrArray with
11569 | * g_ptr_array_free(<array>, true).
11570 | */
11571 | GPtrArray *
11572 | proto_find_finfo(proto_tree *tree, const int id)
11573 | {
11574 | ffdata_t ffdata;
11575 |
11576 | ffdata.array = g_ptr_array_new();
11577 | ffdata.id = id;
11578 |
11579 | proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11580 |
11581 | return ffdata.array;
11582 | }
11583 |
11584 | /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11585 | * This works on any proto_tree, primed or unprimed, but actually searches
11586 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11587 | * The caller does need to free the returned GPtrArray with
11588 | * g_ptr_array_free(<array>, true).
11589 | */
11590 | GPtrArray *
11591 | proto_find_first_finfo(proto_tree *tree, const int id)
11592 | {
11593 | ffdata_t ffdata;
11594 |
11595 | ffdata.array = g_ptr_array_new();
11596 | ffdata.id = id;
11597 |
11598 | proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11599 |
11600 | return ffdata.array;
11601 | }
11602 |
11603 | /* Helper function for proto_all_finfos() */
11604 | static bool_Bool
11605 | every_finfo(proto_node *node, void * data)
11606 | {
11607 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11608 | if (fi && fi->hfinfo) {
11609 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11610 | }
11611 |
11612 | /* Don't stop traversing. */
11613 | return false0;
11614 | }
11615 |
11616 | /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11617 | * The caller does need to free the returned GPtrArray with
11618 | * g_ptr_array_free(<array>, true).
11619 | */
11620 | GPtrArray *
11621 | proto_all_finfos(proto_tree *tree)
11622 | {
11623 | ffdata_t ffdata;
11624 |
11625 | /* Pre allocate enough space to hold all fields in most cases */
11626 | ffdata.array = g_ptr_array_sized_new(512);
11627 | ffdata.id = 0;
11628 |
11629 | proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11630 |
11631 | return ffdata.array;
11632 | }
11633 |
11634 |
11635 | typedef struct {
11636 | unsigned offset;
11637 | field_info *finfo;
11638 | tvbuff_t *tvb;
11639 | } offset_search_t;
11640 |
11641 | static bool_Bool
11642 | check_for_offset(proto_node *node, void * data)
11643 | {
11644 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11645 | offset_search_t *offsearch = (offset_search_t *)data;
11646 |
11647 | /* !fi == the top most container node which holds nothing */
11648 | if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11649 | if (offsearch->offset >= (unsigned) fi->start &&
11650 | offsearch->offset < (unsigned) (fi->start + fi->length)) {
11651 |
11652 | offsearch->finfo = fi;
11653 | return false0; /* keep traversing */
11654 | }
11655 | }
11656 | return false0; /* keep traversing */
11657 | }
11658 |
11659 | /* Search a proto_tree backwards (from leaves to root) looking for the field
11660 | * whose start/length occupies 'offset' */
11661 | /* XXX - I couldn't find an easy way to search backwards, so I search
11662 | * forwards, w/o stopping. Therefore, the last finfo I find will the be
11663 | * the one I want to return to the user. This algorithm is inefficient
11664 | * and could be re-done, but I'd have to handle all the children and
11665 | * siblings of each node myself. When I have more time I'll do that.
11666 | * (yeah right) */
11667 | field_info *
11668 | proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11669 | {
11670 | offset_search_t offsearch;
11671 |
11672 | offsearch.offset = offset;
11673 | offsearch.finfo = NULL((void*)0);
11674 | offsearch.tvb = tvb;
11675 |
11676 | proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11677 |
11678 | return offsearch.finfo;
11679 | }
11680 |
11681 | typedef struct {
11682 | int length;
11683 | char *buf;
11684 | } decoded_data_t;
11685 |
11686 | static bool_Bool
11687 | check_for_undecoded(proto_node *node, void * data)
11688 | {
11689 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11690 | decoded_data_t* decoded = (decoded_data_t*)data;
11691 | int i;
11692 | unsigned byte;
11693 | unsigned bit;
11694 |
11695 | if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11696 | for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11697 | byte = i / 8;
11698 | bit = i % 8;
11699 | decoded->buf[byte] |= (1 << bit);
11700 | }
11701 | }
11702 |
11703 | return false0;
11704 | }
11705 |
11706 | char*
11707 | proto_find_undecoded_data(proto_tree *tree, unsigned length)
11708 | {
11709 | decoded_data_t decoded;
11710 | decoded.length = length;
11711 | decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11712 |
11713 | proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11714 | return decoded.buf;
11715 | }
11716 |
11717 | /* Dumps the protocols in the registration database to stdout. An independent
11718 | * program can take this output and format it into nice tables or HTML or
11719 | * whatever.
11720 | *
11721 | * There is one record per line. The fields are tab-delimited.
11722 | *
11723 | * Field 1 = protocol name
11724 | * Field 2 = protocol short name
11725 | * Field 3 = protocol filter name
11726 | * Field 4 = protocol enabled
11727 | * Field 5 = protocol enabled by default
11728 | * Field 6 = protocol can toggle
11729 | */
11730 | void
11731 | proto_registrar_dump_protocols(void)
11732 | {
11733 | protocol_t *protocol;
11734 | int i;
11735 | void *cookie = NULL((void*)0);
11736 |
11737 |
11738 | i = proto_get_first_protocol(&cookie);
11739 | while (i != -1) {
11740 | protocol = find_protocol_by_id(i);
11741 | printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11742 | protocol->name,
11743 | protocol->short_name,
11744 | protocol->filter_name,
11745 | (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11746 | (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11747 | (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11748 | i = proto_get_next_protocol(&cookie);
11749 | }
11750 | }
11751 |
11752 | /* Dumps the value_strings, extended value string headers, range_strings
11753 | * or true/false strings for fields that have them.
11754 | * There is one record per line. Fields are tab-delimited.
11755 | * There are four types of records: Value String, Extended Value String Header,
11756 | * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11757 | * the type of record.
11758 | *
11759 | * Note that a record will be generated only if the value_string,... is referenced
11760 | * in a registered hfinfo entry.
11761 | *
11762 | *
11763 | * Value Strings
11764 | * -------------
11765 | * Field 1 = 'V'
11766 | * Field 2 = Field abbreviation to which this value string corresponds
11767 | * Field 3 = Integer value
11768 | * Field 4 = String
11769 | *
11770 | * Extended Value String Headers
11771 | * -----------------------------
11772 | * Field 1 = 'E'
11773 | * Field 2 = Field abbreviation to which this extended value string header corresponds
11774 | * Field 3 = Extended Value String "Name"
11775 | * Field 4 = Number of entries in the associated value_string array
11776 | * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11777 | *
11778 | * Range Strings
11779 | * -------------
11780 | * Field 1 = 'R'
11781 | * Field 2 = Field abbreviation to which this range string corresponds
11782 | * Field 3 = Integer value: lower bound
11783 | * Field 4 = Integer value: upper bound
11784 | * Field 5 = String
11785 | *
11786 | * True/False Strings
11787 | * ------------------
11788 | * Field 1 = 'T'
11789 | * Field 2 = Field abbreviation to which this true/false string corresponds
11790 | * Field 3 = True String
11791 | * Field 4 = False String
11792 | */
11793 | void
11794 | proto_registrar_dump_values(void)
11795 | {
11796 | header_field_info *hfinfo;
11797 | int i, len, vi;
11798 | const value_string *vals;
11799 | const val64_string *vals64;
11800 | const range_string *range;
11801 | const true_false_string *tfs;
11802 | const unit_name_string *units;
11803 |
11804 | len = gpa_hfinfo.len;
11805 | for (i = 0; i < len ; i++) {
11806 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11807 | continue; /* This is a deregistered protocol or field */
11808 |
11809 | 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", 11809 , __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", 11809 , "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", 11809, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
11810 |
11811 | if (hfinfo->id == hf_text_only) {
11812 | continue;
11813 | }
11814 |
11815 | /* ignore protocols */
11816 | if (proto_registrar_is_protocol(i)) {
11817 | continue;
11818 | }
11819 | /* process header fields */
11820 | #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11821 | /*
11822 | * If this field isn't at the head of the list of
11823 | * fields with this name, skip this field - all
11824 | * fields with the same name are really just versions
11825 | * of the same field stored in different bits, and
11826 | * should have the same type/radix/value list, and
11827 | * just differ in their bit masks. (If a field isn't
11828 | * a bitfield, but can be, say, 1 or 2 bytes long,
11829 | * it can just be made FT_UINT16, meaning the
11830 | * *maximum* length is 2 bytes, and be used
11831 | * for all lengths.)
11832 | */
11833 | if (hfinfo->same_name_prev_id != -1)
11834 | continue;
11835 | #endif
11836 | vals = NULL((void*)0);
11837 | vals64 = NULL((void*)0);
11838 | range = NULL((void*)0);
11839 | tfs = NULL((void*)0);
11840 | units = NULL((void*)0);
11841 |
11842 | if (hfinfo->strings != NULL((void*)0)) {
11843 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11844 | (hfinfo->type == FT_CHAR ||
11845 | hfinfo->type == FT_UINT8 ||
11846 | hfinfo->type == FT_UINT16 ||
11847 | hfinfo->type == FT_UINT24 ||
11848 | hfinfo->type == FT_UINT32 ||
11849 | hfinfo->type == FT_UINT40 ||
11850 | hfinfo->type == FT_UINT48 ||
11851 | hfinfo->type == FT_UINT56 ||
11852 | hfinfo->type == FT_UINT64 ||
11853 | hfinfo->type == FT_INT8 ||
11854 | hfinfo->type == FT_INT16 ||
11855 | hfinfo->type == FT_INT24 ||
11856 | hfinfo->type == FT_INT32 ||
11857 | hfinfo->type == FT_INT40 ||
11858 | hfinfo->type == FT_INT48 ||
11859 | hfinfo->type == FT_INT56 ||
11860 | hfinfo->type == FT_INT64 ||
11861 | hfinfo->type == FT_FLOAT ||
11862 | hfinfo->type == FT_DOUBLE)) {
11863 |
11864 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11865 | range = (const range_string *)hfinfo->strings;
11866 | } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11867 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11868 | vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11869 | } else {
11870 | vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11871 | }
11872 | } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11873 | vals64 = (const val64_string *)hfinfo->strings;
11874 | } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11875 | units = (const unit_name_string *)hfinfo->strings;
11876 | } else {
11877 | vals = (const value_string *)hfinfo->strings;
11878 | }
11879 | }
11880 | else if (hfinfo->type == FT_BOOLEAN) {
11881 | tfs = (const struct true_false_string *)hfinfo->strings;
11882 | }
11883 | }
11884 |
11885 | /* Print value strings? */
11886 | if (vals) {
11887 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11888 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11889 | val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11890 | if (!val64_string_ext_validate(vse_p)) {
11891 | ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11891, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
11892 | continue;
11893 | }
11894 | try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11895 | printf("E\t%s\t%u\t%s\t%s\n",
11896 | hfinfo->abbrev,
11897 | VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11898 | VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11899 | val64_string_ext_match_type_str(vse_p));
11900 | } else {
11901 | value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11902 | if (!value_string_ext_validate(vse_p)) {
11903 | ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11903, __func__, "Invalid value_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
11904 | continue;
11905 | }
11906 | try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11907 | printf("E\t%s\t%u\t%s\t%s\n",
11908 | hfinfo->abbrev,
11909 | VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11910 | VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11911 | value_string_ext_match_type_str(vse_p));
11912 | }
11913 | }
11914 | vi = 0;
11915 | while (vals[vi].strptr) {
11916 | /* Print in the proper base */
11917 | if (hfinfo->type == FT_CHAR) {
11918 | if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT ) != 0)) {
11919 | printf("V\t%s\t'%c'\t%s\n",
11920 | hfinfo->abbrev,
11921 | vals[vi].value,
11922 | vals[vi].strptr);
11923 | } else {
11924 | if (hfinfo->display == BASE_HEX) {
11925 | printf("V\t%s\t'\\x%02x'\t%s\n",
11926 | hfinfo->abbrev,
11927 | vals[vi].value,
11928 | vals[vi].strptr);
11929 | }
11930 | else {
11931 | printf("V\t%s\t'\\%03o'\t%s\n",
11932 | hfinfo->abbrev,
11933 | vals[vi].value,
11934 | vals[vi].strptr);
11935 | }
11936 | }
11937 | } else {
11938 | if (hfinfo->display == BASE_HEX) {
11939 | printf("V\t%s\t0x%x\t%s\n",
11940 | hfinfo->abbrev,
11941 | vals[vi].value,
11942 | vals[vi].strptr);
11943 | }
11944 | else {
11945 | printf("V\t%s\t%u\t%s\n",
11946 | hfinfo->abbrev,
11947 | vals[vi].value,
11948 | vals[vi].strptr);
11949 | }
11950 | }
11951 | vi++;
11952 | }
11953 | }
11954 | else if (vals64) {
11955 | vi = 0;
11956 | while (vals64[vi].strptr) {
11957 | printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11958 | hfinfo->abbrev,
11959 | vals64[vi].value,
11960 | vals64[vi].strptr);
11961 | vi++;
11962 | }
11963 | }
11964 |
11965 | /* print range strings? */
11966 | else if (range) {
11967 | vi = 0;
11968 | while (range[vi].strptr) {
11969 | /* Print in the proper base */
11970 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11971 | printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11972 | hfinfo->abbrev,
11973 | range[vi].value_min,
11974 | range[vi].value_max,
11975 | range[vi].strptr);
11976 | }
11977 | else {
11978 | printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11979 | hfinfo->abbrev,
11980 | range[vi].value_min,
11981 | range[vi].value_max,
11982 | range[vi].strptr);
11983 | }
11984 | vi++;
11985 | }
11986 | }
11987 |
11988 | /* Print true/false strings? */
11989 | else if (tfs) {
11990 | printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11991 | tfs->true_string, tfs->false_string);
11992 | }
11993 | /* Print unit strings? */
11994 | else if (units) {
11995 | printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11996 | units->singular, units->plural ? units->plural : "(no plural)");
11997 | }
11998 | }
11999 | }
12000 |
12001 | /* Prints the number of registered fields.
12002 | * Useful for determining an appropriate value for
12003 | * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12004 | *
12005 | * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12006 | * the number of fields, true otherwise.
12007 | */
12008 | bool_Bool
12009 | proto_registrar_dump_fieldcount(void)
12010 | {
12011 | uint32_t i;
12012 | header_field_info *hfinfo;
12013 | uint32_t deregistered_count = 0;
12014 | uint32_t same_name_count = 0;
12015 | uint32_t protocol_count = 0;
12016 |
12017 | for (i = 0; i < gpa_hfinfo.len; i++) {
12018 | if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
12019 | deregistered_count++;
12020 | continue; /* This is a deregistered protocol or header field */
12021 | }
12022 |
12023 | 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", 12023 , __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", 12023 , "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", 12023, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12024 |
12025 | if (proto_registrar_is_protocol(i))
12026 | protocol_count++;
12027 |
12028 | if (hfinfo->same_name_prev_id != -1)
12029 | same_name_count++;
12030 | }
12031 |
12032 | printf("There are %u header fields registered, of which:\n"
12033 | "\t%u are deregistered\n"
12034 | "\t%u are protocols\n"
12035 | "\t%u have the same name as another field\n\n",
12036 | gpa_hfinfo.len, deregistered_count, protocol_count,
12037 | same_name_count);
12038 |
12039 | printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12040 | (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12041 | "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12042 | "\n");
12043 |
12044 | printf("The header field table consumes %u KiB of memory.\n",
12045 | (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12046 | printf("The fields themselves consume %u KiB of memory.\n",
12047 | (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12048 |
12049 | return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12050 | }
12051 |
12052 | static void
12053 | elastic_add_base_mapping(json_dumper *dumper)
12054 | {
12055 | json_dumper_set_member_name(dumper, "index_patterns");
12056 | json_dumper_begin_array(dumper);
12057 | // The index names from write_json_index() in print.c
12058 | json_dumper_value_string(dumper, "packets-*");
12059 | json_dumper_end_array(dumper);
12060 |
12061 | json_dumper_set_member_name(dumper, "settings");
12062 | json_dumper_begin_object(dumper);
12063 | json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12064 | json_dumper_value_anyf(dumper, "%d", 1000000);
12065 | json_dumper_end_object(dumper);
12066 | }
12067 |
12068 | static char*
12069 | ws_type_to_elastic(unsigned type)
12070 | {
12071 | switch(type) {
12072 | case FT_INT8:
12073 | return "byte";
12074 | case FT_UINT8:
12075 | case FT_INT16:
12076 | return "short";
12077 | case FT_UINT16:
12078 | case FT_INT32:
12079 | case FT_UINT24:
12080 | case FT_INT24:
12081 | return "integer";
12082 | case FT_FRAMENUM:
12083 | case FT_UINT32:
12084 | case FT_UINT40:
12085 | case FT_UINT48:
12086 | case FT_UINT56:
12087 | case FT_INT40:
12088 | case FT_INT48:
12089 | case FT_INT56:
12090 | case FT_INT64:
12091 | return "long";
12092 | case FT_UINT64:
12093 | return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12094 | case FT_FLOAT:
12095 | return "float";
12096 | case FT_DOUBLE:
12097 | case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12098 | return "double";
12099 | case FT_IPv6:
12100 | case FT_IPv4:
12101 | return "ip";
12102 | case FT_ABSOLUTE_TIME:
12103 | return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12104 | case FT_BOOLEAN:
12105 | return "boolean";
12106 | default:
12107 | return NULL((void*)0);
12108 | }
12109 | }
12110 |
12111 | static char*
12112 | dot_to_underscore(char* str)
12113 | {
12114 | unsigned i;
12115 | for (i = 0; i < strlen(str); i++) {
12116 | if (str[i] == '.')
12117 | str[i] = '_';
12118 | }
12119 | return str;
12120 | }
12121 |
12122 | /* Dumps a mapping file for ElasticSearch
12123 | * This is the v1 (legacy) _template API.
12124 | * At some point it may need to be updated with the composable templates
12125 | * introduced in Elasticsearch 7.8 (_index_template)
12126 | */
12127 | void
12128 | proto_registrar_dump_elastic(const char* filter)
12129 | {
12130 | header_field_info *hfinfo;
12131 | header_field_info *parent_hfinfo;
12132 | unsigned i;
12133 | bool_Bool open_object = true1;
12134 | const char* prev_proto = NULL((void*)0);
12135 | char* str;
12136 | char** protos = NULL((void*)0);
12137 | char* proto;
12138 | bool_Bool found;
12139 | unsigned j;
12140 | char* type;
12141 | char* prev_item = NULL((void*)0);
12142 |
12143 | /* We have filtering protocols. Extract them. */
12144 | if (filter) {
12145 | protos = g_strsplit(filter, ",", -1);
12146 | }
12147 |
12148 | /*
12149 | * To help tracking down the json tree, objects have been appended with a comment:
12150 | * n.label -> where n is the indentation level and label the name of the object
12151 | */
12152 |
12153 | json_dumper dumper = {
12154 | .output_file = stdoutstdout,
12155 | .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12156 | };
12157 | json_dumper_begin_object(&dumper); // 1.root
12158 | elastic_add_base_mapping(&dumper);
12159 |
12160 | json_dumper_set_member_name(&dumper, "mappings");
12161 | json_dumper_begin_object(&dumper); // 2.mappings
12162 |
12163 | json_dumper_set_member_name(&dumper, "properties");
12164 | json_dumper_begin_object(&dumper); // 3.properties
12165 | json_dumper_set_member_name(&dumper, "timestamp");
12166 | json_dumper_begin_object(&dumper); // 4.timestamp
12167 | json_dumper_set_member_name(&dumper, "type");
12168 | json_dumper_value_string(&dumper, "date");
12169 | json_dumper_end_object(&dumper); // 4.timestamp
12170 |
12171 | json_dumper_set_member_name(&dumper, "layers");
12172 | json_dumper_begin_object(&dumper); // 4.layers
12173 | json_dumper_set_member_name(&dumper, "properties");
12174 | json_dumper_begin_object(&dumper); // 5.properties
12175 |
12176 | for (i = 0; i < gpa_hfinfo.len; i++) {
12177 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12178 | continue; /* This is a deregistered protocol or header field */
12179 |
12180 | 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", 12180 , __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", 12180 , "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", 12180, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12181 |
12182 | /*
12183 | * Skip the pseudo-field for "proto_tree_add_text()" since
12184 | * we don't want it in the list of filterable protocols.
12185 | */
12186 | if (hfinfo->id == hf_text_only)
12187 | continue;
12188 |
12189 | if (!proto_registrar_is_protocol(i)) {
12190 | 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", 12190 , __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", 12190 , "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", 12190 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12191 |
12192 | /*
12193 | * Skip the field if filter protocols have been set and this one's
12194 | * parent is not listed.
12195 | */
12196 | if (protos) {
12197 | found = false0;
12198 | j = 0;
12199 | proto = protos[0];
12200 | while(proto) {
12201 | if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12202 | found = true1;
12203 | break;
12204 | }
12205 | j++;
12206 | proto = protos[j];
12207 | }
12208 | if (!found)
12209 | continue;
12210 | }
12211 |
12212 | if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12213 | json_dumper_end_object(&dumper); // 7.properties
12214 | json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12215 | open_object = true1;
12216 | }
12217 |
12218 | prev_proto = parent_hfinfo->abbrev;
12219 |
12220 | if (open_object) {
12221 | json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12222 | json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12223 | json_dumper_set_member_name(&dumper, "properties");
12224 | json_dumper_begin_object(&dumper); // 7.properties
12225 | open_object = false0;
12226 | }
12227 | /* Skip the fields that would map into string. This is the default in elasticsearch. */
12228 | type = ws_type_to_elastic(hfinfo->type);
12229 | /* when type is NULL, we have the default mapping: string */
12230 | if (type) {
12231 | str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo-> abbrev);
12232 | dot_to_underscore(str);
12233 | if (g_strcmp0(prev_item, str)) {
12234 | json_dumper_set_member_name(&dumper, str);
12235 | json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12236 | json_dumper_set_member_name(&dumper, "type");
12237 | json_dumper_value_string(&dumper, type);
12238 | json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12239 | }
12240 | g_free(prev_item);
12241 | prev_item = str;
12242 | }
12243 | }
12244 | }
12245 | g_free(prev_item);
12246 |
12247 | if (prev_proto) {
12248 | json_dumper_end_object(&dumper); // 7.properties
12249 | json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12250 | }
12251 |
12252 | json_dumper_end_object(&dumper); // 5.properties
12253 | json_dumper_end_object(&dumper); // 4.layers
12254 | json_dumper_end_object(&dumper); // 3.properties
12255 | json_dumper_end_object(&dumper); // 2.mappings
12256 | json_dumper_end_object(&dumper); // 1.root
12257 | bool_Bool ret = json_dumper_finish(&dumper);
12258 | DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12258, "ret"))));
12259 |
12260 | g_strfreev(protos);
12261 | }
12262 |
12263 | /* Dumps the contents of the registration database to stdout. An independent
12264 | * program can take this output and format it into nice tables or HTML or
12265 | * whatever.
12266 | *
12267 | * There is one record per line. Each record is either a protocol or a header
12268 | * field, differentiated by the first field. The fields are tab-delimited.
12269 | *
12270 | * Protocols
12271 | * ---------
12272 | * Field 1 = 'P'
12273 | * Field 2 = descriptive protocol name
12274 | * Field 3 = protocol abbreviation
12275 | *
12276 | * Header Fields
12277 | * -------------
12278 | * Field 1 = 'F'
12279 | * Field 2 = descriptive field name
12280 | * Field 3 = field abbreviation
12281 | * Field 4 = type ( textual representation of the ftenum type )
12282 | * Field 5 = parent protocol abbreviation
12283 | * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12284 | * Field 7 = bitmask: format: hex: 0x....
12285 | * Field 8 = blurb describing field
12286 | */
12287 | void
12288 | proto_registrar_dump_fields(void)
12289 | {
12290 | header_field_info *hfinfo, *parent_hfinfo;
12291 | int i, len;
12292 | const char *enum_name;
12293 | const char *base_name;
12294 | const char *blurb;
12295 | char width[5];
12296 |
12297 | len = gpa_hfinfo.len;
12298 | for (i = 0; i < len ; i++) {
12299 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12300 | continue; /* This is a deregistered protocol or header field */
12301 |
12302 | 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", 12302 , __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", 12302 , "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", 12302, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12303 |
12304 | /*
12305 | * Skip the pseudo-field for "proto_tree_add_text()" since
12306 | * we don't want it in the list of filterable fields.
12307 | */
12308 | if (hfinfo->id == hf_text_only)
12309 | continue;
12310 |
12311 | /* format for protocols */
12312 | if (proto_registrar_is_protocol(i)) {
12313 | printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12314 | }
12315 | /* format for header fields */
12316 | else {
12317 | /*
12318 | * If this field isn't at the head of the list of
12319 | * fields with this name, skip this field - all
12320 | * fields with the same name are really just versions
12321 | * of the same field stored in different bits, and
12322 | * should have the same type/radix/value list, and
12323 | * just differ in their bit masks. (If a field isn't
12324 | * a bitfield, but can be, say, 1 or 2 bytes long,
12325 | * it can just be made FT_UINT16, meaning the
12326 | * *maximum* length is 2 bytes, and be used
12327 | * for all lengths.)
12328 | */
12329 | if (hfinfo->same_name_prev_id != -1)
12330 | continue;
12331 |
12332 | 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", 12332 , __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", 12332 , "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", 12332 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12333 |
12334 | enum_name = ftype_name(hfinfo->type);
12335 | base_name = "";
12336 |
12337 | if (hfinfo->type == FT_CHAR ||
12338 | hfinfo->type == FT_UINT8 ||
12339 | hfinfo->type == FT_UINT16 ||
12340 | hfinfo->type == FT_UINT24 ||
12341 | hfinfo->type == FT_UINT32 ||
12342 | hfinfo->type == FT_UINT40 ||
12343 | hfinfo->type == FT_UINT48 ||
12344 | hfinfo->type == FT_UINT56 ||
12345 | hfinfo->type == FT_UINT64 ||
12346 | hfinfo->type == FT_INT8 ||
12347 | hfinfo->type == FT_INT16 ||
12348 | hfinfo->type == FT_INT24 ||
12349 | hfinfo->type == FT_INT32 ||
12350 | hfinfo->type == FT_INT40 ||
12351 | hfinfo->type == FT_INT48 ||
12352 | hfinfo->type == FT_INT56 ||
12353 | hfinfo->type == FT_INT64) {
12354 |
12355 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12356 | case BASE_NONE:
12357 | case BASE_DEC:
12358 | case BASE_HEX:
12359 | case BASE_OCT:
12360 | case BASE_DEC_HEX:
12361 | case BASE_HEX_DEC:
12362 | case BASE_CUSTOM:
12363 | case BASE_PT_UDP:
12364 | case BASE_PT_TCP:
12365 | case BASE_PT_DCCP:
12366 | case BASE_PT_SCTP:
12367 | case BASE_OUI:
12368 | base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12369 | break;
12370 | default:
12371 | base_name = "????";
12372 | break;
12373 | }
12374 | } else if (hfinfo->type == FT_BOOLEAN) {
12375 | /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12376 | snprintf(width, sizeof(width), "%d", hfinfo->display);
12377 | base_name = width;
12378 | }
12379 |
12380 | blurb = hfinfo->blurb;
12381 | if (blurb == NULL((void*)0))
12382 | blurb = "";
12383 | else if (strlen(blurb) == 0)
12384 | blurb = "\"\"";
12385 |
12386 | printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12387 | hfinfo->name, hfinfo->abbrev, enum_name,
12388 | parent_hfinfo->abbrev, base_name,
12389 | hfinfo->bitmask, blurb);
12390 | }
12391 | }
12392 | }
12393 |
12394 | /* Dumps all abbreviated field and protocol completions of the given string to
12395 | * stdout. An independent program may use this for command-line tab completion
12396 | * of fields.
12397 | */
12398 | bool_Bool
12399 | proto_registrar_dump_field_completions(const char *prefix)
12400 | {
12401 | header_field_info *hfinfo;
12402 | int i, len;
12403 | size_t prefix_len;
12404 | bool_Bool matched = false0;
12405 |
12406 | prefix_len = strlen(prefix);
12407 | len = gpa_hfinfo.len;
12408 | for (i = 0; i < len ; i++) {
12409 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12410 | continue; /* This is a deregistered protocol or header field */
12411 |
12412 | 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", 12412 , __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", 12412 , "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", 12412, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12413 |
12414 | /*
12415 | * Skip the pseudo-field for "proto_tree_add_text()" since
12416 | * we don't want it in the list of filterable fields.
12417 | */
12418 | if (hfinfo->id == hf_text_only)
12419 | continue;
12420 |
12421 | /* format for protocols */
12422 | if (proto_registrar_is_protocol(i)) {
12423 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12424 | matched = true1;
12425 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12426 | }
12427 | }
12428 | /* format for header fields */
12429 | else {
12430 | /*
12431 | * If this field isn't at the head of the list of
12432 | * fields with this name, skip this field - all
12433 | * fields with the same name are really just versions
12434 | * of the same field stored in different bits, and
12435 | * should have the same type/radix/value list, and
12436 | * just differ in their bit masks. (If a field isn't
12437 | * a bitfield, but can be, say, 1 or 2 bytes long,
12438 | * it can just be made FT_UINT16, meaning the
12439 | * *maximum* length is 2 bytes, and be used
12440 | * for all lengths.)
12441 | */
12442 | if (hfinfo->same_name_prev_id != -1)
12443 | continue;
12444 |
12445 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12446 | matched = true1;
12447 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12448 | }
12449 | }
12450 | }
12451 | return matched;
12452 | }
12453 |
12454 | /* Dumps field types and descriptive names to stdout. An independent
12455 | * program can take this output and format it into nice tables or HTML or
12456 | * whatever.
12457 | *
12458 | * There is one record per line. The fields are tab-delimited.
12459 | *
12460 | * Field 1 = field type name, e.g. FT_UINT8
12461 | * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12462 | */
12463 | void
12464 | proto_registrar_dump_ftypes(void)
12465 | {
12466 | int fte;
12467 |
12468 | for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12469 | printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12470 | }
12471 | }
12472 |
12473 | /* This function indicates whether it's possible to construct a
12474 | * "match selected" display filter string for the specified field,
12475 | * returns an indication of whether it's possible, and, if it's
12476 | * possible and "filter" is non-null, constructs the filter and
12477 | * sets "*filter" to point to it.
12478 | * You do not need to [g_]free() this string since it will be automatically
12479 | * freed once the next packet is dissected.
12480 | */
12481 | static bool_Bool
12482 | construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12483 | char **filter)
12484 | {
12485 | const header_field_info *hfinfo;
12486 | char *ptr;
12487 | int buf_len;
12488 | int i;
12489 | int start, length, length_remaining;
12490 | uint8_t c;
12491 |
12492 | if (!finfo)
12493 | return false0;
12494 |
12495 | hfinfo = finfo->hfinfo;
12496 | DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12496, "hfinfo"))));
12497 |
12498 | /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12499 | * then "the numeric value ... is not used when preparing
12500 | * filters for the field in question." If it's any other
12501 | * base, we'll generate the filter normally (which will
12502 | * be numeric, even though the human-readable string does
12503 | * work for filtering.)
12504 | *
12505 | * XXX - It might be nice to use fvalue_to_string_repr() in
12506 | * "proto_item_fill_label()" as well, although, there, you'd
12507 | * have to deal with the base *and* with resolved values for
12508 | * addresses.
12509 | *
12510 | * Perhaps in addition to taking the repr type (DISPLAY
12511 | * or DFILTER) and the display (base), fvalue_to_string_repr()
12512 | * should have the the "strings" values in the header_field_info
12513 | * structure for the field as a parameter, so it can have
12514 | * if the field is Boolean or an enumerated integer type,
12515 | * the tables used to generate human-readable values.
12516 | */
12517 | if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12518 | const char *str = NULL((void*)0);
12519 |
12520 | switch (hfinfo->type) {
12521 |
12522 | case FT_INT8:
12523 | case FT_INT16:
12524 | case FT_INT24:
12525 | case FT_INT32:
12526 | str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12527 | break;
12528 |
12529 | case FT_CHAR:
12530 | case FT_UINT8:
12531 | case FT_UINT16:
12532 | case FT_UINT24:
12533 | case FT_UINT32:
12534 | str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12535 | break;
12536 |
12537 | default:
12538 | break;
12539 | }
12540 |
12541 | if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12542 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12543 | return true1;
12544 | }
12545 | }
12546 |
12547 | switch (hfinfo->type) {
12548 |
12549 | case FT_PROTOCOL:
12550 | if (filter != NULL((void*)0))
12551 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12552 | break;
12553 |
12554 | case FT_NONE:
12555 | /*
12556 | * If the length is 0, just match the name of the
12557 | * field.
12558 | *
12559 | * (Also check for negative values, just in case,
12560 | * as we'll cast it to an unsigned value later.)
12561 | */
12562 | length = finfo->length;
12563 | if (length == 0) {
12564 | if (filter != NULL((void*)0))
12565 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12566 | break;
12567 | }
12568 | if (length < 0)
12569 | return false0;
12570 |
12571 | /*
12572 | * This doesn't have a value, so we'd match
12573 | * on the raw bytes at this address.
12574 | *
12575 | * Should we be allowed to access to the raw bytes?
12576 | * If "edt" is NULL, the answer is "no".
12577 | */
12578 | if (edt == NULL((void*)0))
12579 | return false0;
12580 |
12581 | /*
12582 | * Is this field part of the raw frame tvbuff?
12583 | * If not, we can't use "frame[N:M]" to match
12584 | * it.
12585 | *
12586 | * XXX - should this be frame-relative, or
12587 | * protocol-relative?
12588 | *
12589 | * XXX - does this fallback for non-registered
12590 | * fields even make sense?
12591 | */
12592 | if (finfo->ds_tvb != edt->tvb)
12593 | return false0; /* you lose */
12594 |
12595 | /*
12596 | * Don't go past the end of that tvbuff.
12597 | */
12598 | length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12599 | if (length > length_remaining)
12600 | length = length_remaining;
12601 | if (length <= 0)
12602 | return false0;
12603 |
12604 | if (filter != NULL((void*)0)) {
12605 | start = finfo->start;
12606 | buf_len = 32 + length * 3;
12607 | *filter = (char *)wmem_alloc0(NULL((void*)0), buf_len);
12608 | ptr = *filter;
12609 |
12610 | ptr += snprintf(ptr, buf_len-(ptr-*filter),
12611 | "frame[%d:%d] == ", finfo->start, length);
12612 | for (i=0; i<length; i++) {
12613 | c = tvb_get_uint8(finfo->ds_tvb, start);
12614 | start++;
12615 | if (i == 0 ) {
12616 | ptr += snprintf(ptr, buf_len-(ptr-*filter), "%02x", c);
12617 | }
12618 | else {
12619 | ptr += snprintf(ptr, buf_len-(ptr-*filter), ":%02x", c);
12620 | }
12621 | }
12622 | }
12623 | break;
12624 |
12625 | /* By default, use the fvalue's "to_string_repr" method. */
12626 | default:
12627 | if (filter != NULL((void*)0)) {
12628 | char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12629 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12630 | wmem_free(NULL((void*)0), str);
12631 | }
12632 | break;
12633 | }
12634 |
12635 | return true1;
12636 | }
12637 |
12638 | /*
12639 | * Returns true if we can do a "match selected" on the field, false
12640 | * otherwise.
12641 | */
12642 | bool_Bool
12643 | proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12644 | {
12645 | return construct_match_selected_string(finfo, edt, NULL((void*)0));
12646 | }
12647 |
12648 | /* This function attempts to construct a "match selected" display filter
12649 | * string for the specified field; if it can do so, it returns a pointer
12650 | * to the string, otherwise it returns NULL.
12651 | *
12652 | * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12653 | */
12654 | char *
12655 | proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12656 | {
12657 | char *filter = NULL((void*)0);
12658 |
12659 | if (!construct_match_selected_string(finfo, edt, &filter))
12660 | {
12661 | wmem_free(NULL((void*)0), filter);
12662 | return NULL((void*)0);
12663 | }
12664 | return filter;
12665 | }
12666 |
12667 | /* This function is common code for all proto_tree_add_bitmask... functions.
12668 | */
12669 |
12670 | static bool_Bool
12671 | proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12672 | const int len, const int ett, int * const *fields,
12673 | const int flags, bool_Bool first,
12674 | bool_Bool use_parent_tree,
12675 | proto_tree* tree, uint64_t value)
12676 | {
12677 | uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12678 | uint64_t bitmask = 0;
12679 | uint64_t tmpval;
12680 | header_field_info *hf;
12681 | uint32_t integer32;
12682 | int bit_offset;
12683 | int no_of_bits;
12684 |
12685 | if (!*fields)
12686 | 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" );
12687 |
12688 | if (len < 0 || len > 8)
12689 | REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12690 | /**
12691 | * packet-frame.c uses len=0 since the value is taken from the packet
12692 | * metadata, not the packet bytes. In that case, assume that all bits
12693 | * in the provided value are valid.
12694 | */
12695 | if (len > 0) {
12696 | available_bits >>= (8 - (unsigned)len)*8;
12697 | }
12698 |
12699 | if (use_parent_tree == false0)
12700 | tree = proto_item_add_subtree(item, ett);
12701 |
12702 | while (*fields) {
12703 | uint64_t present_bits;
12704 | 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", 12704, __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", 12704 , "**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", 12704, "gpa_hfinfo.hfi[**fields] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];;
12705 | 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", 12705 , "hf->bitmask != 0", hf->abbrev))));
12706 |
12707 | bitmask |= hf->bitmask;
12708 |
12709 | /* Skip fields that aren't fully present */
12710 | present_bits = available_bits & hf->bitmask;
12711 | if (present_bits != hf->bitmask) {
12712 | fields++;
12713 | continue;
12714 | }
12715 |
12716 | switch (hf->type) {
12717 | case FT_CHAR:
12718 | case FT_UINT8:
12719 | case FT_UINT16:
12720 | case FT_UINT24:
12721 | case FT_UINT32:
12722 | proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12723 | break;
12724 |
12725 | case FT_INT8:
12726 | case FT_INT16:
12727 | case FT_INT24:
12728 | case FT_INT32:
12729 | proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12730 | break;
12731 |
12732 | case FT_UINT40:
12733 | case FT_UINT48:
12734 | case FT_UINT56:
12735 | case FT_UINT64:
12736 | proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12737 | break;
12738 |
12739 | case FT_INT40:
12740 | case FT_INT48:
12741 | case FT_INT56:
12742 | case FT_INT64:
12743 | proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12744 | break;
12745 |
12746 | case FT_BOOLEAN:
12747 | proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12748 | break;
12749 |
12750 | default:
12751 | 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))
12752 | 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))
12753 | 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))
12754 | 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));
12755 | break;
12756 | }
12757 | if (flags & BMT_NO_APPEND0x01) {
12758 | fields++;
12759 | continue;
12760 | }
12761 | tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12762 |
12763 | /* XXX: README.developer and the comments have always defined
12764 | * BMT_NO_INT as "only boolean flags are added to the title /
12765 | * don't add non-boolean (integral) fields", but the
12766 | * implementation has always added BASE_CUSTOM and fields with
12767 | * value_strings, though not fields with unit_strings.
12768 | * Possibly this is because some dissectors use a FT_UINT8
12769 | * with a value_string for fields that should be a FT_BOOLEAN.
12770 | */
12771 | switch (hf->type) {
12772 | case FT_CHAR:
12773 | if (hf->display == BASE_CUSTOM) {
12774 | char lbl[ITEM_LABEL_LENGTH240];
12775 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12776 |
12777 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12777, "fmtfunc"))));
12778 | fmtfunc(lbl, (uint32_t) tmpval);
12779 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12780 | hf->name, lbl);
12781 | first = false0;
12782 | }
12783 | else if (hf->strings) {
12784 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12785 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12786 | first = false0;
12787 | }
12788 | else if (!(flags & BMT_NO_INT0x02)) {
12789 | char buf[32];
12790 | const char *out;
12791 |
12792 | if (!first) {
12793 | proto_item_append_text(item, ", ");
12794 | }
12795 |
12796 | out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12797 | proto_item_append_text(item, "%s: %s", hf->name, out);
12798 | first = false0;
12799 | }
12800 |
12801 | break;
12802 |
12803 | case FT_UINT8:
12804 | case FT_UINT16:
12805 | case FT_UINT24:
12806 | case FT_UINT32:
12807 | if (hf->display == BASE_CUSTOM) {
12808 | char lbl[ITEM_LABEL_LENGTH240];
12809 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12810 |
12811 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12811, "fmtfunc"))));
12812 | fmtfunc(lbl, (uint32_t) tmpval);
12813 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12814 | hf->name, lbl);
12815 | first = false0;
12816 | }
12817 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12818 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12819 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12820 | first = false0;
12821 | }
12822 | else if (!(flags & BMT_NO_INT0x02)) {
12823 | char buf[NUMBER_LABEL_LENGTH80];
12824 | const char *out = NULL((void*)0);
12825 |
12826 | if (!first) {
12827 | proto_item_append_text(item, ", ");
12828 | }
12829 |
12830 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12831 | out = hf_try_val_to_str((uint32_t) tmpval, hf);
12832 | }
12833 | if (out == NULL((void*)0)) {
12834 | out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12835 | }
12836 | proto_item_append_text(item, "%s: %s", hf->name, out);
12837 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12838 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12839 | }
12840 | first = false0;
12841 | }
12842 |
12843 | break;
12844 |
12845 | case FT_INT8:
12846 | case FT_INT16:
12847 | case FT_INT24:
12848 | case FT_INT32:
12849 | integer32 = (uint32_t) tmpval;
12850 | if (hf->bitmask) {
12851 | no_of_bits = ws_count_ones(hf->bitmask);
12852 | integer32 = ws_sign_ext32(integer32, no_of_bits);
12853 | }
12854 | if (hf->display == BASE_CUSTOM) {
12855 | char lbl[ITEM_LABEL_LENGTH240];
12856 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12857 |
12858 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12858, "fmtfunc"))));
12859 | fmtfunc(lbl, (int32_t) integer32);
12860 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12861 | hf->name, lbl);
12862 | first = false0;
12863 | }
12864 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12865 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12866 | hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12867 | first = false0;
12868 | }
12869 | else if (!(flags & BMT_NO_INT0x02)) {
12870 | char buf[NUMBER_LABEL_LENGTH80];
12871 | const char *out = NULL((void*)0);
12872 |
12873 | if (!first) {
12874 | proto_item_append_text(item, ", ");
12875 | }
12876 |
12877 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12878 | out = hf_try_val_to_str((int32_t) integer32, hf);
12879 | }
12880 | if (out == NULL((void*)0)) {
12881 | out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12882 | }
12883 | proto_item_append_text(item, "%s: %s", hf->name, out);
12884 | if (hf->display & BASE_UNIT_STRING0x00001000) {
12885 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12886 | }
12887 | first = false0;
12888 | }
12889 |
12890 | break;
12891 |
12892 | case FT_UINT40:
12893 | case FT_UINT48:
12894 | case FT_UINT56:
12895 | case FT_UINT64:
12896 | if (hf->display == BASE_CUSTOM) {
12897 | char lbl[ITEM_LABEL_LENGTH240];
12898 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12899 |
12900 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12900, "fmtfunc"))));
12901 | fmtfunc(lbl, tmpval);
12902 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12903 | hf->name, lbl);
12904 | first = false0;
12905 | }
12906 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12907 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12908 | hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12909 | first = false0;
12910 | }
12911 | else if (!(flags & BMT_NO_INT0x02)) {
12912 | char buf[NUMBER_LABEL_LENGTH80];
12913 | const char *out = NULL((void*)0);
12914 |
12915 | if (!first) {
12916 | proto_item_append_text(item, ", ");
12917 | }
12918 |
12919 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12920 | out = hf_try_val64_to_str(tmpval, hf);
12921 | }
12922 | if (out == NULL((void*)0)) {
12923 | out = hfinfo_number_value_format64(hf, buf, tmpval);
12924 | }
12925 | proto_item_append_text(item, "%s: %s", hf->name, out);
12926 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12927 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12928 | }
12929 | first = false0;
12930 | }
12931 |
12932 | break;
12933 |
12934 | case FT_INT40:
12935 | case FT_INT48:
12936 | case FT_INT56:
12937 | case FT_INT64:
12938 | if (hf->bitmask) {
12939 | no_of_bits = ws_count_ones(hf->bitmask);
12940 | tmpval = ws_sign_ext64(tmpval, no_of_bits);
12941 | }
12942 | if (hf->display == BASE_CUSTOM) {
12943 | char lbl[ITEM_LABEL_LENGTH240];
12944 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12945 |
12946 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12946, "fmtfunc"))));
12947 | fmtfunc(lbl, (int64_t) tmpval);
12948 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12949 | hf->name, lbl);
12950 | first = false0;
12951 | }
12952 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12953 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12954 | hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12955 | first = false0;
12956 | }
12957 | else if (!(flags & BMT_NO_INT0x02)) {
12958 | char buf[NUMBER_LABEL_LENGTH80];
12959 | const char *out = NULL((void*)0);
12960 |
12961 | if (!first) {
12962 | proto_item_append_text(item, ", ");
12963 | }
12964 |
12965 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12966 | out = hf_try_val64_to_str((int64_t) tmpval, hf);
12967 | }
12968 | if (out == NULL((void*)0)) {
12969 | out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12970 | }
12971 | proto_item_append_text(item, "%s: %s", hf->name, out);
12972 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12973 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12974 | }
12975 | first = false0;
12976 | }
12977 |
12978 | break;
12979 |
12980 | case FT_BOOLEAN:
12981 | if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12982 | /* If we have true/false strings, emit full - otherwise messages
12983 | might look weird */
12984 | const struct true_false_string *tfs =
12985 | (const struct true_false_string *)hf->strings;
12986 |
12987 | if (tmpval) {
12988 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12989 | hf->name, tfs->true_string);
12990 | first = false0;
12991 | } else if (!(flags & BMT_NO_FALSE0x04)) {
12992 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12993 | hf->name, tfs->false_string);
12994 | first = false0;
12995 | }
12996 | } else if (hf->bitmask & value) {
12997 | /* If the flag is set, show the name */
12998 | proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12999 | first = false0;
13000 | }
13001 | break;
13002 | default:
13003 | 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))
13004 | 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))
13005 | 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))
13006 | 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));
13007 | break;
13008 | }
13009 |
13010 | fields++;
13011 | }
13012 |
13013 | /* XXX: We don't pass the hfi into this function. Perhaps we should,
13014 | * but then again most dissectors don't set the bitmask field for
13015 | * the higher level bitmask hfi, so calculate the bitmask from the
13016 | * fields present. */
13017 | if (item) {
13018 | bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13019 | no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13020 | 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);
13021 | 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);
13022 | }
13023 | return first;
13024 | }
13025 |
13026 | /* This function will dissect a sequence of bytes that describe a
13027 | * bitmask and supply the value of that sequence through a pointer.
13028 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13029 | * to be dissected.
13030 | * This field will form an expansion under which the individual fields of the
13031 | * bitmask is dissected and displayed.
13032 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13033 | *
13034 | * fields is an array of pointers to int that lists all the fields of the
13035 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13036 | * or another integer of the same type/size as hf_hdr with a mask specified.
13037 | * This array is terminated by a NULL entry.
13038 | *
13039 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13040 | * FT_integer fields that have a value_string attached will have the
13041 | * matched string displayed on the expansion line.
13042 | */
13043 | proto_item *
13044 | proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13045 | const unsigned offset, const int hf_hdr,
13046 | const int ett, int * const *fields,
13047 | const unsigned encoding, uint64_t *retval)
13048 | {
13049 | 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);
13050 | }
13051 |
13052 | /* This function will dissect a sequence of bytes that describe a
13053 | * bitmask.
13054 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13055 | * to be dissected.
13056 | * This field will form an expansion under which the individual fields of the
13057 | * bitmask is dissected and displayed.
13058 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13059 | *
13060 | * fields is an array of pointers to int that lists all the fields of the
13061 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13062 | * or another integer of the same type/size as hf_hdr with a mask specified.
13063 | * This array is terminated by a NULL entry.
13064 | *
13065 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13066 | * FT_integer fields that have a value_string attached will have the
13067 | * matched string displayed on the expansion line.
13068 | */
13069 | proto_item *
13070 | proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13071 | const unsigned offset, const int hf_hdr,
13072 | const int ett, int * const *fields,
13073 | const unsigned encoding)
13074 | {
13075 | return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13076 | }
13077 |
13078 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13079 | * what data is appended to the header.
13080 | */
13081 | proto_item *
13082 | proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13083 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13084 | uint64_t *retval)
13085 | {
13086 | proto_item *item = NULL((void*)0);
13087 | header_field_info *hf;
13088 | int len;
13089 | uint64_t value;
13090 |
13091 | 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", 13091, __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", 13091 , "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", 13091, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13092 | 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", 13092, (hf)->abbrev)));
13093 | len = ftype_wire_size(hf->type);
13094 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13095 |
13096 | if (parent_tree) {
13097 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13098 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13099 | flags, false0, false0, NULL((void*)0), value);
13100 | }
13101 |
13102 | *retval = value;
13103 | if (hf->bitmask) {
13104 | /* Mask out irrelevant portions */
13105 | *retval &= hf->bitmask;
13106 | /* Shift bits */
13107 | *retval >>= hfinfo_bitshift(hf);
13108 | }
13109 |
13110 | return item;
13111 | }
13112 |
13113 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13114 | * what data is appended to the header.
13115 | */
13116 | proto_item *
13117 | proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13118 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13119 | {
13120 | proto_item *item = NULL((void*)0);
13121 | header_field_info *hf;
13122 | int len;
13123 | uint64_t value;
13124 |
13125 | 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", 13125, __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", 13125 , "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", 13125, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13126 | 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", 13126, (hf)->abbrev)));
13127 |
13128 | if (parent_tree) {
13129 | len = ftype_wire_size(hf->type);
13130 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13131 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13132 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13133 | flags, false0, false0, NULL((void*)0), value);
13134 | }
13135 |
13136 | return item;
13137 | }
13138 |
13139 | /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13140 | can't be retrieved directly from tvb) */
13141 | proto_item *
13142 | proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13143 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13144 | {
13145 | return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13146 | hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13147 | }
13148 |
13149 | /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13150 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13151 | proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13152 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13153 | {
13154 | proto_item *item = NULL((void*)0);
13155 | header_field_info *hf;
13156 | int len;
13157 |
13158 | 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", 13158, __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", 13158 , "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", 13158, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13159 | 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", 13159, (hf)->abbrev)));
13160 | /* the proto_tree_add_uint/_uint64() calls below
13161 | will fail if tvb==NULL and len!=0 */
13162 | len = tvb ? ftype_wire_size(hf->type) : 0;
13163 |
13164 | if (parent_tree) {
13165 | if (len <= 4)
13166 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13167 | else
13168 | item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13169 |
13170 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13171 | flags, false0, false0, NULL((void*)0), value);
13172 | }
13173 |
13174 | return item;
13175 | }
13176 |
13177 | /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13178 | void
13179 | proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13180 | const int len, int * const *fields, const unsigned encoding)
13181 | {
13182 | uint64_t value;
13183 |
13184 | if (tree) {
13185 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13186 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13187 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13188 | }
13189 | }
13190 |
13191 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13192 | proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13193 | const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13194 | {
13195 | uint64_t value;
13196 |
13197 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13198 | if (tree) {
13199 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13200 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13201 | }
13202 | if (retval) {
13203 | *retval = value;
13204 | }
13205 | }
13206 |
13207 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13208 | proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13209 | const int len, int * const *fields, const uint64_t value)
13210 | {
13211 | if (tree) {
13212 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13213 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13214 | }
13215 | }
13216 |
13217 |
13218 | /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13219 | * This is intended to support bitmask fields whose lengths can vary, perhaps
13220 | * as the underlying standard evolves over time.
13221 | * With this API there is the possibility of being called to display more or
13222 | * less data than the dissector was coded to support.
13223 | * In such cases, it is assumed that bitmasks are extended on the MSb end.
13224 | * Thus when presented with "too much" or "too little" data, MSbits will be
13225 | * ignored or MSfields sacrificed.
13226 | *
13227 | * Only fields for which all defined bits are available are displayed.
13228 | */
13229 | proto_item *
13230 | proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13231 | const unsigned offset, const unsigned len, const int hf_hdr,
13232 | const int ett, int * const *fields, struct expert_field* exp,
13233 | const unsigned encoding)
13234 | {
13235 | proto_item *item = NULL((void*)0);
13236 | header_field_info *hf;
13237 | unsigned decodable_len;
13238 | unsigned decodable_offset;
13239 | uint32_t decodable_value;
13240 | uint64_t value;
13241 |
13242 | 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", 13242, __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", 13242 , "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", 13242, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13243 | 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", 13243, (hf)->abbrev)));
13244 |
13245 | decodable_offset = offset;
13246 | decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len ) : ((unsigned) ftype_wire_size(hf->type)));
13247 |
13248 | /* If we are ftype_wire_size-limited,
13249 | * make sure we decode as many LSBs as possible.
13250 | */
13251 | if (encoding == ENC_BIG_ENDIAN0x00000000) {
13252 | decodable_offset += (len - decodable_len);
13253 | }
13254 |
13255 | if (parent_tree) {
13256 | decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13257 | decodable_len, encoding);
13258 |
13259 | /* The root item covers all the bytes even if we can't decode them all */
13260 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13261 | decodable_value);
13262 | }
13263 |
13264 | if (decodable_len < len) {
13265 | /* Dissector likely requires updating for new protocol revision */
13266 | expert_add_info_format(NULL((void*)0), item, exp,
13267 | "Only least-significant %d of %d bytes decoded",
13268 | decodable_len, len);
13269 | }
13270 |
13271 | if (item) {
13272 | value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13273 | proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13274 | ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13275 | }
13276 |
13277 | return item;
13278 | }
13279 |
13280 | /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13281 | proto_item *
13282 | proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13283 | const unsigned offset, const unsigned len,
13284 | const char *name, const char *fallback,
13285 | const int ett, int * const *fields,
13286 | const unsigned encoding, const int flags)
13287 | {
13288 | proto_item *item = NULL((void*)0);
13289 | uint64_t value;
13290 |
13291 | if (parent_tree) {
13292 | item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13293 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13294 | if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13295 | flags, true1, false0, NULL((void*)0), value) && fallback) {
13296 | /* Still at first item - append 'fallback' text if any */
13297 | proto_item_append_text(item, "%s", fallback);
13298 | }
13299 | }
13300 |
13301 | return item;
13302 | }
13303 |
13304 | proto_item *
13305 | proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13306 | const unsigned bit_offset, const int no_of_bits,
13307 | const unsigned encoding)
13308 | {
13309 | header_field_info *hfinfo;
13310 | int octet_length;
13311 | int octet_offset;
13312 |
13313 | 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", 13313, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13313 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13313, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13314 |
13315 | if (no_of_bits < 0) {
13316 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13317 | }
13318 | octet_length = (no_of_bits + 7) >> 3;
13319 | octet_offset = bit_offset >> 3;
13320 | test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13321 |
13322 | /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13323 | * but only after doing a bunch more work (which we can, in the common
13324 | * case, shortcut here).
13325 | */
13326 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13327 | 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", 13327 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13327, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13327, "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", 13327, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
13328 |
13329 | return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13330 | }
13331 |
13332 | /*
13333 | * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13334 | * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13335 | * Offset should be given in bits from the start of the tvb.
13336 | */
13337 |
13338 | static proto_item *
13339 | _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13340 | const unsigned bit_offset, const int no_of_bits,
13341 | uint64_t *return_value, const unsigned encoding)
13342 | {
13343 | int offset;
13344 | unsigned length;
13345 | uint8_t tot_no_bits;
13346 | char *bf_str;
13347 | char lbl_str[ITEM_LABEL_LENGTH240];
13348 | uint64_t value = 0;
13349 | uint8_t *bytes = NULL((void*)0);
13350 | size_t bytes_length = 0;
13351 |
13352 | proto_item *pi;
13353 | header_field_info *hf_field;
13354 |
13355 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13356 | 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", 13356, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13356 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13356, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;;
13357 |
13358 | if (hf_field->bitmask != 0) {
13359 | 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)
13360 | " 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)
13361 | 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);
13362 | }
13363 |
13364 | if (no_of_bits < 0) {
13365 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13366 | } else if (no_of_bits == 0) {
13367 | 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)
13368 | 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);
13369 | }
13370 |
13371 | /* Byte align offset */
13372 | offset = bit_offset>>3;
13373 |
13374 | /*
13375 | * Calculate the number of octets used to hold the bits
13376 | */
13377 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13378 | length = (tot_no_bits + 7) >> 3;
13379 |
13380 | if (no_of_bits < 65) {
13381 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13382 | } else if (hf_field->type != FT_BYTES) {
13383 | 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)
13384 | 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);
13385 | return NULL((void*)0);
13386 | }
13387 |
13388 | /* Sign extend for signed types */
13389 | switch (hf_field->type) {
13390 | case FT_INT8:
13391 | case FT_INT16:
13392 | case FT_INT24:
13393 | case FT_INT32:
13394 | case FT_INT40:
13395 | case FT_INT48:
13396 | case FT_INT56:
13397 | case FT_INT64:
13398 | value = ws_sign_ext64(value, no_of_bits);
13399 | break;
13400 |
13401 | default:
13402 | break;
13403 | }
13404 |
13405 | if (return_value) {
13406 | *return_value = value;
13407 | }
13408 |
13409 | /* Coast clear. Try and fake it */
13410 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13411 | 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", 13411 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13411, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13411, "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", 13411, __func__, "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); } } };
13412 |
13413 | bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13414 |
13415 | switch (hf_field->type) {
13416 | case FT_BOOLEAN:
13417 | /* Boolean field */
13418 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13419 | "%s = %s: %s",
13420 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13421 | break;
13422 |
13423 | case FT_CHAR:
13424 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13425 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13426 | break;
13427 |
13428 | case FT_UINT8:
13429 | case FT_UINT16:
13430 | case FT_UINT24:
13431 | case FT_UINT32:
13432 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13433 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13434 | break;
13435 |
13436 | case FT_INT8:
13437 | case FT_INT16:
13438 | case FT_INT24:
13439 | case FT_INT32:
13440 | pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13441 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13442 | break;
13443 |
13444 | case FT_UINT40:
13445 | case FT_UINT48:
13446 | case FT_UINT56:
13447 | case FT_UINT64:
13448 | pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13449 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13450 | break;
13451 |
13452 | case FT_INT40:
13453 | case FT_INT48:
13454 | case FT_INT56:
13455 | case FT_INT64:
13456 | pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13457 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13458 | break;
13459 |
13460 | case FT_BYTES:
13461 | bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13462 | pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13463 | proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13464 | proto_item_set_text(pi, "%s", lbl_str);
13465 | return pi;
13466 |
13467 | /* TODO: should handle FT_UINT_BYTES ? */
13468 |
13469 | default:
13470 | 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))
13471 | 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))
13472 | 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))
13473 | 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));
13474 | return NULL((void*)0);
13475 | }
13476 |
13477 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13478 | return pi;
13479 | }
13480 |
13481 | proto_item *
13482 | proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13483 | const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13484 | uint64_t *return_value)
13485 | {
13486 | proto_item *pi;
13487 | int no_of_bits;
13488 | int octet_offset;
13489 | unsigned mask_initial_bit_offset;
13490 | unsigned mask_greatest_bit_offset;
13491 | unsigned octet_length;
13492 | uint8_t i;
13493 | char bf_str[256];
13494 | char lbl_str[ITEM_LABEL_LENGTH240];
13495 | uint64_t value;
13496 | uint64_t composite_bitmask;
13497 | uint64_t composite_bitmap;
13498 |
13499 | header_field_info *hf_field;
13500 |
13501 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13502 | 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", 13502, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13502 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13502, "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 | →
13503 |
13504 | if (hf_field->bitmask != 0) {
8 | ← | Assuming field 'bitmask' is equal to 0 | →
9 | ← | Taking false branch | →
13505 | 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)
13506 | " 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)
13507 | 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);
13508 | }
13509 |
13510 | mask_initial_bit_offset = bit_offset % 8;
13511 |
13512 | no_of_bits = 0;
13513 | value = 0;
13514 | i = 0;
13515 | mask_greatest_bit_offset = 0;
13516 | composite_bitmask = 0;
13517 | composite_bitmap = 0;
13518 |
13519 | 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 | →
13520 | uint64_t crumb_mask, crumb_value;
13521 | uint8_t crumb_end_bit_offset;
13522 |
13523 | crumb_value = tvb_get_bits64(tvb,
13524 | bit_offset + crumb_spec[i].crumb_bit_offset,
13525 | crumb_spec[i].crumb_bit_length,
13526 | ENC_BIG_ENDIAN0x00000000);
13527 | value += crumb_value;
13528 | no_of_bits += crumb_spec[i].crumb_bit_length;
13529 | 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", 13529 , "no_of_bits <= 64", "a value larger than 64 bits cannot be represented" ))));
12 | ← | Assuming 'no_of_bits' is <= 64 | →
13 | ← | '?' condition is true | →
13530 |
13531 | /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13532 | octet containing the initial offset.
13533 | If the mask is beyond 32 bits, then give up on bit map display.
13534 | This could be improved in future, probably showing a table
13535 | of 32 or 64 bits per row */
13536 | if (mask_greatest_bit_offset
13.1 | 'mask_greatest_bit_offset' is < 32
< 32) {
14 | ← | Taking true branch | →
13537 | crumb_end_bit_offset = mask_initial_bit_offset
13538 | + crumb_spec[i].crumb_bit_offset
13539 | + crumb_spec[i].crumb_bit_length;
13540 | 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' | →
13541 |
13542 | if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17 | ← | Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset' | →
18 | ← | Taking false branch | →
13543 | mask_greatest_bit_offset = crumb_end_bit_offset;
13544 | }
13545 | /* Currently the bitmap of the crumbs are only shown if
13546 | * smaller than 32 bits. Do not bother calculating the
13547 | * mask if it is larger than that. */
13548 | if (crumb_end_bit_offset
18.1 | 'crumb_end_bit_offset' is <= 32
<= 32) {
19 | ← | Taking true branch | →
13549 | 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'
13550 | composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13551 | }
13552 | }
13553 | /* Shift left for the next segment */
13554 | value <<= crumb_spec[++i].crumb_bit_length;
13555 | }
13556 |
13557 | /* Sign extend for signed types */
13558 | switch (hf_field->type) {
13559 | case FT_INT8:
13560 | case FT_INT16:
13561 | case FT_INT24:
13562 | case FT_INT32:
13563 | case FT_INT40:
13564 | case FT_INT48:
13565 | case FT_INT56:
13566 | case FT_INT64:
13567 | value = ws_sign_ext64(value, no_of_bits);
13568 | break;
13569 | default:
13570 | break;
13571 | }
13572 |
13573 | if (return_value) {
13574 | *return_value = value;
13575 | }
13576 |
13577 | /* Coast clear. Try and fake it */
13578 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13579 | 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", 13579 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13579, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13579, "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", 13579, __func__, "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); } } };
13580 |
13581 | /* initialise the format string */
13582 | bf_str[0] = '\0';
13583 |
13584 | octet_offset = bit_offset >> 3;
13585 |
13586 | /* Round up mask length to nearest octet */
13587 | octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13588 | mask_greatest_bit_offset = octet_length << 3;
13589 |
13590 | /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13591 | It would be a useful enhancement to eliminate this restriction. */
13592 | if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13593 | other_decode_bitfield_value(bf_str,
13594 | (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13595 | (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13596 | mask_greatest_bit_offset);
13597 | } else {
13598 | /* If the bitmask is too large, try to describe its contents. */
13599 | snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13600 | }
13601 |
13602 | switch (hf_field->type) {
13603 | case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13604 | /* Boolean field */
13605 | return proto_tree_add_boolean_format(tree, hfindex,
13606 | tvb, octet_offset, octet_length, value,
13607 | "%s = %s: %s",
13608 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13609 | break;
13610 |
13611 | case FT_CHAR:
13612 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13613 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13614 | break;
13615 |
13616 | case FT_UINT8:
13617 | case FT_UINT16:
13618 | case FT_UINT24:
13619 | case FT_UINT32:
13620 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13621 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13622 | break;
13623 |
13624 | case FT_INT8:
13625 | case FT_INT16:
13626 | case FT_INT24:
13627 | case FT_INT32:
13628 | pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13629 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13630 | break;
13631 |
13632 | case FT_UINT40:
13633 | case FT_UINT48:
13634 | case FT_UINT56:
13635 | case FT_UINT64:
13636 | pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13637 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13638 | break;
13639 |
13640 | case FT_INT40:
13641 | case FT_INT48:
13642 | case FT_INT56:
13643 | case FT_INT64:
13644 | pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13645 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13646 | break;
13647 |
13648 | default:
13649 | 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))
13650 | 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))
13651 | 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))
13652 | 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));
13653 | return NULL((void*)0);
13654 | }
13655 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13656 | return pi;
13657 | }
13658 |
13659 | void
13660 | proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13661 | const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13662 | {
13663 | header_field_info *hfinfo;
13664 | int start = bit_offset >> 3;
13665 | int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13666 |
13667 | /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13668 | * so that we can use the tree's memory scope in calculating the string */
13669 | if (length == -1) {
13670 | tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13671 | } else {
13672 | tvb_ensure_bytes_exist(tvb, start, length);
13673 | }
13674 | if (!tree) return;
13675 |
13676 | 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", 13676, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13676 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13676, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13677 | proto_tree_add_text_internal(tree, tvb, start, length,
13678 | "%s crumb %d of %s (decoded above)",
13679 | decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13680 | tvb_get_bits32(tvb,
13681 | bit_offset,
13682 | crumb_spec[crumb_index].crumb_bit_length,
13683 | ENC_BIG_ENDIAN0x00000000),
13684 | ENC_BIG_ENDIAN0x00000000),
13685 | crumb_index,
13686 | hfinfo->name);
13687 | }
13688 |
13689 | proto_item *
13690 | proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13691 | const unsigned bit_offset, const int no_of_bits,
13692 | uint64_t *return_value, const unsigned encoding)
13693 | {
13694 | proto_item *item;
13695 |
13696 | if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13697 | bit_offset, no_of_bits,
13698 | return_value, encoding))) {
13699 | 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);
13700 | 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);
13701 | }
13702 | return item;
13703 | }
13704 |
13705 | static proto_item *
13706 | _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13707 | tvbuff_t *tvb, const unsigned bit_offset,
13708 | const int no_of_bits, void *value_ptr,
13709 | const unsigned encoding, char *value_str)
13710 | {
13711 | int offset;
13712 | unsigned length;
13713 | uint8_t tot_no_bits;
13714 | char *str;
13715 | uint64_t value = 0;
13716 | header_field_info *hf_field;
13717 |
13718 | /* We do not have to return a value, try to fake it as soon as possible */
13719 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13720 | 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", 13720 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13720, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13720, "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", 13720, __func__, "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); } } };
13721 |
13722 | if (hf_field->bitmask != 0) {
13723 | 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)
13724 | " 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)
13725 | 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);
13726 | }
13727 |
13728 | if (no_of_bits < 0) {
13729 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13730 | } else if (no_of_bits == 0) {
13731 | 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)
13732 | 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);
13733 | }
13734 |
13735 | /* Byte align offset */
13736 | offset = bit_offset>>3;
13737 |
13738 | /*
13739 | * Calculate the number of octets used to hold the bits
13740 | */
13741 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13742 | length = tot_no_bits>>3;
13743 | /* If we are using part of the next octet, increase length by 1 */
13744 | if (tot_no_bits & 0x07)
13745 | length++;
13746 |
13747 | if (no_of_bits < 65) {
13748 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13749 | } else {
13750 | 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)
13751 | 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);
13752 | return NULL((void*)0);
13753 | }
13754 |
13755 | str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13756 |
13757 | (void) g_strlcat(str, " = ", 256+64);
13758 | (void) g_strlcat(str, hf_field->name, 256+64);
13759 |
13760 | /*
13761 | * This function does not receive an actual value but a dimensionless pointer to that value.
13762 | * For this reason, the type of the header field is examined in order to determine
13763 | * what kind of value we should read from this address.
13764 | * The caller of this function must make sure that for the specific header field type the address of
13765 | * a compatible value is provided.
13766 | */
13767 | switch (hf_field->type) {
13768 | case FT_BOOLEAN:
13769 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13770 | "%s: %s", str, value_str);
13771 | break;
13772 |
13773 | case FT_CHAR:
13774 | case FT_UINT8:
13775 | case FT_UINT16:
13776 | case FT_UINT24:
13777 | case FT_UINT32:
13778 | return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13779 | "%s: %s", str, value_str);
13780 | break;
13781 |
13782 | case FT_UINT40:
13783 | case FT_UINT48:
13784 | case FT_UINT56:
13785 | case FT_UINT64:
13786 | return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13787 | "%s: %s", str, value_str);
13788 | break;
13789 |
13790 | case FT_INT8:
13791 | case FT_INT16:
13792 | case FT_INT24:
13793 | case FT_INT32:
13794 | return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13795 | "%s: %s", str, value_str);
13796 | break;
13797 |
13798 | case FT_INT40:
13799 | case FT_INT48:
13800 | case FT_INT56:
13801 | case FT_INT64:
13802 | return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13803 | "%s: %s", str, value_str);
13804 | break;
13805 |
13806 | case FT_FLOAT:
13807 | return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13808 | "%s: %s", str, value_str);
13809 | break;
13810 |
13811 | default:
13812 | 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))
13813 | 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))
13814 | 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))
13815 | 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));
13816 | return NULL((void*)0);
13817 | }
13818 | }
13819 |
13820 | static proto_item *
13821 | proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13822 | tvbuff_t *tvb, const unsigned bit_offset,
13823 | const int no_of_bits, void *value_ptr,
13824 | const unsigned encoding, char *value_str)
13825 | {
13826 | proto_item *item;
13827 |
13828 | if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13829 | tvb, bit_offset, no_of_bits,
13830 | value_ptr, encoding, value_str))) {
13831 | 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);
13832 | 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);
13833 | }
13834 | return item;
13835 | }
13836 |
13837 | #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); \
13838 | va_start(ap, format)__builtin_va_start(ap, format); \
13839 | dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13840 | va_end(ap)__builtin_va_end(ap);
13841 |
13842 | proto_item *
13843 | proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13844 | tvbuff_t *tvb, const unsigned bit_offset,
13845 | const int no_of_bits, uint32_t value,
13846 | const unsigned encoding,
13847 | const char *format, ...)
13848 | {
13849 | va_list ap;
13850 | char *dst;
13851 | header_field_info *hf_field;
13852 |
13853 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13854 |
13855 | 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", 13855 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13855, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13855, "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", 13855, __func__, "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); } } };
13856 |
13857 | switch (hf_field->type) {
13858 | case FT_UINT8:
13859 | case FT_UINT16:
13860 | case FT_UINT24:
13861 | case FT_UINT32:
13862 | break;
13863 |
13864 | default:
13865 | 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)
13866 | 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);
13867 | return NULL((void*)0);
13868 | }
13869 |
13870 | 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);;
13871 |
13872 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13873 | }
13874 |
13875 | proto_item *
13876 | proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13877 | tvbuff_t *tvb, const unsigned bit_offset,
13878 | const int no_of_bits, uint64_t value,
13879 | const unsigned encoding,
13880 | const char *format, ...)
13881 | {
13882 | va_list ap;
13883 | char *dst;
13884 | header_field_info *hf_field;
13885 |
13886 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13887 |
13888 | 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", 13888 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13888, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13888, "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", 13888, __func__, "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); } } };
13889 |
13890 | switch (hf_field->type) {
13891 | case FT_UINT40:
13892 | case FT_UINT48:
13893 | case FT_UINT56:
13894 | case FT_UINT64:
13895 | break;
13896 |
13897 | default:
13898 | 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)
13899 | 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);
13900 | return NULL((void*)0);
13901 | }
13902 |
13903 | 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);;
13904 |
13905 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13906 | }
13907 |
13908 | proto_item *
13909 | proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13910 | tvbuff_t *tvb, const unsigned bit_offset,
13911 | const int no_of_bits, float value,
13912 | const unsigned encoding,
13913 | const char *format, ...)
13914 | {
13915 | va_list ap;
13916 | char *dst;
13917 | header_field_info *hf_field;
13918 |
13919 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13920 |
13921 | 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", 13921 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13921, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13921, "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", 13921, __func__, "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); } } };
13922 |
13923 | 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", 13923, ((hf_field))->abbrev))));
13924 |
13925 | 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);;
13926 |
13927 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13928 | }
13929 |
13930 | proto_item *
13931 | proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13932 | tvbuff_t *tvb, const unsigned bit_offset,
13933 | const int no_of_bits, int32_t value,
13934 | const unsigned encoding,
13935 | const char *format, ...)
13936 | {
13937 | va_list ap;
13938 | char *dst;
13939 | header_field_info *hf_field;
13940 |
13941 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13942 |
13943 | 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", 13943 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13943, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13943, "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", 13943, __func__, "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); } } };
13944 |
13945 | switch (hf_field->type) {
13946 | case FT_INT8:
13947 | case FT_INT16:
13948 | case FT_INT24:
13949 | case FT_INT32:
13950 | break;
13951 |
13952 | default:
13953 | 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)
13954 | 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);
13955 | return NULL((void*)0);
13956 | }
13957 |
13958 | 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);;
13959 |
13960 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13961 | }
13962 |
13963 | proto_item *
13964 | proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13965 | tvbuff_t *tvb, const unsigned bit_offset,
13966 | const int no_of_bits, int64_t value,
13967 | const unsigned encoding,
13968 | const char *format, ...)
13969 | {
13970 | va_list ap;
13971 | char *dst;
13972 | header_field_info *hf_field;
13973 |
13974 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13975 |
13976 | 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", 13976 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13976, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13976, "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", 13976, __func__, "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); } } };
13977 |
13978 | switch (hf_field->type) {
13979 | case FT_INT40:
13980 | case FT_INT48:
13981 | case FT_INT56:
13982 | case FT_INT64:
13983 | break;
13984 |
13985 | default:
13986 | 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)
13987 | 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);
13988 | return NULL((void*)0);
13989 | }
13990 |
13991 | 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);;
13992 |
13993 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13994 | }
13995 |
13996 | proto_item *
13997 | proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13998 | tvbuff_t *tvb, const unsigned bit_offset,
13999 | const int no_of_bits, uint64_t value,
14000 | const unsigned encoding,
14001 | const char *format, ...)
14002 | {
14003 | va_list ap;
14004 | char *dst;
14005 | header_field_info *hf_field;
14006 |
14007 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14008 |
14009 | 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", 14009 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14009, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14009, "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", 14009, __func__, "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); } } };
14010 |
14011 | 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" , 14011, ((hf_field))->abbrev))));
14012 |
14013 | CREATE_VALUE_STRING(tree, dst, format, ap)__builtin_va_start(ap, format); dst = wmem_strdup_vprintf(((tree )->tree_data->pinfo->pool), format, ap); __builtin_va_end (ap);;
14014 |
14015 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14016 | }
14017 |
14018 | proto_item *
14019 | proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14020 | const unsigned bit_offset, const int no_of_chars)
14021 | {
14022 | proto_item *pi;
14023 | header_field_info *hfinfo;
14024 | int byte_length;
14025 | int byte_offset;
14026 | char *string;
14027 |
14028 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14029 |
14030 | 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", 14030 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14030, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14030, "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", 14030, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14031 |
14032 | 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" , 14032, ((hfinfo))->abbrev))));
14033 |
14034 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14035 | byte_offset = bit_offset >> 3;
14036 |
14037 | string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14038 |
14039 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14040 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14040, "byte_length >= 0" ))));
14041 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14042 |
14043 | return pi;
14044 | }
14045 |
14046 | proto_item *
14047 | proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14048 | const unsigned bit_offset, const int no_of_chars)
14049 | {
14050 | proto_item *pi;
14051 | header_field_info *hfinfo;
14052 | int byte_length;
14053 | int byte_offset;
14054 | char *string;
14055 |
14056 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14057 |
14058 | 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", 14058 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14058, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14058, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; 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", 14058, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14059 |
14060 | 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" , 14060, ((hfinfo))->abbrev))));
14061 |
14062 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14063 | byte_offset = bit_offset >> 3;
14064 |
14065 | string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14066 |
14067 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14068 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14068, "byte_length >= 0" ))));
14069 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14070 |
14071 | return pi;
14072 | }
14073 |
14074 | const value_string proto_checksum_vals[] = {
14075 | { PROTO_CHECKSUM_E_BAD, "Bad" },
14076 | { PROTO_CHECKSUM_E_GOOD, "Good" },
14077 | { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14078 | { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14079 | { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14080 |
14081 | { 0, NULL((void*)0) }
14082 | };
14083 |
14084 | proto_item *
14085 | proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14086 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14087 | packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14088 | {
14089 | header_field_info *hfinfo;
14090 | uint32_t checksum;
14091 | uint32_t len;
14092 | proto_item* ti = NULL((void*)0);
14093 | proto_item* ti2;
14094 | bool_Bool incorrect_checksum = true1;
14095 |
14096 | 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", 14096, __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", 14096 , "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", 14096, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14097 |
14098 | switch (hfinfo->type) {
14099 | case FT_UINT8:
14100 | len = 1;
14101 | break;
14102 | case FT_UINT16:
14103 | len = 2;
14104 | break;
14105 | case FT_UINT24:
14106 | len = 3;
14107 | break;
14108 | case FT_UINT32:
14109 | len = 4;
14110 | break;
14111 | default:
14112 | 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)
14113 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32" , hfinfo->abbrev);
14114 | }
14115 |
14116 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14117 | ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14118 | proto_item_set_generated(ti);
14119 | if (hf_checksum_status != -1) {
14120 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14121 | proto_item_set_generated(ti2);
14122 | }
14123 | return ti;
14124 | }
14125 |
14126 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14127 | ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14128 | proto_item_set_generated(ti);
14129 | } else {
14130 | ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14131 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14132 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14133 | if (computed_checksum == 0) {
14134 | proto_item_append_text(ti, " [correct]");
14135 | if (hf_checksum_status != -1) {
14136 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14137 | proto_item_set_generated(ti2);
14138 | }
14139 | incorrect_checksum = false0;
14140 | } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14141 | computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14142 | /* XXX - This can't distinguish between "shouldbe"
14143 | * 0x0000 and 0xFFFF unless we know whether there
14144 | * were any nonzero bits (other than the checksum).
14145 | * Protocols should not use this path if they might
14146 | * have an all zero packet.
14147 | * Some implementations put the wrong zero; maybe
14148 | * we should have a special expert info for that?
14149 | */
14150 | }
14151 | } else {
14152 | if (checksum == computed_checksum) {
14153 | proto_item_append_text(ti, " [correct]");
14154 | if (hf_checksum_status != -1) {
14155 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14156 | proto_item_set_generated(ti2);
14157 | }
14158 | incorrect_checksum = false0;
14159 | }
14160 | }
14161 |
14162 | if (incorrect_checksum) {
14163 | if (hf_checksum_status != -1) {
14164 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14165 | proto_item_set_generated(ti2);
14166 | }
14167 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14168 | proto_item_append_text(ti, " [incorrect]");
14169 | if (bad_checksum_expert != NULL((void*)0))
14170 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14171 | } else {
14172 | proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14173 | if (bad_checksum_expert != NULL((void*)0))
14174 | 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);
14175 | }
14176 | }
14177 | } else {
14178 | if (hf_checksum_status != -1) {
14179 | proto_item_append_text(ti, " [unverified]");
14180 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14181 | proto_item_set_generated(ti2);
14182 | }
14183 | }
14184 | }
14185 |
14186 | return ti;
14187 | }
14188 |
14189 | proto_item *
14190 | proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14191 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14192 | packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14193 | {
14194 | header_field_info *hfinfo;
14195 | uint8_t *checksum = NULL((void*)0);
14196 | proto_item* ti = NULL((void*)0);
14197 | proto_item* ti2;
14198 | bool_Bool incorrect_checksum = true1;
14199 |
14200 | 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", 14200, __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", 14200 , "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", 14200, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14201 |
14202 | if (hfinfo->type != FT_BYTES) {
14203 | 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)
14204 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES" , hfinfo->abbrev);
14205 | }
14206 |
14207 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14208 | ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14209 | proto_item_set_generated(ti);
14210 | if (hf_checksum_status != -1) {
14211 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14212 | proto_item_set_generated(ti2);
14213 | }
14214 | return ti;
14215 | }
14216 |
14217 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14218 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14219 | proto_item_set_generated(ti);
14220 | } else {
14221 | 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 ))))));
14222 | tvb_memcpy(tvb, checksum, offset, checksum_len);
14223 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14224 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14225 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14226 | if (computed_checksum == 0) {
14227 | proto_item_append_text(ti, " [correct]");
14228 | if (hf_checksum_status != -1) {
14229 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14230 | proto_item_set_generated(ti2);
14231 | }
14232 | incorrect_checksum = false0;
14233 | }
14234 | } else {
14235 | if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14236 | proto_item_append_text(ti, " [correct]");
14237 | if (hf_checksum_status != -1) {
14238 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14239 | proto_item_set_generated(ti2);
14240 | }
14241 | incorrect_checksum = false0;
14242 | }
14243 | }
14244 |
14245 | if (incorrect_checksum) {
14246 | if (hf_checksum_status != -1) {
14247 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14248 | proto_item_set_generated(ti2);
14249 | }
14250 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14251 | proto_item_append_text(ti, " [incorrect]");
14252 | if (bad_checksum_expert != NULL((void*)0))
14253 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14254 | } else {
14255 | size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14256 | 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))))));
14257 | for (size_t counter = 0; counter < checksum_len; ++counter) {
14258 | snprintf(
14259 | /* On ecah iteration inserts two characters */
14260 | (char*)&computed_checksum_str[counter << 1],
14261 | computed_checksum_str_len - (counter << 1),
14262 | "%02x",
14263 | computed_checksum[counter]);
14264 | }
14265 | proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14266 | if (bad_checksum_expert != NULL((void*)0))
14267 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14268 | }
14269 | }
14270 | } else {
14271 | if (hf_checksum_status != -1) {
14272 | proto_item_append_text(ti, " [unverified]");
14273 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14274 | proto_item_set_generated(ti2);
14275 | }
14276 | }
14277 | }
14278 |
14279 | return ti;
14280 | }
14281 |
14282 | unsigned char
14283 | proto_check_field_name(const char *field_name)
14284 | {
14285 | return module_check_valid_name(field_name, false0);
14286 | }
14287 |
14288 | unsigned char
14289 | proto_check_field_name_lower(const char *field_name)
14290 | {
14291 | return module_check_valid_name(field_name, true1);
14292 | }
14293 |
14294 | bool_Bool
14295 | tree_expanded(int tree_type)
14296 | {
14297 | if (tree_type <= 0) {
14298 | return false0;
14299 | }
14300 | 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", 14300, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14301 | return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14302 | }
14303 |
14304 | void
14305 | tree_expanded_set(int tree_type, bool_Bool value)
14306 | {
14307 | 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", 14307, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14308 |
14309 | if (value)
14310 | tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14311 | else
14312 | tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14313 | }
14314 |
14315 | /*
14316 | * Editor modelines - https://www.wireshark.org/tools/modelines.html
14317 | *
14318 | * Local variables:
14319 | * c-basic-offset: 8
14320 | * tab-width: 8
14321 | * indent-tabs-mode: t
14322 | * End:
14323 | *
14324 | * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14325 | * :indentSize=8:tabSize=8:noTabs=false:
14326 | */