### Bug Summary

File: | epan/proto.c
Warning: | line 13535, 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-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-11-23-100330-3583-1 -x c /builds/wireshark/wireshark/epan/proto.c

Keyboard shortcuts:

- Use 'j/k' keys for keyboard navigation
- Use 'Shift+S' to show/hide relevant lines
- Use '?' to toggle this window

Close
Show only relevant lines Show control flow arrows

1 | /* proto.c
2 | * Routines for protocol tree
3 | *
4 | * Wireshark - Network traffic analyzer
5 | * By Gerald Combs <gerald@wireshark.org>
6 | * Copyright 1998 Gerald Combs
7 | *
8 | * SPDX-License-Identifier: GPL-2.0-or-later
9 | */
10 |
11 | #include "config.h"
12 | #define WS_LOG_DOMAIN"Epan" LOG_DOMAIN_EPAN"Epan"
13 | #include "wireshark.h"
14 |
15 | #include <float.h>
16 | #include <errno(*__errno_location ()).h>
17 |
18 | #include <epan/tfs.h>
19 | #include <epan/unit_strings.h>
20 |
21 | #include <wsutil/array.h>
22 | #include <wsutil/bits_ctz.h>
23 | #include <wsutil/bits_count_ones.h>
24 | #include <wsutil/sign_ext.h>
25 | #include <wsutil/utf8_entities.h>
26 | #include <wsutil/json_dumper.h>
27 | #include <wsutil/pint.h>
28 | #include <wsutil/unicode-utils.h>
29 | #include <wsutil/dtoa.h>
30 | #include <wsutil/filesystem.h>
31 | #ifdef HAVE_UNISTD_H1
32 | #include <unistd.h>
33 | #endif
34 |
35 | #include <ftypes/ftypes.h>
36 | #include <ftypes/ftypes-int.h>
37 |
38 | #include <epan/packet.h>
39 | #include "exceptions.h"
40 | #include "ptvcursor.h"
41 | #include "strutil.h"
42 | #include "addr_resolv.h"
43 | #include "address_types.h"
44 | #include "oids.h"
45 | #include "proto.h"
46 | #include "epan_dissect.h"
47 | #include "dfilter/dfilter.h"
48 | #include "tvbuff.h"
49 | #include "charsets.h"
50 | #include "column-info.h"
51 | #include "to_str.h"
52 | #include "osi-utils.h"
53 | #include "expert.h"
54 | #include "show_exception.h"
55 | #include "in_cksum.h"
56 | #include "register-int.h"
57 |
58 | #include <wsutil/crash_info.h>
59 | #include <wsutil/epochs.h>
60 |
61 | /* Ptvcursor limits */
62 | #define SUBTREE_ONCE_ALLOCATION_NUMBER8 8
63 | #define SUBTREE_MAX_LEVELS256 256
64 |
65 | typedef struct __subtree_lvl {
66 | int cursor_offset;
67 | proto_item *it;
68 | proto_tree *tree;
69 | } subtree_lvl;
70 |
71 | struct ptvcursor {
72 | wmem_allocator_t *scope;
73 | subtree_lvl *pushed_tree;
74 | uint8_t pushed_tree_index;
75 | uint8_t pushed_tree_max;
76 | proto_tree *tree;
77 | tvbuff_t *tvb;
78 | int offset;
79 | };
80 |
81 | #define cVALS(x)(const value_string*)(x) (const value_string*)(x)
82 |
83 | /** See inlined comments.
84 | @param tree the tree to append this item to
85 | @param free_block a code block to call to free resources if this returns
86 | @return NULL if 'tree' is null */
87 | #define CHECK_FOR_NULL_TREE_AND_FREE(tree, free_block)if (!tree) { free_block; return ((void*)0); } \
88 | if (!tree) { \
89 | free_block; \
90 | return NULL((void*)0); \
91 | }
92 |
93 | /** See inlined comments.
94 | @param tree the tree to append this item to
95 | @return NULL if 'tree' is null */
96 | #define CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); } \
97 | CHECK_FOR_NULL_TREE_AND_FREE(tree, ((void)0))if (!tree) { ((void)0); return ((void*)0); }
98 |
99 | /** See inlined comments.
100 | @param length the length of this item
101 | @param cleanup_block a code block to call to free resources if this returns
102 | @return NULL if 'length' is lower -1 or equal 0 */
103 | #define CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, cleanup_block)if (length < -1 || length == 0 ) { cleanup_block; return ( (void*)0); } \
104 | if (length < -1 || length == 0 ) { \
105 | cleanup_block; \
106 | return NULL((void*)0); \
107 | }
108 |
109 | /** See inlined comments.
110 | @param length the length of this item
111 | @return NULL if 'length' is lower -1 or equal 0 */
112 | #define CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); } \
113 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length, ((void)0))if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); }
114 |
115 | /** See inlined comments.
116 | @param tree the tree to append this item to
117 | @param hfindex field index
118 | @param hfinfo header_field
119 | @param free_block a code block to call to free resources if this returns
120 | @return the header field matching 'hfinfo' */
121 | #define TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, free_block)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 121 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 121, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 121, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { free_block; if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 121, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { free_block; return proto_tree_add_fake_node(tree, hfinfo ); } } } \
122 | /* If the tree is not visible and this item is not referenced \
123 | we don't have to do much work at all but we should still \
124 | return a node so that referenced field items below this node \
125 | (think proto_item_add_subtree()) will still have somewhere \
126 | to attach to or else filtering will not work (they would be \
127 | ignored since tree would be NULL). \
128 | DON'T try to fake a node where PTREE_FINFO(tree) is visible \
129 | because that means we can change its length or repr, and we \
130 | don't want to do so with calls intended for this faked new \
131 | item, so this item needs a new (hidden) child node. \
132 | We fake FT_PROTOCOL unless some clients have requested us \
133 | not to do so. \
134 | */ \
135 | PTREE_DATA(tree)((tree)->tree_data)->count++; \
136 | PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 136, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 136, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 136, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; \
137 | if (PTREE_DATA(tree)((tree)->tree_data)->count > prefs.gui_max_tree_items) { \
138 | free_block; \
139 | if (wireshark_abort_on_too_many_items) \
140 | ws_error("Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 141 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)
141 | hfinfo->abbrev, prefs.gui_max_tree_items)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 141 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); \
142 | /* Let the exception handler add items to the tree */ \
143 | PTREE_DATA(tree)((tree)->tree_data)->count = 0; \
144 | THROW_MESSAGE(DissectorError, \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)))
145 | wmem_strdup_printf(PNODE_POOL(tree), \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)))
146 | "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)", \except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items)))
147 | hfinfo->abbrev, prefs.gui_max_tree_items))except_throw(1, (6), (wmem_strdup_printf(((tree)->tree_data ->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); \
148 | } \
149 | if (!(PTREE_DATA(tree)((tree)->tree_data)->visible)) { \
150 | if (PROTO_ITEM_IS_HIDDEN(tree)proto_item_is_hidden((tree))) { \
151 | if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) \
152 | && (hfinfo->ref_type != HF_REF_TYPE_PRINT) \
153 | && (hfinfo->type != FT_PROTOCOL || \
154 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) { \
155 | free_block; \
156 | /* return fake node with no field info */\
157 | return proto_tree_add_fake_node(tree, hfinfo); \
158 | } \
159 | } \
160 | }
161 |
162 | /** See inlined comments.
163 | @param tree the tree to append this item to
164 | @param hfindex field index
165 | @param hfinfo header_field
166 | @return the header field matching 'hfinfo' */
167 | #define TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo)((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 167, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } } \
168 | TRY_TO_FAKE_THIS_ITEM_OR_FREE(tree, hfindex, hfinfo, ((void)0))((tree)->tree_data)->count++; if((hfindex == 0 || (unsigned )hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug ) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 168 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 168, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 168, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 168, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { ((void)0); return proto_tree_add_fake_node(tree, hfinfo) ; } } }
169 |
170 |
171 | /** See inlined comments.
172 | @param pi the created protocol item we're about to return */
173 | #define TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 173, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; } \
174 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 174, __func__, "assertion failed: %s", "pi" ); } while (0); \
175 | if (!PITEM_FINFO(pi)((pi)->finfo)) \
176 | return pi; \
177 | if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
178 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
179 | /* If the tree (GUI) or item isn't visible it's pointless for \
180 | * us to generate the protocol item's string representation */ \
181 | return pi; \
182 | }
183 | /* Same as above but returning void */
184 | #define TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; } \
185 | if (!pi || !PITEM_FINFO(pi)((pi)->finfo)) \
186 | return; \
187 | if (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
188 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi))) { \
189 | /* If the tree (GUI) or item isn't visible it's pointless for \
190 | * us to generate the protocol item's string representation */ \
191 | return; \
192 | }
193 | /* Similar to above, but allows a NULL tree */
194 | #define TRY_TO_FAKE_THIS_REPR_NESTED(pi)if ((pi == ((void*)0)) || (((pi)->finfo) == ((void*)0)) || (!(((pi)->tree_data)->visible) && proto_item_is_hidden ((pi)))) { return pi; } \
195 | if ((pi == NULL((void*)0)) || (PITEM_FINFO(pi)((pi)->finfo) == NULL((void*)0)) || (!(PTREE_DATA(pi)((pi)->tree_data)->visible) && \
196 | PROTO_ITEM_IS_HIDDEN(pi)proto_item_is_hidden((pi)))) { \
197 | /* If the tree (GUI) or item isn't visible it's pointless for \
198 | * us to generate the protocol item's string representation */ \
199 | return pi; \
200 | }
201 |
202 | #ifdef ENABLE_CHECK_FILTER
203 | #define CHECK_HF_VALUE(type, spec, start_values) \
204 | { \
205 | const type *current; \
206 | int n, m; \
207 | current = start_values; \
208 | for (n=0; current; n++, current++) { \
209 | /* Drop out if we reached the end. */ \
210 | if ((current->value == 0) && (current->strptr == NULL((void*)0))) { \
211 | break; \
212 | } \
213 | /* Check value against all previous */ \
214 | for (m=0; m < n; m++) { \
215 | /* There are lots of duplicates with the same string, \
216 | so only report if different... */ \
217 | if ((start_values[m].value == current->value) && \
218 | (strcmp(start_values[m].strptr, current->strptr) != 0)) { \
219 | ws_error("Field '%s' (%s) has a conflicting entry in its" \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr)
220 | " value_string: %" spec " is at indices %u (%s) and %u (%s)", \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr)
221 | hfinfo->name, hfinfo->abbrev, \ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr)
222 | current->value, m, start_values[m].strptr, n, current->strptr)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 222 , __func__, "Field '%s' (%s) has a conflicting entry in its" " value_string: %" spec " is at indices %u (%s) and %u (%s)", hfinfo->name, hfinfo ->abbrev, current->value, m, start_values[m].strptr, n, current->strptr); \
223 | } \
224 | } \
225 | } \
226 | }
227 | #endif
228 |
229 | /* The longest NUMBER-like field label we have is for BASE_OUI, which
230 | * can have up to 64 bytes for the manufacturer name if resolved plus
231 | * 11 bytes for the "XX:XX:XX ()" part = 75 octets.
232 | */
233 | #define NUMBER_LABEL_LENGTH80 80
234 |
235 | static const char *hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo);
236 | static const char *hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo);
237 | static const char *hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str);
238 | static const char *hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str);
239 | static int hfinfo_bitoffset(const header_field_info *hfinfo);
240 | static int hfinfo_mask_bitwidth(const header_field_info *hfinfo);
241 | static int hfinfo_container_bitwidth(const header_field_info *hfinfo);
242 |
243 | #define label_concat(dst, pos, src)ws_label_strcpy(dst, 240, pos, src, 0) \
244 | ws_label_strcpy(dst, ITEM_LABEL_LENGTH240, pos, src, 0)
245 |
246 | static void mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos);
247 | static void label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos);
248 |
249 | static void fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos);
250 | static void fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos);
251 | static void fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
252 | static void fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
253 | static void fill_label_char(const field_info *fi, char *label_str, size_t *value_pos);
254 | static void fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
255 | static void fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed);
256 |
257 | static size_t fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size);
258 | static void fill_label_float(const field_info *fi, char *label_str, size_t *value_pos);
259 | static size_t fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size);
260 | static void fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos);
261 |
262 | static const char *hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
263 | static const char *hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
264 | static const char *hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
265 | static const char* hfinfo_char_value_format_display(int display, char buf[7], uint32_t value);
266 | static const char *hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
267 | static const char *hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
268 | static const char *hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
269 | static const char *hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
270 | static const char *hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value);
271 | static const char *hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value);
272 | static const char *hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value);
273 |
274 | static void proto_cleanup_base(void);
275 |
276 | static proto_item *
277 | proto_tree_add_node(proto_tree *tree, field_info *fi);
278 |
279 | static proto_item *
280 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo);
281 |
282 | static void
283 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
284 | int *item_length, const unsigned encoding);
285 |
286 | static int
287 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
288 | int length, unsigned item_length, const int encoding);
289 |
290 | static field_info *
291 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
292 | const int start, const int item_length);
293 |
294 | static proto_item *
295 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
296 | int start, int *length);
297 |
298 | static void
299 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap);
300 | static void
301 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap);
302 |
303 | static void
304 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length);
305 | static void
306 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length);
307 | static void
308 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length);
309 | static void
310 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value);
311 | static void
312 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr);
313 | static void
314 | proto_tree_set_string(field_info *fi, const char* value);
315 | static void
316 | proto_tree_set_ax25(field_info *fi, const uint8_t* value);
317 | static void
318 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start);
319 | static void
320 | proto_tree_set_vines(field_info *fi, const uint8_t* value);
321 | static void
322 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start);
323 | static void
324 | proto_tree_set_ether(field_info *fi, const uint8_t* value);
325 | static void
326 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start);
327 | static void
328 | proto_tree_set_ipxnet(field_info *fi, uint32_t value);
329 | static void
330 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value);
331 | static void
332 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr* value);
333 | static void
334 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
335 | static void
336 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
337 | static void
338 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr);
339 | static void
340 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
341 | static void
342 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length);
343 | static void
344 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
345 | static void
346 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length);
347 | static void
348 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length);
349 | static void
350 | proto_tree_set_boolean(field_info *fi, uint64_t value);
351 | static void
352 | proto_tree_set_float(field_info *fi, float value);
353 | static void
354 | proto_tree_set_double(field_info *fi, double value);
355 | static void
356 | proto_tree_set_uint(field_info *fi, uint32_t value);
357 | static void
358 | proto_tree_set_int(field_info *fi, int32_t value);
359 | static void
360 | proto_tree_set_uint64(field_info *fi, uint64_t value);
361 | static void
362 | proto_tree_set_int64(field_info *fi, int64_t value);
363 | static void
364 | proto_tree_set_eui64(field_info *fi, const uint64_t value);
365 | static void
366 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding);
367 |
368 | /* Handle type length mismatch (now filterable) expert info */
369 | static int proto_type_length_mismatch;
370 | static expert_field ei_type_length_mismatch_error;
371 | static expert_field ei_type_length_mismatch_warn;
372 | static void register_type_length_mismatch(void);
373 |
374 | /* Handle byte array string decoding errors with expert info */
375 | static int proto_byte_array_string_decoding_error;
376 | static expert_field ei_byte_array_string_decoding_failed_error;
377 | static void register_byte_array_string_decodinws_error(void);
378 |
379 | /* Handle date and time string decoding errors with expert info */
380 | static int proto_date_time_string_decoding_error;
381 | static expert_field ei_date_time_string_decoding_failed_error;
382 | static void register_date_time_string_decodinws_error(void);
383 |
384 | /* Handle string errors expert info */
385 | static int proto_string_errors;
386 | static expert_field ei_string_trailing_characters;
387 | static void register_string_errors(void);
388 |
389 | static int proto_register_field_init(header_field_info *hfinfo, const int parent);
390 |
391 | /* special-case header field used within proto.c */
392 | static header_field_info hfi_text_only =
393 | { "Text item", "text", FT_NONE, BASE_NONE, NULL((void*)0), 0x0, NULL((void*)0), HFILL-1, 0, HF_REF_TYPE_NONE, -1, ((void*)0) };
394 | int hf_text_only;
395 |
396 | /* Structure for information about a protocol */
397 | struct _protocol {
398 | const char *name; /* long description */
399 | const char *short_name; /* short description */
400 | const char *filter_name; /* name of this protocol in filters */
401 | GPtrArray *fields; /* fields for this protocol */
402 | int proto_id; /* field ID for this protocol */
403 | bool_Bool is_enabled; /* true if protocol is enabled */
404 | bool_Bool enabled_by_default; /* true if protocol is enabled by default */
405 | bool_Bool can_toggle; /* true if is_enabled can be changed */
406 | int parent_proto_id; /* Used to identify "pino"s (Protocol In Name Only).
407 | For dissectors that need a protocol name so they
408 | can be added to a dissector table, but use the
409 | parent_proto_id for things like enable/disable */
410 | GList *heur_list; /* Heuristic dissectors associated with this protocol */
411 | };
412 |
413 | /* List of all protocols */
414 | static GList *protocols;
415 |
416 | /* Structure stored for deregistered g_slice */
417 | struct g_slice_data {
418 | size_t block_size;
419 | void *mem_block;
420 | };
421 |
422 | /* Deregistered fields */
423 | static GPtrArray *deregistered_fields;
424 | static GPtrArray *deregistered_data;
425 | static GPtrArray *deregistered_slice;
426 |
427 | /* indexed by prefix, contains initializers */
428 | static GHashTable* prefixes;
429 |
430 | /* Contains information about a field when a dissector calls
431 | * proto_tree_add_item. */
432 | #define FIELD_INFO_NEW(pool, fi)fi = ((field_info*)wmem_alloc((pool), sizeof(field_info))) fi = wmem_new(pool, field_info)((field_info*)wmem_alloc((pool), sizeof(field_info)))
433 | #define FIELD_INFO_FREE(pool, fi)wmem_free(pool, fi) wmem_free(pool, fi)
434 |
435 | /* Contains the space for proto_nodes. */
436 | #define PROTO_NODE_INIT(node)node->first_child = ((void*)0); node->last_child = ((void *)0); node->next = ((void*)0); \
437 | node->first_child = NULL((void*)0); \
438 | node->last_child = NULL((void*)0); \
439 | node->next = NULL((void*)0);
440 |
441 | #define PROTO_NODE_FREE(pool, node)wmem_free(pool, node) \
442 | wmem_free(pool, node)
443 |
444 | /* String space for protocol and field items for the GUI */
445 | #define ITEM_LABEL_NEW(pool, il)il = ((item_label_t*)wmem_alloc((pool), sizeof(item_label_t)) ); il->value_pos = 0; il->value_len = 0; \
446 | il = wmem_new(pool, item_label_t)((item_label_t*)wmem_alloc((pool), sizeof(item_label_t))); \
447 | il->value_pos = 0; \
448 | il->value_len = 0;
449 | #define ITEM_LABEL_FREE(pool, il)wmem_free(pool, il); \
450 | wmem_free(pool, il);
451 |
452 | #define PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 452, __func__, "Unregistered hf! index=%d", hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 452, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 452, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex]; \
453 | if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) \
454 | ws_error("Unregistered hf! index=%d", hfindex)ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 454 , __func__, "Unregistered hf! index=%d", hfindex); \
455 | DISSECTOR_ASSERT_HINT(hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len, "Unregistered hf!")((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo .len) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 455, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))); \
456 | DISSECTOR_ASSERT_HINT(gpa_hfinfo.hfi[hfindex] != NULL, "Unregistered hf!")((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : ( proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 456, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))); \
457 | hfinfo = gpa_hfinfo.hfi[hfindex];
458 |
459 | #define PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000) (300000+PRE_ALLOC_EXPERT_FIELDS_MEM5000)
460 |
461 | /* List which stores protocols and fields that have been registered */
462 | typedef struct _gpa_hfinfo_t {
463 | uint32_t len;
464 | uint32_t allocated_len;
465 | header_field_info **hfi;
466 | } gpa_hfinfo_t;
467 |
468 | static gpa_hfinfo_t gpa_hfinfo;
469 |
470 | /* Hash table of abbreviations and IDs */
471 | static wmem_map_t *gpa_name_map;
472 | static header_field_info *same_name_hfinfo;
473 |
474 | /* Hash table protocol aliases. const char * -> const char * */
475 | static GHashTable *gpa_protocol_aliases;
476 |
477 | /*
478 | * We're called repeatedly with the same field name when sorting a column.
479 | * Cache our last gpa_name_map hit for faster lookups.
480 | */
481 | static char *last_field_name;
482 | static header_field_info *last_hfinfo;
483 |
484 | /* Points to the first element of an array of bits, indexed by
485 | a subtree item type; that array element is true if subtrees of
486 | an item of that type are to be expanded. */
487 | static uint32_t *tree_is_expanded;
488 |
489 | /* Number of elements in that array. The entry with index 0 is not used. */
490 | int num_tree_types = 1;
491 |
492 | /* Name hashtables for fast detection of duplicate names */
493 | static GHashTable* proto_names;
494 | static GHashTable* proto_short_names;
495 | static GHashTable* proto_filter_names;
496 |
497 | static const char *reserved_filter_names[] = {
498 | /* Display filter keywords. */
499 | "eq",
500 | "ne",
501 | "all_eq",
502 | "any_eq",
503 | "all_ne",
504 | "any_ne",
505 | "gt",
506 | "ge",
507 | "lt",
508 | "le",
509 | "bitand",
510 | "bitwise_and",
511 | "contains",
512 | "matches",
513 | "not",
514 | "and",
515 | "or",
516 | "xor",
517 | "in",
518 | "any",
519 | "all",
520 | "true",
521 | "false",
522 | "nan",
523 | "inf",
524 | "infinity",
525 | NULL((void*)0)
526 | };
527 |
528 | static GHashTable *proto_reserved_filter_names;
529 | static GQueue* saved_dir_queue;
530 |
531 | static int
532 | proto_compare_name(const void *p1_arg, const void *p2_arg)
533 | {
534 | const protocol_t *p1 = (const protocol_t *)p1_arg;
535 | const protocol_t *p2 = (const protocol_t *)p2_arg;
536 |
537 | return g_ascii_strcasecmp(p1->short_name, p2->short_name);
538 | }
539 |
540 | static GSList *dissector_plugins;
541 |
542 | #ifdef HAVE_PLUGINS1
543 | void
544 | proto_register_plugin(const proto_plugin *plug)
545 | {
546 | dissector_plugins = g_slist_prepend(dissector_plugins, (proto_plugin *)plug);
547 | }
548 | #else /* HAVE_PLUGINS */
549 | void
550 | proto_register_plugin(const proto_plugin *plug _U___attribute__((unused)))
551 | {
552 | ws_warning("proto_register_plugin: built without support for binary plugins")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 552, __func__, "proto_register_plugin: built without support for binary plugins" ); } } while (0);
553 | }
554 | #endif /* HAVE_PLUGINS */
555 |
556 | static void
557 | call_plugin_register_protoinfo(void *data, void *user_data _U___attribute__((unused)))
558 | {
559 | proto_plugin *plug = (proto_plugin *)data;
560 |
561 | if (plug->register_protoinfo) {
562 | plug->register_protoinfo();
563 | }
564 | }
565 |
566 | static void
567 | call_plugin_register_handoff(void *data, void *user_data _U___attribute__((unused)))
568 | {
569 | proto_plugin *plug = (proto_plugin *)data;
570 |
571 | if (plug->register_handoff) {
572 | plug->register_handoff();
573 | }
574 | }
575 |
576 | void proto_pre_init(void)
577 | {
578 | saved_dir_queue = g_queue_new();
579 |
580 | proto_names = g_hash_table_new(wmem_str_hash, g_str_equal);
581 | proto_short_names = g_hash_table_new(wmem_str_hash, g_str_equal);
582 | proto_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
583 |
584 | proto_reserved_filter_names = g_hash_table_new(wmem_str_hash, g_str_equal);
585 | for (const char** ptr = reserved_filter_names; *ptr != NULL((void*)0); ptr++) {
586 | /* GHashTable has no key destructor so the cast is safe. */
587 | g_hash_table_add(proto_reserved_filter_names, *(char**)ptr);
588 | }
589 |
590 | gpa_hfinfo.len = 0;
591 | gpa_hfinfo.allocated_len = 0;
592 | gpa_hfinfo.hfi = NULL((void*)0);
593 | gpa_name_map = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
594 | wmem_map_reserve(gpa_name_map, PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
595 | gpa_protocol_aliases = g_hash_table_new(wmem_str_hash, g_str_equal);
596 | deregistered_fields = g_ptr_array_new();
597 | deregistered_data = g_ptr_array_new();
598 | deregistered_slice = g_ptr_array_new();
599 | }
600 |
601 | /* initialize data structures and register protocols and fields */
602 | void
603 | proto_init(GSList *register_all_plugin_protocols_list,
604 | GSList *register_all_plugin_handoffs_list,
605 | register_cb cb,
606 | void *client_data)
607 | {
608 | /* Initialize the ftype subsystem */
609 | ftypes_initialize();
610 |
611 | /* Initialize the address type subsystem */
612 | address_types_initialize();
613 |
614 | /* Register one special-case FT_TEXT_ONLY field for use when
615 | converting wireshark to new-style proto_tree. These fields
616 | are merely strings on the GUI tree; they are not filterable */
617 | hf_text_only = proto_register_field_init(&hfi_text_only, -1);
618 |
619 | /* Register the pseudo-protocols used for exceptions. */
620 | register_show_exception();
621 | register_type_length_mismatch();
622 | register_byte_array_string_decodinws_error();
623 | register_date_time_string_decodinws_error();
624 | register_string_errors();
625 | ftypes_register_pseudofields();
626 | col_register_protocol();
627 |
628 | /* Have each built-in dissector register its protocols, fields,
629 | dissector tables, and dissectors to be called through a
630 | handle, and do whatever one-time initialization it needs to
631 | do. */
632 | register_all_protocols(cb, client_data);
633 |
634 | /* Now call the registration routines for all epan plugins. */
635 | for (GSList *l = register_all_plugin_protocols_list; l != NULL((void*)0); l = l->next) {
636 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
637 | }
638 |
639 | /* Now call the registration routines for all dissector plugins. */
640 | if (cb)
641 | (*cb)(RA_PLUGIN_REGISTER, NULL((void*)0), client_data);
642 | g_slist_foreach(dissector_plugins, call_plugin_register_protoinfo, NULL((void*)0));
643 |
644 | /* Now call the "handoff registration" routines of all built-in
645 | dissectors; those routines register the dissector in other
646 | dissectors' handoff tables, and fetch any dissector handles
647 | they need. */
648 | register_all_protocol_handoffs(cb, client_data);
649 |
650 | /* Now do the same with epan plugins. */
651 | for (GSList *l = register_all_plugin_handoffs_list; l != NULL((void*)0); l = l->next) {
652 | ((void (*)(register_cb, void *))l->data)(cb, client_data);
653 | }
654 |
655 | /* Now do the same with dissector plugins. */
656 | if (cb)
657 | (*cb)(RA_PLUGIN_HANDOFF, NULL((void*)0), client_data);
658 | g_slist_foreach(dissector_plugins, call_plugin_register_handoff, NULL((void*)0));
659 |
660 | /* sort the protocols by protocol name */
661 | protocols = g_list_sort(protocols, proto_compare_name);
662 |
663 | /* sort the dissector handles in dissector tables (for -G reports
664 | * and -d error messages. The GUI sorts the handles itself.) */
665 | packet_all_tables_sort_handles();
666 |
667 | /* We've assigned all the subtree type values; allocate the array
668 | for them, and zero it out. */
669 | 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 )));
670 | }
671 |
672 | static void
673 | proto_cleanup_base(void)
674 | {
675 | protocol_t *protocol;
676 | header_field_info *hfinfo;
677 |
678 | /* Free the abbrev/ID hash table */
679 | if (gpa_name_map) {
680 | // XXX - We don't have a wmem_map_destroy, but
681 | // it does get cleaned up when epan scope is
682 | // destroyed
683 | //g_hash_table_destroy(gpa_name_map);
684 | gpa_name_map = NULL((void*)0);
685 | }
686 | if (gpa_protocol_aliases) {
687 | g_hash_table_destroy(gpa_protocol_aliases);
688 | gpa_protocol_aliases = NULL((void*)0);
689 | }
690 | g_free(last_field_name);
691 | last_field_name = NULL((void*)0);
692 |
693 | while (protocols) {
694 | protocol = (protocol_t *)protocols->data;
695 | 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", 695 , __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", 695, "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", 695, "gpa_hfinfo.hfi[protocol->proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[protocol-> proto_id];;
696 | 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", 696, "protocol->proto_id == hfinfo->id" ))));
697 |
698 | 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);
699 | if (protocol->parent_proto_id != -1) {
700 | // pino protocol
701 | DISSECTOR_ASSERT(protocol->fields == NULL)((void) ((protocol->fields == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 701, "protocol->fields == ((void*)0)" )))); //helpers should not have any registered fields
702 | 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" , 702, "protocol->heur_list == ((void*)0)")))); //helpers should not have a heuristic list
703 | } else {
704 | if (protocol->fields) {
705 | g_ptr_array_free(protocol->fields, true1);
706 | }
707 | g_list_free(protocol->heur_list);
708 | }
709 | protocols = g_list_remove(protocols, protocol);
710 | g_free(protocol);
711 | }
712 |
713 | if (proto_names) {
714 | g_hash_table_destroy(proto_names);
715 | proto_names = NULL((void*)0);
716 | }
717 |
718 | if (proto_short_names) {
719 | g_hash_table_destroy(proto_short_names);
720 | proto_short_names = NULL((void*)0);
721 | }
722 |
723 | if (proto_filter_names) {
724 | g_hash_table_destroy(proto_filter_names);
725 | proto_filter_names = NULL((void*)0);
726 | }
727 |
728 | if (proto_reserved_filter_names) {
729 | g_hash_table_destroy(proto_reserved_filter_names);
730 | proto_reserved_filter_names = NULL((void*)0);
731 | }
732 |
733 | if (gpa_hfinfo.allocated_len) {
734 | gpa_hfinfo.len = 0;
735 | gpa_hfinfo.allocated_len = 0;
736 | g_free(gpa_hfinfo.hfi);
737 | gpa_hfinfo.hfi = NULL((void*)0);
738 | }
739 |
740 | if (deregistered_fields) {
741 | g_ptr_array_free(deregistered_fields, true1);
742 | deregistered_fields = NULL((void*)0);
743 | }
744 |
745 | if (deregistered_data) {
746 | g_ptr_array_free(deregistered_data, true1);
747 | deregistered_data = NULL((void*)0);
748 | }
749 |
750 | if (deregistered_slice) {
751 | g_ptr_array_free(deregistered_slice, true1);
752 | deregistered_slice = NULL((void*)0);
753 | }
754 |
755 | g_free(tree_is_expanded);
756 | tree_is_expanded = NULL((void*)0);
757 |
758 | if (prefixes)
759 | g_hash_table_destroy(prefixes);
760 |
761 | if (saved_dir_queue != NULL((void*)0)) {
762 | g_queue_clear_full(saved_dir_queue, g_free);
763 | g_queue_free(saved_dir_queue);
764 | saved_dir_queue = NULL((void*)0);
765 | }
766 | }
767 |
768 | void
769 | proto_cleanup(void)
770 | {
771 | proto_free_deregistered_fields();
772 | proto_cleanup_base();
773 |
774 | g_slist_free(dissector_plugins);
775 | dissector_plugins = NULL((void*)0);
776 | }
777 |
778 | static bool_Bool
779 | ws_pushd(const char* dir)
780 | {
781 | //Save the current working directory
782 | const char* save_wd = get_current_working_dir();
783 | if (save_wd != NULL((void*)0))
784 | g_queue_push_head(saved_dir_queue, g_strdup(save_wd)g_strdup_inline (save_wd));
785 |
786 | //Change to the new one
787 | #ifdef _WIN32
788 | SetCurrentDirectory(utf_8to16(dir));
789 | return true1;
790 | #else
791 | return (chdir(dir) == 0);
792 | #endif
793 | }
794 |
795 | static bool_Bool
796 | ws_popd(void)
797 | {
798 | int ret = 0;
799 | char* saved_wd = g_queue_pop_head(saved_dir_queue);
800 | if (saved_wd == NULL((void*)0))
801 | return false0;
802 |
803 | //Restore the previous one
804 | #ifdef _WIN32
805 | SetCurrentDirectory(utf_8to16(saved_wd));
806 | #else
807 | ret = chdir(saved_wd);
808 | #endif
809 | g_free(saved_wd);
810 | return (ret == 0);
811 | }
812 |
813 | void
814 | proto_execute_in_directory(const char* dir, proto_execute_in_directory_func func, void* param)
815 | {
816 | if (ws_pushd(dir))
817 | {
818 | func(param);
819 | ws_popd();
820 | }
821 | }
822 |
823 | static bool_Bool
824 | // NOLINTNEXTLINE(misc-no-recursion)
825 | proto_tree_traverse_pre_order(proto_tree *tree, proto_tree_traverse_func func,
826 | void *data)
827 | {
828 | proto_node *pnode = tree;
829 | proto_node *child;
830 | proto_node *current;
831 |
832 | if (func(pnode, data))
833 | return true1;
834 |
835 | child = pnode->first_child;
836 | while (child != NULL((void*)0)) {
837 | /*
838 | * The routine we call might modify the child, e.g. by
839 | * freeing it, so we get the child's successor before
840 | * calling that routine.
841 | */
842 | current = child;
843 | child = current->next;
844 | // We recurse here, but we're limited by prefs.gui_max_tree_depth
845 | if (proto_tree_traverse_pre_order((proto_tree *)current, func, data))
846 | return true1;
847 | }
848 |
849 | return false0;
850 | }
851 |
852 | void
853 | proto_tree_children_foreach(proto_tree *tree, proto_tree_foreach_func func,
854 | void *data)
855 | {
856 | proto_node *node = tree;
857 | proto_node *current;
858 |
859 | if (!node)
860 | return;
861 |
862 | node = node->first_child;
863 | while (node != NULL((void*)0)) {
864 | current = node;
865 | node = current->next;
866 | func((proto_tree *)current, data);
867 | }
868 | }
869 |
870 | static void
871 | free_GPtrArray_value(void *key, void *value, void *user_data _U___attribute__((unused)))
872 | {
873 | GPtrArray *ptrs = (GPtrArray *)value;
874 | int hfid = GPOINTER_TO_UINT(key)((guint) (gulong) (key));
875 | header_field_info *hfinfo;
876 |
877 | 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", 877, __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", 877, "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", 877, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
878 | if (hfinfo->ref_type != HF_REF_TYPE_NONE) {
879 | /* when a field is referenced by a filter this also
880 | affects the refcount for the parent protocol so we need
881 | to adjust the refcount for the parent as well
882 | */
883 | if (hfinfo->parent != -1) {
884 | header_field_info *parent_hfinfo;
885 | 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", 885 , __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", 885, "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", 885, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)" , "Unregistered hf!")))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo ->parent];;
886 | parent_hfinfo->ref_type = HF_REF_TYPE_NONE;
887 | }
888 | hfinfo->ref_type = HF_REF_TYPE_NONE;
889 | }
890 |
891 | g_ptr_array_free(ptrs, true1);
892 | }
893 |
894 | static void
895 | proto_tree_free_node(proto_node *node, void *data _U___attribute__((unused)))
896 | {
897 | field_info *finfo = PNODE_FINFO(node)((node)->finfo);
898 |
899 | proto_tree_children_foreach(node, proto_tree_free_node, NULL((void*)0));
900 |
901 | if (finfo) {
902 | fvalue_free(finfo->value);
903 | finfo->value = NULL((void*)0);
904 | }
905 | }
906 |
907 | void
908 | proto_tree_reset(proto_tree *tree)
909 | {
910 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
911 |
912 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
913 |
914 | /* free tree data */
915 | if (tree_data->interesting_hfids) {
916 | /* Free all the GPtrArray's in the interesting_hfids hash. */
917 | g_hash_table_foreach(tree_data->interesting_hfids,
918 | free_GPtrArray_value, NULL((void*)0));
919 |
920 | /* And then remove all values. */
921 | g_hash_table_remove_all(tree_data->interesting_hfids);
922 | }
923 |
924 | /* Reset track of the number of children */
925 | tree_data->count = 0;
926 |
927 | /* Reset our loop checks */
928 | tree_data->idle_count_ds_tvb = NULL((void*)0);
929 | tree_data->max_start = 0;
930 | tree_data->start_idle_count = 0;
931 |
932 | PROTO_NODE_INIT(tree)tree->first_child = ((void*)0); tree->last_child = ((void *)0); tree->next = ((void*)0);;
933 | }
934 |
935 | /* frees the resources that the dissection a proto_tree uses */
936 | void
937 | proto_tree_free(proto_tree *tree)
938 | {
939 | tree_data_t *tree_data = PTREE_DATA(tree)((tree)->tree_data);
940 |
941 | proto_tree_children_foreach(tree, proto_tree_free_node, NULL((void*)0));
942 |
943 | /* free tree data */
944 | if (tree_data->interesting_hfids) {
945 | /* Free all the GPtrArray's in the interesting_hfids hash. */
946 | g_hash_table_foreach(tree_data->interesting_hfids,
947 | free_GPtrArray_value, NULL((void*)0));
948 |
949 | /* And then destroy the hash. */
950 | g_hash_table_destroy(tree_data->interesting_hfids);
951 | }
952 |
953 | 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);
954 |
955 | g_slice_free(proto_tree, tree)do { if (1) g_slice_free1 (sizeof (proto_tree), (tree)); else (void) ((proto_tree*) 0 == (tree)); } while (0);
956 | }
957 |
958 | /* Is the parsing being done for a visible proto_tree or an invisible one?
959 | * By setting this correctly, the proto_tree creation is sped up by not
960 | * having to call vsnprintf and copy strings around.
961 | */
962 | bool_Bool
963 | proto_tree_set_visible(proto_tree *tree, bool_Bool visible)
964 | {
965 | bool_Bool old_visible = PTREE_DATA(tree)((tree)->tree_data)->visible;
966 |
967 | PTREE_DATA(tree)((tree)->tree_data)->visible = visible;
968 |
969 | return old_visible;
970 | }
971 |
972 | void
973 | proto_tree_set_fake_protocols(proto_tree *tree, bool_Bool fake_protocols)
974 | {
975 | if (tree)
976 | PTREE_DATA(tree)((tree)->tree_data)->fake_protocols = fake_protocols;
977 | }
978 |
979 | /* Assume dissector set only its protocol fields.
980 | This function is called by dissectors and allows the speeding up of filtering
981 | in wireshark; if this function returns false it is safe to reset tree to NULL
982 | and thus skip calling most of the expensive proto_tree_add_...()
983 | functions.
984 | If the tree is visible we implicitly assume the field is referenced.
985 | */
986 | bool_Bool
987 | proto_field_is_referenced(proto_tree *tree, int proto_id)
988 | {
989 | register header_field_info *hfinfo;
990 |
991 |
992 | if (!tree)
993 | return false0;
994 |
995 | if (PTREE_DATA(tree)((tree)->tree_data)->visible)
996 | return true1;
997 |
998 | 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", 998, __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", 998, "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", 998, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
999 | if (hfinfo->ref_type != HF_REF_TYPE_NONE)
1000 | return true1;
1001 |
1002 | if (hfinfo->type == FT_PROTOCOL && !PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)
1003 | return true1;
1004 |
1005 | return false0;
1006 | }
1007 |
1008 |
1009 | /* Finds a record in the hfinfo array by id. */
1010 | header_field_info *
1011 | proto_registrar_get_nth(unsigned hfindex)
1012 | {
1013 | register header_field_info *hfinfo;
1014 |
1015 | 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", 1015, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 1015, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 1015, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
1016 | return hfinfo;
1017 | }
1018 |
1019 |
1020 | /* Prefix initialization
1021 | * this allows for a dissector to register a display filter name prefix
1022 | * so that it can delay the initialization of the hf array as long as
1023 | * possible.
1024 | */
1025 |
1026 | /* compute a hash for the part before the dot of a display filter */
1027 | static unsigned
1028 | prefix_hash (const void *key) {
1029 | /* end the string at the dot and compute its hash */
1030 | char* copy = g_strdup((const char *)key)g_strdup_inline ((const char *)key);
1031 | char* c = copy;
1032 | unsigned tmp;
1033 |
1034 | for (; *c; c++) {
1035 | if (*c == '.') {
1036 | *c = 0;
1037 | break;
1038 | }
1039 | }
1040 |
1041 | tmp = wmem_str_hash(copy);
1042 | g_free(copy);
1043 | return tmp;
1044 | }
1045 |
1046 | /* are both strings equal up to the end or the dot? */
1047 | static gboolean
1048 | prefix_equal (const void *ap, const void *bp) {
1049 | const char* a = (const char *)ap;
1050 | const char* b = (const char *)bp;
1051 |
1052 | do {
1053 | char ac = *a++;
1054 | char bc = *b++;
1055 |
1056 | if ( (ac == '.' || ac == '\0') && (bc == '.' || bc == '\0') ) return TRUE(!(0));
1057 |
1058 | if ( (ac == '.' || ac == '\0') && ! (bc == '.' || bc == '\0') ) return FALSE(0);
1059 | if ( (bc == '.' || bc == '\0') && ! (ac == '.' || ac == '\0') ) return FALSE(0);
1060 |
1061 | if (ac != bc) return FALSE(0);
1062 | } while (1);
1063 |
1064 | return FALSE(0);
1065 | }
1066 |
1067 | /* Register a new prefix for "delayed" initialization of field arrays */
1068 | void
1069 | proto_register_prefix(const char *prefix, prefix_initializer_t pi ) {
1070 | if (! prefixes ) {
1071 | prefixes = g_hash_table_new(prefix_hash, prefix_equal);
1072 | }
1073 |
1074 | g_hash_table_insert(prefixes, (void *)prefix, (void *)pi);
1075 | }
1076 |
1077 | /* helper to call all prefix initializers */
1078 | static gboolean
1079 | initialize_prefix(void *k, void *v, void *u _U___attribute__((unused))) {
1080 | ((prefix_initializer_t)v)((const char *)k);
1081 | return TRUE(!(0));
1082 | }
1083 |
1084 | /** Initialize every remaining uninitialized prefix. */
1085 | void
1086 | proto_initialize_all_prefixes(void) {
1087 | g_hash_table_foreach_remove(prefixes, initialize_prefix, NULL((void*)0));
1088 | }
1089 |
1090 | /* Finds a record in the hfinfo array by name.
1091 | * If it fails to find it in the already registered fields,
1092 | * it tries to find and call an initializer in the prefixes
1093 | * table and if so it looks again.
1094 | */
1095 |
1096 | header_field_info *
1097 | proto_registrar_get_byname(const char *field_name)
1098 | {
1099 | header_field_info *hfinfo;
1100 | prefix_initializer_t pi;
1101 |
1102 | if (!field_name)
1103 | return NULL((void*)0);
1104 |
1105 | if (g_strcmp0(field_name, last_field_name) == 0) {
1106 | return last_hfinfo;
1107 | }
1108 |
1109 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1110 |
1111 | if (hfinfo) {
1112 | g_free(last_field_name);
1113 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1114 | last_hfinfo = hfinfo;
1115 | return hfinfo;
1116 | }
1117 |
1118 | if (!prefixes)
1119 | return NULL((void*)0);
1120 |
1121 | if ((pi = (prefix_initializer_t)g_hash_table_lookup(prefixes, field_name) ) != NULL((void*)0)) {
1122 | pi(field_name);
1123 | g_hash_table_remove(prefixes, field_name);
1124 | } else {
1125 | return NULL((void*)0);
1126 | }
1127 |
1128 | hfinfo = (header_field_info *)wmem_map_lookup(gpa_name_map, field_name);
1129 |
1130 | if (hfinfo) {
1131 | g_free(last_field_name);
1132 | last_field_name = g_strdup(field_name)g_strdup_inline (field_name);
1133 | last_hfinfo = hfinfo;
1134 | }
1135 | return hfinfo;
1136 | }
1137 |
1138 | header_field_info*
1139 | proto_registrar_get_byalias(const char *alias_name)
1140 | {
1141 | if (!alias_name) {
1142 | return NULL((void*)0);
1143 | }
1144 |
1145 | /* Find our aliased protocol. */
1146 | char *an_copy = g_strdup(alias_name)g_strdup_inline (alias_name);
1147 | char *dot = strchr(an_copy, '.');
1148 | if (dot) {
1149 | *dot = '\0';
1150 | }
1151 | const char *proto_pfx = (const char *) g_hash_table_lookup(gpa_protocol_aliases, an_copy);
1152 | if (!proto_pfx) {
1153 | g_free(an_copy);
1154 | return NULL((void*)0);
1155 | }
1156 |
1157 | /* Construct our aliased field and look it up. */
1158 | GString *filter_name = g_string_new(proto_pfx);
1159 | if (dot) {
1160 | g_string_append_printf(filter_name, ".%s", dot+1);
1161 | }
1162 | header_field_info *hfinfo = proto_registrar_get_byname(filter_name->str);
1163 | g_free(an_copy);
1164 | 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)))));
1165 |
1166 | return hfinfo;
1167 | }
1168 |
1169 | int
1170 | proto_registrar_get_id_byname(const char *field_name)
1171 | {
1172 | header_field_info *hfinfo;
1173 |
1174 | hfinfo = proto_registrar_get_byname(field_name);
1175 |
1176 | if (!hfinfo)
1177 | return -1;
1178 |
1179 | return hfinfo->id;
1180 | }
1181 |
1182 | static int
1183 | label_strcat_flags(const header_field_info *hfinfo)
1184 | {
1185 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) & BASE_STR_WSP)
1186 | return FORMAT_LABEL_REPLACE_SPACE(0x1 << 0);
1187 |
1188 | return 0;
1189 | }
1190 |
1191 | static char *
1192 | format_bytes_hfinfo_maxlen(wmem_allocator_t *scope, const header_field_info *hfinfo,
1193 | const uint8_t *bytes, unsigned length, size_t max_str_len)
1194 | {
1195 | char *str = NULL((void*)0);
1196 | const uint8_t *p;
1197 | bool_Bool is_printable;
1198 |
1199 | if (bytes) {
1200 | if (hfinfo->display & BASE_SHOW_UTF_8_PRINTABLE0x00020000) {
1201 | /*
1202 | * If all bytes are valid and printable UTF-8, show the
1203 | * bytes as a string - in quotes to indicate that it's
1204 | * a string.
1205 | */
1206 | if (isprint_utf8_string((const char*)bytes, length)) {
1207 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1208 | (int)length, bytes);
1209 | return str;
1210 | }
1211 | } else if (hfinfo->display & BASE_SHOW_ASCII_PRINTABLE0x00010000) {
1212 | /*
1213 | * Check whether all bytes are printable.
1214 | */
1215 | is_printable = true1;
1216 | for (p = bytes; p < bytes+length; p++) {
1217 | if (!g_ascii_isprint(*p)((g_ascii_table[(guchar) (*p)] & G_ASCII_PRINT) != 0)) {
1218 | /* Not printable. */
1219 | is_printable = false0;
1220 | break;
1221 | }
1222 | }
1223 |
1224 | /*
1225 | * If all bytes are printable ASCII, show the bytes
1226 | * as a string - in quotes to indicate that it's
1227 | * a string.
1228 | */
1229 | if (is_printable) {
1230 | str = wmem_strdup_printf(scope, "\"%.*s\"",
1231 | (int)length, bytes);
1232 | return str;
1233 | }
1234 | }
1235 |
1236 | /*
1237 | * Either it's not printable ASCII, or we don't care whether
1238 | * it's printable ASCII; show it as hex bytes.
1239 | */
1240 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
1241 | case SEP_DOT:
1242 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '.', max_str_len/3);
1243 | break;
1244 | case SEP_DASH:
1245 | str = bytes_to_str_punct_maxlen(scope, bytes, length, '-', max_str_len/3);
1246 | break;
1247 | case SEP_COLON:
1248 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ':', max_str_len/3);
1249 | break;
1250 | case SEP_SPACE:
1251 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1252 | break;
1253 | case BASE_NONE:
1254 | default:
1255 | if (prefs.display_byte_fields_with_spaces) {
1256 | str = bytes_to_str_punct_maxlen(scope, bytes, length, ' ', max_str_len/3);
1257 | } else {
1258 | str = bytes_to_str_maxlen(scope, bytes, length, max_str_len/2);
1259 | }
1260 | break;
1261 | }
1262 | }
1263 | else {
1264 | if (hfinfo->display & BASE_ALLOW_ZERO0x00000800) {
1265 | str = wmem_strdup(scope, "<none>");
1266 | } else {
1267 | str = wmem_strdup(scope, "<MISSING>");
1268 | }
1269 | }
1270 | return str;
1271 | }
1272 |
1273 | static char *
1274 | format_bytes_hfinfo(wmem_allocator_t *scope, const header_field_info *hfinfo,
1275 | const uint8_t *bytes, unsigned length)
1276 | {
1277 | return format_bytes_hfinfo_maxlen(scope, hfinfo, bytes, length, ITEM_LABEL_LENGTH240);
1278 | }
1279 |
1280 | static void
1281 | ptvcursor_new_subtree_levels(ptvcursor_t *ptvc)
1282 | {
1283 | subtree_lvl *pushed_tree;
1284 |
1285 | 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" , 1285, "ptvc->pushed_tree_max <= 256-8"))));
1286 | ptvc->pushed_tree_max += SUBTREE_ONCE_ALLOCATION_NUMBER8;
1287 |
1288 | pushed_tree = (subtree_lvl *)wmem_realloc(ptvc->scope, (void *)ptvc->pushed_tree, sizeof(subtree_lvl) * ptvc->pushed_tree_max);
1289 | DISSECTOR_ASSERT(pushed_tree != NULL)((void) ((pushed_tree != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 1289, "pushed_tree != ((void*)0)" ))));
1290 | ptvc->pushed_tree = pushed_tree;
1291 | }
1292 |
1293 | static void
1294 | ptvcursor_free_subtree_levels(ptvcursor_t *ptvc)
1295 | {
1296 | ptvc->pushed_tree = NULL((void*)0);
1297 | ptvc->pushed_tree_max = 0;
1298 | 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", 1298, "ptvc->pushed_tree_index == 0" ))));
1299 | ptvc->pushed_tree_index = 0;
1300 | }
1301 |
1302 | /* Allocates an initializes a ptvcursor_t with 3 variables:
1303 | * proto_tree, tvbuff, and offset. */
1304 | ptvcursor_t *
1305 | ptvcursor_new(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb, int offset)
1306 | {
1307 | ptvcursor_t *ptvc;
1308 |
1309 | ptvc = wmem_new(scope, ptvcursor_t)((ptvcursor_t*)wmem_alloc((scope), sizeof(ptvcursor_t)));
1310 | ptvc->scope = scope;
1311 | ptvc->tree = tree;
1312 | ptvc->tvb = tvb;
1313 | ptvc->offset = offset;
1314 | ptvc->pushed_tree = NULL((void*)0);
1315 | ptvc->pushed_tree_max = 0;
1316 | ptvc->pushed_tree_index = 0;
1317 | return ptvc;
1318 | }
1319 |
1320 |
1321 | /* Frees memory for ptvcursor_t, but nothing deeper than that. */
1322 | void
1323 | ptvcursor_free(ptvcursor_t *ptvc)
1324 | {
1325 | ptvcursor_free_subtree_levels(ptvc);
1326 | /*g_free(ptvc);*/
1327 | }
1328 |
1329 | /* Returns tvbuff. */
1330 | tvbuff_t *
1331 | ptvcursor_tvbuff(ptvcursor_t *ptvc)
1332 | {
1333 | return ptvc->tvb;
1334 | }
1335 |
1336 | /* Returns current offset. */
1337 | int
1338 | ptvcursor_current_offset(ptvcursor_t *ptvc)
1339 | {
1340 | return ptvc->offset;
1341 | }
1342 |
1343 | proto_tree *
1344 | ptvcursor_tree(ptvcursor_t *ptvc)
1345 | {
1346 | if (!ptvc)
1347 | return NULL((void*)0);
1348 |
1349 | return ptvc->tree;
1350 | }
1351 |
1352 | void
1353 | ptvcursor_set_tree(ptvcursor_t *ptvc, proto_tree *tree)
1354 | {
1355 | ptvc->tree = tree;
1356 | }
1357 |
1358 | /* creates a subtree, sets it as the working tree and pushes the old working tree */
1359 | proto_tree *
1360 | ptvcursor_push_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1361 | {
1362 | subtree_lvl *subtree;
1363 | if (ptvc->pushed_tree_index >= ptvc->pushed_tree_max)
1364 | ptvcursor_new_subtree_levels(ptvc);
1365 |
1366 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1367 | subtree->tree = ptvc->tree;
1368 | subtree->it= NULL((void*)0);
1369 | ptvc->pushed_tree_index++;
1370 | return ptvcursor_set_subtree(ptvc, it, ett_subtree);
1371 | }
1372 |
1373 | /* pops a subtree */
1374 | void
1375 | ptvcursor_pop_subtree(ptvcursor_t *ptvc)
1376 | {
1377 | subtree_lvl *subtree;
1378 |
1379 | if (ptvc->pushed_tree_index <= 0)
1380 | return;
1381 |
1382 | ptvc->pushed_tree_index--;
1383 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index;
1384 | if (subtree->it != NULL((void*)0))
1385 | proto_item_set_len(subtree->it, ptvcursor_current_offset(ptvc) - subtree->cursor_offset);
1386 |
1387 | ptvc->tree = subtree->tree;
1388 | }
1389 |
1390 | /* saves the current tvb offset and the item in the current subtree level */
1391 | static void
1392 | ptvcursor_subtree_set_item(ptvcursor_t *ptvc, proto_item *it)
1393 | {
1394 | subtree_lvl *subtree;
1395 |
1396 | 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", 1396, "ptvc->pushed_tree_index > 0" ))));
1397 |
1398 | subtree = ptvc->pushed_tree + ptvc->pushed_tree_index - 1;
1399 | subtree->it = it;
1400 | subtree->cursor_offset = ptvcursor_current_offset(ptvc);
1401 | }
1402 |
1403 | /* Creates a subtree and adds it to the cursor as the working tree but does not
1404 | * save the old working tree */
1405 | proto_tree *
1406 | ptvcursor_set_subtree(ptvcursor_t *ptvc, proto_item *it, int ett_subtree)
1407 | {
1408 | ptvc->tree = proto_item_add_subtree(it, ett_subtree);
1409 | return ptvc->tree;
1410 | }
1411 |
1412 | static proto_tree *
1413 | ptvcursor_add_subtree_item(ptvcursor_t *ptvc, proto_item *it, int ett_subtree, int length)
1414 | {
1415 | ptvcursor_push_subtree(ptvc, it, ett_subtree);
1416 | if (length == SUBTREE_UNDEFINED_LENGTH-1)
1417 | ptvcursor_subtree_set_item(ptvc, it);
1418 | return ptvcursor_tree(ptvc);
1419 | }
1420 |
1421 | /* Add an item to the tree and create a subtree
1422 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1423 | * In this case, when the subtree will be closed, the parent item length will
1424 | * be equal to the advancement of the cursor since the creation of the subtree.
1425 | */
1426 | proto_tree *
1427 | ptvcursor_add_with_subtree(ptvcursor_t *ptvc, int hfindex, int length,
1428 | const unsigned encoding, int ett_subtree)
1429 | {
1430 | proto_item *it;
1431 |
1432 | it = ptvcursor_add_no_advance(ptvc, hfindex, length, encoding);
1433 | return ptvcursor_add_subtree_item(ptvc, it, ett_subtree, length);
1434 | }
1435 |
1436 | static proto_item *
1437 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length);
1438 |
1439 | /* Add a text node to the tree and create a subtree
1440 | * If the length is unknown, length may be defined as SUBTREE_UNDEFINED_LENGTH.
1441 | * In this case, when the subtree will be closed, the item length will be equal
1442 | * to the advancement of the cursor since the creation of the subtree.
1443 | */
1444 | proto_tree *
1445 | ptvcursor_add_text_with_subtree(ptvcursor_t *ptvc, int length,
1446 | int ett_subtree, const char *format, ...)
1447 | {
1448 | proto_item *pi;
1449 | va_list ap;
1450 | header_field_info *hfinfo;
1451 | proto_tree *tree;
1452 |
1453 | tree = ptvcursor_tree(ptvc);
1454 |
1455 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1456 |
1457 | 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", 1457 , __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", 1457, "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", 1457, "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", 1457, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1458 |
1459 | pi = proto_tree_add_text_node(tree, ptvcursor_tvbuff(ptvc),
1460 | ptvcursor_current_offset(ptvc), length);
1461 |
1462 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1462, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1463 |
1464 | va_start(ap, format)__builtin_va_start(ap, format);
1465 | proto_tree_set_representation(pi, format, ap);
1466 | va_end(ap)__builtin_va_end(ap);
1467 |
1468 | return ptvcursor_add_subtree_item(ptvc, pi, ett_subtree, length);
1469 | }
1470 |
1471 | /* Add a text-only node, leaving it to our caller to fill the text in */
1472 | static proto_item *
1473 | proto_tree_add_text_node(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1474 | {
1475 | proto_item *pi;
1476 |
1477 | if (tree == NULL((void*)0))
1478 | return NULL((void*)0);
1479 |
1480 | pi = proto_tree_add_pi(tree, &hfi_text_only, tvb, start, &length);
1481 |
1482 | return pi;
1483 | }
1484 |
1485 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree */
1486 | proto_item *
1487 | proto_tree_add_text_internal(proto_tree *tree, tvbuff_t *tvb, int start, int length,
1488 | const char *format, ...)
1489 | {
1490 | proto_item *pi;
1491 | va_list ap;
1492 | header_field_info *hfinfo;
1493 |
1494 | if (length == -1) {
1495 | length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
1496 | } else {
1497 | tvb_ensure_bytes_exist(tvb, start, length);
1498 | }
1499 |
1500 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1501 |
1502 | 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", 1502 , __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", 1502, "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", 1502, "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", 1502, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1503 |
1504 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1505 |
1506 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1506, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1507 |
1508 | va_start(ap, format)__builtin_va_start(ap, format);
1509 | proto_tree_set_representation(pi, format, ap);
1510 | va_end(ap)__builtin_va_end(ap);
1511 |
1512 | return pi;
1513 | }
1514 |
1515 | /* (INTERNAL USE ONLY) Add a text-only node to the proto_tree (va_list version) */
1516 | proto_item *
1517 | proto_tree_add_text_valist_internal(proto_tree *tree, tvbuff_t *tvb, int start,
1518 | int length, const char *format, va_list ap)
1519 | {
1520 | proto_item *pi;
1521 | header_field_info *hfinfo;
1522 |
1523 | /* proto_tree_add_text_node calls proto_tree_add_pi() with the
1524 | * FT_NONE hf_text_only, which calls get_hfi_length, which adjusts
1525 | * the length to be what's in the tvbuff if length is -1, and the
1526 | * minimum of length and what's in the tvbuff if not.
1527 | */
1528 |
1529 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1530 |
1531 | 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", 1531 , __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", 1531, "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", 1531, "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", 1531, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1532 |
1533 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1534 |
1535 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1535, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1536 |
1537 | proto_tree_set_representation(pi, format, ap);
1538 |
1539 | return pi;
1540 | }
1541 |
1542 | /* Add a text-only node that creates a subtree underneath.
1543 | */
1544 | proto_tree *
1545 | proto_tree_add_subtree(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *text)
1546 | {
1547 | return proto_tree_add_subtree_format(tree, tvb, start, length, idx, tree_item, "%s", text);
1548 | }
1549 |
1550 | /* Add a text-only node that creates a subtree underneath.
1551 | */
1552 | proto_tree *
1553 | proto_tree_add_subtree_format(proto_tree *tree, tvbuff_t *tvb, int start, int length, int idx, proto_item **tree_item, const char *format, ...)
1554 | {
1555 | proto_tree *pt;
1556 | proto_item *pi;
1557 | va_list ap;
1558 |
1559 | va_start(ap, format)__builtin_va_start(ap, format);
1560 | pi = proto_tree_add_text_valist_internal(tree, tvb, start, length, format, ap);
1561 | va_end(ap)__builtin_va_end(ap);
1562 |
1563 | if (tree_item != NULL((void*)0))
1564 | *tree_item = pi;
1565 |
1566 | pt = proto_item_add_subtree(pi, idx);
1567 |
1568 | return pt;
1569 | }
1570 |
1571 | /* Add a text-only node for debugging purposes. The caller doesn't need
1572 | * to worry about tvbuff, start, or length. Debug message gets sent to
1573 | * STDOUT, too */
1574 | proto_item *
1575 | proto_tree_add_debug_text(proto_tree *tree, const char *format, ...)
1576 | {
1577 | proto_item *pi;
1578 | va_list ap;
1579 |
1580 | pi = proto_tree_add_text_node(tree, NULL((void*)0), 0, 0);
1581 |
1582 | if (pi) {
1583 | va_start(ap, format)__builtin_va_start(ap, format);
1584 | proto_tree_set_representation(pi, format, ap);
1585 | va_end(ap)__builtin_va_end(ap);
1586 | }
1587 | va_start(ap, format)__builtin_va_start(ap, format);
1588 | vprintf(format, ap);
1589 | va_end(ap)__builtin_va_end(ap);
1590 | printf("\n");
1591 |
1592 | return pi;
1593 | }
1594 |
1595 | proto_item *
1596 | proto_tree_add_format_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1597 | {
1598 | proto_item *pi;
1599 | header_field_info *hfinfo;
1600 |
1601 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1602 |
1603 | 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", 1603 , __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", 1603, "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", 1603, "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", 1603, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1604 |
1605 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1606 |
1607 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1607, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1608 |
1609 | proto_item_set_text(pi, "%s", tvb_format_text(tree->tree_data->pinfo->pool, tvb, start, length));
1610 |
1611 | return pi;
1612 | }
1613 |
1614 | proto_item *
1615 | proto_tree_add_format_wsp_text(proto_tree *tree, tvbuff_t *tvb, int start, int length)
1616 | {
1617 | proto_item *pi;
1618 | header_field_info *hfinfo;
1619 | char *str;
1620 |
1621 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
1622 |
1623 | 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", 1623 , __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", 1623, "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", 1623, "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", 1623, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
1624 |
1625 | pi = proto_tree_add_text_node(tree, tvb, start, length);
1626 |
1627 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 1627, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
1628 |
1629 | str = tvb_format_text_wsp(NULL((void*)0), tvb, start, length);
1630 | proto_item_set_text(pi, "%s", str);
1631 | wmem_free(NULL((void*)0), str);
1632 |
1633 | return pi;
1634 | }
1635 |
1636 | void proto_report_dissector_bug(const char *format, ...)
1637 | {
1638 | va_list args;
1639 |
1640 | if (wireshark_abort_on_dissector_bug) {
1641 | /*
1642 | * Try to have the error message show up in the crash
1643 | * information.
1644 | */
1645 | va_start(args, format)__builtin_va_start(args, format);
1646 | ws_vadd_crash_info(format, args);
1647 | va_end(args)__builtin_va_end(args);
1648 |
1649 | /*
1650 | * Print the error message.
1651 | */
1652 | va_start(args, format)__builtin_va_start(args, format);
1653 | vfprintf(stderrstderr, format, args);
1654 | va_end(args)__builtin_va_end(args);
1655 | putc('\n', stderrstderr);
1656 |
1657 | /*
1658 | * And crash.
1659 | */
1660 | abort();
1661 | } else {
1662 | va_start(args, format)__builtin_va_start(args, format);
1663 | VTHROW_FORMATTED(DissectorError, format, args)except_vthrowf(1, (6), format, args);
1664 | va_end(args)__builtin_va_end(args);
1665 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 1665 , __func__, "assertion \"not reached\" failed"); /* GCC 12 with ASAN needs this. */
1666 | }
1667 | }
1668 |
1669 | /* We could probably get away with changing is_error to a minimum length value. */
1670 | static void
1671 | report_type_length_mismatch(proto_tree *tree, const char *descr, int length, bool_Bool is_error)
1672 | {
1673 | if (is_error) {
1674 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_error, "Trying to fetch %s with length %d", descr, length);
1675 | } else {
1676 | expert_add_info_format(NULL((void*)0), tree, &ei_type_length_mismatch_warn, "Trying to fetch %s with length %d", descr, length);
1677 | }
1678 |
1679 | if (is_error) {
1680 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
1681 | }
1682 | }
1683 |
1684 | static uint32_t
1685 | get_uint_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1686 | {
1687 | uint32_t value;
1688 | bool_Bool length_error;
1689 |
1690 | switch (length) {
1691 |
1692 | case 1:
1693 | value = tvb_get_uint8(tvb, offset);
1694 | if (encoding & ENC_ZIGBEE0x40000000) {
1695 | if (value == 0xFF) { /* Invalid Zigbee length, set to 0 */
1696 | value = 0;
1697 | }
1698 | }
1699 | break;
1700 |
1701 | case 2:
1702 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohs(tvb, offset)
1703 | : tvb_get_ntohs(tvb, offset);
1704 | if (encoding & ENC_ZIGBEE0x40000000) {
1705 | if (value == 0xFFFF) { /* Invalid Zigbee length, set to 0 */
1706 | value = 0;
1707 | }
1708 | }
1709 | break;
1710 |
1711 | case 3:
1712 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letoh24(tvb, offset)
1713 | : tvb_get_ntoh24(tvb, offset);
1714 | break;
1715 |
1716 | case 4:
1717 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1718 | : tvb_get_ntohl(tvb, offset);
1719 | break;
1720 |
1721 | default:
1722 | if (length < 1) {
1723 | length_error = true1;
1724 | value = 0;
1725 | } else {
1726 | length_error = false0;
1727 | value = (encoding & ENC_LITTLE_ENDIAN0x80000000) ? tvb_get_letohl(tvb, offset)
1728 | : tvb_get_ntohl(tvb, offset);
1729 | }
1730 | report_type_length_mismatch(tree, "an unsigned integer", length, length_error);
1731 | break;
1732 | }
1733 | return value;
1734 | }
1735 |
1736 | static inline uint64_t
1737 | get_uint64_value(proto_tree *tree, tvbuff_t *tvb, int offset, unsigned length, const unsigned encoding)
1738 | {
1739 | uint64_t value;
1740 |
1741 | value = tvb_get_uint64_with_length(tvb, offset, length, encoding);
1742 |
1743 | if (length < 1 || length > 8) {
1744 | report_type_length_mismatch(tree, "an unsigned integer", length, (length < 1));
1745 | }
1746 |
1747 | return value;
1748 | }
1749 |
1750 | static int32_t
1751 | get_int_value(proto_tree *tree, tvbuff_t *tvb, int offset, int length, const unsigned encoding)
1752 | {
1753 | int32_t value;
1754 | bool_Bool length_error;
1755 |
1756 | switch (length) {
1757 |
1758 | case 1:
1759 | value = tvb_get_int8(tvb, offset);
1760 | break;
1761 |
1762 | case 2:
1763 | value = encoding ? tvb_get_letohis(tvb, offset)
1764 | : tvb_get_ntohis(tvb, offset);
1765 | break;
1766 |
1767 | case 3:
1768 | value = encoding ? tvb_get_letohi24(tvb, offset)
1769 | : tvb_get_ntohi24(tvb, offset);
1770 | break;
1771 |
1772 | case 4:
1773 | value = encoding ? tvb_get_letohil(tvb, offset)
1774 | : tvb_get_ntohil(tvb, offset);
1775 | break;
1776 |
1777 | default:
1778 | if (length < 1) {
1779 | length_error = true1;
1780 | value = 0;
1781 | } else {
1782 | length_error = false0;
1783 | value = encoding ? tvb_get_letohil(tvb, offset)
1784 | : tvb_get_ntohil(tvb, offset);
1785 | }
1786 | report_type_length_mismatch(tree, "a signed integer", length, length_error);
1787 | break;
1788 | }
1789 | return value;
1790 | }
1791 |
1792 | /* Note: this returns an unsigned int64, but with the appropriate bit(s) set to
1793 | * be cast-able as a int64_t. This is weird, but what the code has always done.
1794 | */
1795 | static inline uint64_t
1796 | get_int64_value(proto_tree *tree, tvbuff_t *tvb, int start, unsigned length, const unsigned encoding)
1797 | {
1798 | uint64_t value = get_uint64_value(tree, tvb, start, length, encoding);
1799 |
1800 | switch (length) {
1801 | case 7:
1802 | value = ws_sign_ext64(value, 56);
1803 | break;
1804 | case 6:
1805 | value = ws_sign_ext64(value, 48);
1806 | break;
1807 | case 5:
1808 | value = ws_sign_ext64(value, 40);
1809 | break;
1810 | case 4:
1811 | value = ws_sign_ext64(value, 32);
1812 | break;
1813 | case 3:
1814 | value = ws_sign_ext64(value, 24);
1815 | break;
1816 | case 2:
1817 | value = ws_sign_ext64(value, 16);
1818 | break;
1819 | case 1:
1820 | value = ws_sign_ext64(value, 8);
1821 | break;
1822 | }
1823 |
1824 | return value;
1825 | }
1826 |
1827 | /* For FT_STRING */
1828 | static inline const uint8_t *
1829 | get_string_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1830 | int length, int *ret_length, const unsigned encoding)
1831 | {
1832 | if (length == -1) {
1833 | length = tvb_ensure_captured_length_remaining(tvb, start);
1834 | }
1835 | *ret_length = length;
1836 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1837 | }
1838 |
1839 | /* For FT_STRINGZ */
1840 | static inline const uint8_t *
1841 | get_stringz_value(wmem_allocator_t *scope, proto_tree *tree, tvbuff_t *tvb,
1842 | int start, int length, int *ret_length, const unsigned encoding)
1843 | {
1844 | const uint8_t *value;
1845 |
1846 | if (length < -1) {
1847 | report_type_length_mismatch(tree, "a string", length, true1);
1848 | }
1849 | if (length == -1) {
1850 | /* This can throw an exception */
1851 | value = tvb_get_stringz_enc(scope, tvb, start, &length, encoding);
1852 | } else {
1853 | /* In this case, length signifies the length of the string.
1854 | *
1855 | * This could either be a null-padded string, which doesn't
1856 | * necessarily have a '\0' at the end, or a null-terminated
1857 | * string, with a trailing '\0'. (Yes, there are cases
1858 | * where you have a string that's both counted and null-
1859 | * terminated.)
1860 | *
1861 | * In the first case, we must allocate a buffer of length
1862 | * "length+1", to make room for a trailing '\0'.
1863 | *
1864 | * In the second case, we don't assume that there is a
1865 | * trailing '\0' there, as the packet might be malformed.
1866 | * (XXX - should we throw an exception if there's no
1867 | * trailing '\0'?) Therefore, we allocate a buffer of
1868 | * length "length+1", and put in a trailing '\0', just to
1869 | * be safe.
1870 | *
1871 | * (XXX - this would change if we made string values counted
1872 | * rather than null-terminated.)
1873 | */
1874 | value = tvb_get_string_enc(scope, tvb, start, length, encoding);
1875 | }
1876 | *ret_length = length;
1877 | return value;
1878 | }
1879 |
1880 | /* For FT_UINT_STRING */
1881 | static inline const uint8_t *
1882 | get_uint_string_value(wmem_allocator_t *scope, proto_tree *tree,
1883 | tvbuff_t *tvb, int start, int length, int *ret_length,
1884 | const unsigned encoding)
1885 | {
1886 | uint32_t n;
1887 | const uint8_t *value;
1888 |
1889 | /* I believe it's ok if this is called with a NULL tree */
1890 | n = get_uint_value(tree, tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
1891 | value = tvb_get_string_enc(scope, tvb, start + length, n, encoding);
1892 | length += n;
1893 | *ret_length = length;
1894 | return value;
1895 | }
1896 |
1897 | /* For FT_STRINGZPAD */
1898 | static inline const uint8_t *
1899 | get_stringzpad_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1900 | int length, int *ret_length, const unsigned encoding)
1901 | {
1902 | /*
1903 | * XXX - currently, string values are null-
1904 | * terminated, so a "zero-padded" string
1905 | * isn't special. If we represent string
1906 | * values as something that includes a counted
1907 | * array of bytes, we'll need to strip the
1908 | * trailing NULs.
1909 | */
1910 | if (length == -1) {
1911 | length = tvb_ensure_captured_length_remaining(tvb, start);
1912 | }
1913 | *ret_length = length;
1914 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1915 | }
1916 |
1917 | /* For FT_STRINGZTRUNC */
1918 | static inline const uint8_t *
1919 | get_stringztrunc_value(wmem_allocator_t *scope, tvbuff_t *tvb, int start,
1920 | int length, int *ret_length, const unsigned encoding)
1921 | {
1922 | /*
1923 | * XXX - currently, string values are null-
1924 | * terminated, so a "zero-truncated" string
1925 | * isn't special. If we represent string
1926 | * values as something that includes a counted
1927 | * array of bytes, we'll need to strip everything
1928 | * starting with the terminating NUL.
1929 | */
1930 | if (length == -1) {
1931 | length = tvb_ensure_captured_length_remaining(tvb, start);
1932 | }
1933 | *ret_length = length;
1934 | return tvb_get_string_enc(scope, tvb, start, length, encoding);
1935 | }
1936 |
1937 | /*
1938 | * Deltas between the epochs for various non-UN*X time stamp formats and
1939 | * the January 1, 1970, 00:00:00 (proleptic?) UTC epoch for the UN*X time
1940 | * stamp format.
1941 | */
1942 |
1943 | /*
1944 | * NTP Era 0: the epoch is January 1, 1900, 00:00:00 (proleptic?) UTC.
1945 | * XXX - if it's OK if this is unsigned, can we just use
1946 | * EPOCH_DELTA_1900_01_01_00_00_00_UTC?
1947 | */
1948 | #define NTP_TIMEDIFF1900TO1970SEC2208988800L INT64_C(2208988800)2208988800L
1949 |
1950 | /*
1951 | * NTP Era 1: the epoch is February 7, 2036, 06:28:16 UTC.
1952 | */
1953 | #define NTP_TIMEDIFF1970TO2036SEC2085978496L INT64_C(2085978496)2085978496L
1954 |
1955 | /* this can be called when there is no tree, so tree may be null */
1956 | static void
1957 | get_time_value(proto_tree *tree, tvbuff_t *tvb, const int start,
1958 | const int length, const unsigned encoding, nstime_t *time_stamp,
1959 | const bool_Bool is_relative)
1960 | {
1961 | uint32_t tmpsecs;
1962 | uint64_t tmp64secs;
1963 | uint64_t todusecs;
1964 |
1965 | switch (encoding) {
1966 |
1967 | case ENC_TIME_SECS_NSECS0x00000000|ENC_BIG_ENDIAN0x00000000:
1968 | /*
1969 | * If the length is 16, 8-byte seconds, followed
1970 | * by 8-byte fractional time in nanoseconds,
1971 | * both big-endian.
1972 | *
1973 | * If the length is 12, 8-byte seconds, followed
1974 | * by 4-byte fractional time in nanoseconds,
1975 | * both big-endian.
1976 | *
1977 | * If the length is 8, 4-byte seconds, followed
1978 | * by 4-byte fractional time in nanoseconds,
1979 | * both big-endian.
1980 | *
1981 | * For absolute times, the seconds are seconds
1982 | * since the UN*X epoch.
1983 | */
1984 | if (length == 16) {
1985 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1986 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8);
1987 | } else if (length == 12) {
1988 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
1989 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8);
1990 | } else if (length == 8) {
1991 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
1992 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4);
1993 | } else if (length == 4) {
1994 | /*
1995 | * Backwards compatibility.
1996 | * ENC_TIME_SECS_NSECS is 0; using
1997 | * ENC_BIG_ENDIAN by itself with a 4-byte
1998 | * time-in-seconds value was done in the
1999 | * past.
2000 | */
2001 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2002 | time_stamp->nsecs = 0;
2003 | } else {
2004 | time_stamp->secs = 0;
2005 | time_stamp->nsecs = 0;
2006 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2007 | }
2008 | break;
2009 |
2010 | case ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000:
2011 | /*
2012 | * If the length is 16, 8-byte seconds, followed
2013 | * by 8-byte fractional time in nanoseconds,
2014 | * both little-endian.
2015 | *
2016 | * If the length is 12, 8-byte seconds, followed
2017 | * by 4-byte fractional time in nanoseconds,
2018 | * both little-endian.
2019 | *
2020 | * If the length is 8, 4-byte seconds, followed
2021 | * by 4-byte fractional time in nanoseconds,
2022 | * both little-endian.
2023 | *
2024 | * For absolute times, the seconds are seconds
2025 | * since the UN*X epoch.
2026 | */
2027 | if (length == 16) {
2028 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2029 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8);
2030 | } else if (length == 12) {
2031 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2032 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8);
2033 | } else if (length == 8) {
2034 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2035 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4);
2036 | } else if (length == 4) {
2037 | /*
2038 | * Backwards compatibility.
2039 | * ENC_TIME_SECS_NSECS is 0; using
2040 | * ENC_LITTLE_ENDIAN by itself with a 4-byte
2041 | * time-in-seconds value was done in the
2042 | * past.
2043 | */
2044 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2045 | time_stamp->nsecs = 0;
2046 | } else {
2047 | time_stamp->secs = 0;
2048 | time_stamp->nsecs = 0;
2049 | report_type_length_mismatch(tree, "a timespec", length, (length < 4));
2050 | }
2051 | break;
2052 |
2053 | case ENC_TIME_NTP0x00000002|ENC_BIG_ENDIAN0x00000000:
2054 | /*
2055 | * NTP time stamp, big-endian.
2056 | * Only supported for absolute times.
2057 | */
2058 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2058, "!is_relative" ))));
2059 |
2060 | /* We need a temporary variable here so the unsigned math
2061 | * works correctly (for years > 2036 according to RFC 2030
2062 | * chapter 3).
2063 | *
2064 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2065 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2066 | * If bit 0 is not set, the time is in the range 2036-2104 and
2067 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2068 | */
2069 | tmpsecs = tvb_get_ntohl(tvb, start);
2070 | if ((tmpsecs & 0x80000000) != 0)
2071 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2072 | else
2073 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2074 |
2075 | if (length == 8) {
2076 | tmp64secs = tvb_get_ntoh64(tvb, start);
2077 | if (tmp64secs == 0) {
2078 | //This is "NULL" time
2079 | time_stamp->secs = 0;
2080 | time_stamp->nsecs = 0;
2081 | } else {
2082 | /*
2083 | * Convert 1/2^32s of a second to
2084 | * nanoseconds.
2085 | */
2086 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2087 | }
2088 | } else if (length == 4) {
2089 | /*
2090 | * Backwards compatibility.
2091 | */
2092 | if (tmpsecs == 0) {
2093 | //This is "NULL" time
2094 | time_stamp->secs = 0;
2095 | }
2096 | time_stamp->nsecs = 0;
2097 | } else {
2098 | time_stamp->secs = 0;
2099 | time_stamp->nsecs = 0;
2100 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2101 | }
2102 | break;
2103 |
2104 | case ENC_TIME_NTP0x00000002|ENC_LITTLE_ENDIAN0x80000000:
2105 | /*
2106 | * NTP time stamp, little-endian.
2107 | * Only supported for absolute times.
2108 | *
2109 | * NTP doesn't use this, because it's an Internet format
2110 | * and hence big-endian. Any implementation must decide
2111 | * whether the NTP timestamp is a 64-bit unsigned fixed
2112 | * point number (RFC 1305, RFC 4330) or a 64-bit struct
2113 | * with a 32-bit unsigned seconds field followed by a
2114 | * 32-bit fraction field (cf. RFC 5905, which obsoletes
2115 | * the previous two).
2116 | *
2117 | * XXX: We do the latter, but no dissector uses this format.
2118 | * OTOH, ERF timestamps do the former, so perhaps we
2119 | * should switch the interpretation so that packet-erf.c
2120 | * could use this directly?
2121 | */
2122 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2122, "!is_relative" ))));
2123 |
2124 | /* We need a temporary variable here so the unsigned math
2125 | * works correctly (for years > 2036 according to RFC 2030
2126 | * chapter 3).
2127 | *
2128 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2129 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2130 | * If bit 0 is not set, the time is in the range 2036-2104 and
2131 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2132 | */
2133 | tmpsecs = tvb_get_letohl(tvb, start);
2134 | if ((tmpsecs & 0x80000000) != 0)
2135 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2136 | else
2137 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2138 |
2139 | if (length == 8) {
2140 | tmp64secs = tvb_get_letoh64(tvb, start);
2141 | if (tmp64secs == 0) {
2142 | //This is "NULL" time
2143 | time_stamp->secs = 0;
2144 | time_stamp->nsecs = 0;
2145 | } else {
2146 | /*
2147 | * Convert 1/2^32s of a second to
2148 | * nanoseconds.
2149 | */
2150 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2151 | }
2152 | } else if (length == 4) {
2153 | /*
2154 | * Backwards compatibility.
2155 | */
2156 | if (tmpsecs == 0) {
2157 | //This is "NULL" time
2158 | time_stamp->secs = 0;
2159 | }
2160 | time_stamp->nsecs = 0;
2161 | } else {
2162 | time_stamp->secs = 0;
2163 | time_stamp->nsecs = 0;
2164 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length < 4));
2165 | }
2166 | break;
2167 |
2168 | case ENC_TIME_TOD0x00000004|ENC_BIG_ENDIAN0x00000000:
2169 | /*
2170 | * S/3x0 and z/Architecture TOD clock time stamp,
2171 | * big-endian. The epoch is January 1, 1900,
2172 | * 00:00:00 (proleptic?) UTC.
2173 | *
2174 | * Only supported for absolute times.
2175 | */
2176 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2176, "!is_relative" ))));
2177 | DISSECTOR_ASSERT(length == 8)((void) ((length == 8) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2177, "length == 8" ))));
2178 |
2179 | if (length == 8) {
2180 | todusecs = tvb_get_ntoh64(tvb, start) >> 12;
2181 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2182 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2183 | } else {
2184 | time_stamp->secs = 0;
2185 | time_stamp->nsecs = 0;
2186 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2187 | }
2188 | break;
2189 |
2190 | case ENC_TIME_TOD0x00000004|ENC_LITTLE_ENDIAN0x80000000:
2191 | /*
2192 | * S/3x0 and z/Architecture TOD clock time stamp,
2193 | * little-endian. The epoch is January 1, 1900,
2194 | * 00:00:00 (proleptic?) UTC.
2195 | *
2196 | * Only supported for absolute times.
2197 | */
2198 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2198, "!is_relative" ))));
2199 |
2200 | if (length == 8) {
2201 | todusecs = tvb_get_letoh64(tvb, start) >> 12 ;
2202 | time_stamp->secs = (time_t)((todusecs / 1000000) - EPOCH_DELTA_1900_01_01_00_00_00_UTC2208988800U);
2203 | time_stamp->nsecs = (int)((todusecs % 1000000) * 1000);
2204 | } else {
2205 | time_stamp->secs = 0;
2206 | time_stamp->nsecs = 0;
2207 | report_type_length_mismatch(tree, "a TOD clock time stamp", length, (length < 4));
2208 | }
2209 | break;
2210 |
2211 | case ENC_TIME_RTPS0x00000008|ENC_BIG_ENDIAN0x00000000:
2212 | /*
2213 | * Time stamp using the same seconds/fraction format
2214 | * as NTP, but with the origin of the time stamp being
2215 | * the UNIX epoch rather than the NTP epoch; big-
2216 | * endian.
2217 | *
2218 | * Only supported for absolute times.
2219 | */
2220 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2220, "!is_relative" ))));
2221 |
2222 | if (length == 8) {
2223 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2224 | /*
2225 | * Convert 1/2^32s of a second to nanoseconds.
2226 | */
2227 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0));
2228 | } else {
2229 | time_stamp->secs = 0;
2230 | time_stamp->nsecs = 0;
2231 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2232 | }
2233 | break;
2234 |
2235 | case ENC_TIME_RTPS0x00000008|ENC_LITTLE_ENDIAN0x80000000:
2236 | /*
2237 | * Time stamp using the same seconds/fraction format
2238 | * as NTP, but with the origin of the time stamp being
2239 | * the UNIX epoch rather than the NTP epoch; little-
2240 | * endian.
2241 | *
2242 | * Only supported for absolute times.
2243 | *
2244 | * The RTPS specification explicitly supports Little
2245 | * Endian encoding. In one place, it states that its
2246 | * Time_t representation "is the one defined by ...
2247 | * RFC 1305", but in another explicitly defines it as
2248 | * a struct consisting of an 32 bit unsigned seconds
2249 | * field and a 32 bit unsigned fraction field, not a 64
2250 | * bit fixed point, so we do that here.
2251 | * https://www.omg.org/spec/DDSI-RTPS/2.5/PDF
2252 | */
2253 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2253, "!is_relative" ))));
2254 |
2255 | if (length == 8) {
2256 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2257 | /*
2258 | * Convert 1/2^32s of a second to nanoseconds.
2259 | */
2260 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohl(tvb, start+4)/4294967296.0));
2261 | } else {
2262 | time_stamp->secs = 0;
2263 | time_stamp->nsecs = 0;
2264 | report_type_length_mismatch(tree, "an RTPS time stamp", length, (length < 4));
2265 | }
2266 | break;
2267 |
2268 | case ENC_TIME_MIP60x00000024 | ENC_BIG_ENDIAN0x00000000:
2269 | /*
2270 | * MIP6 time stamp, big-endian.
2271 | * A 64-bit unsigned integer field containing a timestamp. The
2272 | * value indicates the number of seconds since January 1, 1970,
2273 | * 00:00 UTC, by using a fixed point format. In this format, the
2274 | * integer number of seconds is contained in the first 48 bits of
2275 | * the field, and the remaining 16 bits indicate the number of
2276 | * 1/65536 fractions of a second.
2277 |
2278 | * Only supported for absolute times.
2279 | */
2280 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2280, "!is_relative" ))));
2281 |
2282 | if (length == 8) {
2283 | /* We need a temporary variable here so the casting and fractions
2284 | * of a second work correctly.
2285 | */
2286 | tmp64secs = tvb_get_ntoh48(tvb, start);
2287 | tmpsecs = tvb_get_ntohs(tvb, start + 6);
2288 | tmpsecs <<= 16;
2289 |
2290 | if ((tmp64secs == 0) && (tmpsecs == 0)) {
2291 | //This is "NULL" time
2292 | time_stamp->secs = 0;
2293 | time_stamp->nsecs = 0;
2294 | } else {
2295 | time_stamp->secs = (time_t)tmp64secs;
2296 | time_stamp->nsecs = (int)((tmpsecs / 4294967296.0) * 1000000000);
2297 | }
2298 | } else {
2299 | time_stamp->secs = 0;
2300 | time_stamp->nsecs = 0;
2301 | report_type_length_mismatch(tree, "an NTP time stamp", length, (length != 8));
2302 | }
2303 | break;
2304 |
2305 | case ENC_TIME_SECS_USECS0x00000010|ENC_BIG_ENDIAN0x00000000:
2306 | /*
2307 | * If the length is 16, 8-byte seconds, followed
2308 | * by 8-byte fractional time in microseconds,
2309 | * both big-endian.
2310 | *
2311 | * If the length is 12, 8-byte seconds, followed
2312 | * by 4-byte fractional time in microseconds,
2313 | * both big-endian.
2314 | *
2315 | * If the length is 8, 4-byte seconds, followed
2316 | * by 4-byte fractional time in microseconds,
2317 | * both big-endian.
2318 | *
2319 | * For absolute times, the seconds are seconds
2320 | * since the UN*X epoch.
2321 | */
2322 | if (length == 16) {
2323 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2324 | time_stamp->nsecs = (uint32_t)tvb_get_ntoh64(tvb, start+8)*1000;
2325 | } else if (length == 12) {
2326 | time_stamp->secs = (time_t)tvb_get_ntoh64(tvb, start);
2327 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+8)*1000;
2328 | } else if (length == 8) {
2329 | time_stamp->secs = (time_t)tvb_get_ntohl(tvb, start);
2330 | time_stamp->nsecs = tvb_get_ntohl(tvb, start+4)*1000;
2331 | } else {
2332 | time_stamp->secs = 0;
2333 | time_stamp->nsecs = 0;
2334 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2335 | }
2336 | break;
2337 |
2338 | case ENC_TIME_SECS_USECS0x00000010|ENC_LITTLE_ENDIAN0x80000000:
2339 | /*
2340 | * If the length is 16, 8-byte seconds, followed
2341 | * by 8-byte fractional time in microseconds,
2342 | * both little-endian.
2343 | *
2344 | * If the length is 12, 8-byte seconds, followed
2345 | * by 4-byte fractional time in microseconds,
2346 | * both little-endian.
2347 | *
2348 | * If the length is 8, 4-byte seconds, followed
2349 | * by 4-byte fractional time in microseconds,
2350 | * both little-endian.
2351 | *
2352 | * For absolute times, the seconds are seconds
2353 | * since the UN*X epoch.
2354 | */
2355 | if (length == 16) {
2356 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2357 | time_stamp->nsecs = (uint32_t)tvb_get_letoh64(tvb, start+8)*1000;
2358 | } else if (length == 12) {
2359 | time_stamp->secs = (time_t)tvb_get_letoh64(tvb, start);
2360 | time_stamp->nsecs = tvb_get_letohl(tvb, start+8)*1000;
2361 | } else if (length == 8) {
2362 | time_stamp->secs = (time_t)tvb_get_letohl(tvb, start);
2363 | time_stamp->nsecs = tvb_get_letohl(tvb, start+4)*1000;
2364 | } else {
2365 | time_stamp->secs = 0;
2366 | time_stamp->nsecs = 0;
2367 | report_type_length_mismatch(tree, "a timeval", length, (length < 4));
2368 | }
2369 | break;
2370 |
2371 | case ENC_TIME_SECS0x00000012|ENC_BIG_ENDIAN0x00000000:
2372 | case ENC_TIME_SECS0x00000012|ENC_LITTLE_ENDIAN0x80000000:
2373 | /*
2374 | * Seconds, 1 to 8 bytes.
2375 | * For absolute times, it's seconds since the
2376 | * UN*X epoch.
2377 | */
2378 | if (length >= 1 && length <= 8) {
2379 | time_stamp->secs = (time_t)get_uint64_value(tree, tvb, start, length, encoding);
2380 | time_stamp->nsecs = 0;
2381 | } else {
2382 | time_stamp->secs = 0;
2383 | time_stamp->nsecs = 0;
2384 | report_type_length_mismatch(tree, "a time-in-seconds time stamp", length, (length < 4));
2385 | }
2386 | break;
2387 |
2388 | case ENC_TIME_MSECS0x00000014|ENC_BIG_ENDIAN0x00000000:
2389 | case ENC_TIME_MSECS0x00000014|ENC_LITTLE_ENDIAN0x80000000:
2390 | /*
2391 | * Milliseconds, 1 to 8 bytes.
2392 | * For absolute times, it's milliseconds since the
2393 | * UN*X epoch.
2394 | */
2395 | if (length >= 1 && length <= 8) {
2396 | uint64_t msecs;
2397 |
2398 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2399 | time_stamp->secs = (time_t)(msecs / 1000);
2400 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2401 | } else {
2402 | time_stamp->secs = 0;
2403 | time_stamp->nsecs = 0;
2404 | report_type_length_mismatch(tree, "a time-in-milliseconds time stamp", length, (length < 4));
2405 | }
2406 | break;
2407 |
2408 | case ENC_TIME_USECS0x00000030|ENC_BIG_ENDIAN0x00000000:
2409 | case ENC_TIME_USECS0x00000030|ENC_LITTLE_ENDIAN0x80000000:
2410 | /*
2411 | * Microseconds, 1 to 8 bytes.
2412 | * For absolute times, it's microseconds since the
2413 | * UN*X epoch.
2414 | */
2415 | if (length >= 1 && length <= 8) {
2416 | uint64_t usecs;
2417 |
2418 | usecs = get_uint64_value(tree, tvb, start, length, encoding);
2419 | time_stamp->secs = (time_t)(usecs / 1000000);
2420 | time_stamp->nsecs = (int)(usecs % 1000000)*1000;
2421 | } else {
2422 | time_stamp->secs = 0;
2423 | time_stamp->nsecs = 0;
2424 | report_type_length_mismatch(tree, "a time-in-microseconds time stamp", length, (length < 4));
2425 | }
2426 | break;
2427 |
2428 | case ENC_TIME_NSECS0x00000028|ENC_BIG_ENDIAN0x00000000:
2429 | case ENC_TIME_NSECS0x00000028|ENC_LITTLE_ENDIAN0x80000000:
2430 | /*
2431 | * nanoseconds, 1 to 8 bytes.
2432 | * For absolute times, it's nanoseconds since the
2433 | * UN*X epoch.
2434 | */
2435 |
2436 | if (length >= 1 && length <= 8) {
2437 | uint64_t nsecs;
2438 |
2439 | nsecs = get_uint64_value(tree, tvb, start, length, encoding);
2440 | time_stamp->secs = (time_t)(nsecs / 1000000000);
2441 | time_stamp->nsecs = (int)(nsecs % 1000000000);
2442 | } else {
2443 | time_stamp->secs = 0;
2444 | time_stamp->nsecs = 0;
2445 | report_type_length_mismatch(tree, "a time-in-nanoseconds time stamp", length, (length < 4));
2446 | }
2447 | break;
2448 |
2449 | case ENC_TIME_RFC_39710x00000020|ENC_BIG_ENDIAN0x00000000:
2450 | /*
2451 | * 1/64ths of a second since the UN*X epoch,
2452 | * big-endian.
2453 | *
2454 | * Only supported for absolute times.
2455 | */
2456 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2456, "!is_relative" ))));
2457 |
2458 | if (length == 8) {
2459 | /*
2460 | * The upper 48 bits are seconds since the
2461 | * UN*X epoch.
2462 | */
2463 | time_stamp->secs = (time_t)tvb_get_ntoh48(tvb, start);
2464 | /*
2465 | * The lower 16 bits are 1/2^16s of a second;
2466 | * convert them to nanoseconds.
2467 | *
2468 | * XXX - this may give the impression of higher
2469 | * precision than you actually get.
2470 | */
2471 | time_stamp->nsecs = (int)(1000000000*(tvb_get_ntohs(tvb, start+6)/65536.0));
2472 | } else {
2473 | time_stamp->secs = 0;
2474 | time_stamp->nsecs = 0;
2475 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2476 | }
2477 | break;
2478 |
2479 | case ENC_TIME_RFC_39710x00000020|ENC_LITTLE_ENDIAN0x80000000:
2480 | /*
2481 | * 1/64ths of a second since the UN*X epoch,
2482 | * little-endian.
2483 | *
2484 | * Only supported for absolute times.
2485 | */
2486 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2486, "!is_relative" ))));
2487 |
2488 | if (length == 8) {
2489 | /*
2490 | * XXX - this is assuming that, if anybody
2491 | * were ever to use this format - RFC 3971
2492 | * doesn't, because that's an Internet
2493 | * protocol, and those use network byte
2494 | * order, i.e. big-endian - they'd treat it
2495 | * as a 64-bit count of 1/2^16s of a second,
2496 | * putting the upper 48 bits at the end.
2497 | *
2498 | * The lower 48 bits are seconds since the
2499 | * UN*X epoch.
2500 | */
2501 | time_stamp->secs = (time_t)tvb_get_letoh48(tvb, start+2);
2502 | /*
2503 | * The upper 16 bits are 1/2^16s of a second;
2504 | * convert them to nanoseconds.
2505 | *
2506 | * XXX - this may give the impression of higher
2507 | * precision than you actually get.
2508 | */
2509 | time_stamp->nsecs = (int)(1000000000*(tvb_get_letohs(tvb, start)/65536.0));
2510 | } else {
2511 | time_stamp->secs = 0;
2512 | time_stamp->nsecs = 0;
2513 | report_type_length_mismatch(tree, "an RFC 3971-style time stamp", length, (length < 4));
2514 | }
2515 | break;
2516 |
2517 | case ENC_TIME_SECS_NTP0x00000018|ENC_BIG_ENDIAN0x00000000:
2518 | /*
2519 | * NTP time stamp, with 1-second resolution (i.e.,
2520 | * seconds since the NTP epoch), big-endian.
2521 | * Only supported for absolute times.
2522 | */
2523 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2523, "!is_relative" ))));
2524 |
2525 | if (length == 4) {
2526 | /*
2527 | * We need a temporary variable here so the unsigned math
2528 | * works correctly (for years > 2036 according to RFC 2030
2529 | * chapter 3).
2530 | *
2531 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2532 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2533 | * If bit 0 is not set, the time is in the range 2036-2104 and
2534 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2535 | */
2536 | tmpsecs = tvb_get_ntohl(tvb, start);
2537 | if ((tmpsecs & 0x80000000) != 0)
2538 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2539 | else
2540 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2541 | time_stamp->nsecs = 0;
2542 | } else {
2543 | time_stamp->secs = 0;
2544 | time_stamp->nsecs = 0;
2545 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2546 | }
2547 | break;
2548 |
2549 | case ENC_TIME_SECS_NTP0x00000018|ENC_LITTLE_ENDIAN0x80000000:
2550 | /*
2551 | * NTP time stamp, with 1-second resolution (i.e.,
2552 | * seconds since the NTP epoch), little-endian.
2553 | * Only supported for absolute times.
2554 | */
2555 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2555, "!is_relative" ))));
2556 |
2557 | /*
2558 | * We need a temporary variable here so the unsigned math
2559 | * works correctly (for years > 2036 according to RFC 2030
2560 | * chapter 3).
2561 | *
2562 | * If bit 0 is set, the UTC time is in the range 1968-2036 and
2563 | * UTC time is reckoned from 0h 0m 0s UTC on 1 January 1900.
2564 | * If bit 0 is not set, the time is in the range 2036-2104 and
2565 | * UTC time is reckoned from 6h 28m 16s UTC on 7 February 2036.
2566 | */
2567 | if (length == 4) {
2568 | tmpsecs = tvb_get_letohl(tvb, start);
2569 | if ((tmpsecs & 0x80000000) != 0)
2570 | time_stamp->secs = (time_t)((int64_t)tmpsecs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2571 | else
2572 | time_stamp->secs = (time_t)((int64_t)tmpsecs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2573 | time_stamp->nsecs = 0;
2574 | } else {
2575 | time_stamp->secs = 0;
2576 | time_stamp->nsecs = 0;
2577 | report_type_length_mismatch(tree, "an NTP seconds-only time stamp", length, (length < 4));
2578 | }
2579 | break;
2580 |
2581 | case ENC_TIME_MSEC_NTP0x00000022 | ENC_BIG_ENDIAN0x00000000:
2582 | /*
2583 | * Milliseconds, 6 to 8 bytes.
2584 | * For absolute times, it's milliseconds since the
2585 | * NTP epoch.
2586 | *
2587 | * ETSI TS 129.274 8.119 defines this as:
2588 | * "a 48 bit unsigned integer in network order format
2589 | * ...encoded as the number of milliseconds since
2590 | * 00:00:00 January 1, 1900 00:00 UTC, i.e. as the
2591 | * rounded value of 1000 x the value of the 64-bit
2592 | * timestamp (Seconds + (Fraction / (1<<32))) defined
2593 | * in clause 6 of IETF RFC 5905."
2594 | *
2595 | * Taken literally, the part after "i.e." would
2596 | * mean that the value rolls over before reaching
2597 | * 2^32 * 1000 = 4294967296000 = 0x3e800000000
2598 | * when the 64 bit timestamp rolls over, and we have
2599 | * to pick an NTP Era equivalence class to support
2600 | * (such as 1968-01-20 to 2104-02-06).
2601 | *
2602 | * OTOH, the extra room might be used to store Era
2603 | * information instead, in which case times until
2604 | * 10819-08-03 can be represented with 6 bytes without
2605 | * ambiguity. We handle both implementations, and assume
2606 | * that times before 1968-01-20 are not represented.
2607 | *
2608 | * Only 6 bytes or more makes sense as an absolute
2609 | * time. 5 bytes or fewer could express a span of
2610 | * less than 35 years, either 1900-1934 or 2036-2070.
2611 | */
2612 | if (length >= 6 && length <= 8) {
2613 | uint64_t msecs;
2614 |
2615 | msecs = get_uint64_value(tree, tvb, start, length, encoding);
2616 | tmp64secs = (msecs / 1000);
2617 | /*
2618 | * Assume that times in the first half of NTP
2619 | * Era 0 really represent times in the NTP
2620 | * Era 1.
2621 | */
2622 | if (tmp64secs >= 0x80000000)
2623 | time_stamp->secs = (time_t)((int64_t)tmp64secs - NTP_TIMEDIFF1900TO1970SEC2208988800L);
2624 | else
2625 | time_stamp->secs = (time_t)((int64_t)tmp64secs + NTP_TIMEDIFF1970TO2036SEC2085978496L);
2626 | time_stamp->nsecs = (int)(msecs % 1000)*1000000;
2627 | }
2628 | else {
2629 | time_stamp->secs = 0;
2630 | time_stamp->nsecs = 0;
2631 | report_type_length_mismatch(tree, "a time-in-milliseconds NTP time stamp", length, (length < 6));
2632 | }
2633 | break;
2634 |
2635 | case ENC_TIME_MP4_FILE_SECS0x00000026|ENC_BIG_ENDIAN0x00000000:
2636 | /*
2637 | * MP4 file time stamps, big-endian.
2638 | * Only supported for absolute times.
2639 | */
2640 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2640, "!is_relative" ))));
2641 |
2642 | if (length == 8) {
2643 | tmp64secs = tvb_get_ntoh64(tvb, start);
2644 | time_stamp->secs = (time_t)(int64_t)(tmp64secs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2645 | time_stamp->nsecs = 0;
2646 | } else if (length == 4) {
2647 | tmpsecs = tvb_get_ntohl(tvb, start);
2648 | time_stamp->secs = (time_t)(int32_t)(tmpsecs - EPOCH_DELTA_1904_01_01_00_00_00_UTC2082844800U);
2649 | time_stamp->nsecs = 0;
2650 | } else {
2651 | time_stamp->secs = 0;
2652 | time_stamp->nsecs = 0;
2653 | report_type_length_mismatch(tree, "an MP4 time stamp", length, (length < 4));
2654 | }
2655 | break;
2656 |
2657 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_BIG_ENDIAN0x00000000:
2658 | /*
2659 | * Zigbee ZCL time stamps, big-endian.
2660 | * Only supported for absolute times.
2661 | */
2662 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2662, "!is_relative" ))));
2663 |
2664 | if (length == 8) {
2665 | tmp64secs = tvb_get_ntoh64(tvb, start);
2666 | 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);
2667 | time_stamp->nsecs = 0;
2668 | } else if (length == 4) {
2669 | tmpsecs = tvb_get_ntohl(tvb, start);
2670 | time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2671 | time_stamp->nsecs = 0;
2672 | } else {
2673 | time_stamp->secs = 0;
2674 | time_stamp->nsecs = 0;
2675 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2676 | }
2677 | break;
2678 |
2679 | case ENC_TIME_ZBEE_ZCL0x00000032 | ENC_LITTLE_ENDIAN0x80000000:
2680 | /*
2681 | * Zigbee ZCL time stamps, little-endian.
2682 | * Only supported for absolute times.
2683 | */
2684 | DISSECTOR_ASSERT(!is_relative)((void) ((!is_relative) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 2684, "!is_relative" ))));
2685 |
2686 | if (length == 8) {
2687 | tmp64secs = tvb_get_letoh64(tvb, start);
2688 | 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);
2689 | time_stamp->nsecs = 0;
2690 | } else if (length == 4) {
2691 | tmpsecs = tvb_get_letohl(tvb, start);
2692 | time_stamp->secs = (time_t)(tmpsecs + EPOCH_DELTA_2000_01_01_00_00_00_UTC((3*365 + 366)*7 + 2*365)*24*3600UL);
2693 | time_stamp->nsecs = 0;
2694 | } else {
2695 | time_stamp->secs = 0;
2696 | time_stamp->nsecs = 0;
2697 | report_type_length_mismatch(tree, "a Zigbee ZCL time stamp", length, (length < 4));
2698 | }
2699 | break;
2700 |
2701 | default:
2702 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 2702));
2703 | break;
2704 | }
2705 | }
2706 |
2707 | static void
2708 | tree_data_add_maybe_interesting_field(tree_data_t *tree_data, field_info *fi)
2709 | {
2710 | const header_field_info *hfinfo = fi->hfinfo;
2711 |
2712 | if (hfinfo->ref_type == HF_REF_TYPE_DIRECT || hfinfo->ref_type == HF_REF_TYPE_PRINT) {
2713 | GPtrArray *ptrs = NULL((void*)0);
2714 |
2715 | if (tree_data->interesting_hfids == NULL((void*)0)) {
2716 | /* Initialize the hash because we now know that it is needed */
2717 | tree_data->interesting_hfids =
2718 | g_hash_table_new(g_direct_hash, NULL((void*)0) /* g_direct_equal */);
2719 | } else if (g_hash_table_size(tree_data->interesting_hfids)) {
2720 | ptrs = (GPtrArray *)g_hash_table_lookup(tree_data->interesting_hfids,
2721 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)));
2722 | }
2723 |
2724 | if (!ptrs) {
2725 | /* First element triggers the creation of pointer array */
2726 | ptrs = g_ptr_array_new();
2727 | g_hash_table_insert(tree_data->interesting_hfids,
2728 | GINT_TO_POINTER(hfinfo->id)((gpointer) (glong) (hfinfo->id)), ptrs);
2729 | }
2730 |
2731 | g_ptr_array_add(ptrs, fi);
2732 | }
2733 | }
2734 |
2735 |
2736 | /*
2737 | * Validates that field length bytes are available starting from
2738 | * start (pos/neg). Throws an exception if they aren't.
2739 | */
2740 | static void
2741 | test_length(header_field_info *hfinfo, tvbuff_t *tvb,
2742 | int start, int length, const unsigned encoding)
2743 | {
2744 | int size = length;
2745 |
2746 | if (!tvb)
2747 | return;
2748 |
2749 | if ((hfinfo->type == FT_STRINGZ) ||
2750 | ((encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) &&
2751 | (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 ))))) {
2752 | /* If we're fetching until the end of the TVB, only validate
2753 | * that the offset is within range.
2754 | */
2755 | if (length == -1)
2756 | size = 0;
2757 | }
2758 |
2759 | tvb_ensure_bytes_exist(tvb, start, size);
2760 | }
2761 |
2762 | static void
2763 | detect_trailing_stray_characters(unsigned encoding, const char *string, int length, proto_item *pi)
2764 | {
2765 | bool_Bool found_stray_character = false0;
2766 |
2767 | if (!string)
2768 | return;
2769 |
2770 | switch (encoding & ENC_CHARENCODING_MASK0x0000FFFE) {
2771 | case ENC_ASCII0x00000000:
2772 | case ENC_UTF_80x00000002:
2773 | for (int i = (int)strlen(string); i < length; i++) {
2774 | if (string[i] != '\0') {
2775 | found_stray_character = true1;
2776 | break;
2777 | }
2778 | }
2779 | break;
2780 |
2781 | default:
2782 | break;
2783 | }
2784 |
2785 | if (found_stray_character) {
2786 | expert_add_info(NULL((void*)0), pi, &ei_string_trailing_characters);
2787 | }
2788 | }
2789 |
2790 | static void
2791 | free_fvalue_cb(void *data)
2792 | {
2793 | fvalue_t *fv = (fvalue_t*)data;
2794 | fvalue_free(fv);
2795 | }
2796 |
2797 | /* Add an item to a proto_tree, using the text label registered to that item;
2798 | the item is extracted from the tvbuff handed to it. */
2799 | static proto_item *
2800 | proto_tree_new_item(field_info *new_fi, proto_tree *tree,
2801 | tvbuff_t *tvb, int start, int length,
2802 | unsigned encoding)
2803 | {
2804 | proto_item *pi;
2805 | uint32_t value, n;
2806 | uint64_t value64;
2807 | ws_in4_addr ipv4_value;
2808 | float floatval;
2809 | double doubleval;
2810 | const char *stringval = NULL((void*)0);
2811 | nstime_t time_stamp;
2812 | bool_Bool length_error;
2813 |
2814 | /* Ensure that the newly created fvalue_t is freed if we throw an
2815 | * exception before adding it to the tree. (gcc creates clobbering
2816 | * when it optimizes the equivalent TRY..EXCEPT implementation.)
2817 | * XXX: Move the new_field_info() call inside here?
2818 | */
2819 | 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));
2820 |
2821 | switch (new_fi->hfinfo->type) {
2822 | case FT_NONE:
2823 | /* no value to set for FT_NONE */
2824 | break;
2825 |
2826 | case FT_PROTOCOL:
2827 | proto_tree_set_protocol_tvb(new_fi, tvb, new_fi->hfinfo->name, length);
2828 | break;
2829 |
2830 | case FT_BYTES:
2831 | proto_tree_set_bytes_tvb(new_fi, tvb, start, length);
2832 | break;
2833 |
2834 | case FT_UINT_BYTES:
2835 | n = get_uint_value(tree, tvb, start, length, encoding);
2836 | proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n);
2837 |
2838 | /* Instead of calling proto_item_set_len(), since we don't yet
2839 | * have a proto_item, we set the field_info's length ourselves. */
2840 | new_fi->length = n + length;
2841 | break;
2842 |
2843 | case FT_BOOLEAN:
2844 | /*
2845 | * Map all non-zero values to little-endian for
2846 | * backwards compatibility.
2847 | */
2848 | if (encoding)
2849 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2850 | proto_tree_set_boolean(new_fi,
2851 | get_uint64_value(tree, tvb, start, length, encoding));
2852 | break;
2853 |
2854 | case FT_CHAR:
2855 | /* XXX - make these just FT_UINT? */
2856 | case FT_UINT8:
2857 | case FT_UINT16:
2858 | case FT_UINT24:
2859 | case FT_UINT32:
2860 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2861 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2862 | value = (uint32_t)value64;
2863 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2864 | new_fi->flags |= FI_VARINT0x00040000;
2865 | }
2866 | }
2867 | else {
2868 | /*
2869 | * Map all non-zero values to little-endian for
2870 | * backwards compatibility.
2871 | */
2872 | if (encoding)
2873 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2874 |
2875 | value = get_uint_value(tree, tvb, start, length, encoding);
2876 | }
2877 | proto_tree_set_uint(new_fi, value);
2878 | break;
2879 |
2880 | case FT_UINT40:
2881 | case FT_UINT48:
2882 | case FT_UINT56:
2883 | case FT_UINT64:
2884 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
2885 | new_fi->length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value64, encoding);
2886 | if (!(encoding & ENC_VARINT_QUIC0x00000004)) {
2887 | new_fi->flags |= FI_VARINT0x00040000;
2888 | }
2889 | }
2890 | else {
2891 | /*
2892 | * Map all other non-zero values to little-endian for
2893 | * backwards compatibility.
2894 | */
2895 | if (encoding)
2896 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2897 |
2898 | value64 = get_uint64_value(tree, tvb, start, length, encoding);
2899 | }
2900 | proto_tree_set_uint64(new_fi, value64);
2901 | break;
2902 |
2903 | /* XXX - make these just FT_INT? */
2904 | case FT_INT8:
2905 | case FT_INT16:
2906 | case FT_INT24:
2907 | case FT_INT32:
2908 | /*
2909 | * Map all non-zero values to little-endian for
2910 | * backwards compatibility.
2911 | */
2912 | if (encoding)
2913 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2914 | proto_tree_set_int(new_fi,
2915 | get_int_value(tree, tvb, start, length, encoding));
2916 | break;
2917 |
2918 | case FT_INT40:
2919 | case FT_INT48:
2920 | case FT_INT56:
2921 | case FT_INT64:
2922 | /*
2923 | * Map all non-zero values to little-endian for
2924 | * backwards compatibility.
2925 | */
2926 | if (encoding)
2927 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2928 | proto_tree_set_int64(new_fi,
2929 | get_int64_value(tree, tvb, start, length, encoding));
2930 | break;
2931 |
2932 | case FT_IPv4:
2933 | /*
2934 | * Map all non-zero values to little-endian for
2935 | * backwards compatibility.
2936 | */
2937 | if (encoding)
2938 | encoding = ENC_LITTLE_ENDIAN0x80000000;
2939 | if (length != FT_IPv4_LEN4) {
2940 | length_error = length < FT_IPv4_LEN4 ? true1 : false0;
2941 | report_type_length_mismatch(tree, "an IPv4 address", length, length_error);
2942 | }
2943 | ipv4_value = tvb_get_ipv4(tvb, start);
2944 | /*
2945 | * NOTE: to support code written when
2946 | * proto_tree_add_item() took a bool as its
2947 | * last argument, with false meaning "big-endian"
2948 | * and true meaning "little-endian", we treat any
2949 | * non-zero value of "encoding" as meaning
2950 | * "little-endian".
2951 | */
2952 | 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);
2953 | break;
2954 |
2955 | case FT_IPXNET:
2956 | if (length != FT_IPXNET_LEN4) {
2957 | length_error = length < FT_IPXNET_LEN4 ? true1 : false0;
2958 | report_type_length_mismatch(tree, "an IPXNET address", length, length_error);
2959 | }
2960 | proto_tree_set_ipxnet(new_fi,
2961 | get_uint_value(tree, tvb, start, FT_IPXNET_LEN4, ENC_BIG_ENDIAN0x00000000));
2962 | break;
2963 |
2964 | case FT_IPv6:
2965 | if (length != FT_IPv6_LEN16) {
2966 | length_error = length < FT_IPv6_LEN16 ? true1 : false0;
2967 | report_type_length_mismatch(tree, "an IPv6 address", length, length_error);
2968 | }
2969 | proto_tree_set_ipv6_tvb(new_fi, tvb, start, length);
2970 | break;
2971 |
2972 | case FT_FCWWN:
2973 | if (length != FT_FCWWN_LEN8) {
2974 | length_error = length < FT_FCWWN_LEN8 ? true1 : false0;
2975 | report_type_length_mismatch(tree, "an FCWWN address", length, length_error);
2976 | }
2977 | proto_tree_set_fcwwn_tvb(new_fi, tvb, start, length);
2978 | break;
2979 |
2980 | case FT_AX25:
2981 | if (length != 7) {
2982 | length_error = length < 7 ? true1 : false0;
2983 | report_type_length_mismatch(tree, "an AX.25 address", length, length_error);
2984 | }
2985 | proto_tree_set_ax25_tvb(new_fi, tvb, start);
2986 | break;
2987 |
2988 | case FT_VINES:
2989 | if (length != VINES_ADDR_LEN6) {
2990 | length_error = length < VINES_ADDR_LEN6 ? true1 : false0;
2991 | report_type_length_mismatch(tree, "a Vines address", length, length_error);
2992 | }
2993 | proto_tree_set_vines_tvb(new_fi, tvb, start);
2994 | break;
2995 |
2996 | case FT_ETHER:
2997 | if (length != FT_ETHER_LEN6) {
2998 | length_error = length < FT_ETHER_LEN6 ? true1 : false0;
2999 | report_type_length_mismatch(tree, "a MAC address", length, length_error);
3000 | }
3001 | proto_tree_set_ether_tvb(new_fi, tvb, start);
3002 | break;
3003 |
3004 | case FT_EUI64:
3005 | /*
3006 | * Map all non-zero values to little-endian for
3007 | * backwards compatibility.
3008 | */
3009 | if (encoding)
3010 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3011 | if (length != FT_EUI64_LEN8) {
3012 | length_error = length < FT_EUI64_LEN8 ? true1 : false0;
3013 | report_type_length_mismatch(tree, "an EUI-64 address", length, length_error);
3014 | }
3015 | proto_tree_set_eui64_tvb(new_fi, tvb, start, encoding);
3016 | break;
3017 | case FT_GUID:
3018 | /*
3019 | * Map all non-zero values to little-endian for
3020 | * backwards compatibility.
3021 | */
3022 | if (encoding)
3023 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3024 | if (length != FT_GUID_LEN16) {
3025 | length_error = length < FT_GUID_LEN16 ? true1 : false0;
3026 | report_type_length_mismatch(tree, "a GUID", length, length_error);
3027 | }
3028 | proto_tree_set_guid_tvb(new_fi, tvb, start, encoding);
3029 | break;
3030 |
3031 | case FT_OID:
3032 | case FT_REL_OID:
3033 | proto_tree_set_oid_tvb(new_fi, tvb, start, length);
3034 | break;
3035 |
3036 | case FT_SYSTEM_ID:
3037 | proto_tree_set_system_id_tvb(new_fi, tvb, start, length);
3038 | break;
3039 |
3040 | case FT_FLOAT:
3041 | /*
3042 | * NOTE: to support code written when
3043 | * proto_tree_add_item() took a bool as its
3044 | * last argument, with false meaning "big-endian"
3045 | * and true meaning "little-endian", we treat any
3046 | * non-zero value of "encoding" as meaning
3047 | * "little-endian".
3048 | *
3049 | * At some point in the future, we might
3050 | * support non-IEEE-binary floating-point
3051 | * formats in the encoding as well
3052 | * (IEEE decimal, System/3x0, VAX).
3053 | */
3054 | if (encoding)
3055 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3056 | if (length != 4) {
3057 | length_error = length < 4 ? true1 : false0;
3058 | report_type_length_mismatch(tree, "a single-precision floating point number", length, length_error);
3059 | }
3060 | if (encoding)
3061 | floatval = tvb_get_letohieee_float(tvb, start);
3062 | else
3063 | floatval = tvb_get_ntohieee_float(tvb, start);
3064 | proto_tree_set_float(new_fi, floatval);
3065 | break;
3066 |
3067 | case FT_DOUBLE:
3068 | /*
3069 | * NOTE: to support code written when
3070 | * proto_tree_add_item() took a bool as its
3071 | * last argument, with false meaning "big-endian"
3072 | * and true meaning "little-endian", we treat any
3073 | * non-zero value of "encoding" as meaning
3074 | * "little-endian".
3075 | *
3076 | * At some point in the future, we might
3077 | * support non-IEEE-binary floating-point
3078 | * formats in the encoding as well
3079 | * (IEEE decimal, System/3x0, VAX).
3080 | */
3081 | if (encoding == true1)
3082 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3083 | if (length != 8) {
3084 | length_error = length < 8 ? true1 : false0;
3085 | report_type_length_mismatch(tree, "a double-precision floating point number", length, length_error);
3086 | }
3087 | if (encoding)
3088 | doubleval = tvb_get_letohieee_double(tvb, start);
3089 | else
3090 | doubleval = tvb_get_ntohieee_double(tvb, start);
3091 | proto_tree_set_double(new_fi, doubleval);
3092 | break;
3093 |
3094 | case FT_STRING:
3095 | stringval = (const char*)get_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3096 | tvb, start, length, &length, encoding);
3097 | proto_tree_set_string(new_fi, stringval);
3098 |
3099 | /* Instead of calling proto_item_set_len(), since we
3100 | * don't yet have a proto_item, we set the
3101 | * field_info's length ourselves.
3102 | *
3103 | * XXX - our caller can't use that length to
3104 | * advance an offset unless they arrange that
3105 | * there always be a protocol tree into which
3106 | * we're putting this item.
3107 | */
3108 | new_fi->length = length;
3109 | break;
3110 |
3111 | case FT_STRINGZ:
3112 | stringval = (const char*)get_stringz_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3113 | tree, tvb, start, length, &length, encoding);
3114 | proto_tree_set_string(new_fi, stringval);
3115 |
3116 | /* Instead of calling proto_item_set_len(),
3117 | * since we don't yet have a proto_item, we
3118 | * set the field_info's length ourselves.
3119 | *
3120 | * XXX - our caller can't use that length to
3121 | * advance an offset unless they arrange that
3122 | * there always be a protocol tree into which
3123 | * we're putting this item.
3124 | */
3125 | new_fi->length = length;
3126 | break;
3127 |
3128 | case FT_UINT_STRING:
3129 | /*
3130 | * NOTE: to support code written when
3131 | * proto_tree_add_item() took a bool as its
3132 | * last argument, with false meaning "big-endian"
3133 | * and true meaning "little-endian", if the
3134 | * encoding value is true, treat that as
3135 | * ASCII with a little-endian length.
3136 | *
3137 | * This won't work for code that passes
3138 | * arbitrary non-zero values; that code
3139 | * will need to be fixed.
3140 | */
3141 | if (encoding == true1)
3142 | encoding = ENC_ASCII0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3143 | stringval = (const char*)get_uint_string_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3144 | tree, tvb, start, length, &length, encoding);
3145 | proto_tree_set_string(new_fi, stringval);
3146 |
3147 | /* Instead of calling proto_item_set_len(), since we
3148 | * don't yet have a proto_item, we set the
3149 | * field_info's length ourselves.
3150 | *
3151 | * XXX - our caller can't use that length to
3152 | * advance an offset unless they arrange that
3153 | * there always be a protocol tree into which
3154 | * we're putting this item.
3155 | */
3156 | new_fi->length = length;
3157 | break;
3158 |
3159 | case FT_STRINGZPAD:
3160 | stringval = (const char*)get_stringzpad_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3161 | tvb, start, length, &length, encoding);
3162 | proto_tree_set_string(new_fi, stringval);
3163 |
3164 | /* Instead of calling proto_item_set_len(), since we
3165 | * don't yet have a proto_item, we set the
3166 | * field_info's length ourselves.
3167 | *
3168 | * XXX - our caller can't use that length to
3169 | * advance an offset unless they arrange that
3170 | * there always be a protocol tree into which
3171 | * we're putting this item.
3172 | */
3173 | new_fi->length = length;
3174 | break;
3175 |
3176 | case FT_STRINGZTRUNC:
3177 | stringval = (const char*)get_stringztrunc_value(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool),
3178 | tvb, start, length, &length, encoding);
3179 | proto_tree_set_string(new_fi, stringval);
3180 |
3181 | /* Instead of calling proto_item_set_len(), since we
3182 | * don't yet have a proto_item, we set the
3183 | * field_info's length ourselves.
3184 | *
3185 | * XXX - our caller can't use that length to
3186 | * advance an offset unless they arrange that
3187 | * there always be a protocol tree into which
3188 | * we're putting this item.
3189 | */
3190 | new_fi->length = length;
3191 | break;
3192 |
3193 | case FT_ABSOLUTE_TIME:
3194 | /*
3195 | * Absolute times can be in any of a number of
3196 | * formats, and they can be big-endian or
3197 | * little-endian.
3198 | *
3199 | * Historically FT_TIMEs were only timespecs;
3200 | * the only question was whether they were stored
3201 | * in big- or little-endian format.
3202 | *
3203 | * For backwards compatibility, we interpret an
3204 | * encoding of 1 as meaning "little-endian timespec",
3205 | * so that passing true is interpreted as that.
3206 | */
3207 | if (encoding == true1)
3208 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3209 |
3210 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
3211 |
3212 | proto_tree_set_time(new_fi, &time_stamp);
3213 | break;
3214 |
3215 | case FT_RELATIVE_TIME:
3216 | /*
3217 | * Relative times can be in any of a number of
3218 | * formats, and they can be big-endian or
3219 | * little-endian.
3220 | *
3221 | * Historically FT_TIMEs were only timespecs;
3222 | * the only question was whether they were stored
3223 | * in big- or little-endian format.
3224 | *
3225 | * For backwards compatibility, we interpret an
3226 | * encoding of 1 as meaning "little-endian timespec",
3227 | * so that passing true is interpreted as that.
3228 | */
3229 | if (encoding == true1)
3230 | encoding = ENC_TIME_SECS_NSECS0x00000000|ENC_LITTLE_ENDIAN0x80000000;
3231 |
3232 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
3233 |
3234 | proto_tree_set_time(new_fi, &time_stamp);
3235 | break;
3236 | case FT_IEEE_11073_SFLOAT:
3237 | if (encoding)
3238 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3239 | if (length != 2) {
3240 | length_error = length < 2 ? true1 : false0;
3241 | report_type_length_mismatch(tree, "a IEEE 11073 SFLOAT", length, length_error);
3242 | }
3243 |
3244 | fvalue_set_uinteger(new_fi->value, tvb_get_uint16(tvb, start, encoding));
3245 |
3246 | break;
3247 | case FT_IEEE_11073_FLOAT:
3248 | if (encoding)
3249 | encoding = ENC_LITTLE_ENDIAN0x80000000;
3250 | if (length != 4) {
3251 | length_error = length < 4 ? true1 : false0;
3252 | report_type_length_mismatch(tree, "a IEEE 11073 FLOAT", length, length_error);
3253 | }
3254 | fvalue_set_uinteger(new_fi->value, tvb_get_uint32(tvb, start, encoding));
3255 |
3256 | break;
3257 | default:
3258 | 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))
3259 | 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))
3260 | 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))
3261 | 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));
3262 | break;
3263 | }
3264 | 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);
3265 |
3266 | /* Don't add new node to proto_tree until now so that any exceptions
3267 | * raised by a tvbuff access method doesn't leave junk in the proto_tree. */
3268 | /* XXX. wouldn't be better to add this item to tree, with some special
3269 | * flag (FI_EXCEPTION?) to know which item caused exception? For
3270 | * strings and bytes, we would have to set new_fi->value to something
3271 | * non-NULL, or otherwise ensure that proto_item_fill_display_label
3272 | * could handle NULL values. */
3273 | CLEANUP_POPexcept_pop(); if (0) except_cl.except_func(except_cl.except_context ); }
3274 | pi = proto_tree_add_node(tree, new_fi);
3275 |
3276 | switch (new_fi->hfinfo->type) {
3277 |
3278 | case FT_STRING:
3279 | /* XXX: trailing stray character detection should be done
3280 | * _before_ conversion to UTF-8, because conversion can change
3281 | * the length, or else get_string_length should return a value
3282 | * for the "length in bytes of the string after conversion
3283 | * including internal nulls." (Noting that we do, for other
3284 | * reasons, still need the "length in bytes in the field",
3285 | * especially for FT_STRINGZ.)
3286 | *
3287 | * This is true even for ASCII and UTF-8, because
3288 | * substituting REPLACEMENT CHARACTERS for illegal characters
3289 | * can also do so (and for UTF-8 possibly even make the
3290 | * string _shorter_).
3291 | */
3292 | detect_trailing_stray_characters(encoding, stringval, length, pi);
3293 | break;
3294 |
3295 | default:
3296 | break;
3297 | }
3298 |
3299 | return pi;
3300 | }
3301 |
3302 | proto_item *
3303 | proto_tree_add_item_ret_int(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3304 | const int start, int length,
3305 | const unsigned encoding, int32_t *retval)
3306 | {
3307 | header_field_info *hfinfo;
3308 | field_info *new_fi;
3309 | int32_t value;
3310 |
3311 | 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", 3311, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3311, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3311, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3312 |
3313 | switch (hfinfo->type) {
3314 | case FT_INT8:
3315 | case FT_INT16:
3316 | case FT_INT24:
3317 | case FT_INT32:
3318 | break;
3319 | case FT_INT64:
3320 | 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)
3321 | hfinfo->abbrev)proto_report_dissector_bug("64-bit signed integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3322 | default:
3323 | 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)
3324 | hfinfo->abbrev)proto_report_dissector_bug("Non-signed-integer field %s used with proto_tree_add_item_ret_int()" , hfinfo->abbrev);
3325 | }
3326 |
3327 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3328 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3329 | if(retval)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 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3332 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3333 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3334 |
3335 | if (encoding & ENC_STRING0x03000000) {
3336 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3337 | }
3338 | /* I believe it's ok if this is called with a NULL tree */
3339 | value = get_int_value(tree, tvb, start, length, encoding);
3340 |
3341 | if (retval) {
3342 | int no_of_bits;
3343 | *retval = value;
3344 | if (hfinfo->bitmask) {
3345 | /* Mask out irrelevant portions */
3346 | *retval &= (uint32_t)(hfinfo->bitmask);
3347 | /* Shift bits */
3348 | *retval >>= hfinfo_bitshift(hfinfo);
3349 | }
3350 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3351 | *retval = ws_sign_ext32(*retval, no_of_bits);
3352 | }
3353 |
3354 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3355 |
3356 | 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", 3356 , __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", 3356, "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", 3356, "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", 3356, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3357 |
3358 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3359 |
3360 | proto_tree_set_int(new_fi, value);
3361 |
3362 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3363 |
3364 | return proto_tree_add_node(tree, new_fi);
3365 | }
3366 |
3367 | proto_item *
3368 | proto_tree_add_item_ret_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3369 | const int start, int length,
3370 | const unsigned encoding, uint32_t *retval)
3371 | {
3372 | header_field_info *hfinfo;
3373 | field_info *new_fi;
3374 | uint32_t value;
3375 |
3376 | 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", 3376, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3376, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3376, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3377 |
3378 | switch (hfinfo->type) {
3379 | case FT_CHAR:
3380 | case FT_UINT8:
3381 | case FT_UINT16:
3382 | case FT_UINT24:
3383 | case FT_UINT32:
3384 | break;
3385 | default:
3386 | 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)
3387 | 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);
3388 | }
3389 |
3390 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3391 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3392 | if(retval)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 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3395 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3396 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3397 |
3398 | if (encoding & ENC_STRING0x03000000) {
3399 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3400 | }
3401 | /* I believe it's ok if this is called with a NULL tree */
3402 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3403 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3404 | uint64_t temp64;
3405 | tvb_get_varint(tvb, start, length, &temp64, encoding);
3406 | value = (uint32_t)temp64;
3407 | } else {
3408 | value = get_uint_value(tree, tvb, start, length, encoding);
3409 | }
3410 |
3411 | if (retval) {
3412 | *retval = value;
3413 | if (hfinfo->bitmask) {
3414 | /* Mask out irrelevant portions */
3415 | *retval &= (uint32_t)(hfinfo->bitmask);
3416 | /* Shift bits */
3417 | *retval >>= hfinfo_bitshift(hfinfo);
3418 | }
3419 | }
3420 |
3421 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3422 |
3423 | 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", 3423 , __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", 3423, "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", 3423, "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", 3423, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3424 |
3425 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3426 |
3427 | proto_tree_set_uint(new_fi, value);
3428 |
3429 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3430 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3431 | new_fi->flags |= FI_VARINT0x00040000;
3432 | }
3433 | return proto_tree_add_node(tree, new_fi);
3434 | }
3435 |
3436 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3437 | * and returns proto_item* and uint value retrieved*/
3438 | proto_item *
3439 | ptvcursor_add_ret_uint(ptvcursor_t *ptvc, int hfindex, int length,
3440 | const unsigned encoding, uint32_t *retval)
3441 | {
3442 | field_info *new_fi;
3443 | header_field_info *hfinfo;
3444 | int item_length;
3445 | int offset;
3446 | uint32_t value;
3447 |
3448 | offset = ptvc->offset;
3449 | 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", 3449, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3449, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3449, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3450 |
3451 | switch (hfinfo->type) {
3452 | case FT_CHAR:
3453 | case FT_UINT8:
3454 | case FT_UINT16:
3455 | case FT_UINT24:
3456 | case FT_UINT32:
3457 | break;
3458 | default:
3459 | 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)
3460 | 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);
3461 | }
3462 |
3463 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3464 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3465 |
3466 | /* I believe it's ok if this is called with a NULL tree */
3467 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3468 | value = get_uint_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3469 |
3470 | if (retval) {
3471 | *retval = value;
3472 | if (hfinfo->bitmask) {
3473 | /* Mask out irrelevant portions */
3474 | *retval &= (uint32_t)(hfinfo->bitmask);
3475 | /* Shift bits */
3476 | *retval >>= hfinfo_bitshift(hfinfo);
3477 | }
3478 | }
3479 |
3480 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3481 |
3482 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3483 |
3484 | /* Coast clear. Try and fake it */
3485 | 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", 3485 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3485, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3485, "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", 3485, __func__, "Adding %s would put more than %d 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); } } };
3486 |
3487 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3488 |
3489 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3490 | offset, length, encoding);
3491 | }
3492 |
3493 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3494 | * and returns proto_item* and int value retrieved*/
3495 | proto_item *
3496 | ptvcursor_add_ret_int(ptvcursor_t *ptvc, int hfindex, int length,
3497 | const unsigned encoding, int32_t *retval)
3498 | {
3499 | field_info *new_fi;
3500 | header_field_info *hfinfo;
3501 | int item_length;
3502 | int offset;
3503 | uint32_t value;
3504 |
3505 | offset = ptvc->offset;
3506 | 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", 3506, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3506, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3506, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3507 |
3508 | switch (hfinfo->type) {
3509 | case FT_INT8:
3510 | case FT_INT16:
3511 | case FT_INT24:
3512 | case FT_INT32:
3513 | break;
3514 | default:
3515 | 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)
3516 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
3517 | }
3518 |
3519 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3520 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3521 |
3522 | /* I believe it's ok if this is called with a NULL tree */
3523 | /* XXX - modify if we ever support EBCDIC FT_CHAR */
3524 | value = get_int_value(ptvc->tree, ptvc->tvb, offset, item_length, encoding);
3525 |
3526 | if (retval) {
3527 | int no_of_bits;
3528 | *retval = value;
3529 | if (hfinfo->bitmask) {
3530 | /* Mask out irrelevant portions */
3531 | *retval &= (uint32_t)(hfinfo->bitmask);
3532 | /* Shift bits */
3533 | *retval >>= hfinfo_bitshift(hfinfo);
3534 | }
3535 | no_of_bits = ws_count_ones(hfinfo->bitmask);
3536 | *retval = ws_sign_ext32(*retval, no_of_bits);
3537 | }
3538 |
3539 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3540 |
3541 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3542 |
3543 | /* Coast clear. Try and fake it */
3544 | 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", 3544 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3544, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3544, "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", 3544, __func__, "Adding %s would put more than %d 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); } } };
3545 |
3546 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3547 |
3548 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3549 | offset, length, encoding);
3550 | }
3551 |
3552 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3553 | * and returns proto_item* and string value retrieved */
3554 | proto_item*
3555 | ptvcursor_add_ret_string(ptvcursor_t* ptvc, int hf, int length, const unsigned encoding, wmem_allocator_t *scope, const uint8_t **retval)
3556 | {
3557 | header_field_info *hfinfo;
3558 | field_info *new_fi;
3559 | const uint8_t *value;
3560 | int item_length;
3561 | int offset;
3562 |
3563 | offset = ptvc->offset;
3564 |
3565 | 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", 3565 , __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", 3565, "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", 3565, "gpa_hfinfo.hfi[hf] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[hf];;
3566 |
3567 | switch (hfinfo->type) {
3568 | case FT_STRING:
3569 | value = get_string_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3570 | break;
3571 | case FT_STRINGZ:
3572 | value = get_stringz_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3573 | break;
3574 | case FT_UINT_STRING:
3575 | value = get_uint_string_value(scope, ptvc->tree, ptvc->tvb, offset, length, &item_length, encoding);
3576 | break;
3577 | case FT_STRINGZPAD:
3578 | value = get_stringzpad_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3579 | break;
3580 | case FT_STRINGZTRUNC:
3581 | value = get_stringztrunc_value(scope, ptvc->tvb, offset, length, &item_length, encoding);
3582 | break;
3583 | default:
3584 | 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)
3585 | 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);
3586 | }
3587 |
3588 | if (retval)
3589 | *retval = value;
3590 |
3591 | ptvcursor_advance(ptvc, item_length);
3592 |
3593 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3594 |
3595 | 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", 3595, __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", 3595, "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", 3595, "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", 3595 , __func__, "Adding %s would put more than %d 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); } } };
3596 |
3597 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3598 |
3599 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3600 | offset, length, encoding);
3601 | }
3602 |
3603 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
3604 | * and returns proto_item* and boolean value retrieved */
3605 | proto_item*
3606 | ptvcursor_add_ret_boolean(ptvcursor_t* ptvc, int hfindex, int length, const unsigned encoding, bool_Bool *retval)
3607 | {
3608 | header_field_info *hfinfo;
3609 | field_info *new_fi;
3610 | int item_length;
3611 | int offset;
3612 | uint64_t value, bitval;
3613 |
3614 | offset = ptvc->offset;
3615 | 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", 3615, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3615, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3615, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3616 |
3617 | if (hfinfo->type != FT_BOOLEAN) {
3618 | 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)
3619 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3620 | }
3621 |
3622 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3623 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3624 | if(retval)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 | *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3627 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3628 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3629 |
3630 | if (encoding & ENC_STRING0x03000000) {
3631 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3632 | }
3633 |
3634 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
3635 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
3636 |
3637 | /* I believe it's ok if this is called with a NULL tree */
3638 | value = get_uint64_value(ptvc->tree, ptvc->tvb, offset, length, encoding);
3639 |
3640 | if (retval) {
3641 | bitval = value;
3642 | if (hfinfo->bitmask) {
3643 | /* Mask out irrelevant portions */
3644 | bitval &= hfinfo->bitmask;
3645 | }
3646 | *retval = (bitval != 0);
3647 | }
3648 |
3649 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
3650 |
3651 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
3652 |
3653 | 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", 3653, __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", 3653, "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", 3653, "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", 3653 , __func__, "Adding %s would put more than %d 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); } } };
3654 |
3655 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
3656 |
3657 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
3658 | offset, length, encoding);
3659 | }
3660 |
3661 | proto_item *
3662 | proto_tree_add_item_ret_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3663 | const int start, int length, const unsigned encoding, uint64_t *retval)
3664 | {
3665 | header_field_info *hfinfo;
3666 | field_info *new_fi;
3667 | uint64_t value;
3668 |
3669 | 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", 3669, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3669, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3669, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3670 |
3671 | switch (hfinfo->type) {
3672 | case FT_UINT40:
3673 | case FT_UINT48:
3674 | case FT_UINT56:
3675 | case FT_UINT64:
3676 | break;
3677 | default:
3678 | 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)
3679 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT40, FT_UINT48, FT_UINT56, or FT_UINT64" , hfinfo->abbrev);
3680 | }
3681 |
3682 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3683 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3684 | if(retval)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 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3687 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3688 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3689 |
3690 | if (encoding & ENC_STRING0x03000000) {
3691 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3692 | }
3693 | /* I believe it's ok if this is called with a NULL tree */
3694 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3695 | tvb_get_varint(tvb, start, length, &value, encoding);
3696 | } else {
3697 | value = get_uint64_value(tree, tvb, start, length, encoding);
3698 | }
3699 |
3700 | if (retval) {
3701 | *retval = value;
3702 | if (hfinfo->bitmask) {
3703 | /* Mask out irrelevant portions */
3704 | *retval &= hfinfo->bitmask;
3705 | /* Shift bits */
3706 | *retval >>= hfinfo_bitshift(hfinfo);
3707 | }
3708 | }
3709 |
3710 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3711 |
3712 | 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", 3712 , __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", 3712, "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", 3712, "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", 3712, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3713 |
3714 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3715 |
3716 | proto_tree_set_uint64(new_fi, value);
3717 |
3718 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3719 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3720 | new_fi->flags |= FI_VARINT0x00040000;
3721 | }
3722 |
3723 | return proto_tree_add_node(tree, new_fi);
3724 | }
3725 |
3726 | proto_item *
3727 | proto_tree_add_item_ret_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3728 | const int start, int length, const unsigned encoding, int64_t *retval)
3729 | {
3730 | header_field_info *hfinfo;
3731 | field_info *new_fi;
3732 | int64_t value;
3733 |
3734 | PROTO_REGISTRAR_GET_NTH(hfindex, hfinfo)if((hfindex == 0 || (unsigned)hfindex > gpa_hfinfo.len) && wireshark_abort_on_dissector_bug) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 3734, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3734, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3734, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3735 |
3736 | switch (hfinfo->type) {
3737 | case FT_INT40:
3738 | case FT_INT48:
3739 | case FT_INT56:
3740 | case FT_INT64:
3741 | break;
3742 | default:
3743 | 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)
3744 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
3745 | }
3746 |
3747 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3748 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3749 | if(retval)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 | *retval = 0;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3752 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3753 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3754 |
3755 | if (encoding & ENC_STRING0x03000000) {
3756 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3757 | }
3758 | /* I believe it's ok if this is called with a NULL tree */
3759 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
3760 | tvb_get_varint(tvb, start, length, (uint64_t*)&value, encoding);
3761 | }
3762 | else {
3763 | value = get_int64_value(tree, tvb, start, length, encoding);
3764 | }
3765 |
3766 | if (retval) {
3767 | *retval = value;
3768 | }
3769 |
3770 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3771 |
3772 | 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", 3772 , __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", 3772, "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", 3772, "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", 3772, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3773 |
3774 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3775 |
3776 | proto_tree_set_int64(new_fi, value);
3777 |
3778 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3779 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3780 | new_fi->flags |= FI_VARINT0x00040000;
3781 | }
3782 |
3783 | return proto_tree_add_node(tree, new_fi);
3784 | }
3785 |
3786 | proto_item *
3787 | proto_tree_add_item_ret_varint(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3788 | const int start, int length, const unsigned encoding, uint64_t *retval, int *lenretval)
3789 | {
3790 | header_field_info *hfinfo;
3791 | field_info *new_fi;
3792 | uint64_t value;
3793 |
3794 | 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", 3794, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3794, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3794, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3795 |
3796 | 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 )))) {
3797 | 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)
3798 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT or FT_INT" , hfinfo->abbrev);
3799 | }
3800 |
3801 | /* length validation for native number encoding caught by get_uint64_value() */
3802 | /* length has to be -1 or > 0 regardless of encoding */
3803 | if (length == 0)
3804 | 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)
3805 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_varint" , length);
3806 |
3807 | if (encoding & ENC_STRING0x03000000) {
3808 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3809 | }
3810 |
3811 | length = tvb_get_varint(tvb, start, (length == -1) ? FT_VARINT_MAX_LEN10 : length, &value, encoding);
3812 |
3813 | if (retval) {
3814 | *retval = value;
3815 | if (hfinfo->bitmask) {
3816 | /* Mask out irrelevant portions */
3817 | *retval &= hfinfo->bitmask;
3818 | /* Shift bits */
3819 | *retval >>= hfinfo_bitshift(hfinfo);
3820 | }
3821 | }
3822 |
3823 | if (lenretval) {
3824 | *lenretval = length;
3825 | }
3826 |
3827 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3828 |
3829 | 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", 3829 , __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", 3829, "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", 3829, "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", 3829, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3830 |
3831 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3832 |
3833 | proto_tree_set_uint64(new_fi, value);
3834 |
3835 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3836 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
3837 | new_fi->flags |= FI_VARINT0x00040000;
3838 | }
3839 |
3840 | return proto_tree_add_node(tree, new_fi);
3841 |
3842 | }
3843 |
3844 | proto_item *
3845 | proto_tree_add_item_ret_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3846 | const int start, int length,
3847 | const unsigned encoding, bool_Bool *retval)
3848 | {
3849 | header_field_info *hfinfo;
3850 | field_info *new_fi;
3851 | uint64_t value, bitval;
3852 |
3853 | 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", 3853, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3853, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3853, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3854 |
3855 | if (hfinfo->type != FT_BOOLEAN) {
3856 | 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)
3857 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BOOLEAN" , hfinfo->abbrev);
3858 | }
3859 |
3860 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3861 | {if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3862 | if(retval)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 | *retval = false;if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3865 | }if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); }
3866 | } )if (length < -1 || length == 0 ) { { if(retval) { *retval = 0; } }; return ((void*)0); };
3867 |
3868 | if (encoding & ENC_STRING0x03000000) {
3869 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3870 | }
3871 | /* I believe it's ok if this is called with a NULL tree */
3872 | value = get_uint64_value(tree, tvb, start, length, encoding);
3873 |
3874 | if (retval) {
3875 | bitval = value;
3876 | if (hfinfo->bitmask) {
3877 | /* Mask out irrelevant portions */
3878 | bitval &= hfinfo->bitmask;
3879 | }
3880 | *retval = (bitval != 0);
3881 | }
3882 |
3883 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3884 |
3885 | 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", 3885 , __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", 3885, "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", 3885, "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", 3885, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3886 |
3887 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3888 |
3889 | proto_tree_set_boolean(new_fi, value);
3890 |
3891 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
3892 |
3893 | return proto_tree_add_node(tree, new_fi);
3894 | }
3895 |
3896 | proto_item *
3897 | proto_tree_add_item_ret_float(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3898 | const int start, int length,
3899 | const unsigned encoding, float *retval)
3900 | {
3901 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3902 | field_info *new_fi;
3903 | float value;
3904 |
3905 | 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", 3905, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3906 |
3907 | if (hfinfo->type != FT_FLOAT) {
3908 | 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);
3909 | }
3910 |
3911 | if (length != 4) {
3912 | report_type_length_mismatch(tree, "a single-precision floating point number", length, true1);
3913 | }
3914 |
3915 | /* treat any nonzero encoding as little endian for backwards compatibility */
3916 | value = encoding ? tvb_get_letohieee_float(tvb, start) : tvb_get_ntohieee_float(tvb, start);
3917 | if (retval) {
3918 | *retval = value;
3919 | }
3920 |
3921 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3922 |
3923 | 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", 3923 , __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", 3923, "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", 3923, "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", 3923, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3924 |
3925 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3926 | if (encoding) {
3927 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3928 | }
3929 |
3930 | proto_tree_set_float(new_fi, value);
3931 |
3932 | return proto_tree_add_node(tree, new_fi);
3933 | }
3934 |
3935 | proto_item *
3936 | proto_tree_add_item_ret_double(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3937 | const int start, int length,
3938 | const unsigned encoding, double *retval)
3939 | {
3940 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
3941 | field_info *new_fi;
3942 | double value;
3943 |
3944 | 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", 3944, "hfinfo != ((void*)0)", "Not passed hfi!"))));
3945 |
3946 | if (hfinfo->type != FT_DOUBLE) {
3947 | 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);
3948 | }
3949 |
3950 | if (length != 8) {
3951 | report_type_length_mismatch(tree, "a double-precision floating point number", length, true1);
3952 | }
3953 |
3954 | /* treat any nonzero encoding as little endian for backwards compatibility */
3955 | value = encoding ? tvb_get_letohieee_double(tvb, start) : tvb_get_ntohieee_double(tvb, start);
3956 | if (retval) {
3957 | *retval = value;
3958 | }
3959 |
3960 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
3961 |
3962 | 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", 3962 , __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", 3962, "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", 3962, "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", 3962, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
3963 |
3964 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
3965 | if (encoding) {
3966 | new_fi->flags |= FI_LITTLE_ENDIAN0x00000008;
3967 | }
3968 |
3969 | proto_tree_set_double(new_fi, value);
3970 |
3971 | return proto_tree_add_node(tree, new_fi);
3972 | }
3973 |
3974 | proto_item *
3975 | proto_tree_add_item_ret_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb,
3976 | const int start, int length,
3977 | const unsigned encoding, ws_in4_addr *retval)
3978 | {
3979 | header_field_info *hfinfo;
3980 | field_info *new_fi;
3981 | ws_in4_addr value;
3982 |
3983 | 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", 3983, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 3983, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 3983, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
3984 |
3985 | switch (hfinfo->type) {
3986 | case FT_IPv4:
3987 | break;
3988 | default:
3989 | 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)
3990 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv4", hfinfo->abbrev);
3991 | }
3992 |
3993 | if (length != FT_IPv4_LEN4)
3994 | 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)
3995 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv4" , length);
3996 |
3997 | if (encoding & (ENC_STRING0x03000000 | ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010))) {
3998 | REPORT_DISSECTOR_BUG("wrong encoding")proto_report_dissector_bug("wrong encoding");
3999 | }
4000 |
4001 | /*
4002 | * NOTE: to support code written when proto_tree_add_item() took
4003 | * a bool as its last argument, with false meaning "big-endian"
4004 | * and true meaning "little-endian", we treat any non-zero value
4005 | * of "encoding" as meaning "little-endian".
4006 | */
4007 | value = tvb_get_ipv4(tvb, start);
4008 | if (encoding)
4009 | 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))));
4010 |
4011 | if (retval) {
4012 | *retval = value;
4013 | }
4014 |
4015 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4016 |
4017 | 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", 4017 , __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", 4017, "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", 4017, "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", 4017, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4018 |
4019 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4020 |
4021 | proto_tree_set_ipv4(new_fi, value);
4022 |
4023 | new_fi->flags |= encoding ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4024 | return proto_tree_add_node(tree, new_fi);
4025 | }
4026 |
4027 | proto_item *
4028 | proto_tree_add_item_ret_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4029 | const int start, int length,
4030 | const unsigned encoding, ws_in6_addr *addr)
4031 | {
4032 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4033 | field_info *new_fi;
4034 |
4035 | 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", 4035, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4036 |
4037 | switch (hfinfo->type) {
4038 | case FT_IPv6:
4039 | break;
4040 | default:
4041 | 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)
4042 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_IPv6", hfinfo->abbrev);
4043 | }
4044 |
4045 | if (length != FT_IPv6_LEN16)
4046 | 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)
4047 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ipv6" , length);
4048 |
4049 | if (encoding) {
4050 | 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" );
4051 | }
4052 |
4053 | tvb_get_ipv6(tvb, start, addr);
4054 |
4055 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4056 |
4057 | 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", 4057 , __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", 4057, "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", 4057, "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", 4057, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4058 |
4059 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4060 |
4061 | proto_tree_set_ipv6(new_fi, addr);
4062 |
4063 | return proto_tree_add_node(tree, new_fi);
4064 | }
4065 |
4066 | proto_item *
4067 | proto_tree_add_item_ret_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4068 | const int start, int length, const unsigned encoding, uint8_t *retval) {
4069 |
4070 | header_field_info *hfinfo = proto_registrar_get_nth(hfindex);
4071 | field_info *new_fi;
4072 |
4073 | 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", 4073, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4074 |
4075 | switch (hfinfo->type) {
4076 | case FT_ETHER:
4077 | break;
4078 | default:
4079 | 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)
4080 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ETHER" , hfinfo->abbrev);
4081 | }
4082 |
4083 | if (length != FT_ETHER_LEN6)
4084 | 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)
4085 | length)proto_report_dissector_bug("Invalid length %d passed to proto_tree_add_item_ret_ether" , length);
4086 |
4087 | if (encoding) {
4088 | 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" );
4089 | }
4090 |
4091 | tvb_memcpy(tvb, retval, start, length);
4092 |
4093 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4094 |
4095 | 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", 4095 , __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", 4095, "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", 4095, "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", 4095, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4096 |
4097 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4098 |
4099 | proto_tree_set_ether(new_fi, retval);
4100 |
4101 | return proto_tree_add_node(tree, new_fi);
4102 | }
4103 |
4104 |
4105 | proto_item *
4106 | proto_tree_add_item_ret_string_and_length(proto_tree *tree, int hfindex,
4107 | tvbuff_t *tvb,
4108 | const int start, int length,
4109 | const unsigned encoding,
4110 | wmem_allocator_t *scope,
4111 | const uint8_t **retval,
4112 | int *lenretval)
4113 | {
4114 | proto_item *pi;
4115 | header_field_info *hfinfo;
4116 | field_info *new_fi;
4117 | const uint8_t *value;
4118 |
4119 | 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", 4119, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4119, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4119, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4120 |
4121 | switch (hfinfo->type) {
4122 | case FT_STRING:
4123 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4124 | break;
4125 | case FT_STRINGZ:
4126 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4127 | break;
4128 | case FT_UINT_STRING:
4129 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4130 | break;
4131 | case FT_STRINGZPAD:
4132 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4133 | break;
4134 | case FT_STRINGZTRUNC:
4135 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4136 | break;
4137 | default:
4138 | 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)
4139 | 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);
4140 | }
4141 |
4142 | if (retval)
4143 | *retval = value;
4144 |
4145 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4146 |
4147 | 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", 4147 , __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", 4147, "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", 4147, "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", 4147, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4148 |
4149 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4150 |
4151 | proto_tree_set_string(new_fi, (const char*)value);
4152 |
4153 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4154 |
4155 | pi = proto_tree_add_node(tree, new_fi);
4156 |
4157 | switch (hfinfo->type) {
4158 |
4159 | case FT_STRINGZ:
4160 | case FT_STRINGZPAD:
4161 | case FT_STRINGZTRUNC:
4162 | case FT_UINT_STRING:
4163 | break;
4164 |
4165 | case FT_STRING:
4166 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4167 | break;
4168 |
4169 | default:
4170 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4170 , __func__, "assertion \"not reached\" failed");
4171 | }
4172 |
4173 | return pi;
4174 | }
4175 |
4176 | proto_item *
4177 | proto_tree_add_item_ret_string(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4178 | const int start, int length,
4179 | const unsigned encoding, wmem_allocator_t *scope,
4180 | const uint8_t **retval)
4181 | {
4182 | return proto_tree_add_item_ret_string_and_length(tree, hfindex,
4183 | tvb, start, length, encoding, scope, retval, &length);
4184 | }
4185 |
4186 | proto_item *
4187 | proto_tree_add_item_ret_display_string_and_length(proto_tree *tree, int hfindex,
4188 | tvbuff_t *tvb,
4189 | const int start, int length,
4190 | const unsigned encoding,
4191 | wmem_allocator_t *scope,
4192 | char **retval,
4193 | int *lenretval)
4194 | {
4195 | proto_item *pi;
4196 | header_field_info *hfinfo;
4197 | field_info *new_fi;
4198 | const uint8_t *value;
4199 | uint32_t n = 0;
4200 |
4201 | 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", 4201, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4201, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4201, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4202 |
4203 | switch (hfinfo->type) {
4204 | case FT_STRING:
4205 | value = get_string_value(scope, tvb, start, length, lenretval, encoding);
4206 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4207 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4208 | break;
4209 | case FT_STRINGZ:
4210 | value = get_stringz_value(scope, tree, tvb, start, length, lenretval, encoding);
4211 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4212 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4213 | break;
4214 | case FT_UINT_STRING:
4215 | value = get_uint_string_value(scope, tree, tvb, start, length, lenretval, encoding);
4216 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4217 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4218 | break;
4219 | case FT_STRINGZPAD:
4220 | value = get_stringzpad_value(scope, tvb, start, length, lenretval, encoding);
4221 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4222 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4223 | break;
4224 | case FT_STRINGZTRUNC:
4225 | value = get_stringztrunc_value(scope, tvb, start, length, lenretval, encoding);
4226 | *retval = wmem_alloc(scope, ITEM_LABEL_LENGTH240);
4227 | ws_label_strcpy(*retval, ITEM_LABEL_LENGTH240, 0, value, label_strcat_flags(hfinfo));
4228 | break;
4229 | case FT_BYTES:
4230 | tvb_ensure_bytes_exist(tvb, start, length);
4231 | value = tvb_get_ptr(tvb, start, length);
4232 | *retval = format_bytes_hfinfo(scope, hfinfo, value, length);
4233 | *lenretval = length;
4234 | break;
4235 | case FT_UINT_BYTES:
4236 | n = get_uint_value(tree, tvb, start, length, encoding);
4237 | tvb_ensure_bytes_exist(tvb, start + length, n);
4238 | value = tvb_get_ptr(tvb, start + length, n);
4239 | *retval = format_bytes_hfinfo(scope, hfinfo, value, n);
4240 | *lenretval = length + n;
4241 | break;
4242 | default:
4243 | 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)
4244 | 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);
4245 | }
4246 |
4247 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4248 |
4249 | 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", 4249 , __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", 4249, "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", 4249, "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", 4249, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4250 |
4251 | new_fi = new_field_info(tree, hfinfo, tvb, start, *lenretval);
4252 |
4253 | switch (hfinfo->type) {
4254 |
4255 | case FT_STRING:
4256 | case FT_STRINGZ:
4257 | case FT_UINT_STRING:
4258 | case FT_STRINGZPAD:
4259 | case FT_STRINGZTRUNC:
4260 | proto_tree_set_string(new_fi, (const char*)value);
4261 | break;
4262 |
4263 | case FT_BYTES:
4264 | proto_tree_set_bytes(new_fi, value, length);
4265 | break;
4266 |
4267 | case FT_UINT_BYTES:
4268 | proto_tree_set_bytes(new_fi, value, n);
4269 | break;
4270 |
4271 | default:
4272 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4272 , __func__, "assertion \"not reached\" failed");
4273 | }
4274 |
4275 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4276 |
4277 | pi = proto_tree_add_node(tree, new_fi);
4278 |
4279 | switch (hfinfo->type) {
4280 |
4281 | case FT_STRINGZ:
4282 | case FT_STRINGZPAD:
4283 | case FT_STRINGZTRUNC:
4284 | case FT_UINT_STRING:
4285 | break;
4286 |
4287 | case FT_STRING:
4288 | detect_trailing_stray_characters(encoding, (const char*)value, length, pi);
4289 | break;
4290 |
4291 | case FT_BYTES:
4292 | case FT_UINT_BYTES:
4293 | break;
4294 |
4295 | default:
4296 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4296 , __func__, "assertion \"not reached\" failed");
4297 | }
4298 |
4299 | return pi;
4300 | }
4301 |
4302 | proto_item *
4303 | proto_tree_add_item_ret_display_string(proto_tree *tree, int hfindex,
4304 | tvbuff_t *tvb,
4305 | const int start, int length,
4306 | const unsigned encoding,
4307 | wmem_allocator_t *scope,
4308 | char **retval)
4309 | {
4310 | return proto_tree_add_item_ret_display_string_and_length(tree, hfindex,
4311 | tvb, start, length, encoding, scope, retval, &length);
4312 | }
4313 |
4314 | proto_item *
4315 | proto_tree_add_item_ret_time_string(proto_tree *tree, int hfindex,
4316 | tvbuff_t *tvb,
4317 | const int start, int length, const unsigned encoding,
4318 | wmem_allocator_t *scope, char **retval)
4319 | {
4320 | header_field_info *hfinfo;
4321 | field_info *new_fi;
4322 | nstime_t time_stamp;
4323 | int flags;
4324 |
4325 | 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", 4325, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4325, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4325, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4326 |
4327 | switch (hfinfo->type) {
4328 | case FT_ABSOLUTE_TIME:
4329 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, false0);
4330 | flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
4331 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
4332 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
4333 | }
4334 | *retval = abs_time_to_str_ex(scope, &time_stamp, hfinfo->display, flags);
4335 | break;
4336 | case FT_RELATIVE_TIME:
4337 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, true1);
4338 | *retval = rel_time_to_secs_str(scope, &time_stamp);
4339 | break;
4340 | default:
4341 | 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)
4342 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_ABSOLUTE_TIME or FT_RELATIVE_TIME" , hfinfo->abbrev);
4343 | }
4344 |
4345 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4346 |
4347 | 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", 4347 , __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", 4347, "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", 4347, "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", 4347, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4348 |
4349 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4350 |
4351 | switch (hfinfo->type) {
4352 |
4353 | case FT_ABSOLUTE_TIME:
4354 | case FT_RELATIVE_TIME:
4355 | proto_tree_set_time(new_fi, &time_stamp);
4356 | break;
4357 | default:
4358 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 4358 , __func__, "assertion \"not reached\" failed");
4359 | }
4360 |
4361 | new_fi->flags |= (encoding & ENC_LITTLE_ENDIAN0x80000000) ? FI_LITTLE_ENDIAN0x00000008 : FI_BIG_ENDIAN0x00000010;
4362 |
4363 | return proto_tree_add_node(tree, new_fi);
4364 | }
4365 |
4366 | /* Gets data from tvbuff, adds it to proto_tree, increments offset,
4367 | and returns proto_item* */
4368 | proto_item *
4369 | ptvcursor_add(ptvcursor_t *ptvc, int hfindex, int length,
4370 | const unsigned encoding)
4371 | {
4372 | field_info *new_fi;
4373 | header_field_info *hfinfo;
4374 | int item_length;
4375 | int offset;
4376 |
4377 | offset = ptvc->offset;
4378 | 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", 4378, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4378, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4378, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4379 | get_hfi_length(hfinfo, ptvc->tvb, offset, &length, &item_length, encoding);
4380 | test_length(hfinfo, ptvc->tvb, offset, item_length, encoding);
4381 |
4382 | ptvcursor_advance(ptvc, get_full_length(hfinfo, ptvc->tvb, offset, length, item_length, encoding));
4383 |
4384 | CHECK_FOR_NULL_TREE(ptvc->tree)if (!ptvc->tree) { ((void)0); return ((void*)0); };
4385 |
4386 | /* Coast clear. Try and fake it */
4387 | 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", 4387 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4387, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4387, "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", 4387, __func__, "Adding %s would put more than %d 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); } } };
4388 |
4389 | new_fi = new_field_info(ptvc->tree, hfinfo, ptvc->tvb, offset, item_length);
4390 |
4391 | return proto_tree_new_item(new_fi, ptvc->tree, ptvc->tvb,
4392 | offset, length, encoding);
4393 | }
4394 |
4395 | /* Add an item to a proto_tree, using the text label registered to that item;
4396 | the item is extracted from the tvbuff handed to it. */
4397 | proto_item *
4398 | proto_tree_add_item_new(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
4399 | const int start, int length, const unsigned encoding)
4400 | {
4401 | field_info *new_fi;
4402 | int item_length;
4403 |
4404 | 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", 4404, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4405 |
4406 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4407 | test_length(hfinfo, tvb, start, item_length, encoding);
4408 |
4409 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4410 |
4411 | 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", 4411 , __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", 4411, "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", 4411, "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", 4411, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4412 |
4413 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4414 |
4415 | return proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4416 | }
4417 |
4418 | proto_item *
4419 | proto_tree_add_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4420 | const int start, int length, const unsigned encoding)
4421 | {
4422 | register header_field_info *hfinfo;
4423 |
4424 | 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", 4424, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4424, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4424, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4425 | return proto_tree_add_item_new(tree, hfinfo, tvb, start, length, encoding);
4426 | }
4427 |
4428 | /* Add an item to a proto_tree, using the text label registered to that item;
4429 | the item is extracted from the tvbuff handed to it.
4430 |
4431 | Return the length of the item through the pointer. */
4432 | proto_item *
4433 | proto_tree_add_item_new_ret_length(proto_tree *tree, header_field_info *hfinfo,
4434 | tvbuff_t *tvb, const int start,
4435 | int length, const unsigned encoding,
4436 | int *lenretval)
4437 | {
4438 | field_info *new_fi;
4439 | int item_length;
4440 | proto_item *item;
4441 |
4442 | 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", 4442, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4443 |
4444 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, encoding);
4445 | test_length(hfinfo, tvb, start, item_length, encoding);
4446 |
4447 | if (!tree) {
4448 | /*
4449 | * We need to get the correct item length here.
4450 | * That's normally done by proto_tree_new_item(),
4451 | * but we won't be calling it.
4452 | */
4453 | *lenretval = get_full_length(hfinfo, tvb, start, length,
4454 | item_length, encoding);
4455 | return NULL((void*)0);
4456 | }
4457 |
4458 | 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", 4465 , __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", 4465, "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", 4465, "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", 4465 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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", 4465 , __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", 4465, "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", 4465, "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", 4465 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 | * 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", 4465 , __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", 4465, "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", 4465, "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", 4465 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 | * 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", 4465 , __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", 4465, "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", 4465, "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", 4465 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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", 4465 , __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", 4465, "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", 4465, "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", 4465 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 | *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", 4465 , __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", 4465, "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", 4465, "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", 4465 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { *lenretval = get_full_length(hfinfo, tvb, start, length , item_length, encoding); }; return proto_tree_add_fake_node( tree, hfinfo); } } }
4464 | 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", 4465 , __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", 4465, "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", 4465, "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", 4465 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4465 | })((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", 4465 , __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", 4465, "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", 4465, "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", 4465 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } };
4466 |
4467 | new_fi = new_field_info(tree, hfinfo, tvb, start, item_length);
4468 |
4469 | item = proto_tree_new_item(new_fi, tree, tvb, start, length, encoding);
4470 | *lenretval = new_fi->length;
4471 | return item;
4472 | }
4473 |
4474 | proto_item *
4475 | proto_tree_add_item_ret_length(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4476 | const int start, int length,
4477 | const unsigned encoding, int *lenretval)
4478 | {
4479 | register header_field_info *hfinfo;
4480 |
4481 | 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", 4481, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4481, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4481, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4482 | return proto_tree_add_item_new_ret_length(tree, hfinfo, tvb, start, length, encoding, lenretval);
4483 | }
4484 |
4485 | /* which FT_ types can use proto_tree_add_bytes_item() */
4486 | static inline bool_Bool
4487 | validate_proto_tree_add_bytes_ftype(const enum ftenum type)
4488 | {
4489 | return (type == FT_BYTES ||
4490 | type == FT_UINT_BYTES ||
4491 | type == FT_OID ||
4492 | type == FT_REL_OID ||
4493 | type == FT_SYSTEM_ID );
4494 | }
4495 |
4496 | /* Note: this does no validation that the byte array of an FT_OID or
4497 | FT_REL_OID is actually valid; and neither does proto_tree_add_item(),
4498 | so I think it's ok to continue not validating it?
4499 | */
4500 | proto_item *
4501 | proto_tree_add_bytes_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4502 | const int start, int length, const unsigned encoding,
4503 | GByteArray *retval, int *endoff, int *err)
4504 | {
4505 | field_info *new_fi;
4506 | GByteArray *bytes = retval;
4507 | GByteArray *created_bytes = NULL((void*)0);
4508 | bool_Bool failed = false0;
4509 | uint32_t n = 0;
4510 | header_field_info *hfinfo;
4511 | bool_Bool generate = (bytes || tree) ? true1 : false0;
4512 |
4513 | 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", 4513, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4513, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4513, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4514 |
4515 | 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", 4515, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4516 |
4517 | 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", 4518, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))))
4518 | "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", 4518, "validate_proto_tree_add_bytes_ftype(hfinfo->type)" , "Called proto_tree_add_bytes_item but not a bytes-based FT_XXX type" ))));
4519 |
4520 | CHECK_FOR_ZERO_OR_MINUS_LENGTH(length)if (length < -1 || length == 0 ) { ((void)0); return ((void *)0); };
4521 |
4522 | if (encoding & ENC_STR_NUM0x01000000) {
4523 | 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" );
4524 | }
4525 |
4526 | if (generate && (encoding & ENC_STR_HEX0x02000000)) {
4527 | if (hfinfo->type == FT_UINT_BYTES) {
4528 | /* can't decode FT_UINT_BYTES from strings */
4529 | 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")
4530 | "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");
4531 | }
4532 |
4533 | unsigned hex_encoding = encoding;
4534 | if (!(encoding & ENC_SEP_MASK0x001F0000)) {
4535 | /* If none of the separator values are used,
4536 | * assume no separator (the common case). */
4537 | hex_encoding |= ENC_SEP_NONE0x00010000;
4538 | #if 0
4539 | 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")
4540 | "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");
4541 | #endif
4542 | }
4543 |
4544 | if (!bytes) {
4545 | /* caller doesn't care about return value, but we need it to
4546 | call tvb_get_string_bytes() and set the tree later */
4547 | bytes = created_bytes = g_byte_array_new();
4548 | }
4549 |
4550 | /*
4551 | * bytes might be NULL after this, but can't add expert
4552 | * error until later; if it's NULL, just note that
4553 | * it failed.
4554 | */
4555 | bytes = tvb_get_string_bytes(tvb, start, length, hex_encoding, bytes, endoff);
4556 | if (bytes == NULL((void*)0))
4557 | failed = true1;
4558 | }
4559 | else if (generate) {
4560 | tvb_ensure_bytes_exist(tvb, start, length);
4561 |
4562 | if (hfinfo->type == FT_UINT_BYTES) {
4563 | n = length; /* n is now the "header" length */
4564 | length = get_uint_value(tree, tvb, start, n, encoding);
4565 | /* length is now the value's length; only store the value in the array */
4566 | tvb_ensure_bytes_exist(tvb, start + n, length);
4567 | if (!bytes) {
4568 | /* caller doesn't care about return value, but
4569 | * we may need it to set the tree later */
4570 | bytes = created_bytes = g_byte_array_new();
4571 | }
4572 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start + n, length), length);
4573 | }
4574 | else if (length > 0) {
4575 | if (!bytes) {
4576 | /* caller doesn't care about return value, but
4577 | * we may need it to set the tree later */
4578 | bytes = created_bytes = g_byte_array_new();
4579 | }
4580 | g_byte_array_append(bytes, tvb_get_ptr(tvb, start, length), length);
4581 | }
4582 |
4583 | if (endoff)
4584 | *endoff = start + n + length;
4585 | }
4586 |
4587 | if (err)
4588 | *err = failed ? EINVAL22 : 0;
4589 |
4590 | 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); }
4591 | {if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4592 | 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); }
4593 | 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); }
4594 | 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); }
4595 | bytes = NULL;if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); }
4596 | } )if (!tree) { { if (created_bytes) g_byte_array_free(created_bytes , 1); created_bytes = ((void*)0); bytes = ((void*)0); }; return ((void*)0); };
4597 |
4598 | 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", 4604 , __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", 4604, "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", 4604, "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", 4604 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 | {((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", 4604 , __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", 4604, "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", 4604, "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", 4604 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 | 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", 4604 , __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", 4604, "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", 4604, "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", 4604 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 | 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", 4604 , __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", 4604, "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", 4604, "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", 4604 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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 | 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", 4604 , __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", 4604, "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", 4604, "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", 4604 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { if ((hfinfo->ref_type != HF_REF_TYPE_DIRECT) && (hfinfo->ref_type != HF_REF_TYPE_PRINT) && (hfinfo ->type != FT_PROTOCOL || ((tree)->tree_data)->fake_protocols )) { { if (created_bytes) g_byte_array_free(created_bytes, 1) ; created_bytes = ((void*)0); bytes = ((void*)0); }; return proto_tree_add_fake_node (tree, hfinfo); } } }
4603 | 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", 4604 , __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", 4604, "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", 4604, "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", 4604 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } }
4604 | } )((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", 4604 , __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", 4604, "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", 4604, "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", 4604 , __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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); } } };
4605 |
4606 | /* n will be zero except when it's a FT_UINT_BYTES */
4607 | new_fi = new_field_info(tree, hfinfo, tvb, start, n + length);
4608 |
4609 | if (encoding & ENC_STRING0x03000000) {
4610 | if (failed)
4611 | expert_add_info(NULL((void*)0), tree, &ei_byte_array_string_decoding_failed_error);
4612 |
4613 | if (bytes)
4614 | proto_tree_set_bytes_gbytearray(new_fi, bytes);
4615 | else
4616 | proto_tree_set_bytes(new_fi, NULL((void*)0), 0);
4617 |
4618 | if (created_bytes)
4619 | g_byte_array_free(created_bytes, true1);
4620 | }
4621 | else {
4622 | /* n will be zero except when it's a FT_UINT_BYTES */
4623 | proto_tree_set_bytes_tvb(new_fi, tvb, start + n, length);
4624 |
4625 | /* XXX: If we have a non-NULL tree but NULL retval, we don't
4626 | * use the byte array created above in this case.
4627 | */
4628 | if (created_bytes)
4629 | g_byte_array_free(created_bytes, true1);
4630 |
4631 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4632 | (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);
4633 | }
4634 |
4635 | return proto_tree_add_node(tree, new_fi);
4636 | }
4637 |
4638 |
4639 | proto_item *
4640 | proto_tree_add_time_item(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4641 | const int start, int length, const unsigned encoding,
4642 | nstime_t *retval, int *endoff, int *err)
4643 | {
4644 | field_info *new_fi;
4645 | nstime_t time_stamp;
4646 | int saved_err = 0;
4647 | header_field_info *hfinfo;
4648 |
4649 | 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", 4649, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4649, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4649, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4650 |
4651 | 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", 4651, "hfinfo != ((void*)0)", "Not passed hfi!"))));
4652 |
4653 | CHECK_FOR_ZERO_OR_MINUS_LENGTH_AND_CLEANUP(length,if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4654 | {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4655 | if(retval)if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4656 | {if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4657 | nstime_set_zero(retval);if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4658 | }if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); }
4659 | } )if (length < -1 || length == 0 ) { { if(retval) { nstime_set_zero (retval); } }; return ((void*)0); };
4660 |
4661 | nstime_set_zero(&time_stamp);
4662 |
4663 | if (encoding & ENC_STR_TIME_MASK0x001F0000) {
4664 | 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", 4664, ((hfinfo))->abbrev))));
4665 | /* The only string format that could be a relative time is
4666 | * ENC_ISO_8601_TIME, and that is treated as an absolute time
4667 | * relative to "now" currently.
4668 | */
4669 | if (!tvb_get_string_time(tvb, start, length, encoding, &time_stamp, endoff))
4670 | saved_err = EINVAL22;
4671 | }
4672 | else {
4673 | 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", 4673, ((hfinfo))->abbrev))));
4674 | const bool_Bool is_relative = (hfinfo->type == FT_RELATIVE_TIME) ? true1 : false0;
4675 |
4676 | tvb_ensure_bytes_exist(tvb, start, length);
4677 | get_time_value(tree, tvb, start, length, encoding, &time_stamp, is_relative);
4678 | if (endoff) *endoff = start + length;
4679 | }
4680 |
4681 | if (err) *err = saved_err;
4682 |
4683 | if (retval) {
4684 | retval->secs = time_stamp.secs;
4685 | retval->nsecs = time_stamp.nsecs;
4686 | }
4687 |
4688 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4689 |
4690 | 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", 4690 , __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", 4690, "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", 4690, "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", 4690, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4691 |
4692 | new_fi = new_field_info(tree, hfinfo, tvb, start, length);
4693 |
4694 | proto_tree_set_time(new_fi, &time_stamp);
4695 |
4696 | if (encoding & ENC_STRING0x03000000) {
4697 | if (saved_err)
4698 | expert_add_info(NULL((void*)0), tree, &ei_date_time_string_decoding_failed_error);
4699 | }
4700 | else {
4701 | FI_SET_FLAG(new_fi,do { if (new_fi) (new_fi)->flags = (new_fi)->flags | (( encoding & 0x80000000) ? 0x00000008 : 0x00000010); } while (0)
4702 | (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);
4703 | }
4704 |
4705 | return proto_tree_add_node(tree, new_fi);
4706 | }
4707 |
4708 | /* Add a FT_NONE to a proto_tree */
4709 | proto_item *
4710 | proto_tree_add_none_format(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
4711 | const int start, int length, const char *format,
4712 | ...)
4713 | {
4714 | proto_item *pi;
4715 | va_list ap;
4716 | header_field_info *hfinfo;
4717 |
4718 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4719 |
4720 | 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", 4720 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4720, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4720, "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", 4720, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4721 |
4722 | 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", 4722 , ((hfinfo))->abbrev))));
4723 |
4724 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4725 |
4726 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4726, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4727 |
4728 | va_start(ap, format)__builtin_va_start(ap, format);
4729 | proto_tree_set_representation(pi, format, ap);
4730 | va_end(ap)__builtin_va_end(ap);
4731 |
4732 | /* no value to set for FT_NONE */
4733 | return pi;
4734 | }
4735 |
4736 | /* Gets data from tvbuff, adds it to proto_tree, *DOES NOT* increment
4737 | * offset, and returns proto_item* */
4738 | proto_item *
4739 | ptvcursor_add_no_advance(ptvcursor_t* ptvc, int hf, int length,
4740 | const unsigned encoding)
4741 | {
4742 | proto_item *item;
4743 |
4744 | item = proto_tree_add_item(ptvc->tree, hf, ptvc->tvb, ptvc->offset,
4745 | length, encoding);
4746 |
4747 | return item;
4748 | }
4749 |
4750 | /* Advance the ptvcursor's offset within its tvbuff without
4751 | * adding anything to the proto_tree. */
4752 | void
4753 | ptvcursor_advance(ptvcursor_t* ptvc, int length)
4754 | {
4755 | if (ckd_add(&ptvc->offset, ptvc->offset, length)__builtin_add_overflow((ptvc->offset), (length), (&ptvc ->offset))) {
4756 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
4757 | }
4758 | }
4759 |
4760 |
4761 | static void
4762 | proto_tree_set_protocol_tvb(field_info *fi, tvbuff_t *tvb, const char* field_data, int length)
4763 | {
4764 | fvalue_set_protocol(fi->value, tvb, field_data, length);
4765 | }
4766 |
4767 | /* Add a FT_PROTOCOL to a proto_tree */
4768 | proto_item *
4769 | proto_tree_add_protocol_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4770 | int start, int length, const char *format, ...)
4771 | {
4772 | proto_item *pi;
4773 | tvbuff_t *protocol_tvb;
4774 | va_list ap;
4775 | header_field_info *hfinfo;
4776 | char* protocol_rep;
4777 |
4778 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4779 |
4780 | 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", 4780 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4780, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4780, "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", 4780, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4781 |
4782 | 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" , 4782, ((hfinfo))->abbrev))));
4783 |
4784 | /*
4785 | * This can throw an exception, so do it before we allocate anything.
4786 | */
4787 | protocol_tvb = (start == 0 ? tvb : tvb_new_subset_length(tvb, start, length));
4788 |
4789 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4790 |
4791 | va_start(ap, format)__builtin_va_start(ap, format);
4792 | protocol_rep = ws_strdup_vprintf(format, ap)wmem_strdup_vprintf(((void*)0), format, ap);
4793 | proto_tree_set_protocol_tvb(PNODE_FINFO(pi)((pi)->finfo), protocol_tvb, protocol_rep, length);
4794 | g_free(protocol_rep);
4795 | va_end(ap)__builtin_va_end(ap);
4796 |
4797 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4797, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4798 |
4799 | va_start(ap, format)__builtin_va_start(ap, format);
4800 | proto_tree_set_representation(pi, format, ap);
4801 | va_end(ap)__builtin_va_end(ap);
4802 |
4803 | return pi;
4804 | }
4805 |
4806 | /* Add a FT_BYTES to a proto_tree */
4807 | proto_item *
4808 | proto_tree_add_bytes(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4809 | int length, const uint8_t *start_ptr)
4810 | {
4811 | proto_item *pi;
4812 | header_field_info *hfinfo;
4813 | int item_length;
4814 |
4815 | 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", 4815, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4815, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4815, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4816 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
4817 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4818 |
4819 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4820 |
4821 | 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", 4821 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4821, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4821, "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", 4821, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4822 |
4823 | 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", 4823, ((hfinfo))->abbrev))));
4824 |
4825 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4826 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, length);
4827 |
4828 | return pi;
4829 | }
4830 |
4831 | /* Add a FT_BYTES to a proto_tree */
4832 | proto_item *
4833 | proto_tree_add_bytes_with_length(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4834 | int tvbuff_length, const uint8_t *start_ptr, int ptr_length)
4835 | {
4836 | proto_item *pi;
4837 | header_field_info *hfinfo;
4838 | int item_length;
4839 |
4840 | 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", 4840, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 4840, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4840, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
4841 | get_hfi_length(hfinfo, tvb, start, &tvbuff_length, &item_length, ENC_NA0x00000000);
4842 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
4843 |
4844 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4845 |
4846 | 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", 4846 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4846, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4846, "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", 4846, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4847 |
4848 | 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", 4848, ((hfinfo))->abbrev))));
4849 |
4850 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &tvbuff_length);
4851 | proto_tree_set_bytes(PNODE_FINFO(pi)((pi)->finfo), start_ptr, ptr_length);
4852 |
4853 | return pi;
4854 | }
4855 |
4856 | proto_item *
4857 | proto_tree_add_bytes_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4858 | int start, int length,
4859 | const uint8_t *start_ptr,
4860 | const char *format, ...)
4861 | {
4862 | proto_item *pi;
4863 | va_list ap;
4864 |
4865 | if (start_ptr == NULL((void*)0))
4866 | start_ptr = tvb_get_ptr(tvb, start, length);
4867 |
4868 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4869 |
4870 | 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; };
4871 |
4872 | va_start(ap, format)__builtin_va_start(ap, format);
4873 | proto_tree_set_representation_value(pi, format, ap);
4874 | va_end(ap)__builtin_va_end(ap);
4875 |
4876 | return pi;
4877 | }
4878 |
4879 | proto_item *
4880 | proto_tree_add_bytes_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4881 | int start, int length, const uint8_t *start_ptr,
4882 | const char *format, ...)
4883 | {
4884 | proto_item *pi;
4885 | va_list ap;
4886 |
4887 | if (start_ptr == NULL((void*)0))
4888 | start_ptr = tvb_get_ptr(tvb, start, length);
4889 |
4890 | pi = proto_tree_add_bytes(tree, hfindex, tvb, start, length, start_ptr);
4891 |
4892 | 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; };
4893 |
4894 | va_start(ap, format)__builtin_va_start(ap, format);
4895 | proto_tree_set_representation(pi, format, ap);
4896 | va_end(ap)__builtin_va_end(ap);
4897 |
4898 | return pi;
4899 | }
4900 |
4901 | static void
4902 | proto_tree_set_bytes(field_info *fi, const uint8_t* start_ptr, int length)
4903 | {
4904 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4904, "length >= 0" ))));
4905 | 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", 4905, "start_ptr != ((void*)0) || length == 0" ))));
4906 |
4907 | fvalue_set_bytes_data(fi->value, start_ptr, length);
4908 | }
4909 |
4910 |
4911 | static void
4912 | proto_tree_set_bytes_tvb(field_info *fi, tvbuff_t *tvb, int offset, int length)
4913 | {
4914 | tvb_ensure_bytes_exist(tvb, offset, length);
4915 | proto_tree_set_bytes(fi, tvb_get_ptr(tvb, offset, length), length);
4916 | }
4917 |
4918 | static void
4919 | proto_tree_set_bytes_gbytearray(field_info *fi, const GByteArray *value)
4920 | {
4921 | GByteArray *bytes;
4922 |
4923 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4923, "value != ((void*)0)" ))));
4924 |
4925 | bytes = byte_array_dup(value);
4926 |
4927 | fvalue_set_byte_array(fi->value, bytes);
4928 | }
4929 |
4930 | /* Add a FT_*TIME to a proto_tree */
4931 | proto_item *
4932 | proto_tree_add_time(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
4933 | int length, const nstime_t *value_ptr)
4934 | {
4935 | proto_item *pi;
4936 | header_field_info *hfinfo;
4937 |
4938 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
4939 |
4940 | 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", 4940 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4940, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 4940, "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", 4940, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
4941 |
4942 | 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", 4942, ((hfinfo))->abbrev))));
4943 |
4944 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
4945 | proto_tree_set_time(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
4946 |
4947 | return pi;
4948 | }
4949 |
4950 | proto_item *
4951 | proto_tree_add_time_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4952 | int start, int length, nstime_t *value_ptr,
4953 | const char *format, ...)
4954 | {
4955 | proto_item *pi;
4956 | va_list ap;
4957 |
4958 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4959 | if (pi != tree) {
4960 | va_start(ap, format)__builtin_va_start(ap, format);
4961 | proto_tree_set_representation_value(pi, format, ap);
4962 | va_end(ap)__builtin_va_end(ap);
4963 | }
4964 |
4965 | return pi;
4966 | }
4967 |
4968 | proto_item *
4969 | proto_tree_add_time_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
4970 | int start, int length, nstime_t *value_ptr,
4971 | const char *format, ...)
4972 | {
4973 | proto_item *pi;
4974 | va_list ap;
4975 |
4976 | pi = proto_tree_add_time(tree, hfindex, tvb, start, length, value_ptr);
4977 | if (pi != tree) {
4978 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 4978, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
4979 |
4980 | va_start(ap, format)__builtin_va_start(ap, format);
4981 | proto_tree_set_representation(pi, format, ap);
4982 | va_end(ap)__builtin_va_end(ap);
4983 | }
4984 |
4985 | return pi;
4986 | }
4987 |
4988 | /* Set the FT_*TIME value */
4989 | static void
4990 | proto_tree_set_time(field_info *fi, const nstime_t *value_ptr)
4991 | {
4992 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 4992, "value_ptr != ((void*)0)" ))));
4993 |
4994 | fvalue_set_time(fi->value, value_ptr);
4995 | }
4996 |
4997 | /* Add a FT_IPXNET to a proto_tree */
4998 | proto_item *
4999 | proto_tree_add_ipxnet(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5000 | int length, uint32_t value)
5001 | {
5002 | proto_item *pi;
5003 | header_field_info *hfinfo;
5004 |
5005 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5006 |
5007 | 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", 5007 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5007, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5007, "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", 5007, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5008 |
5009 | 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" , 5009, ((hfinfo))->abbrev))));
5010 |
5011 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5012 | proto_tree_set_ipxnet(PNODE_FINFO(pi)((pi)->finfo), value);
5013 |
5014 | return pi;
5015 | }
5016 |
5017 | proto_item *
5018 | proto_tree_add_ipxnet_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5019 | int start, int length, uint32_t value,
5020 | const char *format, ...)
5021 | {
5022 | proto_item *pi;
5023 | va_list ap;
5024 |
5025 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5026 | if (pi != tree) {
5027 | va_start(ap, format)__builtin_va_start(ap, format);
5028 | proto_tree_set_representation_value(pi, format, ap);
5029 | va_end(ap)__builtin_va_end(ap);
5030 | }
5031 |
5032 | return pi;
5033 | }
5034 |
5035 | proto_item *
5036 | proto_tree_add_ipxnet_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5037 | int start, int length, uint32_t value,
5038 | const char *format, ...)
5039 | {
5040 | proto_item *pi;
5041 | va_list ap;
5042 |
5043 | pi = proto_tree_add_ipxnet(tree, hfindex, tvb, start, length, value);
5044 | if (pi != tree) {
5045 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5045, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5046 |
5047 | va_start(ap, format)__builtin_va_start(ap, format);
5048 | proto_tree_set_representation(pi, format, ap);
5049 | va_end(ap)__builtin_va_end(ap);
5050 | }
5051 |
5052 | return pi;
5053 | }
5054 |
5055 | /* Set the FT_IPXNET value */
5056 | static void
5057 | proto_tree_set_ipxnet(field_info *fi, uint32_t value)
5058 | {
5059 | fvalue_set_uinteger(fi->value, value);
5060 | }
5061 |
5062 | /* Add a FT_IPv4 to a proto_tree */
5063 | proto_item *
5064 | proto_tree_add_ipv4(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5065 | int length, ws_in4_addr value)
5066 | {
5067 | proto_item *pi;
5068 | header_field_info *hfinfo;
5069 |
5070 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5071 |
5072 | 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", 5072 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5072, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5072, "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", 5072, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5073 |
5074 | 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", 5074 , ((hfinfo))->abbrev))));
5075 |
5076 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5077 | proto_tree_set_ipv4(PNODE_FINFO(pi)((pi)->finfo), value);
5078 |
5079 | return pi;
5080 | }
5081 |
5082 | proto_item *
5083 | proto_tree_add_ipv4_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5084 | int start, int length, ws_in4_addr value,
5085 | const char *format, ...)
5086 | {
5087 | proto_item *pi;
5088 | va_list ap;
5089 |
5090 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5091 | if (pi != tree) {
5092 | va_start(ap, format)__builtin_va_start(ap, format);
5093 | proto_tree_set_representation_value(pi, format, ap);
5094 | va_end(ap)__builtin_va_end(ap);
5095 | }
5096 |
5097 | return pi;
5098 | }
5099 |
5100 | proto_item *
5101 | proto_tree_add_ipv4_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5102 | int start, int length, ws_in4_addr value,
5103 | const char *format, ...)
5104 | {
5105 | proto_item *pi;
5106 | va_list ap;
5107 |
5108 | pi = proto_tree_add_ipv4(tree, hfindex, tvb, start, length, value);
5109 | if (pi != tree) {
5110 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5110, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5111 |
5112 | va_start(ap, format)__builtin_va_start(ap, format);
5113 | proto_tree_set_representation(pi, format, ap);
5114 | va_end(ap)__builtin_va_end(ap);
5115 | }
5116 |
5117 | return pi;
5118 | }
5119 |
5120 | /* Set the FT_IPv4 value */
5121 | static void
5122 | proto_tree_set_ipv4(field_info *fi, ws_in4_addr value)
5123 | {
5124 | ipv4_addr_and_mask ipv4;
5125 | ws_ipv4_addr_and_mask_init(&ipv4, value, 32);
5126 | fvalue_set_ipv4(fi->value, &ipv4);
5127 | }
5128 |
5129 | /* Add a FT_IPv6 to a proto_tree */
5130 | proto_item *
5131 | proto_tree_add_ipv6(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5132 | int length, const ws_in6_addr *value)
5133 | {
5134 | proto_item *pi;
5135 | header_field_info *hfinfo;
5136 |
5137 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5138 |
5139 | 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", 5139 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5139, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5139, "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", 5139, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5140 |
5141 | 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", 5141 , ((hfinfo))->abbrev))));
5142 |
5143 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5144 | proto_tree_set_ipv6(PNODE_FINFO(pi)((pi)->finfo), value);
5145 |
5146 | return pi;
5147 | }
5148 |
5149 | proto_item *
5150 | proto_tree_add_ipv6_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5151 | int start, int length,
5152 | const ws_in6_addr *value_ptr,
5153 | const char *format, ...)
5154 | {
5155 | proto_item *pi;
5156 | va_list ap;
5157 |
5158 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5159 | if (pi != tree) {
5160 | va_start(ap, format)__builtin_va_start(ap, format);
5161 | proto_tree_set_representation_value(pi, format, ap);
5162 | va_end(ap)__builtin_va_end(ap);
5163 | }
5164 |
5165 | return pi;
5166 | }
5167 |
5168 | proto_item *
5169 | proto_tree_add_ipv6_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5170 | int start, int length,
5171 | const ws_in6_addr *value_ptr,
5172 | const char *format, ...)
5173 | {
5174 | proto_item *pi;
5175 | va_list ap;
5176 |
5177 | pi = proto_tree_add_ipv6(tree, hfindex, tvb, start, length, value_ptr);
5178 | if (pi != tree) {
5179 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5179, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5180 |
5181 | va_start(ap, format)__builtin_va_start(ap, format);
5182 | proto_tree_set_representation(pi, format, ap);
5183 | va_end(ap)__builtin_va_end(ap);
5184 | }
5185 |
5186 | return pi;
5187 | }
5188 |
5189 | /* Set the FT_IPv6 value */
5190 | static void
5191 | proto_tree_set_ipv6(field_info *fi, const ws_in6_addr *value)
5192 | {
5193 | DISSECTOR_ASSERT(value != NULL)((void) ((value != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5193, "value != ((void*)0)" ))));
5194 | ipv6_addr_and_prefix ipv6;
5195 | ipv6.addr = *value;
5196 | ipv6.prefix = 128;
5197 | fvalue_set_ipv6(fi->value, &ipv6);
5198 | }
5199 |
5200 | static void
5201 | proto_tree_set_ipv6_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5202 | {
5203 | proto_tree_set_ipv6(fi, (const ws_in6_addr *)tvb_get_ptr(tvb, start, length));
5204 | }
5205 |
5206 | /* Set the FT_FCWWN value */
5207 | static void
5208 | proto_tree_set_fcwwn(field_info *fi, const uint8_t* value_ptr)
5209 | {
5210 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5210, "value_ptr != ((void*)0)" ))));
5211 | fvalue_set_fcwwn(fi->value, value_ptr);
5212 | }
5213 |
5214 | static void
5215 | proto_tree_set_fcwwn_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5216 | {
5217 | proto_tree_set_fcwwn(fi, tvb_get_ptr(tvb, start, length));
5218 | }
5219 |
5220 | /* Add a FT_GUID to a proto_tree */
5221 | proto_item *
5222 | proto_tree_add_guid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5223 | int length, const e_guid_t *value_ptr)
5224 | {
5225 | proto_item *pi;
5226 | header_field_info *hfinfo;
5227 |
5228 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5229 |
5230 | 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", 5230 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5230, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5230, "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", 5230, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5231 |
5232 | 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", 5232 , ((hfinfo))->abbrev))));
5233 |
5234 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5235 | proto_tree_set_guid(PNODE_FINFO(pi)((pi)->finfo), value_ptr);
5236 |
5237 | return pi;
5238 | }
5239 |
5240 | proto_item *
5241 | proto_tree_add_guid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5242 | int start, int length,
5243 | const e_guid_t *value_ptr,
5244 | const char *format, ...)
5245 | {
5246 | proto_item *pi;
5247 | va_list ap;
5248 |
5249 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5250 | if (pi != tree) {
5251 | va_start(ap, format)__builtin_va_start(ap, format);
5252 | proto_tree_set_representation_value(pi, format, ap);
5253 | va_end(ap)__builtin_va_end(ap);
5254 | }
5255 |
5256 | return pi;
5257 | }
5258 |
5259 | proto_item *
5260 | proto_tree_add_guid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5261 | int start, int length, const e_guid_t *value_ptr,
5262 | const char *format, ...)
5263 | {
5264 | proto_item *pi;
5265 | va_list ap;
5266 |
5267 | pi = proto_tree_add_guid(tree, hfindex, tvb, start, length, value_ptr);
5268 | if (pi != tree) {
5269 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5269, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5270 |
5271 | va_start(ap, format)__builtin_va_start(ap, format);
5272 | proto_tree_set_representation(pi, format, ap);
5273 | va_end(ap)__builtin_va_end(ap);
5274 | }
5275 |
5276 | return pi;
5277 | }
5278 |
5279 | /* Set the FT_GUID value */
5280 | static void
5281 | proto_tree_set_guid(field_info *fi, const e_guid_t *value_ptr)
5282 | {
5283 | DISSECTOR_ASSERT(value_ptr != NULL)((void) ((value_ptr != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5283, "value_ptr != ((void*)0)" ))));
5284 | fvalue_set_guid(fi->value, value_ptr);
5285 | }
5286 |
5287 | static void
5288 | proto_tree_set_guid_tvb(field_info *fi, tvbuff_t *tvb, int start,
5289 | const unsigned encoding)
5290 | {
5291 | e_guid_t guid;
5292 |
5293 | tvb_get_guid(tvb, start, &guid, encoding);
5294 | proto_tree_set_guid(fi, &guid);
5295 | }
5296 |
5297 | /* Add a FT_OID to a proto_tree */
5298 | proto_item *
5299 | proto_tree_add_oid(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5300 | int length, const uint8_t* value_ptr)
5301 | {
5302 | proto_item *pi;
5303 | header_field_info *hfinfo;
5304 |
5305 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5306 |
5307 | 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", 5307 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5307, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5307, "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", 5307, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5308 |
5309 | 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", 5309 , ((hfinfo))->abbrev))));
5310 |
5311 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5312 | proto_tree_set_oid(PNODE_FINFO(pi)((pi)->finfo), value_ptr, length);
5313 |
5314 | return pi;
5315 | }
5316 |
5317 | proto_item *
5318 | proto_tree_add_oid_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5319 | int start, int length,
5320 | const uint8_t* value_ptr,
5321 | const char *format, ...)
5322 | {
5323 | proto_item *pi;
5324 | va_list ap;
5325 |
5326 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5327 | if (pi != tree) {
5328 | va_start(ap, format)__builtin_va_start(ap, format);
5329 | proto_tree_set_representation_value(pi, format, ap);
5330 | va_end(ap)__builtin_va_end(ap);
5331 | }
5332 |
5333 | return pi;
5334 | }
5335 |
5336 | proto_item *
5337 | proto_tree_add_oid_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5338 | int start, int length, const uint8_t* value_ptr,
5339 | const char *format, ...)
5340 | {
5341 | proto_item *pi;
5342 | va_list ap;
5343 |
5344 | pi = proto_tree_add_oid(tree, hfindex, tvb, start, length, value_ptr);
5345 | if (pi != tree) {
5346 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5346, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5347 |
5348 | va_start(ap, format)__builtin_va_start(ap, format);
5349 | proto_tree_set_representation(pi, format, ap);
5350 | va_end(ap)__builtin_va_end(ap);
5351 | }
5352 |
5353 | return pi;
5354 | }
5355 |
5356 | /* Set the FT_OID value */
5357 | static void
5358 | proto_tree_set_oid(field_info *fi, const uint8_t* value_ptr, int length)
5359 | {
5360 | GByteArray *bytes;
5361 |
5362 | 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", 5362, "value_ptr != ((void*)0) || length == 0" ))));
5363 |
5364 | bytes = g_byte_array_new();
5365 | if (length > 0) {
5366 | g_byte_array_append(bytes, value_ptr, length);
5367 | }
5368 | fvalue_set_byte_array(fi->value, bytes);
5369 | }
5370 |
5371 | static void
5372 | proto_tree_set_oid_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5373 | {
5374 | proto_tree_set_oid(fi, tvb_get_ptr(tvb, start, length), length);
5375 | }
5376 |
5377 | /* Set the FT_SYSTEM_ID value */
5378 | static void
5379 | proto_tree_set_system_id(field_info *fi, const uint8_t* value_ptr, int length)
5380 | {
5381 | GByteArray *bytes;
5382 |
5383 | 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", 5383, "value_ptr != ((void*)0) || length == 0" ))));
5384 |
5385 | bytes = g_byte_array_new();
5386 | if (length > 0) {
5387 | g_byte_array_append(bytes, value_ptr, length);
5388 | }
5389 | fvalue_set_byte_array(fi->value, bytes);
5390 | }
5391 |
5392 | static void
5393 | proto_tree_set_system_id_tvb(field_info *fi, tvbuff_t *tvb, int start, int length)
5394 | {
5395 | proto_tree_set_system_id(fi, tvb_get_ptr(tvb, start, length), length);
5396 | }
5397 |
5398 | /* Add a FT_STRING, FT_STRINGZ, FT_STRINGZPAD, or FT_STRINGZTRUNC to a
5399 | * proto_tree. Creates own copy of string, and frees it when the proto_tree
5400 | * is destroyed. */
5401 | proto_item *
5402 | proto_tree_add_string(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5403 | int length, const char* value)
5404 | {
5405 | proto_item *pi;
5406 | header_field_info *hfinfo;
5407 | int item_length;
5408 |
5409 | 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", 5409, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 5409, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5409, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
5410 | get_hfi_length(hfinfo, tvb, start, &length, &item_length, ENC_NA0x00000000);
5411 | /*
5412 | * Special case - if the length is 0, skip the test, so that
5413 | * we can have an empty string right after the end of the
5414 | * packet. (This handles URL-encoded forms where the last field
5415 | * has no value so the form ends right after the =.)
5416 | */
5417 | if (item_length != 0)
5418 | test_length(hfinfo, tvb, start, item_length, ENC_NA0x00000000);
5419 |
5420 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5421 |
5422 | 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", 5422 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5422, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5422, "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", 5422, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5423 |
5424 | 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", 5424, ((hfinfo))->abbrev))));
5425 |
5426 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5427 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5427, "length >= 0" ))));
5428 |
5429 | 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", 5429, __func__, value, -1, __uni_endptr); } } while (0); } } while (0);
5430 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), value);
5431 |
5432 | return pi;
5433 | }
5434 |
5435 | proto_item *
5436 | proto_tree_add_string_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5437 | int start, int length, const char* value,
5438 | const char *format,
5439 | ...)
5440 | {
5441 | proto_item *pi;
5442 | va_list ap;
5443 |
5444 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5445 | if (pi != tree) {
5446 | va_start(ap, format)__builtin_va_start(ap, format);
5447 | proto_tree_set_representation_value(pi, format, ap);
5448 | va_end(ap)__builtin_va_end(ap);
5449 | }
5450 |
5451 | return pi;
5452 | }
5453 |
5454 | proto_item *
5455 | proto_tree_add_string_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5456 | int start, int length, const char* value,
5457 | const char *format, ...)
5458 | {
5459 | proto_item *pi;
5460 | va_list ap;
5461 |
5462 | pi = proto_tree_add_string(tree, hfindex, tvb, start, length, value);
5463 | if (pi != tree) {
5464 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5464, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5465 |
5466 | va_start(ap, format)__builtin_va_start(ap, format);
5467 | proto_tree_set_representation(pi, format, ap);
5468 | va_end(ap)__builtin_va_end(ap);
5469 | }
5470 |
5471 | return pi;
5472 | }
5473 |
5474 | /* Set the FT_STRING value */
5475 | static void
5476 | proto_tree_set_string(field_info *fi, const char* value)
5477 | {
5478 | if (value) {
5479 | fvalue_set_string(fi->value, value);
5480 | } else {
5481 | /*
5482 | * XXX - why is a null value for a string field
5483 | * considered valid?
5484 | */
5485 | fvalue_set_string(fi->value, "[ Null ]");
5486 | }
5487 | }
5488 |
5489 | /* Set the FT_AX25 value */
5490 | static void
5491 | proto_tree_set_ax25(field_info *fi, const uint8_t* value)
5492 | {
5493 | fvalue_set_ax25(fi->value, value);
5494 | }
5495 |
5496 | static void
5497 | proto_tree_set_ax25_tvb(field_info *fi, tvbuff_t *tvb, int start)
5498 | {
5499 | proto_tree_set_ax25(fi, tvb_get_ptr(tvb, start, 7));
5500 | }
5501 |
5502 | /* Set the FT_VINES value */
5503 | static void
5504 | proto_tree_set_vines(field_info *fi, const uint8_t* value)
5505 | {
5506 | fvalue_set_vines(fi->value, value);
5507 | }
5508 |
5509 | static void
5510 | proto_tree_set_vines_tvb(field_info *fi, tvbuff_t *tvb, int start)
5511 | {
5512 | proto_tree_set_vines(fi, tvb_get_ptr(tvb, start, FT_VINES_ADDR_LEN6));
5513 | }
5514 |
5515 | /* Add a FT_ETHER to a proto_tree */
5516 | proto_item *
5517 | proto_tree_add_ether(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5518 | int length, const uint8_t* value)
5519 | {
5520 | proto_item *pi;
5521 | header_field_info *hfinfo;
5522 |
5523 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5524 |
5525 | 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", 5525 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5525, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5525, "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", 5525, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5526 |
5527 | 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", 5527, ((hfinfo))->abbrev))));
5528 |
5529 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5530 | proto_tree_set_ether(PNODE_FINFO(pi)((pi)->finfo), value);
5531 |
5532 | return pi;
5533 | }
5534 |
5535 | proto_item *
5536 | proto_tree_add_ether_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5537 | int start, int length, const uint8_t* value,
5538 | const char *format, ...)
5539 | {
5540 | proto_item *pi;
5541 | va_list ap;
5542 |
5543 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5544 | if (pi != tree) {
5545 | va_start(ap, format)__builtin_va_start(ap, format);
5546 | proto_tree_set_representation_value(pi, format, ap);
5547 | va_end(ap)__builtin_va_end(ap);
5548 | }
5549 |
5550 | return pi;
5551 | }
5552 |
5553 | proto_item *
5554 | proto_tree_add_ether_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5555 | int start, int length, const uint8_t* value,
5556 | const char *format, ...)
5557 | {
5558 | proto_item *pi;
5559 | va_list ap;
5560 |
5561 | pi = proto_tree_add_ether(tree, hfindex, tvb, start, length, value);
5562 | if (pi != tree) {
5563 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5563, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5564 |
5565 | va_start(ap, format)__builtin_va_start(ap, format);
5566 | proto_tree_set_representation(pi, format, ap);
5567 | va_end(ap)__builtin_va_end(ap);
5568 | }
5569 |
5570 | return pi;
5571 | }
5572 |
5573 | /* Set the FT_ETHER value */
5574 | static void
5575 | proto_tree_set_ether(field_info *fi, const uint8_t* value)
5576 | {
5577 | fvalue_set_ether(fi->value, value);
5578 | }
5579 |
5580 | static void
5581 | proto_tree_set_ether_tvb(field_info *fi, tvbuff_t *tvb, int start)
5582 | {
5583 | proto_tree_set_ether(fi, tvb_get_ptr(tvb, start, FT_ETHER_LEN6));
5584 | }
5585 |
5586 | /* Add a FT_BOOLEAN to a proto_tree */
5587 | proto_item *
5588 | proto_tree_add_boolean(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5589 | int length, uint64_t value)
5590 | {
5591 | proto_item *pi;
5592 | header_field_info *hfinfo;
5593 |
5594 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5595 |
5596 | 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", 5596 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5596, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5596, "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", 5596, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5597 |
5598 | 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" , 5598, ((hfinfo))->abbrev))));
5599 |
5600 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5601 | proto_tree_set_boolean(PNODE_FINFO(pi)((pi)->finfo), value);
5602 |
5603 | return pi;
5604 | }
5605 |
5606 | proto_item *
5607 | proto_tree_add_boolean_format_value(proto_tree *tree, int hfindex,
5608 | tvbuff_t *tvb, int start, int length,
5609 | uint64_t value, const char *format, ...)
5610 | {
5611 | proto_item *pi;
5612 | va_list ap;
5613 |
5614 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5615 | if (pi != tree) {
5616 | va_start(ap, format)__builtin_va_start(ap, format);
5617 | proto_tree_set_representation_value(pi, format, ap);
5618 | va_end(ap)__builtin_va_end(ap);
5619 | }
5620 |
5621 | return pi;
5622 | }
5623 |
5624 | proto_item *
5625 | proto_tree_add_boolean_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5626 | int start, int length, uint64_t value,
5627 | const char *format, ...)
5628 | {
5629 | proto_item *pi;
5630 | va_list ap;
5631 |
5632 | pi = proto_tree_add_boolean(tree, hfindex, tvb, start, length, value);
5633 | if (pi != tree) {
5634 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5634, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5635 |
5636 | va_start(ap, format)__builtin_va_start(ap, format);
5637 | proto_tree_set_representation(pi, format, ap);
5638 | va_end(ap)__builtin_va_end(ap);
5639 | }
5640 |
5641 | return pi;
5642 | }
5643 |
5644 | /* Set the FT_BOOLEAN value */
5645 | static void
5646 | proto_tree_set_boolean(field_info *fi, uint64_t value)
5647 | {
5648 | proto_tree_set_uint64(fi, value);
5649 | }
5650 |
5651 | /* Generate, into "buf", a string showing the bits of a bitfield.
5652 | Return a pointer to the character after that string. */
5653 | static char *
5654 | other_decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5655 | {
5656 | int i = 0;
5657 | uint64_t bit;
5658 | char *p;
5659 |
5660 | p = buf;
5661 |
5662 | /* This is a devel error. It is safer to stop here. */
5663 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5663, "width >= 1" ))));
5664 |
5665 | bit = UINT64_C(1)1UL << (width - 1);
5666 | for (;;) {
5667 | if (mask & bit) {
5668 | /* This bit is part of the field. Show its value. */
5669 | if (val & bit)
5670 | *p++ = '1';
5671 | else
5672 | *p++ = '0';
5673 | } else {
5674 | /* This bit is not part of the field. */
5675 | *p++ = '.';
5676 | }
5677 | bit >>= 1;
5678 | i++;
5679 | if (i >= width)
5680 | break;
5681 | if (i % 4 == 0)
5682 | *p++ = ' ';
5683 | }
5684 | *p = '\0';
5685 | return p;
5686 | }
5687 |
5688 | static char *
5689 | decode_bitfield_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5690 | {
5691 | char *p;
5692 |
5693 | p = other_decode_bitfield_value(buf, val, mask, width);
5694 | p = g_stpcpy(p, " = ");
5695 |
5696 | return p;
5697 | }
5698 |
5699 | static char *
5700 | other_decode_bitfield_varint_value(char *buf, uint64_t val, uint64_t mask, const int width)
5701 | {
5702 | int i = 0;
5703 | uint64_t bit;
5704 | char *p;
5705 |
5706 | p = buf;
5707 |
5708 | /* This is a devel error. It is safer to stop here. */
5709 | DISSECTOR_ASSERT(width >= 1)((void) ((width >= 1) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 5709, "width >= 1" ))));
5710 |
5711 | bit = UINT64_C(1)1UL << (width - 1);
5712 | for (;;) {
5713 | if (((8-(i % 8)) != 8) && /* MSB is never used for value. */
5714 | (mask & bit)) {
5715 | /* This bit is part of the field. Show its value. */
5716 | if (val & bit)
5717 | *p++ = '1';
5718 | else
5719 | *p++ = '0';
5720 | } else {
5721 | /* This bit is not part of the field. */
5722 | *p++ = '.';
5723 | }
5724 | bit >>= 1;
5725 | i++;
5726 | if (i >= width)
5727 | break;
5728 | if (i % 4 == 0)
5729 | *p++ = ' ';
5730 | }
5731 |
5732 | *p = '\0';
5733 | return p;
5734 | }
5735 |
5736 | static char *
5737 | decode_bitfield_varint_value(char *buf, const uint64_t val, const uint64_t mask, const int width)
5738 | {
5739 | char *p;
5740 |
5741 | p = other_decode_bitfield_varint_value(buf, val, mask, width);
5742 | p = g_stpcpy(p, " = ");
5743 |
5744 | return p;
5745 | }
5746 |
5747 | /* Add a FT_FLOAT to a proto_tree */
5748 | proto_item *
5749 | proto_tree_add_float(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5750 | int length, float value)
5751 | {
5752 | proto_item *pi;
5753 | header_field_info *hfinfo;
5754 |
5755 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5756 |
5757 | 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", 5757 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5757, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5757, "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", 5757, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5758 |
5759 | 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", 5759, ((hfinfo))->abbrev))));
5760 |
5761 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5762 | proto_tree_set_float(PNODE_FINFO(pi)((pi)->finfo), value);
5763 |
5764 | return pi;
5765 | }
5766 |
5767 | proto_item *
5768 | proto_tree_add_float_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5769 | int start, int length, float value,
5770 | const char *format, ...)
5771 | {
5772 | proto_item *pi;
5773 | va_list ap;
5774 |
5775 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5776 | if (pi != tree) {
5777 | va_start(ap, format)__builtin_va_start(ap, format);
5778 | proto_tree_set_representation_value(pi, format, ap);
5779 | va_end(ap)__builtin_va_end(ap);
5780 | }
5781 |
5782 | return pi;
5783 | }
5784 |
5785 | proto_item *
5786 | proto_tree_add_float_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5787 | int start, int length, float value,
5788 | const char *format, ...)
5789 | {
5790 | proto_item *pi;
5791 | va_list ap;
5792 |
5793 | pi = proto_tree_add_float(tree, hfindex, tvb, start, length, value);
5794 | if (pi != tree) {
5795 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5795, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5796 |
5797 | va_start(ap, format)__builtin_va_start(ap, format);
5798 | proto_tree_set_representation(pi, format, ap);
5799 | va_end(ap)__builtin_va_end(ap);
5800 | }
5801 |
5802 | return pi;
5803 | }
5804 |
5805 | /* Set the FT_FLOAT value */
5806 | static void
5807 | proto_tree_set_float(field_info *fi, float value)
5808 | {
5809 | fvalue_set_floating(fi->value, value);
5810 | }
5811 |
5812 | /* Add a FT_DOUBLE to a proto_tree */
5813 | proto_item *
5814 | proto_tree_add_double(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5815 | int length, double value)
5816 | {
5817 | proto_item *pi;
5818 | header_field_info *hfinfo;
5819 |
5820 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5821 |
5822 | 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", 5822 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5822, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5822, "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", 5822, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5823 |
5824 | 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" , 5824, ((hfinfo))->abbrev))));
5825 |
5826 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5827 | proto_tree_set_double(PNODE_FINFO(pi)((pi)->finfo), value);
5828 |
5829 | return pi;
5830 | }
5831 |
5832 | proto_item *
5833 | proto_tree_add_double_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5834 | int start, int length, double value,
5835 | const char *format, ...)
5836 | {
5837 | proto_item *pi;
5838 | va_list ap;
5839 |
5840 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5841 | if (pi != tree) {
5842 | va_start(ap, format)__builtin_va_start(ap, format);
5843 | proto_tree_set_representation_value(pi, format, ap);
5844 | va_end(ap)__builtin_va_end(ap);
5845 | }
5846 |
5847 | return pi;
5848 | }
5849 |
5850 | proto_item *
5851 | proto_tree_add_double_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5852 | int start, int length, double value,
5853 | const char *format, ...)
5854 | {
5855 | proto_item *pi;
5856 | va_list ap;
5857 |
5858 | pi = proto_tree_add_double(tree, hfindex, tvb, start, length, value);
5859 | if (pi != tree) {
5860 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5860, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5861 |
5862 | va_start(ap, format)__builtin_va_start(ap, format);
5863 | proto_tree_set_representation(pi, format, ap);
5864 | va_end(ap)__builtin_va_end(ap);
5865 | }
5866 |
5867 | return pi;
5868 | }
5869 |
5870 | /* Set the FT_DOUBLE value */
5871 | static void
5872 | proto_tree_set_double(field_info *fi, double value)
5873 | {
5874 | fvalue_set_floating(fi->value, value);
5875 | }
5876 |
5877 | /* Add FT_CHAR or FT_UINT{8,16,24,32} to a proto_tree */
5878 | proto_item *
5879 | proto_tree_add_uint(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5880 | int length, uint32_t value)
5881 | {
5882 | proto_item *pi = NULL((void*)0);
5883 | header_field_info *hfinfo;
5884 |
5885 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5886 |
5887 | 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", 5887 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5887, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5887, "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", 5887, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5888 |
5889 | switch (hfinfo->type) {
5890 | case FT_CHAR:
5891 | case FT_UINT8:
5892 | case FT_UINT16:
5893 | case FT_UINT24:
5894 | case FT_UINT32:
5895 | case FT_FRAMENUM:
5896 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5897 | proto_tree_set_uint(PNODE_FINFO(pi)((pi)->finfo), value);
5898 | break;
5899 |
5900 | default:
5901 | 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)
5902 | 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);
5903 | }
5904 |
5905 | return pi;
5906 | }
5907 |
5908 | proto_item *
5909 | proto_tree_add_uint_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5910 | int start, int length, uint32_t value,
5911 | const char *format, ...)
5912 | {
5913 | proto_item *pi;
5914 | va_list ap;
5915 |
5916 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5917 | if (pi != tree) {
5918 | va_start(ap, format)__builtin_va_start(ap, format);
5919 | proto_tree_set_representation_value(pi, format, ap);
5920 | va_end(ap)__builtin_va_end(ap);
5921 | }
5922 |
5923 | return pi;
5924 | }
5925 |
5926 | proto_item *
5927 | proto_tree_add_uint_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
5928 | int start, int length, uint32_t value,
5929 | const char *format, ...)
5930 | {
5931 | proto_item *pi;
5932 | va_list ap;
5933 |
5934 | pi = proto_tree_add_uint(tree, hfindex, tvb, start, length, value);
5935 | if (pi != tree) {
5936 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 5936, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
5937 |
5938 | va_start(ap, format)__builtin_va_start(ap, format);
5939 | proto_tree_set_representation(pi, format, ap);
5940 | va_end(ap)__builtin_va_end(ap);
5941 | }
5942 |
5943 | return pi;
5944 | }
5945 |
5946 | /* Set the FT_UINT{8,16,24,32} value */
5947 | static void
5948 | proto_tree_set_uint(field_info *fi, uint32_t value)
5949 | {
5950 | const header_field_info *hfinfo;
5951 | uint32_t integer;
5952 |
5953 | hfinfo = fi->hfinfo;
5954 | integer = value;
5955 |
5956 | if (hfinfo->bitmask) {
5957 | /* Mask out irrelevant portions */
5958 | integer &= (uint32_t)(hfinfo->bitmask);
5959 |
5960 | /* Shift bits */
5961 | integer >>= hfinfo_bitshift(hfinfo);
5962 |
5963 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
5964 | 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);
5965 | }
5966 |
5967 | fvalue_set_uinteger(fi->value, integer);
5968 | }
5969 |
5970 | /* Add FT_UINT{40,48,56,64} to a proto_tree */
5971 | proto_item *
5972 | proto_tree_add_uint64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
5973 | int length, uint64_t value)
5974 | {
5975 | proto_item *pi = NULL((void*)0);
5976 | header_field_info *hfinfo;
5977 |
5978 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
5979 |
5980 | 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", 5980 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5980, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 5980, "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", 5980, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
5981 |
5982 | switch (hfinfo->type) {
5983 | case FT_UINT40:
5984 | case FT_UINT48:
5985 | case FT_UINT56:
5986 | case FT_UINT64:
5987 | case FT_FRAMENUM:
5988 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
5989 | proto_tree_set_uint64(PNODE_FINFO(pi)((pi)->finfo), value);
5990 | break;
5991 |
5992 | default:
5993 | 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)
5994 | 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);
5995 | }
5996 |
5997 | return pi;
5998 | }
5999 |
6000 | proto_item *
6001 | proto_tree_add_uint64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6002 | int start, int length, uint64_t value,
6003 | const char *format, ...)
6004 | {
6005 | proto_item *pi;
6006 | va_list ap;
6007 |
6008 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6009 | if (pi != tree) {
6010 | va_start(ap, format)__builtin_va_start(ap, format);
6011 | proto_tree_set_representation_value(pi, format, ap);
6012 | va_end(ap)__builtin_va_end(ap);
6013 | }
6014 |
6015 | return pi;
6016 | }
6017 |
6018 | proto_item *
6019 | proto_tree_add_uint64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6020 | int start, int length, uint64_t value,
6021 | const char *format, ...)
6022 | {
6023 | proto_item *pi;
6024 | va_list ap;
6025 |
6026 | pi = proto_tree_add_uint64(tree, hfindex, tvb, start, length, value);
6027 | if (pi != tree) {
6028 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6028, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6029 |
6030 | va_start(ap, format)__builtin_va_start(ap, format);
6031 | proto_tree_set_representation(pi, format, ap);
6032 | va_end(ap)__builtin_va_end(ap);
6033 | }
6034 |
6035 | return pi;
6036 | }
6037 |
6038 | /* Set the FT_UINT{40,48,56,64} value */
6039 | static void
6040 | proto_tree_set_uint64(field_info *fi, uint64_t value)
6041 | {
6042 | const header_field_info *hfinfo;
6043 | uint64_t integer;
6044 |
6045 | hfinfo = fi->hfinfo;
6046 | integer = value;
6047 |
6048 | if (hfinfo->bitmask) {
6049 | /* Mask out irrelevant portions */
6050 | integer &= hfinfo->bitmask;
6051 |
6052 | /* Shift bits */
6053 | integer >>= hfinfo_bitshift(hfinfo);
6054 |
6055 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6056 | 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);
6057 | }
6058 |
6059 | fvalue_set_uinteger64(fi->value, integer);
6060 | }
6061 |
6062 | /* Add FT_INT{8,16,24,32} to a proto_tree */
6063 | proto_item *
6064 | proto_tree_add_int(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6065 | int length, int32_t value)
6066 | {
6067 | proto_item *pi = NULL((void*)0);
6068 | header_field_info *hfinfo;
6069 |
6070 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6071 |
6072 | 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", 6072 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6072, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6072, "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", 6072, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6073 |
6074 | switch (hfinfo->type) {
6075 | case FT_INT8:
6076 | case FT_INT16:
6077 | case FT_INT24:
6078 | case FT_INT32:
6079 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6080 | proto_tree_set_int(PNODE_FINFO(pi)((pi)->finfo), value);
6081 | break;
6082 |
6083 | default:
6084 | 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)
6085 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT8, FT_INT16, FT_INT24, or FT_INT32" , hfinfo->abbrev);
6086 | }
6087 |
6088 | return pi;
6089 | }
6090 |
6091 | proto_item *
6092 | proto_tree_add_int_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6093 | int start, int length, int32_t value,
6094 | const char *format, ...)
6095 | {
6096 | proto_item *pi;
6097 | va_list ap;
6098 |
6099 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6100 | if (pi != tree) {
6101 | va_start(ap, format)__builtin_va_start(ap, format);
6102 | proto_tree_set_representation_value(pi, format, ap);
6103 | va_end(ap)__builtin_va_end(ap);
6104 | }
6105 |
6106 | return pi;
6107 | }
6108 |
6109 | proto_item *
6110 | proto_tree_add_int_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6111 | int start, int length, int32_t value,
6112 | const char *format, ...)
6113 | {
6114 | proto_item *pi;
6115 | va_list ap;
6116 |
6117 | pi = proto_tree_add_int(tree, hfindex, tvb, start, length, value);
6118 | if (pi != tree) {
6119 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6119, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6120 |
6121 | va_start(ap, format)__builtin_va_start(ap, format);
6122 | proto_tree_set_representation(pi, format, ap);
6123 | va_end(ap)__builtin_va_end(ap);
6124 | }
6125 |
6126 | return pi;
6127 | }
6128 |
6129 | /* Set the FT_INT{8,16,24,32} value */
6130 | static void
6131 | proto_tree_set_int(field_info *fi, int32_t value)
6132 | {
6133 | const header_field_info *hfinfo;
6134 | uint32_t integer;
6135 | int no_of_bits;
6136 |
6137 | hfinfo = fi->hfinfo;
6138 | integer = (uint32_t) value;
6139 |
6140 | if (hfinfo->bitmask) {
6141 | /* Mask out irrelevant portions */
6142 | integer &= (uint32_t)(hfinfo->bitmask);
6143 |
6144 | /* Shift bits */
6145 | integer >>= hfinfo_bitshift(hfinfo);
6146 |
6147 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6148 | integer = ws_sign_ext32(integer, no_of_bits);
6149 |
6150 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6151 | 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);
6152 | }
6153 |
6154 | fvalue_set_sinteger(fi->value, integer);
6155 | }
6156 |
6157 | /* Add FT_INT{40,48,56,64} to a proto_tree */
6158 | proto_item *
6159 | proto_tree_add_int64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6160 | int length, int64_t value)
6161 | {
6162 | proto_item *pi = NULL((void*)0);
6163 | header_field_info *hfinfo;
6164 |
6165 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6166 |
6167 | 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", 6167 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6167, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6167, "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", 6167, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6168 |
6169 | switch (hfinfo->type) {
6170 | case FT_INT40:
6171 | case FT_INT48:
6172 | case FT_INT56:
6173 | case FT_INT64:
6174 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6175 | proto_tree_set_int64(PNODE_FINFO(pi)((pi)->finfo), value);
6176 | break;
6177 |
6178 | default:
6179 | 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)
6180 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_INT40, FT_INT48, FT_INT56, or FT_INT64" , hfinfo->abbrev);
6181 | }
6182 |
6183 | return pi;
6184 | }
6185 |
6186 | proto_item *
6187 | proto_tree_add_int64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6188 | int start, int length, int64_t value,
6189 | const char *format, ...)
6190 | {
6191 | proto_item *pi;
6192 | va_list ap;
6193 |
6194 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6195 | if (pi != tree) {
6196 | va_start(ap, format)__builtin_va_start(ap, format);
6197 | proto_tree_set_representation_value(pi, format, ap);
6198 | va_end(ap)__builtin_va_end(ap);
6199 | }
6200 |
6201 | return pi;
6202 | }
6203 |
6204 | /* Set the FT_INT{40,48,56,64} value */
6205 | static void
6206 | proto_tree_set_int64(field_info *fi, int64_t value)
6207 | {
6208 | const header_field_info *hfinfo;
6209 | uint64_t integer;
6210 | int no_of_bits;
6211 |
6212 | hfinfo = fi->hfinfo;
6213 | integer = value;
6214 |
6215 | if (hfinfo->bitmask) {
6216 | /* Mask out irrelevant portions */
6217 | integer &= hfinfo->bitmask;
6218 |
6219 | /* Shift bits */
6220 | integer >>= hfinfo_bitshift(hfinfo);
6221 |
6222 | no_of_bits = ws_count_ones(hfinfo->bitmask);
6223 | integer = ws_sign_ext64(integer, no_of_bits);
6224 |
6225 | FI_SET_FLAG(fi, FI_BITS_OFFSET(hfinfo_bitoffset(hfinfo)))do { if (fi) (fi)->flags = (fi)->flags | ((((hfinfo_bitoffset (hfinfo)) & 63) << 5)); } while(0);
6226 | 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);
6227 | }
6228 |
6229 | fvalue_set_sinteger64(fi->value, integer);
6230 | }
6231 |
6232 | proto_item *
6233 | proto_tree_add_int64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6234 | int start, int length, int64_t value,
6235 | const char *format, ...)
6236 | {
6237 | proto_item *pi;
6238 | va_list ap;
6239 |
6240 | pi = proto_tree_add_int64(tree, hfindex, tvb, start, length, value);
6241 | if (pi != tree) {
6242 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6242, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6243 |
6244 | va_start(ap, format)__builtin_va_start(ap, format);
6245 | proto_tree_set_representation(pi, format, ap);
6246 | va_end(ap)__builtin_va_end(ap);
6247 | }
6248 |
6249 | return pi;
6250 | }
6251 |
6252 | /* Add a FT_EUI64 to a proto_tree */
6253 | proto_item *
6254 | proto_tree_add_eui64(proto_tree *tree, int hfindex, tvbuff_t *tvb, int start,
6255 | int length, const uint64_t value)
6256 | {
6257 | proto_item *pi;
6258 | header_field_info *hfinfo;
6259 |
6260 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
6261 |
6262 | 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", 6262 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6262, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 6262, "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", 6262, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
6263 |
6264 | 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", 6264, ((hfinfo))->abbrev))));
6265 |
6266 | pi = proto_tree_add_pi(tree, hfinfo, tvb, start, &length);
6267 | proto_tree_set_eui64(PNODE_FINFO(pi)((pi)->finfo), value);
6268 |
6269 | return pi;
6270 | }
6271 |
6272 | proto_item *
6273 | proto_tree_add_eui64_format_value(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6274 | int start, int length, const uint64_t value,
6275 | const char *format, ...)
6276 | {
6277 | proto_item *pi;
6278 | va_list ap;
6279 |
6280 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6281 | if (pi != tree) {
6282 | va_start(ap, format)__builtin_va_start(ap, format);
6283 | proto_tree_set_representation_value(pi, format, ap);
6284 | va_end(ap)__builtin_va_end(ap);
6285 | }
6286 |
6287 | return pi;
6288 | }
6289 |
6290 | proto_item *
6291 | proto_tree_add_eui64_format(proto_tree *tree, int hfindex, tvbuff_t *tvb,
6292 | int start, int length, const uint64_t value,
6293 | const char *format, ...)
6294 | {
6295 | proto_item *pi;
6296 | va_list ap;
6297 |
6298 | pi = proto_tree_add_eui64(tree, hfindex, tvb, start, length, value);
6299 | if (pi != tree) {
6300 | TRY_TO_FAKE_THIS_REPR(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6300, __func__, "assertion failed: %s", "pi" ); } while (0); if (!((pi)->finfo)) return pi; if (!(((pi) ->tree_data)->visible) && proto_item_is_hidden( (pi))) { return pi; };
6301 |
6302 | va_start(ap, format)__builtin_va_start(ap, format);
6303 | proto_tree_set_representation(pi, format, ap);
6304 | va_end(ap)__builtin_va_end(ap);
6305 | }
6306 |
6307 | return pi;
6308 | }
6309 |
6310 | /* Set the FT_EUI64 value */
6311 | static void
6312 | proto_tree_set_eui64(field_info *fi, const uint64_t value)
6313 | {
6314 | uint8_t v[FT_EUI64_LEN8];
6315 | phtonu64(v, value);
6316 | fvalue_set_bytes_data(fi->value, v, FT_EUI64_LEN8);
6317 | }
6318 |
6319 | static void
6320 | proto_tree_set_eui64_tvb(field_info *fi, tvbuff_t *tvb, int start, const unsigned encoding)
6321 | {
6322 | if (encoding)
6323 | {
6324 | proto_tree_set_eui64(fi, tvb_get_letoh64(tvb, start));
6325 | } else {
6326 | proto_tree_set_eui64(fi, tvb_get_ntoh64(tvb, start));
6327 | }
6328 | }
6329 |
6330 | proto_item *
6331 | proto_tree_add_mac48_detail(const mac_hf_list_t *list_specific,
6332 | const mac_hf_list_t *list_generic,
6333 | int idx, tvbuff_t *tvb,
6334 | proto_tree *tree, int offset)
6335 | {
6336 | uint8_t addr[6];
6337 | const char *addr_name = NULL((void*)0);
6338 | const char *oui_name = NULL((void*)0);
6339 | proto_item *addr_item = NULL((void*)0);
6340 | proto_tree *addr_tree = NULL((void*)0);
6341 | proto_item *ret_val = NULL((void*)0);
6342 |
6343 | if (tree == NULL((void*)0) || list_specific == NULL((void*)0)) {
6344 | return NULL((void*)0);
6345 | }
6346 |
6347 | /* Resolve what we can of the address */
6348 | tvb_memcpy(tvb, addr, offset, sizeof addr);
6349 | if (list_specific->hf_addr_resolved || (list_generic && list_generic->hf_addr_resolved)) {
6350 | addr_name = get_ether_name(addr);
6351 | }
6352 | if (list_specific->hf_oui_resolved || (list_generic && list_generic->hf_oui_resolved)) {
6353 | oui_name = get_manuf_name_if_known(addr, sizeof(addr));
6354 | }
6355 |
6356 | /* Add the item for the specific address type */
6357 | ret_val = proto_tree_add_item(tree, *list_specific->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6358 | if (idx >= 0) {
6359 | addr_tree = proto_item_add_subtree(ret_val, idx);
6360 | }
6361 | else {
6362 | addr_tree = tree;
6363 | }
6364 |
6365 | if (list_specific->hf_addr_resolved != NULL((void*)0)) {
6366 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_addr_resolved,
6367 | tvb, offset, 6, addr_name);
6368 | proto_item_set_generated(addr_item);
6369 | proto_item_set_hidden(addr_item);
6370 | }
6371 |
6372 | if (list_specific->hf_oui != NULL((void*)0)) {
6373 | addr_item = proto_tree_add_item(addr_tree, *list_specific->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6374 | proto_item_set_generated(addr_item);
6375 | proto_item_set_hidden(addr_item);
6376 |
6377 | if (oui_name != NULL((void*)0) && list_specific->hf_oui_resolved != NULL((void*)0)) {
6378 | addr_item = proto_tree_add_string(addr_tree, *list_specific->hf_oui_resolved, tvb, offset, 6, oui_name);
6379 | proto_item_set_generated(addr_item);
6380 | proto_item_set_hidden(addr_item);
6381 | }
6382 | }
6383 |
6384 | if (list_specific->hf_lg != NULL((void*)0)) {
6385 | proto_tree_add_item(addr_tree, *list_specific->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6386 | }
6387 | if (list_specific->hf_ig != NULL((void*)0)) {
6388 | proto_tree_add_item(addr_tree, *list_specific->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6389 | }
6390 |
6391 | /* Were we given a list for generic address fields? If not, stop here */
6392 | if (list_generic == NULL((void*)0)) {
6393 | return ret_val;
6394 | }
6395 |
6396 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_addr, tvb, offset, 6, ENC_BIG_ENDIAN0x00000000);
6397 | proto_item_set_hidden(addr_item);
6398 |
6399 | if (list_generic->hf_addr_resolved != NULL((void*)0)) {
6400 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_addr_resolved,
6401 | tvb, offset, 6, addr_name);
6402 | proto_item_set_generated(addr_item);
6403 | proto_item_set_hidden(addr_item);
6404 | }
6405 |
6406 | if (list_generic->hf_oui != NULL((void*)0)) {
6407 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_oui, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6408 | proto_item_set_generated(addr_item);
6409 | proto_item_set_hidden(addr_item);
6410 |
6411 | if (oui_name != NULL((void*)0) && list_generic->hf_oui_resolved != NULL((void*)0)) {
6412 | addr_item = proto_tree_add_string(addr_tree, *list_generic->hf_oui_resolved, tvb, offset, 6, oui_name);
6413 | proto_item_set_generated(addr_item);
6414 | proto_item_set_hidden(addr_item);
6415 | }
6416 | }
6417 |
6418 | if (list_generic->hf_lg != NULL((void*)0)) {
6419 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_lg, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6420 | proto_item_set_hidden(addr_item);
6421 | }
6422 | if (list_generic->hf_ig != NULL((void*)0)) {
6423 | addr_item = proto_tree_add_item(addr_tree, *list_generic->hf_ig, tvb, offset, 3, ENC_BIG_ENDIAN0x00000000);
6424 | proto_item_set_hidden(addr_item);
6425 | }
6426 | return ret_val;
6427 | }
6428 |
6429 | static proto_item *
6430 | proto_tree_add_fake_node(proto_tree *tree, const header_field_info *hfinfo)
6431 | {
6432 | proto_node *pnode, *tnode, *sibling;
6433 | field_info *tfi;
6434 | unsigned depth = 1;
6435 |
6436 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6436, __func__, "assertion failed: %s", "tree" ); } while (0);
6437 |
6438 | /*
6439 | * Restrict our depth. proto_tree_traverse_pre_order and
6440 | * proto_tree_traverse_post_order (and possibly others) are recursive
6441 | * so we need to be mindful of our stack size.
6442 | */
6443 | if (tree->first_child == NULL((void*)0)) {
6444 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6445 | depth++;
6446 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6447 | 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__)), 6450)))
6448 | "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__)), 6450)))
6449 | 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__)), 6450)))
6450 | 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__)), 6450)));
6451 | }
6452 | }
6453 | }
6454 |
6455 | /*
6456 | * Make sure "tree" is ready to have subtrees under it, by
6457 | * checking whether it's been given an ett_ value.
6458 | *
6459 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6460 | * node of the protocol tree. That node is not displayed,
6461 | * so it doesn't need an ett_ value to remember whether it
6462 | * was expanded.
6463 | */
6464 | tnode = tree;
6465 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6466 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6467 | 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" , 6468)
6468 | 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" , 6468);
6469 | /* XXX - is it safe to continue here? */
6470 | }
6471 |
6472 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6473 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6474 | pnode->parent = tnode;
6475 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = hfinfo;
6476 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0); // Faked
6477 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6478 |
6479 | if (tnode->last_child != NULL((void*)0)) {
6480 | sibling = tnode->last_child;
6481 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6481, "sibling->next == ((void*)0)" ))));
6482 | sibling->next = pnode;
6483 | } else
6484 | tnode->first_child = pnode;
6485 | tnode->last_child = pnode;
6486 |
6487 | /* We should not be adding a fake node for an interesting field */
6488 | 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", 6488, __func__, "assertion failed: %s" , "hfinfo->ref_type != HF_REF_TYPE_DIRECT && hfinfo->ref_type != HF_REF_TYPE_PRINT" ); } while (0);
6489 |
6490 | /* XXX - Should the proto_item have a header_field_info member, at least
6491 | * for faked items, to know what hfi was faked? (Some dissectors look at
6492 | * the tree items directly.)
6493 | */
6494 | return (proto_item *)pnode;
6495 | }
6496 |
6497 | /* Add a field_info struct to the proto_tree, encapsulating it in a proto_node */
6498 | static proto_item *
6499 | proto_tree_add_node(proto_tree *tree, field_info *fi)
6500 | {
6501 | proto_node *pnode, *tnode, *sibling;
6502 | field_info *tfi;
6503 | unsigned depth = 1;
6504 |
6505 | ws_assert(tree)do { if ((1) && !(tree)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6505, __func__, "assertion failed: %s", "tree" ); } while (0);
6506 |
6507 | /*
6508 | * Restrict our depth. proto_tree_traverse_pre_order and
6509 | * proto_tree_traverse_post_order (and possibly others) are recursive
6510 | * so we need to be mindful of our stack size.
6511 | */
6512 | if (tree->first_child == NULL((void*)0)) {
6513 | for (tnode = tree; tnode != NULL((void*)0); tnode = tnode->parent) {
6514 | depth++;
6515 | if (G_UNLIKELY(depth > prefs.gui_max_tree_depth)(depth > prefs.gui_max_tree_depth)) {
6516 | fvalue_free(fi->value);
6517 | fi->value = NULL((void*)0);
6518 | 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__)), 6521)))
6519 | "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__)), 6521)))
6520 | 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__)), 6521)))
6521 | 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__)), 6521)));
6522 | }
6523 | }
6524 | }
6525 |
6526 | /*
6527 | * Make sure "tree" is ready to have subtrees under it, by
6528 | * checking whether it's been given an ett_ value.
6529 | *
6530 | * "PNODE_FINFO(tnode)" may be null; that's the case for the root
6531 | * node of the protocol tree. That node is not displayed,
6532 | * so it doesn't need an ett_ value to remember whether it
6533 | * was expanded.
6534 | */
6535 | tnode = tree;
6536 | tfi = PNODE_FINFO(tnode)((tnode)->finfo);
6537 | if (tfi != NULL((void*)0) && (tfi->tree_type < 0 || tfi->tree_type >= num_tree_types)) {
6538 | /* Since we are not adding fi to a node, its fvalue won't get
6539 | * freed by proto_tree_free_node(), so free it now.
6540 | */
6541 | fvalue_free(fi->value);
6542 | fi->value = NULL((void*)0);
6543 | 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", 6544)
6544 | 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", 6544);
6545 | /* XXX - is it safe to continue here? */
6546 | }
6547 |
6548 | pnode = wmem_new(PNODE_POOL(tree), proto_node)((proto_node*)wmem_alloc((((tree)->tree_data->pinfo-> pool)), sizeof(proto_node)));
6549 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
6550 | pnode->parent = tnode;
6551 | PNODE_HFINFO(pnode)((pnode)->hfinfo) = fi->hfinfo;
6552 | PNODE_FINFO(pnode)((pnode)->finfo) = fi;
6553 | pnode->tree_data = PTREE_DATA(tree)((tree)->tree_data);
6554 |
6555 | if (tnode->last_child != NULL((void*)0)) {
6556 | sibling = tnode->last_child;
6557 | DISSECTOR_ASSERT(sibling->next == NULL)((void) ((sibling->next == ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6557, "sibling->next == ((void*)0)" ))));
6558 | sibling->next = pnode;
6559 | } else
6560 | tnode->first_child = pnode;
6561 | tnode->last_child = pnode;
6562 |
6563 | tree_data_add_maybe_interesting_field(pnode->tree_data, fi);
6564 |
6565 | return (proto_item *)pnode;
6566 | }
6567 |
6568 |
6569 | /* Generic way to allocate field_info and add to proto_tree.
6570 | * Sets *pfi to address of newly-allocated field_info struct */
6571 | static proto_item *
6572 | proto_tree_add_pi(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb, int start,
6573 | int *length)
6574 | {
6575 | proto_item *pi;
6576 | field_info *fi;
6577 | int item_length;
6578 |
6579 | get_hfi_length(hfinfo, tvb, start, length, &item_length, ENC_NA0x00000000);
6580 | fi = new_field_info(tree, hfinfo, tvb, start, item_length);
6581 | pi = proto_tree_add_node(tree, fi);
6582 |
6583 | return pi;
6584 | }
6585 |
6586 |
6587 | static void
6588 | get_hfi_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start, int *length,
6589 | int *item_length, const unsigned encoding)
6590 | {
6591 | int length_remaining;
6592 |
6593 | /*
6594 | * We only allow a null tvbuff if the item has a zero length,
6595 | * i.e. if there's no data backing it.
6596 | */
6597 | 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", 6597, "tvb != ((void*)0) || *length == 0" ))));
6598 |
6599 | /*
6600 | * XXX - in some protocols, there are 32-bit unsigned length
6601 | * fields, so lengths in protocol tree and tvbuff routines
6602 | * should really be unsigned. We should have, for those
6603 | * field types for which "to the end of the tvbuff" makes sense,
6604 | * additional routines that take no length argument and
6605 | * add fields that run to the end of the tvbuff.
6606 | */
6607 | if (*length == -1) {
6608 | /*
6609 | * For FT_NONE, FT_PROTOCOL, FT_BYTES, FT_STRING,
6610 | * FT_STRINGZPAD, and FT_STRINGZTRUNC fields, a length
6611 | * of -1 means "set the length to what remains in the
6612 | * tvbuff".
6613 | *
6614 | * The assumption is either that
6615 | *
6616 | * 1) the length of the item can only be determined
6617 | * by dissection (typically true of items with
6618 | * subitems, which are probably FT_NONE or
6619 | * FT_PROTOCOL)
6620 | *
6621 | * or
6622 | *
6623 | * 2) if the tvbuff is "short" (either due to a short
6624 | * snapshot length or due to lack of reassembly of
6625 | * fragments/segments/whatever), we want to display
6626 | * what's available in the field (probably FT_BYTES
6627 | * or FT_STRING) and then throw an exception later
6628 | *
6629 | * or
6630 | *
6631 | * 3) the field is defined to be "what's left in the
6632 | * packet"
6633 | *
6634 | * so we set the length to what remains in the tvbuff so
6635 | * that, if we throw an exception while dissecting, it
6636 | * has what is probably the right value.
6637 | *
6638 | * For FT_STRINGZ, it means "the string is null-terminated,
6639 | * not null-padded; set the length to the actual length
6640 | * of the string", and if the tvbuff if short, we just
6641 | * throw an exception.
6642 | *
6643 | * For ENC_VARINT_PROTOBUF|ENC_VARINT_QUIC|ENC_VARIANT_ZIGZAG|ENC_VARINT_SDNV,
6644 | * it means "find the end of the string",
6645 | * and if the tvbuff if short, we just throw an exception.
6646 | *
6647 | * It's not valid for any other type of field. For those
6648 | * fields, we treat -1 the same way we treat other
6649 | * negative values - we assume the length is a Really
6650 | * Big Positive Number, and throw a ReportedBoundsError
6651 | * exception, under the assumption that the Really Big
6652 | * Length would run past the end of the packet.
6653 | */
6654 | 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 )))) {
6655 | if (encoding & (ENC_VARINT_PROTOBUF0x00000002|ENC_VARINT_ZIGZAG0x00000008|ENC_VARINT_SDNV0x00000010)) {
6656 | /*
6657 | * Leave the length as -1, so our caller knows
6658 | * it was -1.
6659 | */
6660 | *item_length = *length;
6661 | return;
6662 | } else if (encoding & ENC_VARINT_QUIC0x00000004) {
6663 | switch (tvb_get_uint8(tvb, start) >> 6)
6664 | {
6665 | case 0: /* 0b00 => 1 byte length (6 bits Usable) */
6666 | *item_length = 1;
6667 | break;
6668 | case 1: /* 0b01 => 2 bytes length (14 bits Usable) */
6669 | *item_length = 2;
6670 | break;
6671 | case 2: /* 0b10 => 4 bytes length (30 bits Usable) */
6672 | *item_length = 4;
6673 | break;
6674 | case 3: /* 0b11 => 8 bytes length (62 bits Usable) */
6675 | *item_length = 8;
6676 | break;
6677 | }
6678 | }
6679 | }
6680 |
6681 | switch (hfinfo->type) {
6682 |
6683 | case FT_PROTOCOL:
6684 | case FT_NONE:
6685 | case FT_BYTES:
6686 | case FT_STRING:
6687 | case FT_STRINGZPAD:
6688 | case FT_STRINGZTRUNC:
6689 | /*
6690 | * We allow FT_PROTOCOLs to be zero-length -
6691 | * for example, an ONC RPC NULL procedure has
6692 | * neither arguments nor reply, so the
6693 | * payload for that protocol is empty.
6694 | *
6695 | * We also allow the others to be zero-length -
6696 | * because that's the way the code has been for a
6697 | * long, long time.
6698 | *
6699 | * However, we want to ensure that the start
6700 | * offset is not *past* the byte past the end
6701 | * of the tvbuff: we throw an exception in that
6702 | * case.
6703 | */
6704 | *length = tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
6705 | DISSECTOR_ASSERT(*length >= 0)((void) ((*length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 6705, "*length >= 0" ))));
6706 | break;
6707 |
6708 | case FT_STRINGZ:
6709 | /*
6710 | * Leave the length as -1, so our caller knows
6711 | * it was -1.
6712 | */
6713 | break;
6714 |
6715 | default:
6716 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6717 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 6717));
6718 | }
6719 | *item_length = *length;
6720 | } else {
6721 | *item_length = *length;
6722 | if (hfinfo->type == FT_PROTOCOL || hfinfo->type == FT_NONE) {
6723 | /*
6724 | * These types are for interior nodes of the
6725 | * tree, and don't have data associated with
6726 | * them; if the length is negative (XXX - see
6727 | * above) or goes past the end of the tvbuff,
6728 | * cut it short at the end of the tvbuff.
6729 | * That way, if this field is selected in
6730 | * Wireshark, we don't highlight stuff past
6731 | * the end of the data.
6732 | */
6733 | /* XXX - what to do, if we don't have a tvb? */
6734 | if (tvb) {
6735 | length_remaining = tvb_captured_length_remaining(tvb, start);
6736 | if (*item_length < 0 ||
6737 | (*item_length > 0 &&
6738 | (length_remaining < *item_length)))
6739 | *item_length = length_remaining;
6740 | }
6741 | }
6742 | if (*item_length < 0) {
6743 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6744 | }
6745 | }
6746 | }
6747 |
6748 | static int
6749 | get_full_length(header_field_info *hfinfo, tvbuff_t *tvb, const int start,
6750 | int length, unsigned item_length, const int encoding)
6751 | {
6752 | uint32_t n;
6753 |
6754 | /*
6755 | * We need to get the correct item length here.
6756 | * That's normally done by proto_tree_new_item(),
6757 | * but we won't be calling it.
6758 | */
6759 | switch (hfinfo->type) {
6760 |
6761 | case FT_NONE:
6762 | case FT_PROTOCOL:
6763 | case FT_BYTES:
6764 | /*
6765 | * The length is the specified length.
6766 | */
6767 | break;
6768 |
6769 | case FT_UINT_BYTES:
6770 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding);
6771 | item_length += n;
6772 | if ((int)item_length < length) {
6773 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6774 | }
6775 | break;
6776 |
6777 | /* XXX - make these just FT_UINT? */
6778 | case FT_UINT8:
6779 | case FT_UINT16:
6780 | case FT_UINT24:
6781 | case FT_UINT32:
6782 | case FT_UINT40:
6783 | case FT_UINT48:
6784 | case FT_UINT56:
6785 | case FT_UINT64:
6786 | /* XXX - make these just FT_INT? */
6787 | case FT_INT8:
6788 | case FT_INT16:
6789 | case FT_INT24:
6790 | case FT_INT32:
6791 | case FT_INT40:
6792 | case FT_INT48:
6793 | case FT_INT56:
6794 | case FT_INT64:
6795 | if (encoding & ENC_VARINT_MASK(0x00000002|0x00000004|0x00000008|0x00000010)) {
6796 | if (length < -1) {
6797 | report_type_length_mismatch(NULL((void*)0), "a FT_[U]INT", length, true1);
6798 | }
6799 | if (length == -1) {
6800 | uint64_t dummy;
6801 | /* This can throw an exception */
6802 | /* XXX - do this without fetching the varint? */
6803 | length = tvb_get_varint(tvb, start, FT_VARINT_MAX_LEN10, &dummy, encoding);
6804 | if (length == 0) {
6805 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6806 | }
6807 | }
6808 | item_length = length;
6809 | break;
6810 | }
6811 |
6812 | /*
6813 | * The length is the specified length.
6814 | */
6815 | break;
6816 |
6817 | case FT_BOOLEAN:
6818 | case FT_CHAR:
6819 | case FT_IPv4:
6820 | case FT_IPXNET:
6821 | case FT_IPv6:
6822 | case FT_FCWWN:
6823 | case FT_AX25:
6824 | case FT_VINES:
6825 | case FT_ETHER:
6826 | case FT_EUI64:
6827 | case FT_GUID:
6828 | case FT_OID:
6829 | case FT_REL_OID:
6830 | case FT_SYSTEM_ID:
6831 | case FT_FLOAT:
6832 | case FT_DOUBLE:
6833 | case FT_STRING:
6834 | /*
6835 | * The length is the specified length.
6836 | */
6837 | break;
6838 |
6839 | case FT_STRINGZ:
6840 | if (length < -1) {
6841 | report_type_length_mismatch(NULL((void*)0), "a string", length, true1);
6842 | }
6843 | if (length == -1) {
6844 | /* This can throw an exception */
6845 | /* XXX - do this without fetching the string? */
6846 | wmem_free(NULL((void*)0), tvb_get_stringz_enc(NULL((void*)0), tvb, start, &length, encoding));
6847 | }
6848 | item_length = length;
6849 | break;
6850 |
6851 | case FT_UINT_STRING:
6852 | n = get_uint_value(NULL((void*)0), tvb, start, length, encoding & ~ENC_CHARENCODING_MASK0x0000FFFE);
6853 | item_length += n;
6854 | if ((int)item_length < length) {
6855 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
6856 | }
6857 | break;
6858 |
6859 | case FT_STRINGZPAD:
6860 | case FT_STRINGZTRUNC:
6861 | case FT_ABSOLUTE_TIME:
6862 | case FT_RELATIVE_TIME:
6863 | case FT_IEEE_11073_SFLOAT:
6864 | case FT_IEEE_11073_FLOAT:
6865 | /*
6866 | * The length is the specified length.
6867 | */
6868 | break;
6869 |
6870 | default:
6871 | 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 ))
6872 | 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 ))
6873 | 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 ))
6874 | 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 ));
6875 | break;
6876 | }
6877 | return item_length;
6878 | }
6879 |
6880 | // This was arbitrarily chosen, but if you're adding 50K items to the tree
6881 | // without advancing the offset you should probably take a long, hard look
6882 | // at what you're doing.
6883 | // We *could* make this a configurable option, but I (Gerald) would like to
6884 | // avoid adding yet another nerd knob.
6885 | # define PROTO_TREE_MAX_IDLE50000 50000
6886 | static field_info *
6887 | new_field_info(proto_tree *tree, header_field_info *hfinfo, tvbuff_t *tvb,
6888 | const int start, const int item_length)
6889 | {
6890 | field_info *fi;
6891 |
6892 | FIELD_INFO_NEW(PNODE_POOL(tree), fi)fi = ((field_info*)wmem_alloc((((tree)->tree_data->pinfo ->pool)), sizeof(field_info)));
6893 |
6894 | fi->hfinfo = hfinfo;
6895 | fi->start = start;
6896 | fi->start += (tvb)?tvb_raw_offset(tvb):0;
6897 | /* add the data source tvbuff */
6898 | fi->ds_tvb = tvb ? tvb_get_ds_tvb(tvb) : NULL((void*)0);
6899 |
6900 | // If our start offset hasn't advanced after adding many items it probably
6901 | // means we're in a large or infinite loop.
6902 | if (fi->start > 0) {
6903 | if (fi->ds_tvb == PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb && fi->start <= PTREE_DATA(tree)((tree)->tree_data)->max_start) {
6904 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count++;
6905 | 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", 6905, "((tree)->tree_data)->start_idle_count < 50000" , fi->hfinfo->abbrev))));
6906 | } else {
6907 | PTREE_DATA(tree)((tree)->tree_data)->idle_count_ds_tvb = fi->ds_tvb;
6908 | PTREE_DATA(tree)((tree)->tree_data)->max_start = fi->start;
6909 | PTREE_DATA(tree)((tree)->tree_data)->start_idle_count = 0;
6910 | }
6911 | }
6912 | fi->length = item_length;
6913 | fi->tree_type = -1;
6914 | fi->flags = 0;
6915 | if (!PTREE_DATA(tree)((tree)->tree_data)->visible) {
6916 | /* If the tree is not visible, set the item hidden, unless we
6917 | * need the representation or length and can't fake them.
6918 | */
6919 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT && (hfinfo->type != FT_PROTOCOL || PTREE_DATA(tree)((tree)->tree_data)->fake_protocols)) {
6920 | FI_SET_FLAG(fi, FI_HIDDEN)do { if (fi) (fi)->flags = (fi)->flags | (0x00000001); } while(0);
6921 | }
6922 | }
6923 | fi->value = fvalue_new(fi->hfinfo->type);
6924 | fi->rep = NULL((void*)0);
6925 |
6926 | fi->appendix_start = 0;
6927 | fi->appendix_length = 0;
6928 |
6929 | fi->total_layer_num = tree->tree_data->pinfo->curr_layer_num;
6930 | fi->proto_layer_num = tree->tree_data->pinfo->curr_proto_layer_num;
6931 |
6932 | return fi;
6933 | }
6934 |
6935 | static size_t proto_find_value_pos(const header_field_info *hfinfo, const char *representation)
6936 | {
6937 | if (hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000) {
6938 | return 0;
6939 | }
6940 |
6941 | /* Search for field name */
6942 | char *ptr = strstr(representation, hfinfo->name);
6943 | if (!ptr) {
6944 | return 0;
6945 | }
6946 |
6947 | /* Check if field name ends with the ": " delimiter */
6948 | ptr += strlen(hfinfo->name);
6949 | if (strncmp(ptr, ": ", 2) == 0) {
6950 | ptr += 2;
6951 | }
6952 |
6953 | /* Return offset to after field name */
6954 | return ptr - representation;
6955 | }
6956 |
6957 | static size_t label_find_name_pos(const item_label_t *rep)
6958 | {
6959 | size_t name_pos = 0;
6960 |
6961 | /* If the value_pos is too small or too large, we can't find the expected format */
6962 | if (rep->value_pos <= 2 || rep->value_pos >= sizeof(rep->representation)) {
6963 | return 0;
6964 | }
6965 |
6966 | /* Check if the format looks like "label: value", then set name_pos before ':'. */
6967 | if (rep->representation[rep->value_pos-2] == ':') {
6968 | name_pos = rep->value_pos - 2;
6969 | }
6970 |
6971 | return name_pos;
6972 | }
6973 |
6974 | /* If the protocol tree is to be visible, set the representation of a
6975 | proto_tree entry with the name of the field for the item and with
6976 | the value formatted with the supplied printf-style format and
6977 | argument list. */
6978 | static void
6979 | proto_tree_set_representation_value(proto_item *pi, const char *format, va_list ap)
6980 | {
6981 | ws_assert(pi)do { if ((1) && !(pi)) ws_log_fatal_full("Epan", LOG_LEVEL_ERROR , "epan/proto.c", 6981, __func__, "assertion failed: %s", "pi" ); } while (0);
6982 |
6983 | /* If the tree (GUI) or item isn't visible it's pointless for us to generate the protocol
6984 | * items string representation */
6985 | if (PTREE_DATA(pi)((pi)->tree_data)->visible || !proto_item_is_hidden(pi)) {
6986 | size_t name_pos, ret = 0;
6987 | char *str;
6988 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
6989 | const header_field_info *hf;
6990 |
6991 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 6991, "fi"))));
6992 |
6993 | hf = fi->hfinfo;
6994 |
6995 | 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;;
6996 | 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)))) {
6997 | uint64_t val;
6998 | char *p;
6999 |
7000 | 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))
7001 | val = fvalue_get_uinteger(fi->value);
7002 | else
7003 | val = fvalue_get_uinteger64(fi->value);
7004 |
7005 | val <<= hfinfo_bitshift(hf);
7006 |
7007 | p = decode_bitfield_value(fi->rep->representation, val, hf->bitmask, hfinfo_container_bitwidth(hf));
7008 | ret = (p - fi->rep->representation);
7009 | }
7010 |
7011 | /* put in the hf name */
7012 | name_pos = ret = label_concat(fi->rep->representation, ret, (const uint8_t*)hf->name)ws_label_strcpy(fi->rep->representation, 240, ret, (const uint8_t*)hf->name, 0);
7013 |
7014 | ret = label_concat(fi->rep->representation, ret, (const uint8_t*)": ")ws_label_strcpy(fi->rep->representation, 240, ret, (const uint8_t*)": ", 0);
7015 | /* If possible, Put in the value of the string */
7016 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7017 | 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" , 7017, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7018 | fi->rep->value_pos = ret;
7019 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, ret, (const uint8_t*)str, 0);
7020 | if (ret >= ITEM_LABEL_LENGTH240) {
7021 | /* Uh oh, we don't have enough room. Tell the user
7022 | * that the field is truncated.
7023 | */
7024 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7025 | }
7026 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7027 | }
7028 | }
7029 |
7030 | /* If the protocol tree is to be visible, set the representation of a
7031 | proto_tree entry with the representation formatted with the supplied
7032 | printf-style format and argument list. */
7033 | static void
7034 | proto_tree_set_representation(proto_item *pi, const char *format, va_list ap)
7035 | {
7036 | size_t ret; /*tmp return value */
7037 | char *str;
7038 | field_info *fi = PITEM_FINFO(pi)((pi)->finfo);
7039 |
7040 | DISSECTOR_ASSERT(fi)((void) ((fi) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7040, "fi"))));
7041 |
7042 | if (!proto_item_is_hidden(pi)) {
7043 | 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;;
7044 |
7045 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7046 | 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" , 7046, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7047 | fi->rep->value_pos = proto_find_value_pos(fi->hfinfo, str);
7048 | ret = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7049 | if (ret >= ITEM_LABEL_LENGTH240) {
7050 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7051 | size_t name_pos = label_find_name_pos(fi->rep);
7052 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7053 | }
7054 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7055 | }
7056 | }
7057 |
7058 | static int
7059 | proto_strlcpy(char *dest, const char *src, size_t dest_size)
7060 | {
7061 | if (dest_size == 0) return 0;
7062 |
7063 | size_t res = g_strlcpy(dest, src, dest_size);
7064 |
7065 | /* At most dest_size - 1 characters will be copied
7066 | * (unless dest_size is 0). */
7067 | if (res >= dest_size)
7068 | res = dest_size - 1;
7069 | return (int) res;
7070 | }
7071 |
7072 | static header_field_info *
7073 | hfinfo_same_name_get_prev(const header_field_info *hfinfo)
7074 | {
7075 | header_field_info *dup_hfinfo;
7076 |
7077 | if (hfinfo->same_name_prev_id == -1)
7078 | return NULL((void*)0);
7079 | 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", 7079 , __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", 7079, "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", 7079, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; dup_hfinfo = gpa_hfinfo.hfi[hfinfo ->same_name_prev_id];;
7080 | return dup_hfinfo;
7081 | }
7082 |
7083 | static void
7084 | hfinfo_remove_from_gpa_name_map(const header_field_info *hfinfo)
7085 | {
7086 | g_free(last_field_name);
7087 | last_field_name = NULL((void*)0);
7088 |
7089 | if (!hfinfo->same_name_next && hfinfo->same_name_prev_id == -1) {
7090 | /* No hfinfo with the same name */
7091 | wmem_map_remove(gpa_name_map, hfinfo->abbrev);
7092 | return;
7093 | }
7094 |
7095 | if (hfinfo->same_name_next) {
7096 | hfinfo->same_name_next->same_name_prev_id = hfinfo->same_name_prev_id;
7097 | }
7098 |
7099 | if (hfinfo->same_name_prev_id != -1) {
7100 | header_field_info *same_name_prev = hfinfo_same_name_get_prev(hfinfo);
7101 | same_name_prev->same_name_next = hfinfo->same_name_next;
7102 | if (!hfinfo->same_name_next) {
7103 | /* It's always the latest added hfinfo which is stored in gpa_name_map */
7104 | wmem_map_insert(gpa_name_map, (void *) (same_name_prev->abbrev), same_name_prev);
7105 | }
7106 | }
7107 | }
7108 |
7109 | int
7110 | proto_item_fill_display_label(const field_info *finfo, char *display_label_str, const int label_str_size)
7111 | {
7112 | const header_field_info *hfinfo = finfo->hfinfo;
7113 | int label_len = 0;
7114 | char *tmp_str;
7115 | const char *str;
7116 | const uint8_t *bytes;
7117 | uint32_t number;
7118 | uint64_t number64;
7119 | const char *hf_str_val;
7120 | char number_buf[NUMBER_LABEL_LENGTH80];
7121 | const char *number_out;
7122 | address addr;
7123 | const ipv4_addr_and_mask *ipv4;
7124 | const ipv6_addr_and_prefix *ipv6;
7125 |
7126 | switch (hfinfo->type) {
7127 |
7128 | case FT_NONE:
7129 | case FT_PROTOCOL:
7130 | return proto_strlcpy(display_label_str, UTF8_CHECK_MARK"\u2713", label_str_size);
7131 |
7132 | case FT_UINT_BYTES:
7133 | case FT_BYTES:
7134 | tmp_str = format_bytes_hfinfo_maxlen(NULL((void*)0),
7135 | hfinfo,
7136 | fvalue_get_bytes_data(finfo->value),
7137 | (unsigned)fvalue_length2(finfo->value),
7138 | label_str_size);
7139 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7140 | wmem_free(NULL((void*)0), tmp_str);
7141 | break;
7142 |
7143 | case FT_ABSOLUTE_TIME:
7144 | {
7145 | const nstime_t *value = fvalue_get_time(finfo->value);
7146 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
7147 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_COLUMN) {
7148 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
7149 | }
7150 | if (hfinfo->strings) {
7151 | const char *time_string = try_time_val_to_str(value, (const time_value_string*)hfinfo->strings);
7152 | if (time_string != NULL((void*)0)) {
7153 | label_len = proto_strlcpy(display_label_str, time_string, label_str_size);
7154 | break;
7155 | }
7156 | }
7157 | tmp_str = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
7158 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7159 | wmem_free(NULL((void*)0), tmp_str);
7160 | break;
7161 | }
7162 |
7163 | case FT_RELATIVE_TIME:
7164 | tmp_str = rel_time_to_secs_str(NULL((void*)0), fvalue_get_time(finfo->value));
7165 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7166 | wmem_free(NULL((void*)0), tmp_str);
7167 | break;
7168 |
7169 | case FT_BOOLEAN:
7170 | number64 = fvalue_get_uinteger64(finfo->value);
7171 | label_len = proto_strlcpy(display_label_str,
7172 | tfs_get_string(!!number64, hfinfo->strings), label_str_size);
7173 | break;
7174 |
7175 | case FT_CHAR:
7176 | number = fvalue_get_uinteger(finfo->value);
7177 |
7178 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7179 | char tmp[ITEM_LABEL_LENGTH240];
7180 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7181 |
7182 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7182, "fmtfunc"))));
7183 | fmtfunc(tmp, number);
7184 |
7185 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7186 |
7187 | } else if (hfinfo->strings) {
7188 | number_out = hf_try_val_to_str(number, hfinfo);
7189 |
7190 | if (!number_out) {
7191 | number_out = hfinfo_char_value_format_display(BASE_HEX, number_buf, number);
7192 | }
7193 |
7194 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7195 |
7196 | } else {
7197 | number_out = hfinfo_char_value_format(hfinfo, number_buf, number);
7198 |
7199 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7200 | }
7201 |
7202 | break;
7203 |
7204 | /* XXX - make these just FT_NUMBER? */
7205 | case FT_INT8:
7206 | case FT_INT16:
7207 | case FT_INT24:
7208 | case FT_INT32:
7209 | case FT_UINT8:
7210 | case FT_UINT16:
7211 | case FT_UINT24:
7212 | case FT_UINT32:
7213 | case FT_FRAMENUM:
7214 | hf_str_val = NULL((void*)0);
7215 | 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 )) ?
7216 | (uint32_t) fvalue_get_sinteger(finfo->value) :
7217 | fvalue_get_uinteger(finfo->value);
7218 |
7219 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7220 | char tmp[ITEM_LABEL_LENGTH240];
7221 | custom_fmt_func_t fmtfunc = (custom_fmt_func_t)hfinfo->strings;
7222 |
7223 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 7223, "fmtfunc"))));
7224 | fmtfunc(tmp, number);
7225 |
7226 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7227 |
7228 | } else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
7229 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7230 | number_out = hfinfo_numeric_value_format(hfinfo, number_buf, number);
7231 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7232 | hf_str_val = hf_try_val_to_str(number, hfinfo);
7233 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7234 | } else {
7235 | number_out = hf_try_val_to_str(number, hfinfo);
7236 |
7237 | if (!number_out) {
7238 | number_out = hfinfo_number_value_format_display(hfinfo, hfinfo->display, number_buf, number);
7239 | }
7240 |
7241 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7242 | }
7243 | } else {
7244 | number_out = hfinfo_number_value_format(hfinfo, number_buf, number);
7245 |
7246 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7247 | }
7248 |
7249 | break;
7250 |
7251 | case FT_INT40:
7252 | case FT_INT48:
7253 | case FT_INT56:
7254 | case FT_INT64:
7255 | case FT_UINT40:
7256 | case FT_UINT48:
7257 | case FT_UINT56:
7258 | case FT_UINT64:
7259 | hf_str_val = NULL((void*)0);
7260 | 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 )) ?
7261 | (uint64_t) fvalue_get_sinteger64(finfo->value) :
7262 | fvalue_get_uinteger64(finfo->value);
7263 |
7264 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_CUSTOM) {
7265 | char tmp[ITEM_LABEL_LENGTH240];
7266 | custom_fmt_func_64_t fmtfunc64 = (custom_fmt_func_64_t)hfinfo->strings;
7267 |
7268 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 7268, "fmtfunc64" ))));
7269 | fmtfunc64(tmp, number64);
7270 |
7271 | label_len = proto_strlcpy(display_label_str, tmp, label_str_size);
7272 | } else if (hfinfo->strings) {
7273 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
7274 | number_out = hfinfo_numeric_value_format64(hfinfo, number_buf, number64);
7275 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7276 | hf_str_val = hf_try_val64_to_str(number64, hfinfo);
7277 | label_len += proto_strlcpy(display_label_str+label_len, hf_str_val, label_str_size-label_len);
7278 | } else {
7279 | number_out = hf_try_val64_to_str(number64, hfinfo);
7280 |
7281 | if (!number_out)
7282 | number_out = hfinfo_number_value_format_display64(hfinfo, hfinfo->display, number_buf, number64);
7283 |
7284 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7285 | }
7286 | } else {
7287 | number_out = hfinfo_number_value_format64(hfinfo, number_buf, number64);
7288 |
7289 | label_len = proto_strlcpy(display_label_str, number_out, label_str_size);
7290 | }
7291 |
7292 | break;
7293 |
7294 | case FT_EUI64:
7295 | set_address (&addr, AT_EUI64, EUI64_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7296 | tmp_str = address_to_display(NULL((void*)0), &addr);
7297 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7298 | wmem_free(NULL((void*)0), tmp_str);
7299 | break;
7300 |
7301 | case FT_IPv4:
7302 | ipv4 = fvalue_get_ipv4(finfo->value);
7303 | //XXX: Should we ignore the mask?
7304 | set_address_ipv4(&addr, ipv4);
7305 | tmp_str = address_to_display(NULL((void*)0), &addr);
7306 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7307 | wmem_free(NULL((void*)0), tmp_str);
7308 | free_address(&addr);
7309 | break;
7310 |
7311 | case FT_IPv6:
7312 | ipv6 = fvalue_get_ipv6(finfo->value);
7313 | set_address_ipv6(&addr, ipv6);
7314 | tmp_str = address_to_display(NULL((void*)0), &addr);
7315 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7316 | wmem_free(NULL((void*)0), tmp_str);
7317 | free_address(&addr);
7318 | break;
7319 |
7320 | case FT_FCWWN:
7321 | set_address (&addr, AT_FCWWN, FCWWN_ADDR_LEN8, fvalue_get_bytes_data(finfo->value));
7322 | tmp_str = address_to_display(NULL((void*)0), &addr);
7323 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7324 | wmem_free(NULL((void*)0), tmp_str);
7325 | break;
7326 |
7327 | case FT_ETHER:
7328 | set_address (&addr, AT_ETHER, FT_ETHER_LEN6, fvalue_get_bytes_data(finfo->value));
7329 | tmp_str = address_to_display(NULL((void*)0), &addr);
7330 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7331 | wmem_free(NULL((void*)0), tmp_str);
7332 | break;
7333 |
7334 | case FT_GUID:
7335 | tmp_str = guid_to_str(NULL((void*)0), fvalue_get_guid(finfo->value));
7336 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7337 | wmem_free(NULL((void*)0), tmp_str);
7338 | break;
7339 |
7340 | case FT_REL_OID:
7341 | bytes = fvalue_get_bytes_data(finfo->value);
7342 | tmp_str = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7343 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7344 | wmem_free(NULL((void*)0), tmp_str);
7345 | break;
7346 |
7347 | case FT_OID:
7348 | bytes = fvalue_get_bytes_data(finfo->value);
7349 | tmp_str = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7350 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7351 | wmem_free(NULL((void*)0), tmp_str);
7352 | break;
7353 |
7354 | case FT_SYSTEM_ID:
7355 | bytes = fvalue_get_bytes_data(finfo->value);
7356 | tmp_str = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(finfo->value));
7357 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7358 | wmem_free(NULL((void*)0), tmp_str);
7359 | break;
7360 |
7361 | case FT_FLOAT:
7362 | case FT_DOUBLE:
7363 | label_len = (int)fill_display_label_float(finfo, display_label_str, label_str_size);
7364 | break;
7365 |
7366 | case FT_IEEE_11073_SFLOAT:
7367 | case FT_IEEE_11073_FLOAT:
7368 | label_len = (int)fill_display_label_ieee_11073_float(finfo, display_label_str, label_str_size);
7369 | break;
7370 |
7371 | case FT_STRING:
7372 | case FT_STRINGZ:
7373 | case FT_UINT_STRING:
7374 | case FT_STRINGZPAD:
7375 | case FT_STRINGZTRUNC:
7376 | str = fvalue_get_string(finfo->value);
7377 | label_len = (int)ws_label_strcpy(display_label_str, label_str_size, 0, (const uint8_t*)str, label_strcat_flags(hfinfo));
7378 | if (label_len >= label_str_size) {
7379 | /* Truncation occurred. Get the real length
7380 | * copied (not including '\0') */
7381 | label_len = label_str_size ? label_str_size - 1 : 0;
7382 | }
7383 | break;
7384 |
7385 | default:
7386 | /* First try ftype string representation */
7387 | tmp_str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DISPLAY, hfinfo->display);
7388 | if (!tmp_str) {
7389 | /* Default to show as bytes */
7390 | bytes = fvalue_get_bytes_data(finfo->value);
7391 | tmp_str = bytes_to_str(NULL, bytes, fvalue_length2(finfo->value))bytes_to_str_maxlen(((void*)0), bytes, fvalue_length2(finfo-> value), 36);
7392 | }
7393 | label_len = proto_strlcpy(display_label_str, tmp_str, label_str_size);
7394 | wmem_free(NULL((void*)0), tmp_str);
7395 | break;
7396 | }
7397 | return label_len;
7398 | }
7399 |
7400 | const char *
7401 | proto_custom_set(proto_tree* tree, GSList *field_ids, int occurrence, bool_Bool display_details,
7402 | char *result, char *expr, const int size)
7403 | {
7404 | int len, prev_len, last, i, offset_r = 0, offset_e = 0;
7405 | GPtrArray *finfos;
7406 | field_info *finfo = NULL((void*)0);
7407 | header_field_info* hfinfo;
7408 | const char *abbrev = NULL((void*)0);
7409 |
7410 | char *str;
7411 | col_custom_t *field_idx;
7412 | int field_id;
7413 | int ii = 0;
7414 |
7415 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7415, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7416 | while ((field_idx = (col_custom_t *) g_slist_nth_data(field_ids, ii++))) {
7417 | field_id = field_idx->field_id;
7418 | if (field_id == 0) {
7419 | GPtrArray *fvals = NULL((void*)0);
7420 | bool_Bool passed = dfilter_apply_full(field_idx->dfilter, tree, &fvals);
7421 | if (fvals != NULL((void*)0)) {
7422 |
7423 | // XXX - Handling occurrences is unusual when more
7424 | // than one field is involved, e.g. there's four
7425 | // results for tcp.port + tcp.port. We may really
7426 | // want to apply it to the operands, not the output.
7427 | // Note that occurrences are not quite the same as
7428 | // the layer operator (should the grammar support
7429 | // both?)
7430 | /* Calculate single index or set outer boundaries */
7431 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7432 | if (occurrence < 0) {
7433 | i = occurrence + len;
7434 | last = i;
7435 | } else if (occurrence > 0) {
7436 | i = occurrence - 1;
7437 | last = i;
7438 | } else {
7439 | i = 0;
7440 | last = len - 1;
7441 | }
7442 | if (i < 0 || i >= len) {
7443 | g_ptr_array_unref(fvals);
7444 | continue;
7445 | }
7446 | for (; i <= last; i++) {
7447 | /* XXX - We could have a "resolved" result
7448 | * for types where the value depends only
7449 | * on the type, e.g. FT_IPv4, and not on
7450 | * hfinfo->strings. Supporting the latter
7451 | * requires knowing which hfinfo matched
7452 | * if there are multiple with the same
7453 | * abbreviation. In any case, we need to
7454 | * know the expected return type of the
7455 | * field expression.
7456 | */
7457 | str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DISPLAY, BASE_NONE);
7458 | if (offset_r && (offset_r < (size - 1)))
7459 | result[offset_r++] = ',';
7460 | if (offset_e && (offset_e < (size - 1)))
7461 | expr[offset_e++] = ',';
7462 | offset_r += proto_strlcpy(result+offset_r, str, size-offset_r);
7463 | // col_{add,append,set}_* calls ws_label_strcpy
7464 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7465 |
7466 | g_free(str);
7467 | }
7468 | g_ptr_array_unref(fvals);
7469 | } else if (passed) {
7470 | // XXX - Occurrence doesn't make sense for a test
7471 | // output, it should be applied to the operands.
7472 | if (offset_r && (offset_r < (size - 1)))
7473 | result[offset_r++] = ',';
7474 | if (offset_e && (offset_e < (size - 1)))
7475 | expr[offset_e++] = ',';
7476 | /* Prevent multiple check marks */
7477 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7478 | offset_r += proto_strlcpy(result+offset_r, UTF8_CHECK_MARK"\u2713", size-offset_r);
7479 | } else {
7480 | result[--offset_r] = '\0'; /* Remove the added trailing ',' */
7481 | }
7482 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7483 | offset_e += proto_strlcpy(expr+offset_e, UTF8_CHECK_MARK"\u2713", size-offset_e);
7484 | } else {
7485 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' */
7486 | }
7487 | }
7488 | continue;
7489 | }
7490 | 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", 7490 , __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", 7490, "(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", 7490, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7491 |
7492 | /* do we need to rewind ? */
7493 | if (!hfinfo)
7494 | return "";
7495 |
7496 | if (occurrence < 0) {
7497 | /* Search other direction */
7498 | while (hfinfo->same_name_prev_id != -1) {
7499 | 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", 7499 , __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", 7499, "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", 7499, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7500 | }
7501 | }
7502 |
7503 | prev_len = 0; /* Reset handled occurrences */
7504 |
7505 | while (hfinfo) {
7506 | finfos = proto_get_finfo_ptr_array(tree, hfinfo->id);
7507 |
7508 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7509 | if (occurrence < 0) {
7510 | hfinfo = hfinfo->same_name_next;
7511 | } else {
7512 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7513 | }
7514 | continue;
7515 | }
7516 |
7517 | /* Are there enough occurrences of the field? */
7518 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7519 | if (occurrence < 0) {
7520 | hfinfo = hfinfo->same_name_next;
7521 | } else {
7522 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7523 | }
7524 | prev_len += len;
7525 | continue;
7526 | }
7527 |
7528 | /* Calculate single index or set outer boundaries */
7529 | if (occurrence < 0) {
7530 | i = occurrence + len + prev_len;
7531 | last = i;
7532 | } else if (occurrence > 0) {
7533 | i = occurrence - 1 - prev_len;
7534 | last = i;
7535 | } else {
7536 | i = 0;
7537 | last = len - 1;
7538 | }
7539 |
7540 | prev_len += len; /* Count handled occurrences */
7541 |
7542 | while (i <= last) {
7543 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7544 |
7545 | if (offset_r && (offset_r < (size - 1)))
7546 | result[offset_r++] = ',';
7547 |
7548 | if (display_details) {
7549 | char representation[ITEM_LABEL_LENGTH240];
7550 | size_t offset = 0;
7551 |
7552 | if (finfo->rep && finfo->rep->value_len) {
7553 | g_strlcpy(representation, &finfo->rep->representation[finfo->rep->value_pos],
7554 | MIN(finfo->rep->value_len + 1, ITEM_LABEL_LENGTH)(((finfo->rep->value_len + 1) < (240)) ? (finfo-> rep->value_len + 1) : (240)));
7555 | } else {
7556 | proto_item_fill_label(finfo, representation, &offset);
7557 | }
7558 | offset_r += proto_strlcpy(result+offset_r, &representation[offset], size-offset_r);
7559 | } else {
7560 | switch (hfinfo->type) {
7561 |
7562 | case FT_NONE:
7563 | case FT_PROTOCOL:
7564 | /* Prevent multiple check marks */
7565 | if (strstr(result, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7566 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7567 | } else {
7568 | result[--offset_r] = '\0'; /* Remove the added trailing ',' again */
7569 | }
7570 | break;
7571 |
7572 | default:
7573 | offset_r += proto_item_fill_display_label(finfo, result+offset_r, size-offset_r);
7574 | break;
7575 | }
7576 | }
7577 |
7578 | if (offset_e && (offset_e < (size - 1)))
7579 | expr[offset_e++] = ',';
7580 |
7581 | 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 )))) {
7582 | const char *hf_str_val;
7583 | /* Integer types with BASE_NONE never get the numeric value. */
7584 | if (FT_IS_INT32(hfinfo->type)((hfinfo->type) == FT_INT8 || (hfinfo->type) == FT_INT16 || (hfinfo->type) == FT_INT24 || (hfinfo->type) == FT_INT32 )) {
7585 | hf_str_val = hf_try_val_to_str_const(fvalue_get_sinteger(finfo->value), hfinfo, "Unknown");
7586 | } 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 )) {
7587 | hf_str_val = hf_try_val_to_str_const(fvalue_get_uinteger(finfo->value), hfinfo, "Unknown");
7588 | } else if (FT_IS_INT64(hfinfo->type)((hfinfo->type) == FT_INT40 || (hfinfo->type) == FT_INT48 || (hfinfo->type) == FT_INT56 || (hfinfo->type) == FT_INT64 )) {
7589 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_sinteger64(finfo->value), hfinfo, "Unknown");
7590 | } else { // if (FT_IS_UINT64(hfinfo->type)) {
7591 | hf_str_val = hf_try_val64_to_str_const(fvalue_get_uinteger64(finfo->value), hfinfo, "Unknown");
7592 | }
7593 | snprintf(expr+offset_e, size-offset_e, "\"%s\"", hf_str_val);
7594 | offset_e = (int)strlen(expr);
7595 | } else if (hfinfo->type == FT_NONE || hfinfo->type == FT_PROTOCOL) {
7596 | /* Prevent multiple check marks */
7597 | if (strstr(expr, UTF8_CHECK_MARK"\u2713" ",") == NULL((void*)0)) {
7598 | offset_e += proto_item_fill_display_label(finfo, expr+offset_e, size-offset_e);
7599 | } else {
7600 | expr[--offset_e] = '\0'; /* Remove the added trailing ',' again */
7601 | }
7602 | } else {
7603 | str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_RAW, finfo->hfinfo->display);
7604 | // col_{add,append,set}_* calls ws_label_strcpy
7605 | offset_e = (int) ws_label_strcpy(expr, size, offset_e, (const uint8_t*)str, 0);
7606 | wmem_free(NULL((void*)0), str);
7607 | }
7608 | i++;
7609 | }
7610 |
7611 | /* XXX: Why is only the first abbreviation returned for a multifield
7612 | * custom column? */
7613 | if (!abbrev) {
7614 | /* Store abbrev for return value */
7615 | abbrev = hfinfo->abbrev;
7616 | }
7617 |
7618 | if (occurrence == 0) {
7619 | /* Fetch next hfinfo with same name (abbrev) */
7620 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7621 | } else {
7622 | hfinfo = NULL((void*)0);
7623 | }
7624 | }
7625 | }
7626 |
7627 | if (offset_r >= (size - 1)) {
7628 | mark_truncated(result, 0, size, NULL((void*)0));
7629 | }
7630 | if (offset_e >= (size - 1)) {
7631 | mark_truncated(expr, 0, size, NULL((void*)0));
7632 | }
7633 | return abbrev ? abbrev : "";
7634 | }
7635 |
7636 | char *
7637 | proto_custom_get_filter(epan_dissect_t* edt, GSList *field_ids, int occurrence)
7638 | {
7639 | int len, prev_len, last, i;
7640 | GPtrArray *finfos;
7641 | field_info *finfo = NULL((void*)0);
7642 | header_field_info* hfinfo;
7643 |
7644 | char *filter = NULL((void*)0);
7645 | GPtrArray *filter_array;
7646 |
7647 | col_custom_t *col_custom;
7648 | int field_id;
7649 |
7650 | ws_assert(field_ids != NULL)do { if ((1) && !(field_ids != ((void*)0))) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 7650, __func__, "assertion failed: %s" , "field_ids != ((void*)0)"); } while (0);
7651 | filter_array = g_ptr_array_new_full(g_slist_length(field_ids), g_free);
7652 | for (GSList *iter = field_ids; iter; iter = iter->next) {
7653 | col_custom = (col_custom_t*)iter->data;
7654 | field_id = col_custom->field_id;
7655 | if (field_id == 0) {
7656 | GPtrArray *fvals = NULL((void*)0);
7657 | bool_Bool passed = dfilter_apply_full(col_custom->dfilter, edt->tree, &fvals);
7658 | if (fvals != NULL((void*)0)) {
7659 | // XXX - Handling occurrences is unusual when more
7660 | // than one field is involved, e.g. there's four
7661 | // results for tcp.port + tcp.port. We really
7662 | // want to apply it to the operands, not the output.
7663 | /* Calculate single index or set outer boundaries */
7664 | len = g_ptr_array_len(fvals)((fvals) ? (fvals)->len : 0);
7665 | if (occurrence < 0) {
7666 | i = occurrence + len;
7667 | last = i;
7668 | } else if (occurrence > 0) {
7669 | i = occurrence - 1;
7670 | last = i;
7671 | } else {
7672 | i = 0;
7673 | last = len - 1;
7674 | }
7675 | if (i < 0 || i >= len) {
7676 | g_ptr_array_unref(fvals);
7677 | continue;
7678 | }
7679 | for (; i <= last; i++) {
7680 | /* XXX - Should multiple values for one
7681 | * field use set membership to reduce
7682 | * verbosity, here and below? */
7683 | char *str = fvalue_to_string_repr(NULL((void*)0), fvals->pdata[i], FTREPR_DFILTER, BASE_NONE);
7684 | filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", col_custom->dftext, str);
7685 | wmem_free(NULL((void*)0), str);
7686 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7687 | g_ptr_array_add(filter_array, filter);
7688 | }
7689 | }
7690 | g_ptr_array_unref(fvals);
7691 | } else if (passed) {
7692 | filter = wmem_strdup(NULL((void*)0), col_custom->dftext);
7693 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7694 | g_ptr_array_add(filter_array, filter);
7695 | }
7696 | } else {
7697 | filter = wmem_strdup_printf(NULL((void*)0), "!(%s)", col_custom->dftext);
7698 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7699 | g_ptr_array_add(filter_array, filter);
7700 | }
7701 | }
7702 | continue;
7703 | }
7704 |
7705 | 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", 7705 , __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", 7705, "(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", 7705, "gpa_hfinfo.hfi[(unsigned)field_id] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[(unsigned)field_id];;
7706 |
7707 | /* do we need to rewind ? */
7708 | if (!hfinfo)
7709 | return NULL((void*)0);
7710 |
7711 | if (occurrence < 0) {
7712 | /* Search other direction */
7713 | while (hfinfo->same_name_prev_id != -1) {
7714 | 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", 7714 , __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", 7714, "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", 7714, "gpa_hfinfo.hfi[hfinfo->same_name_prev_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfinfo-> same_name_prev_id];;
7715 | }
7716 | }
7717 |
7718 | prev_len = 0; /* Reset handled occurrences */
7719 |
7720 | while (hfinfo) {
7721 | finfos = proto_get_finfo_ptr_array(edt->tree, hfinfo->id);
7722 |
7723 | if (!finfos || !(len = g_ptr_array_len(finfos)((finfos) ? (finfos)->len : 0))) {
7724 | if (occurrence < 0) {
7725 | hfinfo = hfinfo->same_name_next;
7726 | } else {
7727 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7728 | }
7729 | continue;
7730 | }
7731 |
7732 | /* Are there enough occurrences of the field? */
7733 | if (((occurrence - prev_len) > len) || ((occurrence + prev_len) < -len)) {
7734 | if (occurrence < 0) {
7735 | hfinfo = hfinfo->same_name_next;
7736 | } else {
7737 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7738 | }
7739 | prev_len += len;
7740 | continue;
7741 | }
7742 |
7743 | /* Calculate single index or set outer boundaries */
7744 | if (occurrence < 0) {
7745 | i = occurrence + len + prev_len;
7746 | last = i;
7747 | } else if (occurrence > 0) {
7748 | i = occurrence - 1 - prev_len;
7749 | last = i;
7750 | } else {
7751 | i = 0;
7752 | last = len - 1;
7753 | }
7754 |
7755 | prev_len += len; /* Count handled occurrences */
7756 |
7757 | while (i <= last) {
7758 | finfo = (field_info *)g_ptr_array_index(finfos, i)((finfos)->pdata)[i];
7759 |
7760 | filter = proto_construct_match_selected_string(finfo, edt);
7761 | if (filter) {
7762 | /* Only add the same expression once (especially for FT_PROTOCOL).
7763 | * The ptr array doesn't have NULL entries so g_str_equal is fine.
7764 | */
7765 | if (!g_ptr_array_find_with_equal_func(filter_array, filter, g_str_equal, NULL((void*)0))) {
7766 | g_ptr_array_add(filter_array, filter);
7767 | }
7768 | }
7769 | i++;
7770 | }
7771 |
7772 | if (occurrence == 0) {
7773 | /* Fetch next hfinfo with same name (abbrev) */
7774 | hfinfo = hfinfo_same_name_get_prev(hfinfo);
7775 | } else {
7776 | hfinfo = NULL((void*)0);
7777 | }
7778 | }
7779 | }
7780 |
7781 | g_ptr_array_add(filter_array, NULL((void*)0));
7782 |
7783 | /* XXX: Should this be || or && ? */
7784 | char *output = g_strjoinv(" || ", (char **)filter_array->pdata);
7785 |
7786 | g_ptr_array_free(filter_array, true1);
7787 |
7788 | return output;
7789 | }
7790 |
7791 | /* Set text of proto_item after having already been created. */
7792 | void
7793 | proto_item_set_text(proto_item *pi, const char *format, ...)
7794 | {
7795 | field_info *fi = NULL((void*)0);
7796 | va_list ap;
7797 |
7798 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7799 |
7800 | fi = PITEM_FINFO(pi)((pi)->finfo);
7801 | if (fi == NULL((void*)0))
7802 | return;
7803 |
7804 | if (fi->rep) {
7805 | ITEM_LABEL_FREE(PNODE_POOL(pi), fi->rep)wmem_free(((pi)->tree_data->pinfo->pool), fi->rep );;
7806 | fi->rep = NULL((void*)0);
7807 | }
7808 |
7809 | va_start(ap, format)__builtin_va_start(ap, format);
7810 | proto_tree_set_representation(pi, format, ap);
7811 | va_end(ap)__builtin_va_end(ap);
7812 | }
7813 |
7814 | /* Append to text of proto_item after having already been created. */
7815 | void
7816 | proto_item_append_text(proto_item *pi, const char *format, ...)
7817 | {
7818 | field_info *fi = NULL((void*)0);
7819 | size_t curlen;
7820 | char *str;
7821 | va_list ap;
7822 |
7823 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7824 |
7825 | fi = PITEM_FINFO(pi)((pi)->finfo);
7826 | if (fi == NULL((void*)0)) {
7827 | return;
7828 | }
7829 |
7830 | if (!proto_item_is_hidden(pi)) {
7831 | /*
7832 | * If we don't already have a representation,
7833 | * generate the default representation.
7834 | */
7835 | if (fi->rep == NULL((void*)0)) {
7836 | 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;;
7837 | proto_item_fill_label(fi, fi->rep->representation, &fi->rep->value_pos);
7838 | /* Check for special case append value to FT_NONE or FT_PROTOCOL */
7839 | if ((fi->hfinfo->type == FT_NONE || fi->hfinfo->type == FT_PROTOCOL) &&
7840 | (strncmp(format, ": ", 2) == 0)) {
7841 | fi->rep->value_pos += 2;
7842 | }
7843 | }
7844 | if (fi->rep) {
7845 | curlen = strlen(fi->rep->representation);
7846 | /* curlen doesn't include the \0 byte.
7847 | * XXX: If curlen + 4 > ITEM_LABEL_LENGTH, we can't tell if
7848 | * the representation has already been truncated (of an up
7849 | * to 4 byte UTF-8 character) or is just at the maximum length
7850 | * unless we search for " [truncated]" (which may not be
7851 | * at the start.)
7852 | * It's safer to do nothing.
7853 | */
7854 | if (ITEM_LABEL_LENGTH240 > (curlen + 4)) {
7855 | va_start(ap, format)__builtin_va_start(ap, format);
7856 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7857 | va_end(ap)__builtin_va_end(ap);
7858 | 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" , 7858, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7859 | /* Keep fi->rep->value_pos */
7860 | curlen = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, curlen, (const uint8_t*)str, 0);
7861 | if (curlen >= ITEM_LABEL_LENGTH240) {
7862 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7863 | size_t name_pos = label_find_name_pos(fi->rep);
7864 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7865 | }
7866 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7867 | }
7868 | }
7869 | }
7870 | }
7871 |
7872 | /* Prepend to text of proto_item after having already been created. */
7873 | void
7874 | proto_item_prepend_text(proto_item *pi, const char *format, ...)
7875 | {
7876 | field_info *fi = NULL((void*)0);
7877 | size_t pos;
7878 | char representation[ITEM_LABEL_LENGTH240];
7879 | char *str;
7880 | va_list ap;
7881 |
7882 | TRY_TO_FAKE_THIS_REPR_VOID(pi)if (!pi || !((pi)->finfo)) return; if (!(((pi)->tree_data )->visible) && proto_item_is_hidden((pi))) { return ; };
7883 |
7884 | fi = PITEM_FINFO(pi)((pi)->finfo);
7885 | if (fi == NULL((void*)0)) {
7886 | return;
7887 | }
7888 |
7889 | if (!proto_item_is_hidden(pi)) {
7890 | /*
7891 | * If we don't already have a representation,
7892 | * generate the default representation.
7893 | */
7894 | if (fi->rep == NULL((void*)0)) {
7895 | 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;;
7896 | proto_item_fill_label(fi, representation, &fi->rep->value_pos);
7897 | } else
7898 | (void) g_strlcpy(representation, fi->rep->representation, ITEM_LABEL_LENGTH240);
7899 |
7900 | va_start(ap, format)__builtin_va_start(ap, format);
7901 | str = wmem_strdup_vprintf(PNODE_POOL(pi)((pi)->tree_data->pinfo->pool), format, ap);
7902 | va_end(ap)__builtin_va_end(ap);
7903 | 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" , 7903, __func__, str, -1, __uni_endptr); } } while (0); } } while (0);
7904 | fi->rep->value_pos += strlen(str);
7905 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, 0, (const uint8_t*)str, 0);
7906 | pos = ws_label_strcpy(fi->rep->representation, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)representation, 0);
7907 | /* XXX: As above, if the old representation is close to the label
7908 | * length, it might already be marked as truncated. */
7909 | if (pos >= ITEM_LABEL_LENGTH240 && (strlen(representation) + 4) <= ITEM_LABEL_LENGTH240) {
7910 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
7911 | size_t name_pos = label_find_name_pos(fi->rep);
7912 | label_mark_truncated(fi->rep->representation, name_pos, &fi->rep->value_pos);
7913 | }
7914 | fi->rep->value_len = strlen(fi->rep->representation) - fi->rep->value_pos;
7915 | }
7916 | }
7917 |
7918 | static void
7919 | finfo_set_len(field_info *fi, const int length)
7920 | {
7921 | int length_remaining;
7922 |
7923 | 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", 7923, "length >= 0", fi->hfinfo->abbrev))));
7924 | length_remaining = tvb_captured_length_remaining(fi->ds_tvb, fi->start);
7925 | if (length > length_remaining)
7926 | fi->length = length_remaining;
7927 | else
7928 | fi->length = length;
7929 |
7930 | /* If we have an FT_PROTOCOL we need to set the length of the fvalue tvbuff as well. */
7931 | if (fvalue_type_ftenum(fi->value) == FT_PROTOCOL) {
7932 | fvalue_set_protocol_length(fi->value, fi->length);
7933 | }
7934 |
7935 | /*
7936 | * You cannot just make the "len" field of a GByteArray
7937 | * larger, if there's no data to back that length;
7938 | * you can only make it smaller.
7939 | */
7940 | if (fvalue_type_ftenum(fi->value) == FT_BYTES && fi->length > 0) {
7941 | GBytes *bytes = fvalue_get_bytes(fi->value);
7942 | size_t size;
7943 | const void *data = g_bytes_get_data(bytes, &size);
7944 | if ((size_t)fi->length <= size) {
7945 | fvalue_set_bytes_data(fi->value, data, fi->length);
7946 | }
7947 | g_bytes_unref(bytes);
7948 | }
7949 | }
7950 |
7951 | void
7952 | proto_item_set_len(proto_item *pi, const int length)
7953 | {
7954 | field_info *fi;
7955 |
7956 | if (pi == NULL((void*)0))
7957 | return;
7958 |
7959 | fi = PITEM_FINFO(pi)((pi)->finfo);
7960 | if (fi == NULL((void*)0))
7961 | return;
7962 |
7963 | finfo_set_len(fi, length);
7964 | }
7965 |
7966 | /*
7967 | * Sets the length of the item based on its start and on the specified
7968 | * offset, which is the offset past the end of the item; as the start
7969 | * in the item is relative to the beginning of the data source tvbuff,
7970 | * we need to pass in a tvbuff - the end offset is relative to the beginning
7971 | * of that tvbuff.
7972 | */
7973 | void
7974 | proto_item_set_end(proto_item *pi, tvbuff_t *tvb, int end)
7975 | {
7976 | field_info *fi;
7977 | int length;
7978 |
7979 | if (pi == NULL((void*)0))
7980 | return;
7981 |
7982 | fi = PITEM_FINFO(pi)((pi)->finfo);
7983 | if (fi == NULL((void*)0))
7984 | return;
7985 |
7986 | end += tvb_raw_offset(tvb);
7987 | DISSECTOR_ASSERT(end >= fi->start)((void) ((end >= fi->start) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 7987, "end >= fi->start" ))));
7988 | length = end - fi->start;
7989 |
7990 | finfo_set_len(fi, length);
7991 | }
7992 |
7993 | int
7994 | proto_item_get_len(const proto_item *pi)
7995 | {
7996 | field_info *fi;
7997 |
7998 | if (!pi)
7999 | return -1;
8000 | fi = PITEM_FINFO(pi)((pi)->finfo);
8001 | return fi ? fi->length : -1;
8002 | }
8003 |
8004 | void
8005 | proto_item_set_bits_offset_len(proto_item *ti, int bits_offset, int bits_len) {
8006 | if (!ti) {
8007 | return;
8008 | }
8009 | 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);
8010 | 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);
8011 | }
8012 |
8013 | char *
8014 | proto_item_get_display_repr(wmem_allocator_t *scope, proto_item *pi)
8015 | {
8016 | field_info *fi;
8017 |
8018 | if (!pi)
8019 | return wmem_strdup(scope, "");
8020 | fi = PITEM_FINFO(pi)((pi)->finfo);
8021 | if (!fi)
8022 | return wmem_strdup(scope, "");
8023 | DISSECTOR_ASSERT(fi->hfinfo != NULL)((void) ((fi->hfinfo != ((void*)0)) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8023, "fi->hfinfo != ((void*)0)" ))));
8024 | return fvalue_to_string_repr(scope, fi->value, FTREPR_DISPLAY, fi->hfinfo->display);
8025 | }
8026 |
8027 | proto_tree *
8028 | proto_tree_create_root(packet_info *pinfo)
8029 | {
8030 | proto_node *pnode;
8031 |
8032 | /* Initialize the proto_node */
8033 | pnode = g_slice_new(proto_tree)((proto_tree*) g_slice_alloc (sizeof (proto_tree)));
8034 | PROTO_NODE_INIT(pnode)pnode->first_child = ((void*)0); pnode->last_child = (( void*)0); pnode->next = ((void*)0);;
8035 | pnode->parent = NULL((void*)0);
8036 | PNODE_FINFO(pnode)((pnode)->finfo) = NULL((void*)0);
8037 | pnode->tree_data = g_slice_new(tree_data_t)((tree_data_t*) g_slice_alloc (sizeof (tree_data_t)));
8038 |
8039 | /* Make sure we can access pinfo everywhere */
8040 | pnode->tree_data->pinfo = pinfo;
8041 |
8042 | /* Don't initialize the tree_data_t. Wait until we know we need it */
8043 | pnode->tree_data->interesting_hfids = NULL((void*)0);
8044 |
8045 | /* Set the default to false so it's easier to
8046 | * find errors; if we expect to see the protocol tree
8047 | * but for some reason the default 'visible' is not
8048 | * changed, then we'll find out very quickly. */
8049 | pnode->tree_data->visible = false0;
8050 |
8051 | /* Make sure that we fake protocols (if possible) */
8052 | pnode->tree_data->fake_protocols = true1;
8053 |
8054 | /* Keep track of the number of children */
8055 | pnode->tree_data->count = 0;
8056 |
8057 | /* Initialize our loop checks */
8058 | pnode->tree_data->idle_count_ds_tvb = NULL((void*)0);
8059 | pnode->tree_data->max_start = 0;
8060 | pnode->tree_data->start_idle_count = 0;
8061 |
8062 | return (proto_tree *)pnode;
8063 | }
8064 |
8065 |
8066 | /* "prime" a proto_tree with a single hfid that a dfilter
8067 | * is interested in. */
8068 | void
8069 | proto_tree_prime_with_hfid(proto_tree *tree _U___attribute__((unused)), const int hfid)
8070 | {
8071 | header_field_info *hfinfo;
8072 |
8073 | 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", 8073, __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", 8073, "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", 8073, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8074 | /* this field is referenced by a filter so increase the refcount.
8075 | also increase the refcount for the parent, i.e the protocol.
8076 | Don't increase the refcount if we're already printing the
8077 | type, as that is a superset of direct reference.
8078 | */
8079 | if (hfinfo->ref_type != HF_REF_TYPE_PRINT) {
8080 | hfinfo->ref_type = HF_REF_TYPE_DIRECT;
8081 | }
8082 | /* only increase the refcount if there is a parent.
8083 | if this is a protocol and not a field then parent will be -1
8084 | and there is no parent to add any refcounting for.
8085 | */
8086 | if (hfinfo->parent != -1) {
8087 | header_field_info *parent_hfinfo;
8088 | 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", 8088 , __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", 8088, "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", 8088, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8089 |
8090 | /* Mark parent as indirectly referenced unless it is already directly
8091 | * referenced, i.e. the user has specified the parent in a filter.
8092 | */
8093 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8094 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8095 | }
8096 | }
8097 |
8098 | /* "prime" a proto_tree with a single hfid that a dfilter
8099 | * is interested in. */
8100 | void
8101 | proto_tree_prime_with_hfid_print(proto_tree *tree _U___attribute__((unused)), const int hfid)
8102 | {
8103 | header_field_info *hfinfo;
8104 |
8105 | 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", 8105, __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", 8105, "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", 8105, "gpa_hfinfo.hfi[hfid] != ((void*)0)", "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfid];;
8106 | /* this field is referenced by an (output) filter so increase the refcount.
8107 | also increase the refcount for the parent, i.e the protocol.
8108 | */
8109 | hfinfo->ref_type = HF_REF_TYPE_PRINT;
8110 | /* only increase the refcount if there is a parent.
8111 | if this is a protocol and not a field then parent will be -1
8112 | and there is no parent to add any refcounting for.
8113 | */
8114 | if (hfinfo->parent != -1) {
8115 | header_field_info *parent_hfinfo;
8116 | 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", 8116 , __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", 8116, "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", 8116, "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
8117 |
8118 | /* Mark parent as indirectly referenced unless it is already directly
8119 | * referenced, i.e. the user has specified the parent in a filter.
8120 | */
8121 | if (parent_hfinfo->ref_type == HF_REF_TYPE_NONE)
8122 | parent_hfinfo->ref_type = HF_REF_TYPE_INDIRECT;
8123 | }
8124 | }
8125 |
8126 | proto_tree *
8127 | proto_item_add_subtree(proto_item *pi, const int idx) {
8128 | field_info *fi;
8129 |
8130 | if (!pi)
8131 | return NULL((void*)0);
8132 |
8133 | 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", 8133, "idx >= 0 && idx < num_tree_types" ))));
8134 |
8135 | fi = PITEM_FINFO(pi)((pi)->finfo);
8136 | if (!fi)
8137 | return (proto_tree *)pi;
8138 |
8139 | fi->tree_type = idx;
8140 |
8141 | return (proto_tree *)pi;
8142 | }
8143 |
8144 | proto_tree *
8145 | proto_item_get_subtree(proto_item *pi) {
8146 | field_info *fi;
8147 |
8148 | if (!pi)
8149 | return NULL((void*)0);
8150 | fi = PITEM_FINFO(pi)((pi)->finfo);
8151 | if ( (fi) && (fi->tree_type == -1) )
8152 | return NULL((void*)0);
8153 | return (proto_tree *)pi;
8154 | }
8155 |
8156 | proto_item *
8157 | proto_item_get_parent(const proto_item *ti) {
8158 | if (!ti)
8159 | return NULL((void*)0);
8160 | return ti->parent;
8161 | }
8162 |
8163 | proto_item *
8164 | proto_item_get_parent_nth(proto_item *ti, int gen) {
8165 | if (!ti)
8166 | return NULL((void*)0);
8167 | while (gen--) {
8168 | ti = ti->parent;
8169 | if (!ti)
8170 | return NULL((void*)0);
8171 | }
8172 | return ti;
8173 | }
8174 |
8175 |
8176 | proto_item *
8177 | proto_tree_get_parent(proto_tree *tree) {
8178 | if (!tree)
8179 | return NULL((void*)0);
8180 | return (proto_item *)tree;
8181 | }
8182 |
8183 | proto_tree *
8184 | proto_tree_get_parent_tree(proto_tree *tree) {
8185 | if (!tree)
8186 | return NULL((void*)0);
8187 |
8188 | /* we're the root tree, there's no parent
8189 | return ourselves so the caller has at least a tree to attach to */
8190 | if (!tree->parent)
8191 | return tree;
8192 |
8193 | return (proto_tree *)tree->parent;
8194 | }
8195 |
8196 | proto_tree *
8197 | proto_tree_get_root(proto_tree *tree) {
8198 | if (!tree)
8199 | return NULL((void*)0);
8200 | while (tree->parent) {
8201 | tree = tree->parent;
8202 | }
8203 | return tree;
8204 | }
8205 |
8206 | void
8207 | proto_tree_move_item(proto_tree *tree, proto_item *fixed_item,
8208 | proto_item *item_to_move)
8209 | {
8210 | /* This function doesn't generate any values. It only reorganizes the protocol tree
8211 | * so we can bail out immediately if it isn't visible. */
8212 | if (!tree || !PTREE_DATA(tree)((tree)->tree_data)->visible)
8213 | return;
8214 |
8215 | 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", 8215, "item_to_move->parent == tree" ))));
8216 | 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", 8216, "fixed_item->parent == tree" ))));
8217 |
8218 | /*** cut item_to_move out ***/
8219 |
8220 | /* is item_to_move the first? */
8221 | if (tree->first_child == item_to_move) {
8222 | /* simply change first child to next */
8223 | tree->first_child = item_to_move->next;
8224 |
8225 | 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", 8225, "tree->last_child != item_to_move" ))));
8226 | } else {
8227 | proto_item *curr_item;
8228 | /* find previous and change it's next */
8229 | for (curr_item = tree->first_child; curr_item != NULL((void*)0); curr_item = curr_item->next) {
8230 | if (curr_item->next == item_to_move) {
8231 | break;
8232 | }
8233 | }
8234 |
8235 | DISSECTOR_ASSERT(curr_item)((void) ((curr_item) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 8235, "curr_item" ))));
8236 |
8237 | curr_item->next = item_to_move->next;
8238 |
8239 | /* fix last_child if required */
8240 | if (tree->last_child == item_to_move) {
8241 | tree->last_child = curr_item;
8242 | }
8243 | }
8244 |
8245 | /*** insert to_move after fixed ***/
8246 | item_to_move->next = fixed_item->next;
8247 | fixed_item->next = item_to_move;
8248 | if (tree->last_child == fixed_item) {
8249 | tree->last_child = item_to_move;
8250 | }
8251 | }
8252 |
8253 | void
8254 | proto_tree_set_appendix(proto_tree *tree, tvbuff_t *tvb, int start,
8255 | const int length)
8256 | {
8257 | field_info *fi;
8258 |
8259 | if (tree == NULL((void*)0))
8260 | return;
8261 |
8262 | fi = PTREE_FINFO(tree)((tree)->finfo);
8263 | if (fi == NULL((void*)0))
8264 | return;
8265 |
8266 | start += tvb_raw_offset(tvb);
8267 | DISSECTOR_ASSERT(start >= 0)((void) ((start >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8267, "start >= 0" ))));
8268 | DISSECTOR_ASSERT(length >= 0)((void) ((length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8268, "length >= 0" ))));
8269 |
8270 | fi->appendix_start = start;
8271 | fi->appendix_length = length;
8272 | }
8273 |
8274 | static void
8275 | check_protocol_filter_name_or_fail(const char *filter_name)
8276 | {
8277 | /* Require at least two characters. */
8278 | if (filter_name[0] == '\0' || filter_name[1] == '\0') {
8279 | 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);
8280 | }
8281 |
8282 | if (proto_check_field_name(filter_name) != '\0') {
8283 | 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)
8284 | " 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)
8285 | " 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);
8286 | }
8287 |
8288 | /* Check that it doesn't match some very common numeric forms. */
8289 | if (filter_name[0] == '0' &&
8290 | (filter_name[1] == 'x' || filter_name[1] == 'X' ||
8291 | filter_name[1] == 'b' || filter_name[1] == 'B')) {
8292 | 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])
8293 | 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]);
8294 | }
8295 |
8296 | /* Names starting with a digit must not contain a minus sign (currently not checked at runtime). */
8297 |
8298 | /* Check that it contains at least one letter. */
8299 | bool_Bool have_letter = false0;
8300 | for (const char *s = filter_name; *s != '\0'; s++) {
8301 | if (g_ascii_isalpha(*s)((g_ascii_table[(guchar) (*s)] & G_ASCII_ALPHA) != 0)) {
8302 | have_letter = true1;
8303 | break;
8304 | }
8305 | }
8306 | if (!have_letter) {
8307 | 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)
8308 | filter_name)proto_report_dissector_bug("Protocol filter name \"%s\" must contain at least one letter a-z." , filter_name);
8309 | }
8310 |
8311 | /* Check for reserved keywords. */
8312 | if (g_hash_table_contains(proto_reserved_filter_names, filter_name)) {
8313 | 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)
8314 | " 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);
8315 | }
8316 | }
8317 |
8318 | int
8319 | proto_register_protocol(const char *name, const char *short_name,
8320 | const char *filter_name)
8321 | {
8322 | protocol_t *protocol;
8323 | header_field_info *hfinfo;
8324 |
8325 | check_protocol_filter_name_or_fail(filter_name);
8326 |
8327 | /*
8328 | * Add this protocol to the list of known protocols;
8329 | * the list is sorted by protocol short name.
8330 | */
8331 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8332 | protocol->name = name;
8333 | protocol->short_name = short_name;
8334 | protocol->filter_name = filter_name;
8335 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8336 | protocol->is_enabled = true1; /* protocol is enabled by default */
8337 | protocol->enabled_by_default = true1; /* see previous comment */
8338 | protocol->can_toggle = true1;
8339 | protocol->parent_proto_id = -1;
8340 | protocol->heur_list = NULL((void*)0);
8341 |
8342 | /* List will be sorted later by name, when all protocols completed registering */
8343 | protocols = g_list_prepend(protocols, protocol);
8344 | /*
8345 | * Make sure there's not already a protocol with any of those
8346 | * names. Crash if there is, as that's an error in the code
8347 | * or an inappropriate plugin.
8348 | * This situation has to be fixed to not register more than one
8349 | * protocol with the same name.
8350 | */
8351 | if (!g_hash_table_insert(proto_names, (void *)name, protocol)) {
8352 | /* ws_error will terminate the program */
8353 | 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)
8354 | " 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);
8355 | }
8356 | if (!g_hash_table_insert(proto_filter_names, (void *)filter_name, protocol)) {
8357 | 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)
8358 | " 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);
8359 | }
8360 | if (!g_hash_table_insert(proto_short_names, (void *)short_name, protocol)) {
8361 | 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)
8362 | " 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);
8363 | }
8364 |
8365 | /* Here we allocate a new header_field_info struct */
8366 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info )));
8367 | hfinfo->name = name;
8368 | hfinfo->abbrev = filter_name;
8369 | hfinfo->type = FT_PROTOCOL;
8370 | hfinfo->display = BASE_NONE;
8371 | hfinfo->strings = protocol;
8372 | hfinfo->bitmask = 0;
8373 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8374 | hfinfo->blurb = NULL((void*)0);
8375 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8376 |
8377 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8378 | return protocol->proto_id;
8379 | }
8380 |
8381 | int
8382 | proto_register_protocol_in_name_only(const char *name, const char *short_name, const char *filter_name, int parent_proto, enum ftenum field_type)
8383 | {
8384 | protocol_t *protocol;
8385 | header_field_info *hfinfo;
8386 |
8387 | /*
8388 | * Helper protocols don't need the strict rules as a "regular" protocol
8389 | * Just register it in a list and make a hf_ field from it
8390 | */
8391 | if ((field_type != FT_PROTOCOL) && (field_type != FT_BYTES)) {
8392 | 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);
8393 | }
8394 |
8395 | if (parent_proto <= 0) {
8396 | 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)
8397 | " 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);
8398 | }
8399 |
8400 | check_protocol_filter_name_or_fail(filter_name);
8401 |
8402 | /* Add this protocol to the list of helper protocols (just so it can be properly freed) */
8403 | protocol = g_new(protocol_t, 1)((protocol_t *) g_malloc_n ((1), sizeof (protocol_t)));
8404 | protocol->name = name;
8405 | protocol->short_name = short_name;
8406 | protocol->filter_name = filter_name;
8407 | protocol->fields = NULL((void*)0); /* Delegate until actually needed */
8408 |
8409 | /* Enabling and toggling is really determined by parent protocol,
8410 | but provide default values here */
8411 | protocol->is_enabled = true1;
8412 | protocol->enabled_by_default = true1;
8413 | protocol->can_toggle = true1;
8414 |
8415 | protocol->parent_proto_id = parent_proto;
8416 | protocol->heur_list = NULL((void*)0);
8417 |
8418 | /* List will be sorted later by name, when all protocols completed registering */
8419 | protocols = g_list_prepend(protocols, protocol);
8420 |
8421 | /* Here we allocate a new header_field_info struct */
8422 | hfinfo = g_slice_new(header_field_info)((header_field_info*) g_slice_alloc (sizeof (header_field_info )));
8423 | hfinfo->name = name;
8424 | hfinfo->abbrev = filter_name;
8425 | hfinfo->type = field_type;
8426 | hfinfo->display = BASE_NONE;
8427 | if (field_type == FT_BYTES) {
8428 | hfinfo->display |= (BASE_NO_DISPLAY_VALUE0x00002000|BASE_PROTOCOL_INFO0x00004000);
8429 | }
8430 | hfinfo->strings = protocol;
8431 | hfinfo->bitmask = 0;
8432 | hfinfo->ref_type = HF_REF_TYPE_NONE;
8433 | hfinfo->blurb = NULL((void*)0);
8434 | hfinfo->parent = -1; /* This field differentiates protos and fields */
8435 |
8436 | protocol->proto_id = proto_register_field_init(hfinfo, hfinfo->parent);
8437 | return protocol->proto_id;
8438 | }
8439 |
8440 | bool_Bool
8441 | proto_deregister_protocol(const char *short_name)
8442 | {
8443 | protocol_t *protocol;
8444 | header_field_info *hfinfo;
8445 | int proto_id;
8446 | unsigned i;
8447 |
8448 | proto_id = proto_get_id_by_short_name(short_name);
8449 | protocol = find_protocol_by_id(proto_id);
8450 | if (protocol == NULL((void*)0))
8451 | return false0;
8452 |
8453 | g_hash_table_remove(proto_names, protocol->name);
8454 | g_hash_table_remove(proto_short_names, (void *)short_name);
8455 | g_hash_table_remove(proto_filter_names, (void *)protocol->filter_name);
8456 |
8457 | if (protocol->fields) {
8458 | for (i = 0; i < protocol->fields->len; i++) {
8459 | hfinfo = (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8460 | hfinfo_remove_from_gpa_name_map(hfinfo);
8461 | expert_deregister_expertinfo(hfinfo->abbrev);
8462 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
8463 | }
8464 | g_ptr_array_free(protocol->fields, true1);
8465 | protocol->fields = NULL((void*)0);
8466 | }
8467 |
8468 | g_list_free(protocol->heur_list);
8469 |
8470 | /* Remove this protocol from the list of known protocols */
8471 | protocols = g_list_remove(protocols, protocol);
8472 |
8473 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[proto_id]);
8474 | wmem_map_remove(gpa_name_map, protocol->filter_name);
8475 |
8476 | g_free(last_field_name);
8477 | last_field_name = NULL((void*)0);
8478 |
8479 | return true1;
8480 | }
8481 |
8482 | void
8483 | proto_register_alias(const int proto_id, const char *alias_name)
8484 | {
8485 | protocol_t *protocol;
8486 |
8487 | protocol = find_protocol_by_id(proto_id);
8488 | if (alias_name && protocol) {
8489 | g_hash_table_insert(gpa_protocol_aliases, (void *) alias_name, (void *)protocol->filter_name);
8490 | }
8491 | }
8492 |
8493 | /*
8494 | * Routines to use to iterate over the protocols.
8495 | * The argument passed to the iterator routines is an opaque cookie to
8496 | * their callers; it's the GList pointer for the current element in
8497 | * the list.
8498 | * The ID of the protocol is returned, or -1 if there is no protocol.
8499 | */
8500 | int
8501 | proto_get_first_protocol(void **cookie)
8502 | {
8503 | protocol_t *protocol;
8504 |
8505 | if (protocols == NULL((void*)0))
8506 | return -1;
8507 | *cookie = protocols;
8508 | protocol = (protocol_t *)protocols->data;
8509 | return protocol->proto_id;
8510 | }
8511 |
8512 | int
8513 | proto_get_data_protocol(void *cookie)
8514 | {
8515 | GList *list_item = (GList *)cookie;
8516 |
8517 | protocol_t *protocol = (protocol_t *)list_item->data;
8518 | return protocol->proto_id;
8519 | }
8520 |
8521 | int
8522 | proto_get_next_protocol(void **cookie)
8523 | {
8524 | GList *list_item = (GList *)*cookie;
8525 | protocol_t *protocol;
8526 |
8527 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8528 | if (list_item == NULL((void*)0))
8529 | return -1;
8530 | *cookie = list_item;
8531 | protocol = (protocol_t *)list_item->data;
8532 | return protocol->proto_id;
8533 | }
8534 |
8535 | header_field_info *
8536 | proto_get_first_protocol_field(const int proto_id, void **cookie)
8537 | {
8538 | protocol_t *protocol = find_protocol_by_id(proto_id);
8539 |
8540 | if ((protocol == NULL((void*)0)) || (protocol->fields == NULL((void*)0)) || (protocol->fields->len == 0))
8541 | return NULL((void*)0);
8542 |
8543 | *cookie = GUINT_TO_POINTER(0)((gpointer) (gulong) (0));
8544 | return (header_field_info *)g_ptr_array_index(protocol->fields, 0)((protocol->fields)->pdata)[0];
8545 | }
8546 |
8547 | header_field_info *
8548 | proto_get_next_protocol_field(const int proto_id, void **cookie)
8549 | {
8550 | protocol_t *protocol = find_protocol_by_id(proto_id);
8551 | unsigned i = GPOINTER_TO_UINT(*cookie)((guint) (gulong) (*cookie));
8552 |
8553 | i++;
8554 |
8555 | if ((protocol->fields == NULL((void*)0)) || (i >= protocol->fields->len))
8556 | return NULL((void*)0);
8557 |
8558 | *cookie = GUINT_TO_POINTER(i)((gpointer) (gulong) (i));
8559 | return (header_field_info *)g_ptr_array_index(protocol->fields, i)((protocol->fields)->pdata)[i];
8560 | }
8561 |
8562 | protocol_t *
8563 | find_protocol_by_id(const int proto_id)
8564 | {
8565 | header_field_info *hfinfo;
8566 |
8567 | if (proto_id <= 0)
8568 | return NULL((void*)0);
8569 |
8570 | 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", 8570, __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", 8570, "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", 8570, "gpa_hfinfo.hfi[proto_id] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[proto_id];;
8571 | if (hfinfo->type != FT_PROTOCOL) {
8572 | 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", 8572, "hfinfo->display & 0x00004000" ))));
8573 | }
8574 | return (protocol_t *)hfinfo->strings;
8575 | }
8576 |
8577 | int
8578 | proto_get_id(const protocol_t *protocol)
8579 | {
8580 | return protocol->proto_id;
8581 | }
8582 |
8583 | bool_Bool
8584 | proto_name_already_registered(const char *name)
8585 | {
8586 | DISSECTOR_ASSERT_HINT(name, "No name present")((void) ((name) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 8586, "name", "No name present"))));
8587 |
8588 | if (g_hash_table_lookup(proto_names, name) != NULL((void*)0))
8589 | return true1;
8590 | return false0;
8591 | }
8592 |
8593 | int
8594 | proto_get_id_by_filter_name(const char *filter_name)
8595 | {
8596 | const protocol_t *protocol = NULL((void*)0);
8597 |
8598 | 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", 8598, "filter_name", "No filter name present"))));
8599 |
8600 | protocol = (const protocol_t *)g_hash_table_lookup(proto_filter_names, filter_name);
8601 |
8602 | if (protocol == NULL((void*)0))
8603 | return -1;
8604 | return protocol->proto_id;
8605 | }
8606 |
8607 | int
8608 | proto_get_id_by_short_name(const char *short_name)
8609 | {
8610 | const protocol_t *protocol = NULL((void*)0);
8611 |
8612 | 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", 8612, "short_name", "No short name present"))));
8613 |
8614 | protocol = (const protocol_t *)g_hash_table_lookup(proto_short_names, short_name);
8615 |
8616 | if (protocol == NULL((void*)0))
8617 | return -1;
8618 | return protocol->proto_id;
8619 | }
8620 |
8621 | const char *
8622 | proto_get_protocol_name(const int proto_id)
8623 | {
8624 | protocol_t *protocol;
8625 |
8626 | protocol = find_protocol_by_id(proto_id);
8627 |
8628 | if (protocol == NULL((void*)0))
8629 | return NULL((void*)0);
8630 | return protocol->name;
8631 | }
8632 |
8633 | const char *
8634 | proto_get_protocol_short_name(const protocol_t *protocol)
8635 | {
8636 | if (protocol == NULL((void*)0))
8637 | return "(none)";
8638 | return protocol->short_name;
8639 | }
8640 |
8641 | const char *
8642 | proto_get_protocol_long_name(const protocol_t *protocol)
8643 | {
8644 | if (protocol == NULL((void*)0))
8645 | return "(none)";
8646 | return protocol->name;
8647 | }
8648 |
8649 | const char *
8650 | proto_get_protocol_filter_name(const int proto_id)
8651 | {
8652 | protocol_t *protocol;
8653 |
8654 | protocol = find_protocol_by_id(proto_id);
8655 | if (protocol == NULL((void*)0))
8656 | return "(none)";
8657 | return protocol->filter_name;
8658 | }
8659 |
8660 | void proto_add_heuristic_dissector(protocol_t *protocol, const char *short_name)
8661 | {
8662 | heur_dtbl_entry_t* heuristic_dissector;
8663 |
8664 | if (protocol == NULL((void*)0))
8665 | return;
8666 |
8667 | heuristic_dissector = find_heur_dissector_by_unique_short_name(short_name);
8668 | if (heuristic_dissector != NULL((void*)0))
8669 | {
8670 | protocol->heur_list = g_list_prepend (protocol->heur_list, heuristic_dissector);
8671 | }
8672 | }
8673 |
8674 | void proto_heuristic_dissector_foreach(const protocol_t *protocol, GFunc func, void *user_data)
8675 | {
8676 | if (protocol == NULL((void*)0))
8677 | return;
8678 |
8679 | g_list_foreach(protocol->heur_list, func, user_data);
8680 | }
8681 |
8682 | void
8683 | proto_get_frame_protocols(const wmem_list_t *layers, bool_Bool *is_ip,
8684 | bool_Bool *is_tcp, bool_Bool *is_udp,
8685 | bool_Bool *is_sctp, bool_Bool *is_tls,
8686 | bool_Bool *is_rtp,
8687 | bool_Bool *is_lte_rlc)
8688 | {
8689 | wmem_list_frame_t *protos = wmem_list_head(layers);
8690 | int proto_id;
8691 | const char *proto_name;
8692 |
8693 | /* Walk the list of a available protocols in the packet and
8694 | attempt to find "major" ones. */
8695 | /* It might make more sense to assemble and return a bitfield. */
8696 | while (protos != NULL((void*)0))
8697 | {
8698 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8699 | proto_name = proto_get_protocol_filter_name(proto_id);
8700 |
8701 | if (is_ip && ((!strcmp(proto_name, "ip")) ||
8702 | (!strcmp(proto_name, "ipv6")))) {
8703 | *is_ip = true1;
8704 | } else if (is_tcp && !strcmp(proto_name, "tcp")) {
8705 | *is_tcp = true1;
8706 | } else if (is_udp && !strcmp(proto_name, "udp")) {
8707 | *is_udp = true1;
8708 | } else if (is_sctp && !strcmp(proto_name, "sctp")) {
8709 | *is_sctp = true1;
8710 | } else if (is_tls && !strcmp(proto_name, "tls")) {
8711 | *is_tls = true1;
8712 | } else if (is_rtp && !strcmp(proto_name, "rtp")) {
8713 | *is_rtp = true1;
8714 | } else if (is_lte_rlc && (!strcmp(proto_name, "rlc-lte") || !strcmp(proto_name, "rlc-nr"))) {
8715 | *is_lte_rlc = true1;
8716 | }
8717 |
8718 | protos = wmem_list_frame_next(protos);
8719 | }
8720 | }
8721 |
8722 | bool_Bool
8723 | proto_is_frame_protocol(const wmem_list_t *layers, const char* proto_name)
8724 | {
8725 | wmem_list_frame_t *protos = wmem_list_head(layers);
8726 | int proto_id;
8727 | const char *name;
8728 |
8729 | /* Walk the list of a available protocols in the packet and
8730 | attempt to find the specified protocol. */
8731 | while (protos != NULL((void*)0))
8732 | {
8733 | proto_id = GPOINTER_TO_INT(wmem_list_frame_data(protos))((gint) (glong) (wmem_list_frame_data(protos)));
8734 | name = proto_get_protocol_filter_name(proto_id);
8735 |
8736 | if (!strcmp(name, proto_name))
8737 | {
8738 | return true1;
8739 | }
8740 |
8741 | protos = wmem_list_frame_next(protos);
8742 | }
8743 |
8744 | return false0;
8745 | }
8746 |
8747 | char *
8748 | proto_list_layers(const packet_info *pinfo)
8749 | {
8750 | wmem_strbuf_t *buf;
8751 | wmem_list_frame_t *layers = wmem_list_head(pinfo->layers);
8752 |
8753 | buf = wmem_strbuf_new_sized(pinfo->pool, 128);
8754 |
8755 | /* Walk the list of layers in the packet and
8756 | return a string of all entries. */
8757 | while (layers != NULL((void*)0))
8758 | {
8759 | wmem_strbuf_append(buf, proto_get_protocol_filter_name(GPOINTER_TO_UINT(wmem_list_frame_data(layers))((guint) (gulong) (wmem_list_frame_data(layers)))));
8760 |
8761 | layers = wmem_list_frame_next(layers);
8762 | if (layers != NULL((void*)0)) {
8763 | wmem_strbuf_append_c(buf, ':');
8764 | }
8765 | }
8766 |
8767 | return wmem_strbuf_finalize(buf);
8768 | }
8769 |
8770 | uint8_t
8771 | proto_get_layer_num(const packet_info *pinfo, const int proto_id)
8772 | {
8773 | int *proto_layer_num_ptr;
8774 |
8775 | proto_layer_num_ptr = wmem_map_lookup(pinfo->proto_layers, GINT_TO_POINTER(proto_id)((gpointer) (glong) (proto_id)));
8776 | if (proto_layer_num_ptr == NULL((void*)0)) {
8777 | return 0;
8778 | }
8779 |
8780 | return (uint8_t)*proto_layer_num_ptr;
8781 | }
8782 |
8783 | bool_Bool
8784 | proto_is_pino(const protocol_t *protocol)
8785 | {
8786 | return (protocol->parent_proto_id != -1);
8787 | }
8788 |
8789 | bool_Bool
8790 | // NOLINTNEXTLINE(misc-no-recursion)
8791 | proto_is_protocol_enabled(const protocol_t *protocol)
8792 | {
8793 | if (protocol == NULL((void*)0))
8794 | return false0;
8795 |
8796 | //parent protocol determines enable/disable for helper dissectors
8797 | if (proto_is_pino(protocol))
8798 | return proto_is_protocol_enabled(find_protocol_by_id(protocol->parent_proto_id));
8799 |
8800 | return protocol->is_enabled;
8801 | }
8802 |
8803 | bool_Bool
8804 | // NOLINTNEXTLINE(misc-no-recursion)
8805 | proto_is_protocol_enabled_by_default(const protocol_t *protocol)
8806 | {
8807 | //parent protocol determines enable/disable for helper dissectors
8808 | if (proto_is_pino(protocol))
8809 | return proto_is_protocol_enabled_by_default(find_protocol_by_id(protocol->parent_proto_id));
8810 |
8811 | return protocol->enabled_by_default;
8812 | }
8813 |
8814 | bool_Bool
8815 | // NOLINTNEXTLINE(misc-no-recursion)
8816 | proto_can_toggle_protocol(const int proto_id)
8817 | {
8818 | protocol_t *protocol;
8819 |
8820 | protocol = find_protocol_by_id(proto_id);
8821 | //parent protocol determines toggling for helper dissectors
8822 | if (proto_is_pino(protocol))
8823 | return proto_can_toggle_protocol(protocol->parent_proto_id);
8824 |
8825 | return protocol->can_toggle;
8826 | }
8827 |
8828 | void
8829 | proto_disable_by_default(const int proto_id)
8830 | {
8831 | protocol_t *protocol;
8832 |
8833 | protocol = find_protocol_by_id(proto_id);
8834 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8834, "protocol->can_toggle" ))));
8835 | 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", 8835, "proto_is_pino(protocol) == 0" ))));
8836 | protocol->is_enabled = false0;
8837 | protocol->enabled_by_default = false0;
8838 | }
8839 |
8840 | void
8841 | proto_set_decoding(const int proto_id, const bool_Bool enabled)
8842 | {
8843 | protocol_t *protocol;
8844 |
8845 | protocol = find_protocol_by_id(proto_id);
8846 | DISSECTOR_ASSERT(protocol->can_toggle)((void) ((protocol->can_toggle) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 8846, "protocol->can_toggle" ))));
8847 | 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", 8847, "proto_is_pino(protocol) == 0" ))));
8848 | protocol->is_enabled = enabled;
8849 | }
8850 |
8851 | void
8852 | proto_disable_all(void)
8853 | {
8854 | /* This doesn't explicitly disable heuristic protocols,
8855 | * but the heuristic doesn't get called if the parent
8856 | * protocol isn't enabled.
8857 | */
8858 | protocol_t *protocol;
8859 | GList *list_item = protocols;
8860 |
8861 | if (protocols == NULL((void*)0))
8862 | return;
8863 |
8864 | while (list_item) {
8865 | protocol = (protocol_t *)list_item->data;
8866 | if (protocol->can_toggle) {
8867 | protocol->is_enabled = false0;
8868 | }
8869 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8870 | }
8871 | }
8872 |
8873 | static void
8874 | heur_reenable_cb(void *data, void *user_data _U___attribute__((unused)))
8875 | {
8876 | heur_dtbl_entry_t *heur = (heur_dtbl_entry_t*)data;
8877 |
8878 | heur->enabled = heur->enabled_by_default;
8879 | }
8880 |
8881 | void
8882 | proto_reenable_all(void)
8883 | {
8884 | protocol_t *protocol;
8885 | GList *list_item = protocols;
8886 |
8887 | if (protocols == NULL((void*)0))
8888 | return;
8889 |
8890 | while (list_item) {
8891 | protocol = (protocol_t *)list_item->data;
8892 | if (protocol->can_toggle)
8893 | protocol->is_enabled = protocol->enabled_by_default;
8894 | proto_heuristic_dissector_foreach(protocol, heur_reenable_cb, NULL((void*)0));
8895 | list_item = g_list_next(list_item)((list_item) ? (((GList *)(list_item))->next) : ((void*)0) );
8896 | }
8897 | }
8898 |
8899 | void
8900 | proto_set_cant_toggle(const int proto_id)
8901 | {
8902 | protocol_t *protocol;
8903 |
8904 | protocol = find_protocol_by_id(proto_id);
8905 | protocol->can_toggle = false0;
8906 | }
8907 |
8908 | static int
8909 | proto_register_field_common(protocol_t *proto, header_field_info *hfi, const int parent)
8910 | {
8911 | g_ptr_array_add(proto->fields, hfi);
8912 |
8913 | return proto_register_field_init(hfi, parent);
8914 | }
8915 |
8916 | /* for use with static arrays only, since we don't allocate our own copies
8917 | of the header_field_info struct contained within the hf_register_info struct */
8918 | void
8919 | proto_register_field_array(const int parent, hf_register_info *hf, const int num_records)
8920 | {
8921 | hf_register_info *ptr = hf;
8922 | protocol_t *proto;
8923 | int i;
8924 |
8925 | proto = find_protocol_by_id(parent);
8926 |
8927 | /* if (proto == NULL) - error or return? */
8928 |
8929 | if (proto->fields == NULL((void*)0)) {
8930 | /* Ironically, the NEW_PROTO_TREE_API was removed shortly before
8931 | * GLib introduced g_ptr_array_new_from_array, which might have
8932 | * given a reason to actually use it. (#17774)
8933 | */
8934 | proto->fields = g_ptr_array_sized_new(num_records);
8935 | }
8936 |
8937 | for (i = 0; i < num_records; i++, ptr++) {
8938 | /*
8939 | * Make sure we haven't registered this yet.
8940 | * Most fields have variables associated with them that
8941 | * are initialized to 0; some are initialized to -1 (which
8942 | * was the standard before 4.4).
8943 | *
8944 | * XXX - Since this is called almost 300000 times at startup,
8945 | * it might be nice to compare to only 0 and require
8946 | * dissectors to pass in zero for unregistered fields.
8947 | */
8948 | if (*ptr->p_id != -1 && *ptr->p_id != 0) {
8949 | REPORT_DISSECTOR_BUG(proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev)
8950 | "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)
8951 | ptr->hfinfo.abbrev)proto_report_dissector_bug("Duplicate field detected in call to proto_register_field_array: %s is already registered" , ptr->hfinfo.abbrev);
8952 | return;
8953 | }
8954 |
8955 | *ptr->p_id = proto_register_field_common(proto, &ptr->hfinfo, parent);
8956 | }
8957 | }
8958 |
8959 | /* deregister already registered fields */
8960 | void
8961 | proto_deregister_field (const int parent, int hf_id)
8962 | {
8963 | header_field_info *hfi;
8964 | protocol_t *proto;
8965 | unsigned i;
8966 |
8967 | g_free(last_field_name);
8968 | last_field_name = NULL((void*)0);
8969 |
8970 | if (hf_id == -1 || hf_id == 0)
8971 | return;
8972 |
8973 | proto = find_protocol_by_id (parent);
8974 | if (!proto || proto->fields == NULL((void*)0)) {
8975 | return;
8976 | }
8977 |
8978 | for (i = 0; i < proto->fields->len; i++) {
8979 | hfi = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
8980 | if (hfi->id == hf_id) {
8981 | /* Found the hf_id in this protocol */
8982 | wmem_map_remove(gpa_name_map, hfi->abbrev);
8983 | g_ptr_array_remove_index_fast(proto->fields, i);
8984 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hf_id]);
8985 | return;
8986 | }
8987 | }
8988 | }
8989 |
8990 | /* Deregister all registered fields starting with a prefix. Use for dynamic registered fields only! */
8991 | void
8992 | proto_deregister_all_fields_with_prefix(const int parent, const char *prefix)
8993 | {
8994 | header_field_info *hfinfo;
8995 | protocol_t *proto;
8996 |
8997 | g_free(last_field_name);
8998 | last_field_name = NULL((void*)0);
8999 |
9000 | proto = find_protocol_by_id(parent);
9001 | if (proto && proto->fields && proto->fields->len > 0) {
9002 | unsigned i = proto->fields->len;
9003 | do {
9004 | i--;
9005 |
9006 | hfinfo = (header_field_info *)g_ptr_array_index(proto->fields, i)((proto->fields)->pdata)[i];
9007 | 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) )) {
9008 | hfinfo_remove_from_gpa_name_map(hfinfo);
9009 | expert_deregister_expertinfo(hfinfo->abbrev);
9010 | g_ptr_array_add(deregistered_fields, gpa_hfinfo.hfi[hfinfo->id]);
9011 | g_ptr_array_remove_index_fast(proto->fields, i);
9012 | }
9013 | } while (i > 0);
9014 | }
9015 | }
9016 |
9017 | void
9018 | proto_add_deregistered_data (void *data)
9019 | {
9020 | g_ptr_array_add(deregistered_data, data);
9021 | }
9022 |
9023 | void
9024 | proto_add_deregistered_slice (size_t block_size, void *mem_block)
9025 | {
9026 | 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 )));
9027 |
9028 | slice_data->block_size = block_size;
9029 | slice_data->mem_block = mem_block;
9030 |
9031 | g_ptr_array_add(deregistered_slice, slice_data);
9032 | }
9033 |
9034 | void proto_free_field_strings (ftenum_t field_type, unsigned int field_display, const void *field_strings)
9035 | {
9036 | if (field_strings == NULL((void*)0)) {
9037 | return;
9038 | }
9039 |
9040 | switch (field_type) {
9041 | case FT_FRAMENUM:
9042 | /* This is just an integer represented as a pointer */
9043 | break;
9044 | case FT_PROTOCOL: {
9045 | protocol_t *protocol = (protocol_t *)field_strings;
9046 | g_free((char *)protocol->short_name);
9047 | break;
9048 | }
9049 | case FT_BOOLEAN: {
9050 | true_false_string *tf = (true_false_string *)field_strings;
9051 | g_free((char *)tf->true_string);
9052 | g_free((char *)tf->false_string);
9053 | break;
9054 | }
9055 | case FT_UINT40:
9056 | case FT_INT40:
9057 | case FT_UINT48:
9058 | case FT_INT48:
9059 | case FT_UINT56:
9060 | case FT_INT56:
9061 | case FT_UINT64:
9062 | case FT_INT64: {
9063 | if (field_display & BASE_UNIT_STRING0x00001000) {
9064 | unit_name_string *unit = (unit_name_string *)field_strings;
9065 | g_free((char *)unit->singular);
9066 | g_free((char *)unit->plural);
9067 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9068 | range_string *rs = (range_string *)field_strings;
9069 | while (rs->strptr) {
9070 | g_free((char *)rs->strptr);
9071 | rs++;
9072 | }
9073 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9074 | val64_string_ext *vse = (val64_string_ext *)field_strings;
9075 | val64_string *vs = (val64_string *)vse->_vs_p;
9076 | while (vs->strptr) {
9077 | g_free((char *)vs->strptr);
9078 | vs++;
9079 | }
9080 | val64_string_ext_free(vse);
9081 | field_strings = NULL((void*)0);
9082 | } else if (field_display == BASE_CUSTOM) {
9083 | /* this will be a pointer to a function, don't free that */
9084 | field_strings = NULL((void*)0);
9085 | } else {
9086 | val64_string *vs64 = (val64_string *)field_strings;
9087 | while (vs64->strptr) {
9088 | g_free((char *)vs64->strptr);
9089 | vs64++;
9090 | }
9091 | }
9092 | break;
9093 | }
9094 | case FT_CHAR:
9095 | case FT_UINT8:
9096 | case FT_INT8:
9097 | case FT_UINT16:
9098 | case FT_INT16:
9099 | case FT_UINT24:
9100 | case FT_INT24:
9101 | case FT_UINT32:
9102 | case FT_INT32:
9103 | case FT_FLOAT:
9104 | case FT_DOUBLE: {
9105 | if (field_display & BASE_UNIT_STRING0x00001000) {
9106 | unit_name_string *unit = (unit_name_string *)field_strings;
9107 | g_free((char *)unit->singular);
9108 | g_free((char *)unit->plural);
9109 | } else if (field_display & BASE_RANGE_STRING0x00000100) {
9110 | range_string *rs = (range_string *)field_strings;
9111 | while (rs->strptr) {
9112 | g_free((char *)rs->strptr);
9113 | rs++;
9114 | }
9115 | } else if (field_display & BASE_EXT_STRING0x00000200) {
9116 | value_string_ext *vse = (value_string_ext *)field_strings;
9117 | value_string *vs = (value_string *)vse->_vs_p;
9118 | while (vs->strptr) {
9119 | g_free((char *)vs->strptr);
9120 | vs++;
9121 | }
9122 | value_string_ext_free(vse);
9123 | field_strings = NULL((void*)0);
9124 | } else if (field_display == BASE_CUSTOM) {
9125 | /* this will be a pointer to a function, don't free that */
9126 | field_strings = NULL((void*)0);
9127 | } else {
9128 | value_string *vs = (value_string *)field_strings;
9129 | while (vs->strptr) {
9130 | g_free((char *)vs->strptr);
9131 | vs++;
9132 | }
9133 | }
9134 | break;
9135 | default:
9136 | break;
9137 | }
9138 | }
9139 |
9140 | if (field_type != FT_FRAMENUM) {
9141 | g_free((void *)field_strings);
9142 | }
9143 | }
9144 |
9145 | static void
9146 | free_deregistered_field (void *data, void *user_data _U___attribute__((unused)))
9147 | {
9148 | header_field_info *hfi = (header_field_info *) data;
9149 | int hf_id = hfi->id;
9150 |
9151 | g_free((char *)hfi->name);
9152 | g_free((char *)hfi->abbrev);
9153 | g_free((char *)hfi->blurb);
9154 |
9155 | proto_free_field_strings(hfi->type, hfi->display, hfi->strings);
9156 |
9157 | if (hfi->parent == -1)
9158 | 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);
9159 |
9160 | gpa_hfinfo.hfi[hf_id] = NULL((void*)0); /* Invalidate this hf_id / proto_id */
9161 | }
9162 |
9163 | static void
9164 | free_deregistered_data (void *data, void *user_data _U___attribute__((unused)))
9165 | {
9166 | g_free (data);
9167 | }
9168 |
9169 | static void
9170 | free_deregistered_slice (void *data, void *user_data _U___attribute__((unused)))
9171 | {
9172 | struct g_slice_data *slice_data = (struct g_slice_data *)data;
9173 |
9174 | g_slice_free1(slice_data->block_size, slice_data->mem_block);
9175 | 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);
9176 | }
9177 |
9178 | /* free deregistered fields and data */
9179 | void
9180 | proto_free_deregistered_fields (void)
9181 | {
9182 | expert_free_deregistered_expertinfos();
9183 |
9184 | g_ptr_array_foreach(deregistered_fields, free_deregistered_field, NULL((void*)0));
9185 | g_ptr_array_free(deregistered_fields, true1);
9186 | deregistered_fields = g_ptr_array_new();
9187 |
9188 | g_ptr_array_foreach(deregistered_data, free_deregistered_data, NULL((void*)0));
9189 | g_ptr_array_free(deregistered_data, true1);
9190 | deregistered_data = g_ptr_array_new();
9191 |
9192 | g_ptr_array_foreach(deregistered_slice, free_deregistered_slice, NULL((void*)0));
9193 | g_ptr_array_free(deregistered_slice, true1);
9194 | deregistered_slice = g_ptr_array_new();
9195 | }
9196 |
9197 | static const value_string hf_display[] = {
9198 | { BASE_NONE, "BASE_NONE" },
9199 | { BASE_DEC, "BASE_DEC" },
9200 | { BASE_HEX, "BASE_HEX" },
9201 | { BASE_OCT, "BASE_OCT" },
9202 | { BASE_DEC_HEX, "BASE_DEC_HEX" },
9203 | { BASE_HEX_DEC, "BASE_HEX_DEC" },
9204 | { BASE_CUSTOM, "BASE_CUSTOM" },
9205 | { BASE_NONE|BASE_RANGE_STRING0x00000100, "BASE_NONE|BASE_RANGE_STRING" },
9206 | { BASE_DEC|BASE_RANGE_STRING0x00000100, "BASE_DEC|BASE_RANGE_STRING" },
9207 | { BASE_HEX|BASE_RANGE_STRING0x00000100, "BASE_HEX|BASE_RANGE_STRING" },
9208 | { BASE_OCT|BASE_RANGE_STRING0x00000100, "BASE_OCT|BASE_RANGE_STRING" },
9209 | { BASE_DEC_HEX|BASE_RANGE_STRING0x00000100, "BASE_DEC_HEX|BASE_RANGE_STRING" },
9210 | { BASE_HEX_DEC|BASE_RANGE_STRING0x00000100, "BASE_HEX_DEC|BASE_RANGE_STRING" },
9211 | { BASE_CUSTOM|BASE_RANGE_STRING0x00000100, "BASE_CUSTOM|BASE_RANGE_STRING" },
9212 | { BASE_NONE|BASE_VAL64_STRING0x00000400, "BASE_NONE|BASE_VAL64_STRING" },
9213 | { BASE_DEC|BASE_VAL64_STRING0x00000400, "BASE_DEC|BASE_VAL64_STRING" },
9214 | { BASE_HEX|BASE_VAL64_STRING0x00000400, "BASE_HEX|BASE_VAL64_STRING" },
9215 | { BASE_OCT|BASE_VAL64_STRING0x00000400, "BASE_OCT|BASE_VAL64_STRING" },
9216 | { BASE_DEC_HEX|BASE_VAL64_STRING0x00000400, "BASE_DEC_HEX|BASE_VAL64_STRING" },
9217 | { BASE_HEX_DEC|BASE_VAL64_STRING0x00000400, "BASE_HEX_DEC|BASE_VAL64_STRING" },
9218 | { BASE_CUSTOM|BASE_VAL64_STRING0x00000400, "BASE_CUSTOM|BASE_VAL64_STRING" },
9219 | { ABSOLUTE_TIME_LOCAL, "ABSOLUTE_TIME_LOCAL" },
9220 | { ABSOLUTE_TIME_UTC, "ABSOLUTE_TIME_UTC" },
9221 | { ABSOLUTE_TIME_DOY_UTC, "ABSOLUTE_TIME_DOY_UTC" },
9222 | { BASE_PT_UDP, "BASE_PT_UDP" },
9223 | { BASE_PT_TCP, "BASE_PT_TCP" },
9224 | { BASE_PT_DCCP, "BASE_PT_DCCP" },
9225 | { BASE_PT_SCTP, "BASE_PT_SCTP" },
9226 | { BASE_OUI, "BASE_OUI" },
9227 | { 0, NULL((void*)0) } };
9228 |
9229 | const char* proto_field_display_to_string(int field_display)
9230 | {
9231 | return val_to_str_const(field_display, hf_display, "Unknown");
9232 | }
9233 |
9234 | static inline port_type
9235 | display_to_port_type(field_display_e e)
9236 | {
9237 | switch (e) {
9238 | case BASE_PT_UDP:
9239 | return PT_UDP;
9240 | case BASE_PT_TCP:
9241 | return PT_TCP;
9242 | case BASE_PT_DCCP:
9243 | return PT_DCCP;
9244 | case BASE_PT_SCTP:
9245 | return PT_SCTP;
9246 | default:
9247 | break;
9248 | }
9249 | return PT_NONE;
9250 | }
9251 |
9252 | /* temporary function containing assert part for easier profiling */
9253 | static void
9254 | tmp_fld_check_assert(header_field_info *hfinfo)
9255 | {
9256 | char* tmp_str;
9257 |
9258 | /* The field must have a name (with length > 0) */
9259 | if (!hfinfo->name || !hfinfo->name[0]) {
9260 | if (hfinfo->abbrev)
9261 | /* Try to identify the field */
9262 | 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)
9263 | hfinfo->abbrev)proto_report_dissector_bug("Field (abbrev='%s') does not have a name" , hfinfo->abbrev);
9264 | else
9265 | /* Hum, no luck */
9266 | 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)" );
9267 | }
9268 |
9269 | /* fields with an empty string for an abbreviation aren't filterable */
9270 | if (!hfinfo->abbrev || !hfinfo->abbrev[0])
9271 | 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);
9272 |
9273 | /* TODO: This check is a significant percentage of startup time (~10%),
9274 | although not nearly as slow as what's enabled by ENABLE_CHECK_FILTER.
9275 | It might be nice to have a way to disable this check when, e.g.,
9276 | running TShark many times with the same configuration. */
9277 | /* Check that the filter name (abbreviation) is legal;
9278 | * it must contain only alphanumerics, '-', "_", and ".". */
9279 | unsigned char c;
9280 | c = module_check_valid_name(hfinfo->abbrev, false0);
9281 | if (c) {
9282 | if (c == '.') {
9283 | 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);
9284 | } else if (g_ascii_isprint(c)((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)) {
9285 | 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);
9286 | } else {
9287 | 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);
9288 | }
9289 | }
9290 |
9291 | /* These types of fields are allowed to have value_strings,
9292 | * true_false_strings or a protocol_t struct
9293 | */
9294 | if (hfinfo->strings != NULL((void*)0) && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM) {
9295 | switch (hfinfo->type) {
9296 |
9297 | /*
9298 | * These types are allowed to support display value_strings,
9299 | * value64_strings, the extended versions of the previous
9300 | * two, range strings, or unit strings.
9301 | */
9302 | case FT_CHAR:
9303 | case FT_UINT8:
9304 | case FT_UINT16:
9305 | case FT_UINT24:
9306 | case FT_UINT32:
9307 | case FT_UINT40:
9308 | case FT_UINT48:
9309 | case FT_UINT56:
9310 | case FT_UINT64:
9311 | case FT_INT8:
9312 | case FT_INT16:
9313 | case FT_INT24:
9314 | case FT_INT32:
9315 | case FT_INT40:
9316 | case FT_INT48:
9317 | case FT_INT56:
9318 | case FT_INT64:
9319 | case FT_BOOLEAN:
9320 | case FT_PROTOCOL:
9321 | break;
9322 |
9323 | /*
9324 | * This is allowed to have a value of type
9325 | * enum ft_framenum_type to indicate what relationship
9326 | * the frame in question has to the frame in which
9327 | * the field is put.
9328 | */
9329 | case FT_FRAMENUM:
9330 | break;
9331 |
9332 | /*
9333 | * These types are allowed to support only unit strings.
9334 | */
9335 | case FT_FLOAT:
9336 | case FT_DOUBLE:
9337 | case FT_IEEE_11073_SFLOAT:
9338 | case FT_IEEE_11073_FLOAT:
9339 | if (!(hfinfo->display & BASE_UNIT_STRING0x00001000)) {
9340 | 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))
9341 | " (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))
9342 | 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));
9343 | }
9344 | break;
9345 |
9346 | /*
9347 | * These types are allowed to support display
9348 | * time_value_strings.
9349 | */
9350 | case FT_ABSOLUTE_TIME:
9351 | if (hfinfo->display & BASE_RANGE_STRING0x00000100 ||
9352 | hfinfo->display & BASE_EXT_STRING0x00000200 ||
9353 | hfinfo->display & BASE_VAL64_STRING0x00000400 ||
9354 | hfinfo->display & BASE_UNIT_STRING0x00001000) {
9355 | 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))
9356 | " (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))
9357 | 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));
9358 | }
9359 | break;
9360 |
9361 | /*
9362 | * This type is only allowed to support a string if it's
9363 | * a protocol (for pinos).
9364 | */
9365 | case FT_BYTES:
9366 | if (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)) {
9367 | 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))
9368 | " (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))
9369 | 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));
9370 | }
9371 | break;
9372 |
9373 | default:
9374 | 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))
9375 | " (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))
9376 | 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));
9377 | }
9378 | }
9379 |
9380 | /* TODO: This check may slow down startup, and output quite a few warnings.
9381 | It would be good to be able to enable this (and possibly other checks?)
9382 | in non-release builds. */
9383 | #ifdef ENABLE_CHECK_FILTER
9384 | /* Check for duplicate value_string values.
9385 | There are lots that have the same value *and* string, so for now only
9386 | report those that have same value but different string. */
9387 | if ((hfinfo->strings != NULL((void*)0)) &&
9388 | !(hfinfo->display & BASE_RANGE_STRING0x00000100) &&
9389 | !(hfinfo->display & BASE_UNIT_STRING0x00001000) &&
9390 | !((hfinfo->display & FIELD_DISPLAY_E_MASK0xFF) == BASE_CUSTOM) &&
9391 | (
9392 | (hfinfo->type == FT_CHAR) ||
9393 | (hfinfo->type == FT_UINT8) ||
9394 | (hfinfo->type == FT_UINT16) ||
9395 | (hfinfo->type == FT_UINT24) ||
9396 | (hfinfo->type == FT_UINT32) ||
9397 | (hfinfo->type == FT_INT8) ||
9398 | (hfinfo->type == FT_INT16) ||
9399 | (hfinfo->type == FT_INT24) ||
9400 | (hfinfo->type == FT_INT32) )) {
9401 |
9402 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
9403 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
9404 | const val64_string *start_values = VAL64_STRING_EXT_VS_P((const val64_string_ext*)hfinfo->strings)((const val64_string_ext*)hfinfo->strings)->_vs_p;
9405 | CHECK_HF_VALUE(val64_string, PRIu64"l" "u", start_values);
9406 | } else {
9407 | const value_string *start_values = VALUE_STRING_EXT_VS_P((const value_string_ext*)hfinfo->strings)((const value_string_ext*)hfinfo->strings)->_vs_p;
9408 | CHECK_HF_VALUE(value_string, "u", start_values);
9409 | }
9410 | } else {
9411 | const value_string *start_values = (const value_string*)hfinfo->strings;
9412 | CHECK_HF_VALUE(value_string, "u", start_values);
9413 | }
9414 | }
9415 |
9416 | if (hfinfo->type == FT_BOOLEAN) {
9417 | const true_false_string *tfs = (const true_false_string*)hfinfo->strings;
9418 | if (tfs) {
9419 | if (strcmp(tfs->false_string, tfs->true_string) == 0) {
9420 | 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" , 9422, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string); } } while (0)
9421 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9422, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string); } } while (0)
9422 | tfs->false_string, tfs->true_string)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9422, __func__, "Field '%s' (%s) has identical true and false strings (\"%s\", \"%s\")" , hfinfo->name, hfinfo->abbrev, tfs->false_string, tfs ->true_string); } } while (0);
9423 | }
9424 | }
9425 | }
9426 |
9427 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
9428 | const range_string *rs = (const range_string*)(hfinfo->strings);
9429 | if (rs) {
9430 | const range_string *this_it = rs;
9431 |
9432 | do {
9433 | if (this_it->value_max < this_it->value_min) {
9434 | 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" , 9438, __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 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9438, __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->strptr,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9438, __func__, "value_range_string error: %s (%s) entry for \"%s\" - max(%" "l" "u"" 0x%""l" "x"") is less than min(%""l" "u"" 0x%""l" "x" ")", hfinfo->name, hfinfo->abbrev, this_it->strptr, this_it ->value_max, this_it->value_max, this_it->value_min, this_it->value_min); } } while (0)
9437 | this_it->value_max, this_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9438, __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)
9438 | this_it->value_min, this_it->value_min)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9438, __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);
9439 | ++this_it;
9440 | continue;
9441 | }
9442 |
9443 | for (const range_string *prev_it=rs; prev_it < this_it; ++prev_it) {
9444 | /* Not OK if this one is completely hidden by an earlier one! */
9445 | if ((prev_it->value_min <= this_it->value_min) && (prev_it->value_max >= this_it->value_max)) {
9446 | 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" , 9452, __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=\"%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" , 9452, __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 | hfinfo->name, hfinfo->abbrev,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9452, __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 | prev_it->strptr, prev_it->value_min, prev_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9452, __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 | prev_it->value_max, prev_it->value_max,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9452, __func__, "value_range_string error: %s (%s) hidden by earlier entry " "(prev=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%" "l" "x"") (this=\"%s\": %""l" "u"" 0x%""l" "x"" -> %""l" "u"" 0x%""l" "x"")", hfinfo->name, hfinfo->abbrev, prev_it ->strptr, prev_it->value_min, prev_it->value_min, prev_it ->value_max, prev_it->value_max, this_it->strptr, this_it ->value_min, this_it->value_min, this_it->value_max, this_it->value_max); } } while (0)
9451 | this_it->strptr, this_it->value_min, this_it->value_min,do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9452, __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)
9452 | this_it->value_max, this_it->value_max)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 9452, __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);
9453 | }
9454 | }
9455 | ++this_it;
9456 | } while (this_it->strptr);
9457 | }
9458 | }
9459 | #endif
9460 |
9461 | switch (hfinfo->type) {
9462 |
9463 | case FT_CHAR:
9464 | /* Require the char type to have BASE_HEX, BASE_OCT,
9465 | * BASE_CUSTOM, or BASE_NONE as its base.
9466 | *
9467 | * If the display value is BASE_NONE and there is a
9468 | * strings conversion then the dissector writer is
9469 | * telling us that the field's numerical value is
9470 | * meaningless; we'll avoid showing the value to the
9471 | * user.
9472 | */
9473 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9474 | case BASE_HEX:
9475 | case BASE_OCT:
9476 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9477 | break;
9478 | case BASE_NONE:
9479 | if (hfinfo->strings == NULL((void*)0))
9480 | 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 ))
9481 | " 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 ))
9482 | " 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 ))
9483 | 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 ))
9484 | 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 ));
9485 | break;
9486 | default:
9487 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9488 | 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)
9489 | " 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)
9490 | 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)
9491 | 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);
9492 | //wmem_free(NULL, tmp_str);
9493 | }
9494 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
9495 | 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 ))
9496 | 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 ))
9497 | 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 ));
9498 | }
9499 | break;
9500 | case FT_INT8:
9501 | case FT_INT16:
9502 | case FT_INT24:
9503 | case FT_INT32:
9504 | case FT_INT40:
9505 | case FT_INT48:
9506 | case FT_INT56:
9507 | case FT_INT64:
9508 | /* Hexadecimal and octal are, in printf() and everywhere
9509 | * else, unsigned so don't allow dissectors to register a
9510 | * signed field to be displayed unsigned. (Else how would
9511 | * we display negative values?)
9512 | */
9513 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9514 | case BASE_HEX:
9515 | case BASE_OCT:
9516 | case BASE_DEC_HEX:
9517 | case BASE_HEX_DEC:
9518 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9519 | 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)
9520 | 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)
9521 | 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);
9522 | //wmem_free(NULL, tmp_str);
9523 | }
9524 | /* FALL THROUGH */
9525 | case FT_UINT8:
9526 | case FT_UINT16:
9527 | case FT_UINT24:
9528 | case FT_UINT32:
9529 | case FT_UINT40:
9530 | case FT_UINT48:
9531 | case FT_UINT56:
9532 | case FT_UINT64:
9533 | 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 ))) {
9534 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9535 | if (hfinfo->type != FT_UINT16) {
9536 | 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))
9537 | 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))
9538 | 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));
9539 | }
9540 | if (hfinfo->strings != NULL((void*)0)) {
9541 | 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)
9542 | 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)
9543 | 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);
9544 | }
9545 | if (hfinfo->bitmask != 0) {
9546 | 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)
9547 | 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)
9548 | 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);
9549 | }
9550 | wmem_free(NULL((void*)0), tmp_str);
9551 | break;
9552 | }
9553 |
9554 | if (hfinfo->display == BASE_OUI) {
9555 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9556 | if (hfinfo->type != FT_UINT24) {
9557 | 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))
9558 | 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))
9559 | 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));
9560 | }
9561 | if (hfinfo->strings != NULL((void*)0)) {
9562 | 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)
9563 | 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)
9564 | 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);
9565 | }
9566 | if (hfinfo->bitmask != 0) {
9567 | 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)
9568 | 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)
9569 | 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);
9570 | }
9571 | wmem_free(NULL((void*)0), tmp_str);
9572 | break;
9573 | }
9574 |
9575 | /* Require integral types (other than frame number,
9576 | * which is always displayed in decimal) to have a
9577 | * number base.
9578 | *
9579 | * If the display value is BASE_NONE and there is a
9580 | * strings conversion then the dissector writer is
9581 | * telling us that the field's numerical value is
9582 | * meaningless; we'll avoid showing the value to the
9583 | * user.
9584 | */
9585 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9586 | case BASE_DEC:
9587 | case BASE_HEX:
9588 | case BASE_OCT:
9589 | case BASE_DEC_HEX:
9590 | case BASE_HEX_DEC:
9591 | case BASE_CUSTOM: /* hfinfo_numeric_value_format() treats this as decimal */
9592 | break;
9593 | case BASE_NONE:
9594 | if (hfinfo->strings == NULL((void*)0)) {
9595 | 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 ))
9596 | " 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 ))
9597 | " 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 ))
9598 | 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 ))
9599 | 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 ));
9600 | }
9601 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
9602 | 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 ))
9603 | " 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 ))
9604 | " 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 ))
9605 | 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 ))
9606 | 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 ));
9607 | }
9608 | break;
9609 |
9610 | default:
9611 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9612 | 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)
9613 | " 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)
9614 | 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)
9615 | 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);
9616 | //wmem_free(NULL, tmp_str);
9617 | }
9618 | break;
9619 | case FT_BYTES:
9620 | case FT_UINT_BYTES:
9621 | /* Require bytes to have a "display type" that could
9622 | * add a character between displayed bytes.
9623 | */
9624 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9625 | case BASE_NONE:
9626 | case SEP_DOT:
9627 | case SEP_DASH:
9628 | case SEP_COLON:
9629 | case SEP_SPACE:
9630 | break;
9631 | default:
9632 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9633 | 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)
9634 | 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);
9635 | //wmem_free(NULL, tmp_str);
9636 | }
9637 | if (hfinfo->bitmask != 0)
9638 | 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 ))
9639 | 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 ))
9640 | 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 ));
9641 | //allowed to support string if its a protocol (for pinos)
9642 | if ((hfinfo->strings != NULL((void*)0)) && (!(hfinfo->display & BASE_PROTOCOL_INFO0x00004000)))
9643 | 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 ))
9644 | 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 ))
9645 | 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 ));
9646 | break;
9647 |
9648 | case FT_PROTOCOL:
9649 | case FT_FRAMENUM:
9650 | if (hfinfo->display != BASE_NONE) {
9651 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9652 | 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)
9653 | 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)
9654 | 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);
9655 | //wmem_free(NULL, tmp_str);
9656 | }
9657 | if (hfinfo->bitmask != 0)
9658 | 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 ))
9659 | 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 ))
9660 | 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 ));
9661 | break;
9662 |
9663 | case FT_BOOLEAN:
9664 | break;
9665 |
9666 | case FT_ABSOLUTE_TIME:
9667 | if (!FIELD_DISPLAY_IS_ABSOLUTE_TIME(hfinfo->display)(((hfinfo->display) & 0xFF) >= ABSOLUTE_TIME_LOCAL && ((hfinfo->display) & 0xFF) <= ABSOLUTE_TIME_UNIX)) {
9668 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9669 | 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)
9670 | 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);
9671 | //wmem_free(NULL, tmp_str);
9672 | }
9673 | if (hfinfo->bitmask != 0)
9674 | 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 ))
9675 | 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 ))
9676 | 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 ));
9677 | break;
9678 |
9679 | case FT_STRING:
9680 | case FT_STRINGZ:
9681 | case FT_UINT_STRING:
9682 | case FT_STRINGZPAD:
9683 | case FT_STRINGZTRUNC:
9684 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9685 | case BASE_NONE:
9686 | case BASE_STR_WSP:
9687 | break;
9688 |
9689 | default:
9690 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9691 | 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)
9692 | " 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)
9693 | 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)
9694 | 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);
9695 | //wmem_free(NULL, tmp_str);
9696 | }
9697 |
9698 | if (hfinfo->bitmask != 0)
9699 | 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 ))
9700 | 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 ))
9701 | 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 ));
9702 | if (hfinfo->strings != NULL((void*)0))
9703 | 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 ))
9704 | 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 ))
9705 | 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 ));
9706 | break;
9707 |
9708 | case FT_IPv4:
9709 | switch (hfinfo->display) {
9710 | case BASE_NONE:
9711 | case BASE_NETMASK:
9712 | break;
9713 |
9714 | default:
9715 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9716 | 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)
9717 | " 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)
9718 | 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)
9719 | 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);
9720 | //wmem_free(NULL, tmp_str);
9721 | break;
9722 | }
9723 | break;
9724 | case FT_FLOAT:
9725 | case FT_DOUBLE:
9726 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
9727 | case BASE_NONE:
9728 | case BASE_DEC:
9729 | case BASE_HEX:
9730 | case BASE_EXP:
9731 | case BASE_CUSTOM:
9732 | break;
9733 | default:
9734 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Unknown: 0x%x)");
9735 | 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)
9736 | " 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)
9737 | 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)
9738 | 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);
9739 | //wmem_free(NULL, tmp_str);
9740 | }
9741 | if (hfinfo->bitmask != 0)
9742 | 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 ))
9743 | 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 ))
9744 | 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 ));
9745 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM && (hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9746 | 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 ))
9747 | 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 ))
9748 | 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 ));
9749 | break;
9750 | case FT_IEEE_11073_SFLOAT:
9751 | case FT_IEEE_11073_FLOAT:
9752 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_NONE) {
9753 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9754 | 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)
9755 | 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)
9756 | 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)
9757 | 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);
9758 | //wmem_free(NULL, tmp_str);
9759 | }
9760 | if (hfinfo->bitmask != 0)
9761 | 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 ))
9762 | 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 ))
9763 | 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 ));
9764 | if ((hfinfo->strings != NULL((void*)0)) && !(hfinfo->display & BASE_UNIT_STRING0x00001000))
9765 | 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 ))
9766 | 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 ))
9767 | 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 ));
9768 | break;
9769 | default:
9770 | if (hfinfo->display != BASE_NONE) {
9771 | tmp_str = val_to_str(NULL((void*)0), hfinfo->display, hf_display, "(Bit count: %d)");
9772 | 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)
9773 | 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)
9774 | 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)
9775 | 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);
9776 | //wmem_free(NULL, tmp_str);
9777 | }
9778 | if (hfinfo->bitmask != 0)
9779 | 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 ))
9780 | 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 ))
9781 | 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 ));
9782 | if (hfinfo->strings != NULL((void*)0))
9783 | 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 ))
9784 | 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 ))
9785 | 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 ));
9786 | break;
9787 | }
9788 | }
9789 |
9790 | static void
9791 | register_type_length_mismatch(void)
9792 | {
9793 | static ei_register_info ei[] = {
9794 | { &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)}} }},
9795 | { &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)}} }},
9796 | };
9797 |
9798 | expert_module_t* expert_type_length_mismatch;
9799 |
9800 | proto_type_length_mismatch = proto_register_protocol("Type Length Mismatch", "Type length mismatch", "_ws.type_length");
9801 |
9802 | expert_type_length_mismatch = expert_register_protocol(proto_type_length_mismatch);
9803 | expert_register_field_array(expert_type_length_mismatch, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9804 |
9805 | /* "Type Length Mismatch" isn't really a protocol, it's an error indication;
9806 | disabling them makes no sense. */
9807 | proto_set_cant_toggle(proto_type_length_mismatch);
9808 | }
9809 |
9810 | static void
9811 | register_byte_array_string_decodinws_error(void)
9812 | {
9813 | static ei_register_info ei[] = {
9814 | { &ei_byte_array_string_decoding_failed_error,
9815 | { "_ws.byte_array_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9816 | "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)}}
9817 | }
9818 | },
9819 | };
9820 |
9821 | expert_module_t* expert_byte_array_string_decoding_error;
9822 |
9823 | proto_byte_array_string_decoding_error =
9824 | proto_register_protocol("Byte Array-String Decoding Error",
9825 | "Byte Array-string decoding error",
9826 | "_ws.byte_array_string.decoding_error");
9827 |
9828 | expert_byte_array_string_decoding_error =
9829 | expert_register_protocol(proto_byte_array_string_decoding_error);
9830 | expert_register_field_array(expert_byte_array_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9831 |
9832 | /* "Byte Array-String Decoding Error" isn't really a protocol, it's an error indication;
9833 | disabling them makes no sense. */
9834 | proto_set_cant_toggle(proto_byte_array_string_decoding_error);
9835 | }
9836 |
9837 | static void
9838 | register_date_time_string_decodinws_error(void)
9839 | {
9840 | static ei_register_info ei[] = {
9841 | { &ei_date_time_string_decoding_failed_error,
9842 | { "_ws.date_time_string.decoding_error.failed", PI_MALFORMED0x07000000, PI_ERROR0x00800000,
9843 | "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)}}
9844 | }
9845 | },
9846 | };
9847 |
9848 | expert_module_t* expert_date_time_string_decoding_error;
9849 |
9850 | proto_date_time_string_decoding_error =
9851 | proto_register_protocol("Date and Time-String Decoding Error",
9852 | "Date and Time-string decoding error",
9853 | "_ws.date_time_string.decoding_error");
9854 |
9855 | expert_date_time_string_decoding_error =
9856 | expert_register_protocol(proto_date_time_string_decoding_error);
9857 | expert_register_field_array(expert_date_time_string_decoding_error, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9858 |
9859 | /* "Date and Time-String Decoding Error" isn't really a protocol, it's an error indication;
9860 | disabling them makes no sense. */
9861 | proto_set_cant_toggle(proto_date_time_string_decoding_error);
9862 | }
9863 |
9864 | static void
9865 | register_string_errors(void)
9866 | {
9867 | static ei_register_info ei[] = {
9868 | { &ei_string_trailing_characters,
9869 | { "_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)}} }
9870 | },
9871 | };
9872 |
9873 | expert_module_t* expert_string_errors;
9874 |
9875 | proto_string_errors = proto_register_protocol("String Errors", "String errors", "_ws.string");
9876 |
9877 | expert_string_errors = expert_register_protocol(proto_string_errors);
9878 | expert_register_field_array(expert_string_errors, ei, array_length(ei)(sizeof (ei) / sizeof (ei)[0]));
9879 |
9880 | /* "String Errors" isn't really a protocol, it's an error indication;
9881 | disabling them makes no sense. */
9882 | proto_set_cant_toggle(proto_string_errors);
9883 | }
9884 |
9885 | static int
9886 | proto_register_field_init(header_field_info *hfinfo, const int parent)
9887 | {
9888 |
9889 | tmp_fld_check_assert(hfinfo);
9890 |
9891 | hfinfo->parent = parent;
9892 | hfinfo->same_name_next = NULL((void*)0);
9893 | hfinfo->same_name_prev_id = -1;
9894 |
9895 | /* if we always add and never delete, then id == len - 1 is correct */
9896 | if (gpa_hfinfo.len >= gpa_hfinfo.allocated_len) {
9897 | if (!gpa_hfinfo.hfi) {
9898 | gpa_hfinfo.allocated_len = PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000);
9899 | gpa_hfinfo.hfi = (header_field_info **)g_malloc(sizeof(header_field_info *)*PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
9900 | /* The entry with index 0 is not used. */
9901 | gpa_hfinfo.hfi[0] = NULL((void*)0);
9902 | gpa_hfinfo.len = 1;
9903 | } else {
9904 | gpa_hfinfo.allocated_len += 1000;
9905 | gpa_hfinfo.hfi = (header_field_info **)g_realloc(gpa_hfinfo.hfi,
9906 | sizeof(header_field_info *)*gpa_hfinfo.allocated_len);
9907 | /*ws_warning("gpa_hfinfo.allocated_len %u", gpa_hfinfo.allocated_len);*/
9908 | }
9909 | }
9910 | gpa_hfinfo.hfi[gpa_hfinfo.len] = hfinfo;
9911 | gpa_hfinfo.len++;
9912 | hfinfo->id = gpa_hfinfo.len - 1;
9913 |
9914 | /* if we have real names, enter this field in the name tree */
9915 | /* Already checked in tmp_fld_check_assert */
9916 | /*if ((hfinfo->name[0] != 0) && (hfinfo->abbrev[0] != 0 )) */
9917 | {
9918 |
9919 | header_field_info *same_name_next_hfinfo;
9920 |
9921 | /* We allow multiple hfinfo's to be registered under the same
9922 | * abbreviation. This was done for X.25, as, depending
9923 | * on whether it's modulo-8 or modulo-128 operation,
9924 | * some bitfield fields may be in different bits of
9925 | * a byte, and we want to be able to refer to that field
9926 | * with one name regardless of whether the packets
9927 | * are modulo-8 or modulo-128 packets. */
9928 |
9929 | /* wmem_map_insert - if key is already present the previous
9930 | * hfinfo with the same key/name is returned, otherwise NULL */
9931 | same_name_hfinfo = wmem_map_insert(gpa_name_map, (void *) (hfinfo->abbrev), hfinfo);
9932 | if (same_name_hfinfo) {
9933 | /* There's already a field with this name.
9934 | * Put the current field *before* that field
9935 | * in the list of fields with this name, Thus,
9936 | * we end up with an effectively
9937 | * doubly-linked-list of same-named hfinfo's,
9938 | * with the head of the list (stored in the
9939 | * hash) being the last seen hfinfo.
9940 | */
9941 | same_name_next_hfinfo =
9942 | same_name_hfinfo->same_name_next;
9943 |
9944 | hfinfo->same_name_next = same_name_next_hfinfo;
9945 | if (same_name_next_hfinfo)
9946 | same_name_next_hfinfo->same_name_prev_id = hfinfo->id;
9947 |
9948 | same_name_hfinfo->same_name_next = hfinfo;
9949 | hfinfo->same_name_prev_id = same_name_hfinfo->id;
9950 | #ifdef ENABLE_CHECK_FILTER
9951 | while (same_name_hfinfo) {
9952 | if (!ftype_similar_types(hfinfo->type, same_name_hfinfo->type))
9953 | 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" , 9953, __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);
9954 | same_name_hfinfo = same_name_hfinfo->same_name_next;
9955 | }
9956 | #endif
9957 | }
9958 | }
9959 |
9960 | return hfinfo->id;
9961 | }
9962 |
9963 | void
9964 | proto_register_subtree_array(int * const *indices, const int num_indices)
9965 | {
9966 | int i;
9967 | int *const *ptr = indices;
9968 |
9969 | /*
9970 | * If we've already allocated the array of tree types, expand
9971 | * it; this lets plugins such as mate add tree types after
9972 | * the initial startup. (If we haven't already allocated it,
9973 | * we don't allocate it; on the first pass, we just assign
9974 | * ett values and keep track of how many we've assigned, and
9975 | * when we're finished registering all dissectors we allocate
9976 | * the array, so that we do only one allocation rather than
9977 | * wasting CPU time and memory by growing the array for each
9978 | * dissector that registers ett values.)
9979 | */
9980 | if (tree_is_expanded != NULL((void*)0)) {
9981 | tree_is_expanded = (uint32_t *)g_realloc(tree_is_expanded, (1+((num_tree_types + num_indices)/32)) * sizeof(uint32_t));
9982 |
9983 | /* set new items to 0 */
9984 | /* XXX, slow!!! optimize when needed (align 'i' to 32, and set rest of uint32_t to 0) */
9985 | for (i = num_tree_types; i < num_tree_types + num_indices; i++)
9986 | tree_is_expanded[i >> 5] &= ~(1U << (i & 31));
9987 | }
9988 |
9989 | /*
9990 | * Assign "num_indices" subtree numbers starting at "num_tree_types",
9991 | * returning the indices through the pointers in the array whose
9992 | * first element is pointed to by "indices", and update
9993 | * "num_tree_types" appropriately.
9994 | */
9995 | for (i = 0; i < num_indices; i++, ptr++, num_tree_types++) {
9996 | if (**ptr != -1 && **ptr != 0) {
9997 | 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.")
9998 | " 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.")
9999 | " 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.")
10000 | " 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.");
10001 | }
10002 | **ptr = num_tree_types;
10003 | }
10004 | }
10005 |
10006 | static void
10007 | mark_truncated(char *label_str, size_t name_pos, const size_t size, size_t *value_pos)
10008 | {
10009 | static const char trunc_str[] = " [" UTF8_HORIZONTAL_ELLIPSIS"\u2026" "] ";
10010 | const size_t trunc_len = sizeof(trunc_str)-2; /* Default do not include the trailing space. */
10011 | char *last_char;
10012 |
10013 | /* ..... field_name: dataaaaaaaaaaaaa
10014 | * |
10015 | * ^^^^^ name_pos
10016 | *
10017 | * ..... field_name […]: dataaaaaaaaaaaaa
10018 | *
10019 | * name_pos==0 means that we have only data or only a field_name
10020 | */
10021 |
10022 | ws_assert(size > trunc_len)do { if ((1) && !(size > trunc_len)) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10022, __func__, "assertion failed: %s" , "size > trunc_len"); } while (0);
10023 |
10024 | if (name_pos >= size - trunc_len) {
10025 | /* No room for trunc_str after the field_name, put it first. */
10026 | name_pos = 0;
10027 | }
10028 |
10029 | memmove(label_str + name_pos + trunc_len, label_str + name_pos, size - name_pos - trunc_len);
10030 | if (name_pos == 0) {
10031 | /* Copy the trunc_str after the first byte, so that we don't have a leading space in the label. */
10032 | memcpy(label_str, trunc_str + 1, trunc_len);
10033 | } else {
10034 | memcpy(label_str + name_pos, trunc_str, trunc_len);
10035 | }
10036 | /* in general, label_str is UTF-8
10037 | we can truncate it only at the beginning of a new character
10038 | we go backwards from the byte right after our buffer and
10039 | find the next starting byte of a UTF-8 character, this is
10040 | where we cut
10041 | there's no need to use g_utf8_find_prev_char(), the search
10042 | will always succeed since we copied trunc_str into the
10043 | buffer */
10044 | /* g_utf8_prev_char does not deference the memory address
10045 | * passed in (until after decrementing it, so it is perfectly
10046 | * legal to pass in a pointer one past the last element.
10047 | */
10048 | last_char = g_utf8_prev_char(label_str + size);
10049 | *last_char = '\0';
10050 |
10051 | if (value_pos && *value_pos > 0) {
10052 | if (name_pos == 0) {
10053 | *value_pos += trunc_len;
10054 | } else {
10055 | /* Move one back to include trunc_str in the value. */
10056 | *value_pos -= 1;
10057 | }
10058 | }
10059 |
10060 | /* Check if value_pos is past label_str. */
10061 | if (value_pos && *value_pos >= size) {
10062 | *value_pos = size - 1;
10063 | }
10064 | }
10065 |
10066 | static void
10067 | label_mark_truncated(char *label_str, size_t name_pos, size_t *value_pos)
10068 | {
10069 | mark_truncated(label_str, name_pos, ITEM_LABEL_LENGTH240, value_pos);
10070 | }
10071 |
10072 | static size_t
10073 | label_fill(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, size_t *value_pos)
10074 | {
10075 | size_t name_pos;
10076 |
10077 | /* "%s: %s", hfinfo->name, text */
10078 | name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hfinfo-> name, 0);
10079 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10080 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10081 | if (value_pos) {
10082 | *value_pos = pos;
10083 | }
10084 | pos = ws_label_strcpy(label_str, ITEM_LABEL_LENGTH240, pos, (const uint8_t*)(text ? text : "(null)"), label_strcat_flags(hfinfo));
10085 | }
10086 |
10087 | if (pos >= ITEM_LABEL_LENGTH240) {
10088 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10089 | label_mark_truncated(label_str, name_pos, value_pos);
10090 | }
10091 |
10092 | return pos;
10093 | }
10094 |
10095 | static size_t
10096 | label_fill_descr(char *label_str, size_t pos, const header_field_info *hfinfo, const char *text, const char *descr, size_t *value_pos)
10097 | {
10098 | size_t name_pos;
10099 |
10100 | /* "%s: %s (%s)", hfinfo->name, text, descr */
10101 | name_pos = pos = label_concat(label_str, pos, (const uint8_t*)hfinfo->name)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hfinfo-> name, 0);
10102 | if (!(hfinfo->display & BASE_NO_DISPLAY_VALUE0x00002000)) {
10103 | pos = label_concat(label_str, pos, (const uint8_t*)": ")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)": ", 0);
10104 | if (value_pos) {
10105 | *value_pos = pos;
10106 | }
10107 | if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
10108 | pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(descr ? descr : "(null)"), 0);
10109 | pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(text ? text : "(null)"), 0);
10110 | } else {
10111 | pos = label_concat(label_str, pos, (const uint8_t*)(text ? text : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(text ? text : "(null)"), 0);
10112 | pos = label_concat(label_str, pos, (const uint8_t*)" (")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)" (", 0);
10113 | pos = label_concat(label_str, pos, (const uint8_t*)(descr ? descr : "(null)"))ws_label_strcpy(label_str, 240, pos, (const uint8_t*)(descr ? descr : "(null)"), 0);
10114 | pos = label_concat(label_str, pos, (const uint8_t*)")")ws_label_strcpy(label_str, 240, pos, (const uint8_t*)")", 0);
10115 | }
10116 | }
10117 |
10118 | if (pos >= ITEM_LABEL_LENGTH240) {
10119 | /* Uh oh, we don't have enough room. Tell the user that the field is truncated. */
10120 | label_mark_truncated(label_str, name_pos, value_pos);
10121 | }
10122 |
10123 | return pos;
10124 | }
10125 |
10126 | void
10127 | proto_item_fill_label(const field_info *fi, char *label_str, size_t *value_pos)
10128 | {
10129 | const header_field_info *hfinfo;
10130 | const char *str;
10131 | const uint8_t *bytes;
10132 | uint32_t integer;
10133 | const ipv4_addr_and_mask *ipv4;
10134 | const ipv6_addr_and_prefix *ipv6;
10135 | const e_guid_t *guid;
10136 | char *name;
10137 | address addr;
10138 | char *addr_str;
10139 | char *tmp;
10140 |
10141 | if (!label_str) {
10142 | ws_warning("NULL label_str passed to proto_item_fill_label.")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10142, __func__, "NULL label_str passed to proto_item_fill_label." ); } } while (0);
10143 | return;
10144 | }
10145 |
10146 | label_str[0]= '\0';
10147 |
10148 | if (!fi) {
10149 | return;
10150 | }
10151 |
10152 | hfinfo = fi->hfinfo;
10153 |
10154 | switch (hfinfo->type) {
10155 | case FT_NONE:
10156 | case FT_PROTOCOL:
10157 | (void) g_strlcpy(label_str, hfinfo->name, ITEM_LABEL_LENGTH240);
10158 | if (value_pos) {
10159 | *value_pos = strlen(hfinfo->name);
10160 | }
10161 | break;
10162 |
10163 | case FT_BOOLEAN:
10164 | fill_label_boolean(fi, label_str, value_pos);
10165 | break;
10166 |
10167 | case FT_BYTES:
10168 | case FT_UINT_BYTES:
10169 | tmp = format_bytes_hfinfo(NULL((void*)0), hfinfo,
10170 | fvalue_get_bytes_data(fi->value),
10171 | (unsigned)fvalue_length2(fi->value));
10172 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10173 | wmem_free(NULL((void*)0), tmp);
10174 | break;
10175 |
10176 | case FT_CHAR:
10177 | if (hfinfo->bitmask) {
10178 | fill_label_bitfield_char(fi, label_str, value_pos);
10179 | } else {
10180 | fill_label_char(fi, label_str, value_pos);
10181 | }
10182 | break;
10183 |
10184 | /* Four types of integers to take care of:
10185 | * Bitfield, with val_string
10186 | * Bitfield, w/o val_string
10187 | * Non-bitfield, with val_string
10188 | * Non-bitfield, w/o val_string
10189 | */
10190 | case FT_UINT8:
10191 | case FT_UINT16:
10192 | case FT_UINT24:
10193 | case FT_UINT32:
10194 | if (hfinfo->bitmask) {
10195 | fill_label_bitfield(fi, label_str, value_pos, false0);
10196 | } else {
10197 | fill_label_number(fi, label_str, value_pos, false0);
10198 | }
10199 | break;
10200 |
10201 | case FT_FRAMENUM:
10202 | fill_label_number(fi, label_str, value_pos, false0);
10203 | break;
10204 |
10205 | case FT_UINT40:
10206 | case FT_UINT48:
10207 | case FT_UINT56:
10208 | case FT_UINT64:
10209 | if (hfinfo->bitmask) {
10210 | fill_label_bitfield64(fi, label_str, value_pos, false0);
10211 | } else {
10212 | fill_label_number64(fi, label_str, value_pos, false0);
10213 | }
10214 | break;
10215 |
10216 | case FT_INT8:
10217 | case FT_INT16:
10218 | case FT_INT24:
10219 | case FT_INT32:
10220 | if (hfinfo->bitmask) {
10221 | fill_label_bitfield(fi, label_str, value_pos, true1);
10222 | } else {
10223 | fill_label_number(fi, label_str, value_pos, true1);
10224 | }
10225 | break;
10226 |
10227 | case FT_INT40:
10228 | case FT_INT48:
10229 | case FT_INT56:
10230 | case FT_INT64:
10231 | if (hfinfo->bitmask) {
10232 | fill_label_bitfield64(fi, label_str, value_pos, true1);
10233 | } else {
10234 | fill_label_number64(fi, label_str, value_pos, true1);
10235 | }
10236 | break;
10237 |
10238 | case FT_FLOAT:
10239 | case FT_DOUBLE:
10240 | fill_label_float(fi, label_str, value_pos);
10241 | break;
10242 |
10243 | case FT_ABSOLUTE_TIME:
10244 | {
10245 | const nstime_t *value = fvalue_get_time(fi->value);
10246 | int flags = ABS_TIME_TO_STR_SHOW_ZONE(1U << 0);
10247 | if (prefs.display_abs_time_ascii < ABS_TIME_ASCII_TREE) {
10248 | flags |= ABS_TIME_TO_STR_ISO8601(1U << 3);
10249 | }
10250 | if (hfinfo->strings) {
10251 | /*
10252 | * Table of time valus to be displayed
10253 | * specially.
10254 | */
10255 | const char *time_string = try_time_val_to_str(value, (const time_value_string *)hfinfo->strings);
10256 | if (time_string != NULL((void*)0)) {
10257 | label_fill(label_str, 0, hfinfo, time_string, value_pos);
10258 | break;
10259 | }
10260 | }
10261 | tmp = abs_time_to_str_ex(NULL((void*)0), value, hfinfo->display, flags);
10262 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10263 | wmem_free(NULL((void*)0), tmp);
10264 | break;
10265 | }
10266 | case FT_RELATIVE_TIME:
10267 | tmp = rel_time_to_str(NULL((void*)0), fvalue_get_time(fi->value));
10268 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10269 | wmem_free(NULL((void*)0), tmp);
10270 | break;
10271 |
10272 | case FT_IPXNET:
10273 | integer = fvalue_get_uinteger(fi->value);
10274 | tmp = get_ipxnet_name(NULL((void*)0), integer);
10275 | addr_str = wmem_strdup_printf(NULL((void*)0), "0x%08X", integer);
10276 | label_fill_descr(label_str, 0, hfinfo, tmp, addr_str, value_pos);
10277 | wmem_free(NULL((void*)0), tmp);
10278 | wmem_free(NULL((void*)0), addr_str);
10279 | break;
10280 |
10281 | case FT_VINES:
10282 | addr.type = AT_VINES;
10283 | addr.len = VINES_ADDR_LEN6;
10284 | addr.data = fvalue_get_bytes_data(fi->value);
10285 |
10286 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10287 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10288 | wmem_free(NULL((void*)0), addr_str);
10289 | break;
10290 |
10291 | case FT_ETHER:
10292 | bytes = fvalue_get_bytes_data(fi->value);
10293 |
10294 | addr.type = AT_ETHER;
10295 | addr.len = 6;
10296 | addr.data = bytes;
10297 |
10298 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10299 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10300 | wmem_free(NULL((void*)0), addr_str);
10301 | break;
10302 |
10303 | case FT_IPv4:
10304 | ipv4 = fvalue_get_ipv4(fi->value);
10305 | set_address_ipv4(&addr, ipv4);
10306 |
10307 | if (hfinfo->display == BASE_NETMASK) {
10308 | addr_str = (char*)address_to_str(NULL((void*)0), &addr);
10309 | } else {
10310 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10311 | }
10312 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10313 | wmem_free(NULL((void*)0), addr_str);
10314 | free_address(&addr);
10315 | break;
10316 |
10317 | case FT_IPv6:
10318 | ipv6 = fvalue_get_ipv6(fi->value);
10319 | set_address_ipv6(&addr, ipv6);
10320 |
10321 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10322 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10323 | wmem_free(NULL((void*)0), addr_str);
10324 | free_address(&addr);
10325 | break;
10326 |
10327 | case FT_FCWWN:
10328 | bytes = fvalue_get_bytes_data(fi->value);
10329 | addr.type = AT_FCWWN;
10330 | addr.len = FCWWN_ADDR_LEN8;
10331 | addr.data = bytes;
10332 |
10333 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10334 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10335 | wmem_free(NULL((void*)0), addr_str);
10336 | break;
10337 |
10338 | case FT_GUID:
10339 | guid = fvalue_get_guid(fi->value);
10340 | tmp = guid_to_str(NULL((void*)0), guid);
10341 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10342 | wmem_free(NULL((void*)0), tmp);
10343 | break;
10344 |
10345 | case FT_OID:
10346 | bytes = fvalue_get_bytes_data(fi->value);
10347 | name = oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10348 | tmp = oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10349 | if (name) {
10350 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10351 | wmem_free(NULL((void*)0), name);
10352 | } else {
10353 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10354 | }
10355 | wmem_free(NULL((void*)0), tmp);
10356 | break;
10357 |
10358 | case FT_REL_OID:
10359 | bytes = fvalue_get_bytes_data(fi->value);
10360 | name = rel_oid_resolved_from_encoded(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10361 | tmp = rel_oid_encoded2string(NULL((void*)0), bytes, (unsigned)fvalue_length2(fi->value));
10362 | if (name) {
10363 | label_fill_descr(label_str, 0, hfinfo, tmp, name, value_pos);
10364 | wmem_free(NULL((void*)0), name);
10365 | } else {
10366 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10367 | }
10368 | wmem_free(NULL((void*)0), tmp);
10369 | break;
10370 |
10371 | case FT_SYSTEM_ID:
10372 | bytes = fvalue_get_bytes_data(fi->value);
10373 | tmp = print_system_id(NULL((void*)0), bytes, (int)fvalue_length2(fi->value));
10374 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10375 | wmem_free(NULL((void*)0), tmp);
10376 | break;
10377 |
10378 | case FT_EUI64:
10379 | bytes = fvalue_get_bytes_data(fi->value);
10380 | addr.type = AT_EUI64;
10381 | addr.len = EUI64_ADDR_LEN8;
10382 | addr.data = bytes;
10383 |
10384 | addr_str = (char*)address_with_resolution_to_str(NULL((void*)0), &addr);
10385 | label_fill(label_str, 0, hfinfo, addr_str, value_pos);
10386 | wmem_free(NULL((void*)0), addr_str);
10387 | break;
10388 | case FT_STRING:
10389 | case FT_STRINGZ:
10390 | case FT_UINT_STRING:
10391 | case FT_STRINGZPAD:
10392 | case FT_STRINGZTRUNC:
10393 | case FT_AX25:
10394 | str = fvalue_get_string(fi->value);
10395 | label_fill(label_str, 0, hfinfo, str, value_pos);
10396 | break;
10397 |
10398 | case FT_IEEE_11073_SFLOAT:
10399 | case FT_IEEE_11073_FLOAT:
10400 | fill_label_ieee_11073_float(fi, label_str, value_pos);
10401 | break;
10402 |
10403 | default:
10404 | 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 ))
10405 | 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 ))
10406 | 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 ))
10407 | 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 ));
10408 | break;
10409 | }
10410 | }
10411 |
10412 | static void
10413 | fill_label_boolean(const field_info *fi, char *label_str, size_t *value_pos)
10414 | {
10415 | char *p;
10416 | int bitfield_byte_length = 0, bitwidth;
10417 | uint64_t unshifted_value;
10418 | uint64_t value;
10419 |
10420 | const header_field_info *hfinfo = fi->hfinfo;
10421 |
10422 | value = fvalue_get_uinteger64(fi->value);
10423 | if (hfinfo->bitmask) {
10424 | /* Figure out the bit width */
10425 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10426 |
10427 | /* Un-shift bits */
10428 | unshifted_value = value;
10429 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10430 |
10431 | /* Create the bitfield first */
10432 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10433 | bitfield_byte_length = (int) (p - label_str);
10434 | }
10435 |
10436 | /* Fill in the textual info */
10437 | label_fill(label_str, bitfield_byte_length, hfinfo, tfs_get_string(!!value, hfinfo->strings), value_pos);
10438 | }
10439 |
10440 | static const char *
10441 | hf_try_val_to_str(uint32_t value, const header_field_info *hfinfo)
10442 | {
10443 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10444 | return try_rval_to_str(value, (const range_string *) hfinfo->strings);
10445 |
10446 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
10447 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10448 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10449 | else
10450 | return try_val_to_str_ext(value, (value_string_ext *) hfinfo->strings);
10451 | }
10452 |
10453 | if (hfinfo->display & BASE_VAL64_STRING0x00000400)
10454 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10455 |
10456 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10457 | return unit_name_string_get_value(value, (const struct unit_name_string*) hfinfo->strings);
10458 |
10459 | return try_val_to_str(value, (const value_string *) hfinfo->strings);
10460 | }
10461 |
10462 | static const char *
10463 | hf_try_val64_to_str(uint64_t value, const header_field_info *hfinfo)
10464 | {
10465 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
10466 | if (hfinfo->display & BASE_EXT_STRING0x00000200)
10467 | return try_val64_to_str_ext(value, (val64_string_ext *) hfinfo->strings);
10468 | else
10469 | return try_val64_to_str(value, (const val64_string *) hfinfo->strings);
10470 | }
10471 |
10472 | if (hfinfo->display & BASE_RANGE_STRING0x00000100)
10473 | return try_rval64_to_str(value, (const range_string *) hfinfo->strings);
10474 |
10475 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10476 | return unit_name_string_get_value64(value, (const struct unit_name_string*) hfinfo->strings);
10477 |
10478 | /* If this is reached somebody registered a 64-bit field with a 32-bit
10479 | * value-string, which isn't right. */
10480 | 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)
10481 | hfinfo->abbrev)proto_report_dissector_bug("field %s is a 64-bit field with a 32-bit value_string" , hfinfo->abbrev);
10482 |
10483 | /* This is necessary to squelch MSVC errors; is there
10484 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10485 | never returns? */
10486 | return NULL((void*)0);
10487 | }
10488 |
10489 | static const char *
10490 | hf_try_double_val_to_str(double value, const header_field_info *hfinfo)
10491 | {
10492 | if (hfinfo->display & BASE_UNIT_STRING0x00001000)
10493 | return unit_name_string_get_double(value, (const struct unit_name_string*)hfinfo->strings);
10494 |
10495 | 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);
10496 |
10497 | /* This is necessary to squelch MSVC errors; is there
10498 | any way to tell it that DISSECTOR_ASSERT_NOT_REACHED()
10499 | never returns? */
10500 | return NULL((void*)0);
10501 | }
10502 |
10503 | static const char *
10504 | hf_try_val_to_str_const(uint32_t value, const header_field_info *hfinfo, const char *unknown_str)
10505 | {
10506 | const char *str = hf_try_val_to_str(value, hfinfo);
10507 |
10508 | return (str) ? str : unknown_str;
10509 | }
10510 |
10511 | static const char *
10512 | hf_try_val64_to_str_const(uint64_t value, const header_field_info *hfinfo, const char *unknown_str)
10513 | {
10514 | const char *str = hf_try_val64_to_str(value, hfinfo);
10515 |
10516 | return (str) ? str : unknown_str;
10517 | }
10518 |
10519 | /* Fills data for bitfield chars with val_strings */
10520 | static void
10521 | fill_label_bitfield_char(const field_info *fi, char *label_str, size_t *value_pos)
10522 | {
10523 | char *p;
10524 | int bitfield_byte_length, bitwidth;
10525 | uint32_t unshifted_value;
10526 | uint32_t value;
10527 |
10528 | char buf[32];
10529 | const char *out;
10530 |
10531 | const header_field_info *hfinfo = fi->hfinfo;
10532 |
10533 | /* Figure out the bit width */
10534 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10535 |
10536 | /* Un-shift bits */
10537 | value = fvalue_get_uinteger(fi->value);
10538 |
10539 | unshifted_value = value;
10540 | if (hfinfo->bitmask) {
10541 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10542 | }
10543 |
10544 | /* Create the bitfield first */
10545 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10546 | bitfield_byte_length = (int) (p - label_str);
10547 |
10548 | /* Fill in the textual info using stored (shifted) value */
10549 | if (hfinfo->display == BASE_CUSTOM) {
10550 | char tmp[ITEM_LABEL_LENGTH240];
10551 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10552 |
10553 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10553, "fmtfunc"))));
10554 | fmtfunc(tmp, value);
10555 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10556 | }
10557 | else if (hfinfo->strings) {
10558 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10559 |
10560 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10561 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10562 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10563 | else
10564 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10565 | }
10566 | else {
10567 | out = hfinfo_char_value_format(hfinfo, buf, value);
10568 |
10569 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10570 | }
10571 | }
10572 |
10573 | /* Fills data for bitfield ints with val_strings */
10574 | static void
10575 | fill_label_bitfield(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10576 | {
10577 | char *p;
10578 | int bitfield_byte_length, bitwidth;
10579 | uint32_t value, unshifted_value;
10580 | char buf[NUMBER_LABEL_LENGTH80];
10581 | const char *out;
10582 |
10583 | const header_field_info *hfinfo = fi->hfinfo;
10584 |
10585 | /* Figure out the bit width */
10586 | if (fi->flags & FI_VARINT0x00040000)
10587 | bitwidth = fi->length*8;
10588 | else
10589 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10590 |
10591 | /* Un-shift bits */
10592 | if (is_signed)
10593 | value = fvalue_get_sinteger(fi->value);
10594 | else
10595 | value = fvalue_get_uinteger(fi->value);
10596 |
10597 | unshifted_value = value;
10598 | if (hfinfo->bitmask) {
10599 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10600 | }
10601 |
10602 | /* Create the bitfield first */
10603 | if (fi->flags & FI_VARINT0x00040000)
10604 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10605 | else
10606 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10607 | bitfield_byte_length = (int) (p - label_str);
10608 |
10609 | /* Fill in the textual info using stored (shifted) value */
10610 | if (hfinfo->display == BASE_CUSTOM) {
10611 | char tmp[ITEM_LABEL_LENGTH240];
10612 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10613 |
10614 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10614, "fmtfunc"))));
10615 | fmtfunc(tmp, value);
10616 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10617 | }
10618 | else if (hfinfo->strings) {
10619 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10620 |
10621 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10622 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10623 | /*
10624 | * Unique values only display value_string string
10625 | * if there is a match. Otherwise it's just a number
10626 | */
10627 | if (val_str) {
10628 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10629 | } else {
10630 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10631 | }
10632 | } else {
10633 | if (val_str == NULL((void*)0))
10634 | val_str = "Unknown";
10635 |
10636 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10637 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10638 | else
10639 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10640 | }
10641 | }
10642 | else {
10643 | out = hfinfo_number_value_format(hfinfo, buf, value);
10644 |
10645 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10646 | }
10647 | }
10648 |
10649 | static void
10650 | fill_label_bitfield64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10651 | {
10652 | char *p;
10653 | int bitfield_byte_length, bitwidth;
10654 | uint64_t value, unshifted_value;
10655 | char buf[NUMBER_LABEL_LENGTH80];
10656 | const char *out;
10657 |
10658 | const header_field_info *hfinfo = fi->hfinfo;
10659 |
10660 | /* Figure out the bit width */
10661 | if (fi->flags & FI_VARINT0x00040000)
10662 | bitwidth = fi->length*8;
10663 | else
10664 | bitwidth = hfinfo_container_bitwidth(hfinfo);
10665 |
10666 | /* Un-shift bits */
10667 | if (is_signed)
10668 | value = fvalue_get_sinteger64(fi->value);
10669 | else
10670 | value = fvalue_get_uinteger64(fi->value);
10671 |
10672 | unshifted_value = value;
10673 | if (hfinfo->bitmask) {
10674 | unshifted_value <<= hfinfo_bitshift(hfinfo);
10675 | }
10676 |
10677 | /* Create the bitfield first */
10678 | if (fi->flags & FI_VARINT0x00040000)
10679 | p = decode_bitfield_varint_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10680 | else
10681 | p = decode_bitfield_value(label_str, unshifted_value, hfinfo->bitmask, bitwidth);
10682 | bitfield_byte_length = (int) (p - label_str);
10683 |
10684 | /* Fill in the textual info using stored (shifted) value */
10685 | if (hfinfo->display == BASE_CUSTOM) {
10686 | char tmp[ITEM_LABEL_LENGTH240];
10687 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10688 |
10689 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 10689, "fmtfunc64" ))));
10690 | fmtfunc64(tmp, value);
10691 | label_fill(label_str, bitfield_byte_length, hfinfo, tmp, value_pos);
10692 | }
10693 | else if (hfinfo->strings) {
10694 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
10695 |
10696 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
10697 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10698 | /*
10699 | * Unique values only display value_string string
10700 | * if there is a match. Otherwise it's just a number
10701 | */
10702 | if (val_str) {
10703 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10704 | } else {
10705 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10706 | }
10707 | } else {
10708 | if (val_str == NULL((void*)0))
10709 | val_str = "Unknown";
10710 |
10711 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10712 | label_fill(label_str, bitfield_byte_length, hfinfo, val_str, value_pos);
10713 | else
10714 | label_fill_descr(label_str, bitfield_byte_length, hfinfo, val_str, out, value_pos);
10715 | }
10716 | }
10717 | else {
10718 | out = hfinfo_number_value_format64(hfinfo, buf, value);
10719 |
10720 | label_fill(label_str, bitfield_byte_length, hfinfo, out, value_pos);
10721 | }
10722 | }
10723 |
10724 | static void
10725 | fill_label_char(const field_info *fi, char *label_str, size_t *value_pos)
10726 | {
10727 | const header_field_info *hfinfo = fi->hfinfo;
10728 | uint32_t value;
10729 |
10730 | char buf[32];
10731 | const char *out;
10732 |
10733 | value = fvalue_get_uinteger(fi->value);
10734 |
10735 | /* Fill in the textual info */
10736 | if (hfinfo->display == BASE_CUSTOM) {
10737 | char tmp[ITEM_LABEL_LENGTH240];
10738 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10739 |
10740 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10740, "fmtfunc"))));
10741 | fmtfunc(tmp, value);
10742 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10743 | }
10744 | else if (hfinfo->strings) {
10745 | const char *val_str = hf_try_val_to_str_const(value, hfinfo, "Unknown");
10746 |
10747 | out = hfinfo_char_vals_format(hfinfo, buf, value);
10748 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10749 | }
10750 | else {
10751 | out = hfinfo_char_value_format(hfinfo, buf, value);
10752 |
10753 | label_fill(label_str, 0, hfinfo, out, value_pos);
10754 | }
10755 | }
10756 |
10757 | static void
10758 | fill_label_number(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10759 | {
10760 | const header_field_info *hfinfo = fi->hfinfo;
10761 | uint32_t value;
10762 |
10763 | char buf[NUMBER_LABEL_LENGTH80];
10764 | const char *out;
10765 |
10766 | if (is_signed)
10767 | value = fvalue_get_sinteger(fi->value);
10768 | else
10769 | value = fvalue_get_uinteger(fi->value);
10770 |
10771 | /* Fill in the textual info */
10772 | if (hfinfo->display == BASE_CUSTOM) {
10773 | char tmp[ITEM_LABEL_LENGTH240];
10774 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hfinfo->strings;
10775 |
10776 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10776, "fmtfunc"))));
10777 | fmtfunc(tmp, value);
10778 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10779 | }
10780 | else if (hfinfo->strings && hfinfo->type != FT_FRAMENUM) {
10781 | /*
10782 | * It makes no sense to have a value-string table for a
10783 | * frame-number field - they're just integers giving
10784 | * the ordinal frame number.
10785 | */
10786 | const char *val_str = hf_try_val_to_str(value, hfinfo);
10787 |
10788 | out = hfinfo_number_vals_format(hfinfo, buf, value);
10789 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10790 | /*
10791 | * Unique values only display value_string string
10792 | * if there is a match. Otherwise it's just a number
10793 | */
10794 | if (val_str) {
10795 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10796 | } else {
10797 | label_fill(label_str, 0, hfinfo, out, value_pos);
10798 | }
10799 | } else {
10800 | if (val_str == NULL((void*)0))
10801 | val_str = "Unknown";
10802 |
10803 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10804 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
10805 | else
10806 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10807 | }
10808 | }
10809 | 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 ))) {
10810 | char tmp[ITEM_LABEL_LENGTH240];
10811 |
10812 | port_with_resolution_to_str_buf(tmp, sizeof(tmp),
10813 | display_to_port_type((field_display_e)hfinfo->display), value);
10814 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10815 | }
10816 | else {
10817 | out = hfinfo_number_value_format(hfinfo, buf, value);
10818 |
10819 | label_fill(label_str, 0, hfinfo, out, value_pos);
10820 | }
10821 | }
10822 |
10823 | static void
10824 | fill_label_number64(const field_info *fi, char *label_str, size_t *value_pos, bool_Bool is_signed)
10825 | {
10826 | const header_field_info *hfinfo = fi->hfinfo;
10827 | uint64_t value;
10828 |
10829 | char buf[NUMBER_LABEL_LENGTH80];
10830 | const char *out;
10831 |
10832 | if (is_signed)
10833 | value = fvalue_get_sinteger64(fi->value);
10834 | else
10835 | value = fvalue_get_uinteger64(fi->value);
10836 |
10837 | /* Fill in the textual info */
10838 | if (hfinfo->display == BASE_CUSTOM) {
10839 | char tmp[ITEM_LABEL_LENGTH240];
10840 | const custom_fmt_func_64_t fmtfunc64 = (const custom_fmt_func_64_t)hfinfo->strings;
10841 |
10842 | DISSECTOR_ASSERT(fmtfunc64)((void) ((fmtfunc64) ? (void)0 : (proto_report_dissector_bug( "%s:%u: failed assertion \"%s\"", "epan/proto.c", 10842, "fmtfunc64" ))));
10843 | fmtfunc64(tmp, value);
10844 | label_fill(label_str, 0, hfinfo, tmp, value_pos);
10845 | }
10846 | else if (hfinfo->strings) {
10847 | const char *val_str = hf_try_val64_to_str(value, hfinfo);
10848 |
10849 | out = hfinfo_number_vals_format64(hfinfo, buf, value);
10850 | if (hfinfo->display & BASE_SPECIAL_VALS0x00008000) {
10851 | /*
10852 | * Unique values only display value_string string
10853 | * if there is a match. Otherwise it's just a number
10854 | */
10855 | if (val_str) {
10856 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10857 | } else {
10858 | label_fill(label_str, 0, hfinfo, out, value_pos);
10859 | }
10860 | } else {
10861 | if (val_str == NULL((void*)0))
10862 | val_str = "Unknown";
10863 |
10864 | if (out == NULL((void*)0)) /* BASE_NONE so don't put integer in descr */
10865 | label_fill(label_str, 0, hfinfo, val_str, value_pos);
10866 | else
10867 | label_fill_descr(label_str, 0, hfinfo, val_str, out, value_pos);
10868 | }
10869 | }
10870 | else {
10871 | out = hfinfo_number_value_format64(hfinfo, buf, value);
10872 |
10873 | label_fill(label_str, 0, hfinfo, out, value_pos);
10874 | }
10875 | }
10876 |
10877 | static size_t
10878 | fill_display_label_float(const field_info *fi, char *label_str, const int label_str_size)
10879 | {
10880 | int display;
10881 | int n;
10882 | double value;
10883 |
10884 | if (label_str_size < 12) {
10885 | /* Not enough room to write an entire floating point value. */
10886 | return 0;
10887 | }
10888 |
10889 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10890 | value = fvalue_get_floating(fi->value);
10891 |
10892 | if (display == BASE_CUSTOM) {
10893 | const custom_fmt_func_double_t fmtfunc = (const custom_fmt_func_double_t)fi->hfinfo->strings;
10894 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 10894, "fmtfunc"))));
10895 | fmtfunc(label_str, value);
10896 | return strlen(label_str);
10897 | }
10898 |
10899 | switch (display) {
10900 | case BASE_NONE:
10901 | if (fi->hfinfo->type == FT_FLOAT) {
10902 | n = snprintf(label_str, label_str_size, "%.*g", FLT_DIG6, value);
10903 | } else {
10904 | n = (int)strlen(dtoa_g_fmt(label_str, value));
10905 | }
10906 | break;
10907 | case BASE_DEC:
10908 | n = snprintf(label_str, label_str_size, "%f", value);
10909 | break;
10910 | case BASE_HEX:
10911 | n = snprintf(label_str, label_str_size, "%a", value);
10912 | break;
10913 | case BASE_EXP:
10914 | n = snprintf(label_str, label_str_size, "%e", value);
10915 | break;
10916 | default:
10917 | ws_assert_not_reached()ws_log_fatal_full("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 10917 , __func__, "assertion \"not reached\" failed");
10918 | }
10919 | if (n < 0) {
10920 | return 0; /* error */
10921 | }
10922 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10923 | const char *hf_str_val;
10924 | hf_str_val = hf_try_double_val_to_str(value, fi->hfinfo);
10925 | n += proto_strlcpy(label_str + n, hf_str_val, label_str_size - n);
10926 | }
10927 | if (n > label_str_size) {
10928 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10928, __func__, "label length too small"); } } while (0);
10929 | return strlen(label_str);
10930 | }
10931 |
10932 | return n;
10933 | }
10934 |
10935 | void
10936 | fill_label_float(const field_info *fi, char *label_str, size_t *value_pos)
10937 | {
10938 | char tmp[ITEM_LABEL_LENGTH240];
10939 |
10940 | fill_display_label_float(fi, tmp, ITEM_LABEL_LENGTH240);
10941 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10942 | }
10943 |
10944 | static size_t
10945 | fill_display_label_ieee_11073_float(const field_info *fi, char *label_str, const int label_str_size)
10946 | {
10947 | int display;
10948 | size_t pos = 0;
10949 | double value;
10950 | char* tmp_str;
10951 |
10952 | if (label_str_size < 12) {
10953 | /* Not enough room to write an entire floating point value. */
10954 | return 0;
10955 | }
10956 |
10957 | display = FIELD_DISPLAY(fi->hfinfo->display)((fi->hfinfo->display) & 0xFF);
10958 | tmp_str = fvalue_to_string_repr(NULL((void*)0), fi->value, FTREPR_DISPLAY, display);
10959 | pos = label_concat(label_str, pos, (const uint8_t*)tmp_str)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)tmp_str, 0);
10960 | wmem_free(NULL((void*)0), tmp_str);
10961 |
10962 | if ((fi->hfinfo->strings) && (fi->hfinfo->display & BASE_UNIT_STRING0x00001000)) {
10963 | const char *hf_str_val;
10964 | fvalue_to_double(fi->value, &value);
10965 | hf_str_val = unit_name_string_get_double(value, (const struct unit_name_string*)fi->hfinfo->strings);
10966 | pos = label_concat(label_str, pos, (const uint8_t*)hf_str_val)ws_label_strcpy(label_str, 240, pos, (const uint8_t*)hf_str_val , 0);
10967 | }
10968 | if ((int)pos > label_str_size) {
10969 | ws_warning("label length too small")do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 10969, __func__, "label length too small"); } } while (0);
10970 | return strlen(label_str);
10971 | }
10972 |
10973 | return pos;
10974 | }
10975 |
10976 | void
10977 | fill_label_ieee_11073_float(const field_info *fi, char *label_str, size_t *value_pos)
10978 | {
10979 | char tmp[ITEM_LABEL_LENGTH240];
10980 |
10981 | fill_display_label_ieee_11073_float(fi, tmp, ITEM_LABEL_LENGTH240);
10982 | label_fill(label_str, 0, fi->hfinfo, tmp, value_pos);
10983 | }
10984 |
10985 | int
10986 | hfinfo_bitshift(const header_field_info *hfinfo)
10987 | {
10988 | return ws_ctz(hfinfo->bitmask);
10989 | }
10990 |
10991 |
10992 | static int
10993 | hfinfo_bitoffset(const header_field_info *hfinfo)
10994 | {
10995 | if (!hfinfo->bitmask) {
10996 | return 0;
10997 | }
10998 |
10999 | /* ilog2 = first set bit, counting 0 as the last bit; we want 0
11000 | * as the first bit */
11001 | return hfinfo_container_bitwidth(hfinfo) - 1 - ws_ilog2(hfinfo->bitmask);
11002 | }
11003 |
11004 | static int
11005 | hfinfo_mask_bitwidth(const header_field_info *hfinfo)
11006 | {
11007 | if (!hfinfo->bitmask) {
11008 | return 0;
11009 | }
11010 |
11011 | /* ilog2 = first set bit, ctz = last set bit */
11012 | return ws_ilog2(hfinfo->bitmask) - ws_ctz(hfinfo->bitmask) + 1;
11013 | }
11014 |
11015 | static int
11016 | hfinfo_type_bitwidth(enum ftenum type)
11017 | {
11018 | int bitwidth = 0;
11019 |
11020 | switch (type) {
11021 | case FT_CHAR:
11022 | case FT_UINT8:
11023 | case FT_INT8:
11024 | bitwidth = 8;
11025 | break;
11026 | case FT_UINT16:
11027 | case FT_INT16:
11028 | bitwidth = 16;
11029 | break;
11030 | case FT_UINT24:
11031 | case FT_INT24:
11032 | bitwidth = 24;
11033 | break;
11034 | case FT_UINT32:
11035 | case FT_INT32:
11036 | bitwidth = 32;
11037 | break;
11038 | case FT_UINT40:
11039 | case FT_INT40:
11040 | bitwidth = 40;
11041 | break;
11042 | case FT_UINT48:
11043 | case FT_INT48:
11044 | bitwidth = 48;
11045 | break;
11046 | case FT_UINT56:
11047 | case FT_INT56:
11048 | bitwidth = 56;
11049 | break;
11050 | case FT_UINT64:
11051 | case FT_INT64:
11052 | bitwidth = 64;
11053 | break;
11054 | default:
11055 | DISSECTOR_ASSERT_NOT_REACHED()(proto_report_dissector_bug("%s:%u: failed assertion \"DISSECTOR_ASSERT_NOT_REACHED\"" , "epan/proto.c", 11055));
11056 | ;
11057 | }
11058 | return bitwidth;
11059 | }
11060 |
11061 |
11062 | static int
11063 | hfinfo_container_bitwidth(const header_field_info *hfinfo)
11064 | {
11065 | if (!hfinfo->bitmask) {
11066 | return 0;
11067 | }
11068 |
11069 | if (hfinfo->type == FT_BOOLEAN) {
11070 | return hfinfo->display; /* hacky? :) */
11071 | }
11072 |
11073 | return hfinfo_type_bitwidth(hfinfo->type);
11074 | }
11075 |
11076 | static int
11077 | hfinfo_hex_digits(const header_field_info *hfinfo)
11078 | {
11079 | int bitwidth;
11080 |
11081 | /* If we have a bitmask, hfinfo->type is the width of the container, so not
11082 | * appropriate to determine the number of hex digits for the field.
11083 | * So instead, we compute it from the bitmask.
11084 | */
11085 | if (hfinfo->bitmask != 0) {
11086 | bitwidth = hfinfo_mask_bitwidth(hfinfo);
11087 | } else {
11088 | bitwidth = hfinfo_type_bitwidth(hfinfo->type);
11089 | }
11090 |
11091 | /* Divide by 4, rounding up, to get number of hex digits. */
11092 | return (bitwidth + 3) / 4;
11093 | }
11094 |
11095 | const char *
11096 | hfinfo_char_value_format_display(int display, char buf[7], uint32_t value)
11097 | {
11098 | char *ptr = &buf[6];
11099 | static const char hex_digits[16] =
11100 | { '0', '1', '2', '3', '4', '5', '6', '7',
11101 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
11102 |
11103 | *ptr = '\0';
11104 | *(--ptr) = '\'';
11105 | /* Properly format value */
11106 | if (g_ascii_isprint(value)((g_ascii_table[(guchar) (value)] & G_ASCII_PRINT) != 0)) {
11107 | /*
11108 | * Printable, so just show the character, and, if it needs
11109 | * to be escaped, escape it.
11110 | */
11111 | *(--ptr) = value;
11112 | if (value == '\\' || value == '\'')
11113 | *(--ptr) = '\\';
11114 | } else {
11115 | /*
11116 | * Non-printable; show it as an escape sequence.
11117 | */
11118 | switch (value) {
11119 |
11120 | case '\0':
11121 | /*
11122 | * Show a NUL with only one digit.
11123 | */
11124 | *(--ptr) = '0';
11125 | break;
11126 |
11127 | case '\a':
11128 | case '\b':
11129 | case '\f':
11130 | case '\n':
11131 | case '\r':
11132 | case '\t':
11133 | case '\v':
11134 | *(--ptr) = value - '\a' + 'a';
11135 | break;
11136 |
11137 | default:
11138 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11139 |
11140 | case BASE_OCT:
11141 | *(--ptr) = (value & 0x7) + '0';
11142 | value >>= 3;
11143 | *(--ptr) = (value & 0x7) + '0';
11144 | value >>= 3;
11145 | *(--ptr) = (value & 0x7) + '0';
11146 | break;
11147 |
11148 | case BASE_HEX:
11149 | *(--ptr) = hex_digits[value & 0x0F];
11150 | value >>= 4;
11151 | *(--ptr) = hex_digits[value & 0x0F];
11152 | *(--ptr) = 'x';
11153 | break;
11154 |
11155 | default:
11156 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11157 | }
11158 | }
11159 | *(--ptr) = '\\';
11160 | }
11161 | *(--ptr) = '\'';
11162 | return ptr;
11163 | }
11164 |
11165 | static const char *
11166 | hfinfo_number_value_format_display(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11167 | {
11168 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11169 | 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 ));
11170 |
11171 | *ptr = '\0';
11172 | /* Properly format value */
11173 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11174 | case BASE_DEC:
11175 | return isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11176 |
11177 | case BASE_DEC_HEX:
11178 | *(--ptr) = ')';
11179 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11180 | *(--ptr) = '(';
11181 | *(--ptr) = ' ';
11182 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11183 | return ptr;
11184 |
11185 | case BASE_OCT:
11186 | return oct_to_str_back(ptr, value);
11187 |
11188 | case BASE_HEX:
11189 | return hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11190 |
11191 | case BASE_HEX_DEC:
11192 | *(--ptr) = ')';
11193 | ptr = isint ? int_to_str_back(ptr, (int32_t) value) : uint_to_str_back(ptr, value);
11194 | *(--ptr) = '(';
11195 | *(--ptr) = ' ';
11196 | ptr = hex_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11197 | return ptr;
11198 |
11199 | case BASE_PT_UDP:
11200 | case BASE_PT_TCP:
11201 | case BASE_PT_DCCP:
11202 | case BASE_PT_SCTP:
11203 | port_with_resolution_to_str_buf(buf, NUMBER_LABEL_LENGTH80,
11204 | display_to_port_type((field_display_e)display), value);
11205 | return buf;
11206 | case BASE_OUI:
11207 | {
11208 | uint8_t p_oui[3];
11209 | const char *manuf_name;
11210 |
11211 | p_oui[0] = value >> 16 & 0xFF;
11212 | p_oui[1] = value >> 8 & 0xFF;
11213 | p_oui[2] = value & 0xFF;
11214 |
11215 | /* Attempt an OUI lookup. */
11216 | manuf_name = uint_get_manuf_name_if_known(value);
11217 | if (manuf_name == NULL((void*)0)) {
11218 | /* Could not find an OUI. */
11219 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x", p_oui[0], p_oui[1], p_oui[2]);
11220 | }
11221 | else {
11222 | /* Found an address string. */
11223 | snprintf(buf, NUMBER_LABEL_LENGTH80, "%02x:%02x:%02x (%s)", p_oui[0], p_oui[1], p_oui[2], manuf_name);
11224 | }
11225 | return buf;
11226 | }
11227 |
11228 | default:
11229 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11230 | }
11231 | return ptr;
11232 | }
11233 |
11234 | static const char *
11235 | hfinfo_number_value_format_display64(const header_field_info *hfinfo, int display, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11236 | {
11237 | char *ptr = &buf[NUMBER_LABEL_LENGTH80-1];
11238 | 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 ));
11239 |
11240 | *ptr = '\0';
11241 | /* Properly format value */
11242 | switch (FIELD_DISPLAY(display)((display) & 0xFF)) {
11243 | case BASE_DEC:
11244 | return isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11245 |
11246 | case BASE_DEC_HEX:
11247 | *(--ptr) = ')';
11248 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11249 | *(--ptr) = '(';
11250 | *(--ptr) = ' ';
11251 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11252 | return ptr;
11253 |
11254 | case BASE_OCT:
11255 | return oct64_to_str_back(ptr, value);
11256 |
11257 | case BASE_HEX:
11258 | return hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11259 |
11260 | case BASE_HEX_DEC:
11261 | *(--ptr) = ')';
11262 | ptr = isint ? int64_to_str_back(ptr, (int64_t) value) : uint64_to_str_back(ptr, value);
11263 | *(--ptr) = '(';
11264 | *(--ptr) = ' ';
11265 | ptr = hex64_to_str_back_len(ptr, value, hfinfo_hex_digits(hfinfo));
11266 | return ptr;
11267 |
11268 | default:
11269 | REPORT_DISSECTOR_BUG("Invalid base: %d", FIELD_DISPLAY(display))proto_report_dissector_bug("Invalid base: %d", ((display) & 0xFF));
11270 | }
11271 |
11272 | return ptr;
11273 | }
11274 |
11275 | static const char *
11276 | hfinfo_number_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11277 | {
11278 | int display = hfinfo->display;
11279 |
11280 | if (hfinfo->type == FT_FRAMENUM) {
11281 | /*
11282 | * Frame numbers are always displayed in decimal.
11283 | */
11284 | display = BASE_DEC;
11285 | }
11286 |
11287 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11288 | }
11289 |
11290 | static const char *
11291 | hfinfo_number_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11292 | {
11293 | int display = hfinfo->display;
11294 |
11295 | if (hfinfo->type == FT_FRAMENUM) {
11296 | /*
11297 | * Frame numbers are always displayed in decimal.
11298 | */
11299 | display = BASE_DEC;
11300 | }
11301 |
11302 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11303 | }
11304 |
11305 | static const char *
11306 | hfinfo_char_value_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11307 | {
11308 | /* Get the underlying BASE_ value */
11309 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11310 |
11311 | return hfinfo_char_value_format_display(display, buf, value);
11312 | }
11313 |
11314 | static const char *
11315 | hfinfo_numeric_value_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11316 | {
11317 | /* Get the underlying BASE_ value */
11318 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11319 |
11320 | if (hfinfo->type == FT_FRAMENUM) {
11321 | /*
11322 | * Frame numbers are always displayed in decimal.
11323 | */
11324 | display = BASE_DEC;
11325 | }
11326 |
11327 | if (IS_BASE_PORT(display)(((display)==BASE_PT_UDP||(display)==BASE_PT_TCP||(display)== BASE_PT_DCCP||(display)==BASE_PT_SCTP))) {
11328 | display = BASE_DEC;
11329 | } else if (display == BASE_OUI) {
11330 | display = BASE_HEX;
11331 | }
11332 |
11333 | switch (display) {
11334 | case BASE_NONE:
11335 | /* case BASE_DEC: */
11336 | case BASE_DEC_HEX:
11337 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11338 | case BASE_CUSTOM:
11339 | display = BASE_DEC;
11340 | break;
11341 |
11342 | /* case BASE_HEX: */
11343 | case BASE_HEX_DEC:
11344 | display = BASE_HEX;
11345 | break;
11346 | }
11347 |
11348 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11349 | }
11350 |
11351 | static const char *
11352 | hfinfo_numeric_value_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11353 | {
11354 | /* Get the underlying BASE_ value */
11355 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11356 |
11357 | if (hfinfo->type == FT_FRAMENUM) {
11358 | /*
11359 | * Frame numbers are always displayed in decimal.
11360 | */
11361 | display = BASE_DEC;
11362 | }
11363 |
11364 | switch (display) {
11365 | case BASE_NONE:
11366 | /* case BASE_DEC: */
11367 | case BASE_DEC_HEX:
11368 | case BASE_OCT: /* XXX, why we're changing BASE_OCT to BASE_DEC? */
11369 | case BASE_CUSTOM:
11370 | display = BASE_DEC;
11371 | break;
11372 |
11373 | /* case BASE_HEX: */
11374 | case BASE_HEX_DEC:
11375 | display = BASE_HEX;
11376 | break;
11377 | }
11378 |
11379 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11380 | }
11381 |
11382 | static const char *
11383 | hfinfo_char_vals_format(const header_field_info *hfinfo, char buf[32], uint32_t value)
11384 | {
11385 | /* Get the underlying BASE_ value */
11386 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11387 |
11388 | return hfinfo_char_value_format_display(display, buf, value);
11389 | }
11390 |
11391 | static const char *
11392 | hfinfo_number_vals_format(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint32_t value)
11393 | {
11394 | /* Get the underlying BASE_ value */
11395 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11396 |
11397 | if (display == BASE_NONE)
11398 | return NULL((void*)0);
11399 |
11400 | if (display == BASE_DEC_HEX)
11401 | display = BASE_DEC;
11402 | if (display == BASE_HEX_DEC)
11403 | display = BASE_HEX;
11404 |
11405 | return hfinfo_number_value_format_display(hfinfo, display, buf, value);
11406 | }
11407 |
11408 | static const char *
11409 | hfinfo_number_vals_format64(const header_field_info *hfinfo, char buf[NUMBER_LABEL_LENGTH80], uint64_t value)
11410 | {
11411 | /* Get the underlying BASE_ value */
11412 | int display = FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF);
11413 |
11414 | if (display == BASE_NONE)
11415 | return NULL((void*)0);
11416 |
11417 | if (display == BASE_DEC_HEX)
11418 | display = BASE_DEC;
11419 | if (display == BASE_HEX_DEC)
11420 | display = BASE_HEX;
11421 |
11422 | return hfinfo_number_value_format_display64(hfinfo, display, buf, value);
11423 | }
11424 |
11425 | const char *
11426 | proto_registrar_get_name(const int n)
11427 | {
11428 | header_field_info *hfinfo;
11429 |
11430 | 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", 11430 , __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", 11430 , "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", 11430, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11431 | return hfinfo->name;
11432 | }
11433 |
11434 | const char *
11435 | proto_registrar_get_abbrev(const int n)
11436 | {
11437 | header_field_info *hfinfo;
11438 |
11439 | 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", 11439 , __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", 11439 , "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", 11439, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11440 | return hfinfo->abbrev;
11441 | }
11442 |
11443 | enum ftenum
11444 | proto_registrar_get_ftype(const int n)
11445 | {
11446 | header_field_info *hfinfo;
11447 |
11448 | 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", 11448 , __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", 11448 , "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", 11448, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11449 | return hfinfo->type;
11450 | }
11451 |
11452 | int
11453 | proto_registrar_get_parent(const int n)
11454 | {
11455 | header_field_info *hfinfo;
11456 |
11457 | 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", 11457 , __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", 11457 , "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", 11457, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11458 | return hfinfo->parent;
11459 | }
11460 |
11461 | bool_Bool
11462 | proto_registrar_is_protocol(const int n)
11463 | {
11464 | header_field_info *hfinfo;
11465 |
11466 | 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", 11466 , __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", 11466 , "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", 11466, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11467 | return (((hfinfo->id != hf_text_only) && (hfinfo->parent == -1)) ? true1 : false0);
11468 | }
11469 |
11470 | /* Returns length of field in packet (not necessarily the length
11471 | * in our internal representation, as in the case of IPv4).
11472 | * 0 means undeterminable at time of registration
11473 | * -1 means the field is not registered. */
11474 | int
11475 | proto_registrar_get_length(const int n)
11476 | {
11477 | header_field_info *hfinfo;
11478 |
11479 | 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", 11479 , __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", 11479 , "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", 11479, "gpa_hfinfo.hfi[n] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[n];;
11480 | return ftype_wire_size(hfinfo->type);
11481 | }
11482 |
11483 | /* Looks for a protocol or a field in a proto_tree. Returns true if
11484 | * it exists anywhere, or false if it exists nowhere. */
11485 | bool_Bool
11486 | proto_check_for_protocol_or_field(const proto_tree* tree, const int id)
11487 | {
11488 | GPtrArray *ptrs = proto_get_finfo_ptr_array(tree, id);
11489 |
11490 | if (g_ptr_array_len(ptrs)((ptrs) ? (ptrs)->len : 0) > 0) {
11491 | return true1;
11492 | }
11493 | else {
11494 | return false0;
11495 | }
11496 | }
11497 |
11498 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in tree.
11499 | * This only works if the hfindex was "primed" before the dissection
11500 | * took place, as we just pass back the already-created GPtrArray*.
11501 | * The caller should *not* free the GPtrArray*; proto_tree_free_node()
11502 | * handles that. */
11503 | GPtrArray *
11504 | proto_get_finfo_ptr_array(const proto_tree *tree, const int id)
11505 | {
11506 | if (!tree)
11507 | return NULL((void*)0);
11508 |
11509 | if (PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids != NULL((void*)0))
11510 | return (GPtrArray *)g_hash_table_lookup(PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids,
11511 | GINT_TO_POINTER(id)((gpointer) (glong) (id)));
11512 | else
11513 | return NULL((void*)0);
11514 | }
11515 |
11516 | bool_Bool
11517 | proto_tracking_interesting_fields(const proto_tree *tree)
11518 | {
11519 | GHashTable *interesting_hfids;
11520 |
11521 | if (!tree)
11522 | return false0;
11523 |
11524 | interesting_hfids = PTREE_DATA(tree)((tree)->tree_data)->interesting_hfids;
11525 |
11526 | return (interesting_hfids != NULL((void*)0)) && g_hash_table_size(interesting_hfids);
11527 | }
11528 |
11529 | /* Helper struct for proto_find_info() and proto_all_finfos() */
11530 | typedef struct {
11531 | GPtrArray *array;
11532 | int id;
11533 | } ffdata_t;
11534 |
11535 | /* Helper function for proto_find_info() */
11536 | static bool_Bool
11537 | find_finfo(proto_node *node, void * data)
11538 | {
11539 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11540 | if (fi && fi->hfinfo) {
11541 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11542 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11543 | }
11544 | }
11545 |
11546 | /* Don't stop traversing. */
11547 | return false0;
11548 | }
11549 |
11550 | /* Helper function for proto_find_first_info() */
11551 | static bool_Bool
11552 | find_first_finfo(proto_node *node, void *data)
11553 | {
11554 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11555 | if (fi && fi->hfinfo) {
11556 | if (fi->hfinfo->id == ((ffdata_t*)data)->id) {
11557 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11558 |
11559 | /* Stop traversing. */
11560 | return true1;
11561 | }
11562 | }
11563 |
11564 | /* Continue traversing. */
11565 | return false0;
11566 | }
11567 |
11568 | /* Return GPtrArray* of field_info pointers for all hfindex that appear in a tree.
11569 | * This works on any proto_tree, primed or unprimed, but actually searches
11570 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11571 | * The caller does need to free the returned GPtrArray with
11572 | * g_ptr_array_free(<array>, true).
11573 | */
11574 | GPtrArray *
11575 | proto_find_finfo(proto_tree *tree, const int id)
11576 | {
11577 | ffdata_t ffdata;
11578 |
11579 | ffdata.array = g_ptr_array_new();
11580 | ffdata.id = id;
11581 |
11582 | proto_tree_traverse_pre_order(tree, find_finfo, &ffdata);
11583 |
11584 | return ffdata.array;
11585 | }
11586 |
11587 | /* Return GPtrArray* of first field_info pointers for the searched hfindex that appear in a tree.
11588 | * This works on any proto_tree, primed or unprimed, but actually searches
11589 | * the tree, so it is slower than using proto_get_finfo_ptr_array on a primed tree.
11590 | * The caller does need to free the returned GPtrArray with
11591 | * g_ptr_array_free(<array>, true).
11592 | */
11593 | GPtrArray *
11594 | proto_find_first_finfo(proto_tree *tree, const int id)
11595 | {
11596 | ffdata_t ffdata;
11597 |
11598 | ffdata.array = g_ptr_array_new();
11599 | ffdata.id = id;
11600 |
11601 | proto_tree_traverse_pre_order(tree, find_first_finfo, &ffdata);
11602 |
11603 | return ffdata.array;
11604 | }
11605 |
11606 | /* Helper function for proto_all_finfos() */
11607 | static bool_Bool
11608 | every_finfo(proto_node *node, void * data)
11609 | {
11610 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11611 | if (fi && fi->hfinfo) {
11612 | g_ptr_array_add(((ffdata_t*)data)->array, fi);
11613 | }
11614 |
11615 | /* Don't stop traversing. */
11616 | return false0;
11617 | }
11618 |
11619 | /* Return GPtrArray* of field_info pointers containing all hfindexes that appear in a tree.
11620 | * The caller does need to free the returned GPtrArray with
11621 | * g_ptr_array_free(<array>, true).
11622 | */
11623 | GPtrArray *
11624 | proto_all_finfos(proto_tree *tree)
11625 | {
11626 | ffdata_t ffdata;
11627 |
11628 | /* Pre allocate enough space to hold all fields in most cases */
11629 | ffdata.array = g_ptr_array_sized_new(512);
11630 | ffdata.id = 0;
11631 |
11632 | proto_tree_traverse_pre_order(tree, every_finfo, &ffdata);
11633 |
11634 | return ffdata.array;
11635 | }
11636 |
11637 |
11638 | typedef struct {
11639 | unsigned offset;
11640 | field_info *finfo;
11641 | tvbuff_t *tvb;
11642 | } offset_search_t;
11643 |
11644 | static bool_Bool
11645 | check_for_offset(proto_node *node, void * data)
11646 | {
11647 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11648 | offset_search_t *offsearch = (offset_search_t *)data;
11649 |
11650 | /* !fi == the top most container node which holds nothing */
11651 | if (fi && !proto_item_is_hidden(node) && !proto_item_is_generated(node) && fi->ds_tvb && offsearch->tvb == fi->ds_tvb) {
11652 | if (offsearch->offset >= (unsigned) fi->start &&
11653 | offsearch->offset < (unsigned) (fi->start + fi->length)) {
11654 |
11655 | offsearch->finfo = fi;
11656 | return false0; /* keep traversing */
11657 | }
11658 | }
11659 | return false0; /* keep traversing */
11660 | }
11661 |
11662 | /* Search a proto_tree backwards (from leaves to root) looking for the field
11663 | * whose start/length occupies 'offset' */
11664 | /* XXX - I couldn't find an easy way to search backwards, so I search
11665 | * forwards, w/o stopping. Therefore, the last finfo I find will the be
11666 | * the one I want to return to the user. This algorithm is inefficient
11667 | * and could be re-done, but I'd have to handle all the children and
11668 | * siblings of each node myself. When I have more time I'll do that.
11669 | * (yeah right) */
11670 | field_info *
11671 | proto_find_field_from_offset(proto_tree *tree, unsigned offset, tvbuff_t *tvb)
11672 | {
11673 | offset_search_t offsearch;
11674 |
11675 | offsearch.offset = offset;
11676 | offsearch.finfo = NULL((void*)0);
11677 | offsearch.tvb = tvb;
11678 |
11679 | proto_tree_traverse_pre_order(tree, check_for_offset, &offsearch);
11680 |
11681 | return offsearch.finfo;
11682 | }
11683 |
11684 | typedef struct {
11685 | int length;
11686 | char *buf;
11687 | } decoded_data_t;
11688 |
11689 | static bool_Bool
11690 | check_for_undecoded(proto_node *node, void * data)
11691 | {
11692 | field_info *fi = PNODE_FINFO(node)((node)->finfo);
11693 | decoded_data_t* decoded = (decoded_data_t*)data;
11694 | int i;
11695 | unsigned byte;
11696 | unsigned bit;
11697 |
11698 | if (fi && fi->hfinfo->type != FT_PROTOCOL) {
11699 | for (i = fi->start; i < fi->start + fi->length && i < decoded->length; i++) {
11700 | byte = i / 8;
11701 | bit = i % 8;
11702 | decoded->buf[byte] |= (1 << bit);
11703 | }
11704 | }
11705 |
11706 | return false0;
11707 | }
11708 |
11709 | char*
11710 | proto_find_undecoded_data(proto_tree *tree, unsigned length)
11711 | {
11712 | decoded_data_t decoded;
11713 | decoded.length = length;
11714 | decoded.buf = (char*)wmem_alloc0(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), length / 8 + 1);
11715 |
11716 | proto_tree_traverse_pre_order(tree, check_for_undecoded, &decoded);
11717 | return decoded.buf;
11718 | }
11719 |
11720 | /* Dumps the protocols in the registration database to stdout. An independent
11721 | * program can take this output and format it into nice tables or HTML or
11722 | * whatever.
11723 | *
11724 | * There is one record per line. The fields are tab-delimited.
11725 | *
11726 | * Field 1 = protocol name
11727 | * Field 2 = protocol short name
11728 | * Field 3 = protocol filter name
11729 | * Field 4 = protocol enabled
11730 | * Field 5 = protocol enabled by default
11731 | * Field 6 = protocol can toggle
11732 | */
11733 | void
11734 | proto_registrar_dump_protocols(void)
11735 | {
11736 | protocol_t *protocol;
11737 | int i;
11738 | void *cookie = NULL((void*)0);
11739 |
11740 |
11741 | i = proto_get_first_protocol(&cookie);
11742 | while (i != -1) {
11743 | protocol = find_protocol_by_id(i);
11744 | printf("%s\t%s\t%s\t%c\t%c\t%c\n",
11745 | protocol->name,
11746 | protocol->short_name,
11747 | protocol->filter_name,
11748 | (proto_is_protocol_enabled_by_default(protocol) ? 'T' : 'F'),
11749 | (proto_is_protocol_enabled(protocol) ? 'T' : 'F'),
11750 | (proto_can_toggle_protocol(protocol->proto_id) ? 'T' : 'F'));
11751 | i = proto_get_next_protocol(&cookie);
11752 | }
11753 | }
11754 |
11755 | /* Dumps the value_strings, extended value string headers, range_strings
11756 | * or true/false strings for fields that have them.
11757 | * There is one record per line. Fields are tab-delimited.
11758 | * There are four types of records: Value String, Extended Value String Header,
11759 | * Range String and True/False String. The first field, 'V', 'E', 'R' or 'T', indicates
11760 | * the type of record.
11761 | *
11762 | * Note that a record will be generated only if the value_string,... is referenced
11763 | * in a registered hfinfo entry.
11764 | *
11765 | *
11766 | * Value Strings
11767 | * -------------
11768 | * Field 1 = 'V'
11769 | * Field 2 = Field abbreviation to which this value string corresponds
11770 | * Field 3 = Integer value
11771 | * Field 4 = String
11772 | *
11773 | * Extended Value String Headers
11774 | * -----------------------------
11775 | * Field 1 = 'E'
11776 | * Field 2 = Field abbreviation to which this extended value string header corresponds
11777 | * Field 3 = Extended Value String "Name"
11778 | * Field 4 = Number of entries in the associated value_string array
11779 | * Field 5 = Access Type: "Linear Search", "Binary Search", "Direct (indexed) Access"
11780 | *
11781 | * Range Strings
11782 | * -------------
11783 | * Field 1 = 'R'
11784 | * Field 2 = Field abbreviation to which this range string corresponds
11785 | * Field 3 = Integer value: lower bound
11786 | * Field 4 = Integer value: upper bound
11787 | * Field 5 = String
11788 | *
11789 | * True/False Strings
11790 | * ------------------
11791 | * Field 1 = 'T'
11792 | * Field 2 = Field abbreviation to which this true/false string corresponds
11793 | * Field 3 = True String
11794 | * Field 4 = False String
11795 | */
11796 | void
11797 | proto_registrar_dump_values(void)
11798 | {
11799 | header_field_info *hfinfo;
11800 | int i, len, vi;
11801 | const value_string *vals;
11802 | const val64_string *vals64;
11803 | const range_string *range;
11804 | const true_false_string *tfs;
11805 | const unit_name_string *units;
11806 |
11807 | len = gpa_hfinfo.len;
11808 | for (i = 0; i < len ; i++) {
11809 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
11810 | continue; /* This is a deregistered protocol or field */
11811 |
11812 | 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", 11812 , __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", 11812 , "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", 11812, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
11813 |
11814 | if (hfinfo->id == hf_text_only) {
11815 | continue;
11816 | }
11817 |
11818 | /* ignore protocols */
11819 | if (proto_registrar_is_protocol(i)) {
11820 | continue;
11821 | }
11822 | /* process header fields */
11823 | #if 0 /* XXX: We apparently allow fields with the same name but with differing "strings" content */
11824 | /*
11825 | * If this field isn't at the head of the list of
11826 | * fields with this name, skip this field - all
11827 | * fields with the same name are really just versions
11828 | * of the same field stored in different bits, and
11829 | * should have the same type/radix/value list, and
11830 | * just differ in their bit masks. (If a field isn't
11831 | * a bitfield, but can be, say, 1 or 2 bytes long,
11832 | * it can just be made FT_UINT16, meaning the
11833 | * *maximum* length is 2 bytes, and be used
11834 | * for all lengths.)
11835 | */
11836 | if (hfinfo->same_name_prev_id != -1)
11837 | continue;
11838 | #endif
11839 | vals = NULL((void*)0);
11840 | vals64 = NULL((void*)0);
11841 | range = NULL((void*)0);
11842 | tfs = NULL((void*)0);
11843 | units = NULL((void*)0);
11844 |
11845 | if (hfinfo->strings != NULL((void*)0)) {
11846 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) != BASE_CUSTOM &&
11847 | (hfinfo->type == FT_CHAR ||
11848 | hfinfo->type == FT_UINT8 ||
11849 | hfinfo->type == FT_UINT16 ||
11850 | hfinfo->type == FT_UINT24 ||
11851 | hfinfo->type == FT_UINT32 ||
11852 | hfinfo->type == FT_UINT40 ||
11853 | hfinfo->type == FT_UINT48 ||
11854 | hfinfo->type == FT_UINT56 ||
11855 | hfinfo->type == FT_UINT64 ||
11856 | hfinfo->type == FT_INT8 ||
11857 | hfinfo->type == FT_INT16 ||
11858 | hfinfo->type == FT_INT24 ||
11859 | hfinfo->type == FT_INT32 ||
11860 | hfinfo->type == FT_INT40 ||
11861 | hfinfo->type == FT_INT48 ||
11862 | hfinfo->type == FT_INT56 ||
11863 | hfinfo->type == FT_INT64 ||
11864 | hfinfo->type == FT_FLOAT ||
11865 | hfinfo->type == FT_DOUBLE)) {
11866 |
11867 | if (hfinfo->display & BASE_RANGE_STRING0x00000100) {
11868 | range = (const range_string *)hfinfo->strings;
11869 | } else if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11870 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11871 | vals64 = VAL64_STRING_EXT_VS_P((const val64_string_ext *)hfinfo->strings)((const val64_string_ext *)hfinfo->strings)->_vs_p;
11872 | } else {
11873 | vals = VALUE_STRING_EXT_VS_P((const value_string_ext *)hfinfo->strings)((const value_string_ext *)hfinfo->strings)->_vs_p;
11874 | }
11875 | } else if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11876 | vals64 = (const val64_string *)hfinfo->strings;
11877 | } else if (hfinfo->display & BASE_UNIT_STRING0x00001000) {
11878 | units = (const unit_name_string *)hfinfo->strings;
11879 | } else {
11880 | vals = (const value_string *)hfinfo->strings;
11881 | }
11882 | }
11883 | else if (hfinfo->type == FT_BOOLEAN) {
11884 | tfs = (const struct true_false_string *)hfinfo->strings;
11885 | }
11886 | }
11887 |
11888 | /* Print value strings? */
11889 | if (vals) {
11890 | if (hfinfo->display & BASE_EXT_STRING0x00000200) {
11891 | if (hfinfo->display & BASE_VAL64_STRING0x00000400) {
11892 | val64_string_ext *vse_p = (val64_string_ext *)hfinfo->strings;
11893 | if (!val64_string_ext_validate(vse_p)) {
11894 | ws_warning("Invalid val64_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11894, __func__, "Invalid val64_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
11895 | continue;
11896 | }
11897 | try_val64_to_str_ext(0, vse_p); /* "prime" the extended val64_string */
11898 | printf("E\t%s\t%u\t%s\t%s\n",
11899 | hfinfo->abbrev,
11900 | VAL64_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11901 | VAL64_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11902 | val64_string_ext_match_type_str(vse_p));
11903 | } else {
11904 | value_string_ext *vse_p = (value_string_ext *)hfinfo->strings;
11905 | if (!value_string_ext_validate(vse_p)) {
11906 | ws_warning("Invalid value_string_ext ptr for: %s", hfinfo->abbrev)do { if (1) { ws_log_full("Epan", LOG_LEVEL_WARNING, "epan/proto.c" , 11906, __func__, "Invalid value_string_ext ptr for: %s", hfinfo ->abbrev); } } while (0);
11907 | continue;
11908 | }
11909 | try_val_to_str_ext(0, vse_p); /* "prime" the extended value_string */
11910 | printf("E\t%s\t%u\t%s\t%s\n",
11911 | hfinfo->abbrev,
11912 | VALUE_STRING_EXT_VS_NUM_ENTRIES(vse_p)(vse_p)->_vs_num_entries,
11913 | VALUE_STRING_EXT_VS_NAME(vse_p)(vse_p)->_vs_name,
11914 | value_string_ext_match_type_str(vse_p));
11915 | }
11916 | }
11917 | vi = 0;
11918 | while (vals[vi].strptr) {
11919 | /* Print in the proper base */
11920 | if (hfinfo->type == FT_CHAR) {
11921 | if (g_ascii_isprint(vals[vi].value)((g_ascii_table[(guchar) (vals[vi].value)] & G_ASCII_PRINT ) != 0)) {
11922 | printf("V\t%s\t'%c'\t%s\n",
11923 | hfinfo->abbrev,
11924 | vals[vi].value,
11925 | vals[vi].strptr);
11926 | } else {
11927 | if (hfinfo->display == BASE_HEX) {
11928 | printf("V\t%s\t'\\x%02x'\t%s\n",
11929 | hfinfo->abbrev,
11930 | vals[vi].value,
11931 | vals[vi].strptr);
11932 | }
11933 | else {
11934 | printf("V\t%s\t'\\%03o'\t%s\n",
11935 | hfinfo->abbrev,
11936 | vals[vi].value,
11937 | vals[vi].strptr);
11938 | }
11939 | }
11940 | } else {
11941 | if (hfinfo->display == BASE_HEX) {
11942 | printf("V\t%s\t0x%x\t%s\n",
11943 | hfinfo->abbrev,
11944 | vals[vi].value,
11945 | vals[vi].strptr);
11946 | }
11947 | else {
11948 | printf("V\t%s\t%u\t%s\n",
11949 | hfinfo->abbrev,
11950 | vals[vi].value,
11951 | vals[vi].strptr);
11952 | }
11953 | }
11954 | vi++;
11955 | }
11956 | }
11957 | else if (vals64) {
11958 | vi = 0;
11959 | while (vals64[vi].strptr) {
11960 | printf("V64\t%s\t%" PRIu64"l" "u" "\t%s\n",
11961 | hfinfo->abbrev,
11962 | vals64[vi].value,
11963 | vals64[vi].strptr);
11964 | vi++;
11965 | }
11966 | }
11967 |
11968 | /* print range strings? */
11969 | else if (range) {
11970 | vi = 0;
11971 | while (range[vi].strptr) {
11972 | /* Print in the proper base */
11973 | if (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_HEX) {
11974 | printf("R\t%s\t0x%"PRIx64"l" "x""\t0x%"PRIx64"l" "x""\t%s\n",
11975 | hfinfo->abbrev,
11976 | range[vi].value_min,
11977 | range[vi].value_max,
11978 | range[vi].strptr);
11979 | }
11980 | else {
11981 | printf("R\t%s\t%"PRIu64"l" "u""\t%"PRIu64"l" "u""\t%s\n",
11982 | hfinfo->abbrev,
11983 | range[vi].value_min,
11984 | range[vi].value_max,
11985 | range[vi].strptr);
11986 | }
11987 | vi++;
11988 | }
11989 | }
11990 |
11991 | /* Print true/false strings? */
11992 | else if (tfs) {
11993 | printf("T\t%s\t%s\t%s\n", hfinfo->abbrev,
11994 | tfs->true_string, tfs->false_string);
11995 | }
11996 | /* Print unit strings? */
11997 | else if (units) {
11998 | printf("U\t%s\t%s\t%s\n", hfinfo->abbrev,
11999 | units->singular, units->plural ? units->plural : "(no plural)");
12000 | }
12001 | }
12002 | }
12003 |
12004 | /* Prints the number of registered fields.
12005 | * Useful for determining an appropriate value for
12006 | * PROTO_PRE_ALLOC_HF_FIELDS_MEM.
12007 | *
12008 | * Returns false if PROTO_PRE_ALLOC_HF_FIELDS_MEM is larger than or equal to
12009 | * the number of fields, true otherwise.
12010 | */
12011 | bool_Bool
12012 | proto_registrar_dump_fieldcount(void)
12013 | {
12014 | uint32_t i;
12015 | header_field_info *hfinfo;
12016 | uint32_t deregistered_count = 0;
12017 | uint32_t same_name_count = 0;
12018 | uint32_t protocol_count = 0;
12019 |
12020 | for (i = 0; i < gpa_hfinfo.len; i++) {
12021 | if (gpa_hfinfo.hfi[i] == NULL((void*)0)) {
12022 | deregistered_count++;
12023 | continue; /* This is a deregistered protocol or header field */
12024 | }
12025 |
12026 | 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", 12026 , __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", 12026 , "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", 12026, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12027 |
12028 | if (proto_registrar_is_protocol(i))
12029 | protocol_count++;
12030 |
12031 | if (hfinfo->same_name_prev_id != -1)
12032 | same_name_count++;
12033 | }
12034 |
12035 | printf("There are %u header fields registered, of which:\n"
12036 | "\t%u are deregistered\n"
12037 | "\t%u are protocols\n"
12038 | "\t%u have the same name as another field\n\n",
12039 | gpa_hfinfo.len, deregistered_count, protocol_count,
12040 | same_name_count);
12041 |
12042 | printf("%d fields were pre-allocated.\n%s", PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000),
12043 | (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000)) ?
12044 | "* * Please increase PROTO_PRE_ALLOC_HF_FIELDS_MEM (in epan/proto.c)! * *\n\n" :
12045 | "\n");
12046 |
12047 | printf("The header field table consumes %u KiB of memory.\n",
12048 | (unsigned int)(gpa_hfinfo.allocated_len * sizeof(header_field_info *) / 1024));
12049 | printf("The fields themselves consume %u KiB of memory.\n",
12050 | (unsigned int)(gpa_hfinfo.len * sizeof(header_field_info) / 1024));
12051 |
12052 | return (gpa_hfinfo.allocated_len > PROTO_PRE_ALLOC_HF_FIELDS_MEM(300000+5000));
12053 | }
12054 |
12055 | static void
12056 | elastic_add_base_mapping(json_dumper *dumper)
12057 | {
12058 | json_dumper_set_member_name(dumper, "index_patterns");
12059 | json_dumper_begin_array(dumper);
12060 | // The index names from write_json_index() in print.c
12061 | json_dumper_value_string(dumper, "packets-*");
12062 | json_dumper_end_array(dumper);
12063 |
12064 | json_dumper_set_member_name(dumper, "settings");
12065 | json_dumper_begin_object(dumper);
12066 | json_dumper_set_member_name(dumper, "index.mapping.total_fields.limit");
12067 | json_dumper_value_anyf(dumper, "%d", 1000000);
12068 | json_dumper_end_object(dumper);
12069 | }
12070 |
12071 | static char*
12072 | ws_type_to_elastic(unsigned type)
12073 | {
12074 | switch(type) {
12075 | case FT_INT8:
12076 | return "byte";
12077 | case FT_UINT8:
12078 | case FT_INT16:
12079 | return "short";
12080 | case FT_UINT16:
12081 | case FT_INT32:
12082 | case FT_UINT24:
12083 | case FT_INT24:
12084 | return "integer";
12085 | case FT_FRAMENUM:
12086 | case FT_UINT32:
12087 | case FT_UINT40:
12088 | case FT_UINT48:
12089 | case FT_UINT56:
12090 | case FT_INT40:
12091 | case FT_INT48:
12092 | case FT_INT56:
12093 | case FT_INT64:
12094 | return "long";
12095 | case FT_UINT64:
12096 | return "unsigned long"; // ElasticSearch since 7.0, OpenSearch 2.8
12097 | case FT_FLOAT:
12098 | return "float";
12099 | case FT_DOUBLE:
12100 | case FT_RELATIVE_TIME: // "scaled_float" with "scaling_factor" 1e9 superior?
12101 | return "double";
12102 | case FT_IPv6:
12103 | case FT_IPv4:
12104 | return "ip";
12105 | case FT_ABSOLUTE_TIME:
12106 | return "date_nanos"; // This is a 64 bit integer of nanoseconds, so it does have a Y2262 problem
12107 | case FT_BOOLEAN:
12108 | return "boolean";
12109 | default:
12110 | return NULL((void*)0);
12111 | }
12112 | }
12113 |
12114 | static char*
12115 | dot_to_underscore(char* str)
12116 | {
12117 | unsigned i;
12118 | for (i = 0; i < strlen(str); i++) {
12119 | if (str[i] == '.')
12120 | str[i] = '_';
12121 | }
12122 | return str;
12123 | }
12124 |
12125 | /* Dumps a mapping file for ElasticSearch
12126 | * This is the v1 (legacy) _template API.
12127 | * At some point it may need to be updated with the composable templates
12128 | * introduced in Elasticsearch 7.8 (_index_template)
12129 | */
12130 | void
12131 | proto_registrar_dump_elastic(const char* filter)
12132 | {
12133 | header_field_info *hfinfo;
12134 | header_field_info *parent_hfinfo;
12135 | unsigned i;
12136 | bool_Bool open_object = true1;
12137 | const char* prev_proto = NULL((void*)0);
12138 | char* str;
12139 | char** protos = NULL((void*)0);
12140 | char* proto;
12141 | bool_Bool found;
12142 | unsigned j;
12143 | char* type;
12144 | char* prev_item = NULL((void*)0);
12145 |
12146 | /* We have filtering protocols. Extract them. */
12147 | if (filter) {
12148 | protos = g_strsplit(filter, ",", -1);
12149 | }
12150 |
12151 | /*
12152 | * To help tracking down the json tree, objects have been appended with a comment:
12153 | * n.label -> where n is the indentation level and label the name of the object
12154 | */
12155 |
12156 | json_dumper dumper = {
12157 | .output_file = stdoutstdout,
12158 | .flags = JSON_DUMPER_FLAGS_PRETTY_PRINT(1 << 0),
12159 | };
12160 | json_dumper_begin_object(&dumper); // 1.root
12161 | elastic_add_base_mapping(&dumper);
12162 |
12163 | json_dumper_set_member_name(&dumper, "mappings");
12164 | json_dumper_begin_object(&dumper); // 2.mappings
12165 |
12166 | json_dumper_set_member_name(&dumper, "properties");
12167 | json_dumper_begin_object(&dumper); // 3.properties
12168 | json_dumper_set_member_name(&dumper, "timestamp");
12169 | json_dumper_begin_object(&dumper); // 4.timestamp
12170 | json_dumper_set_member_name(&dumper, "type");
12171 | json_dumper_value_string(&dumper, "date");
12172 | json_dumper_end_object(&dumper); // 4.timestamp
12173 |
12174 | json_dumper_set_member_name(&dumper, "layers");
12175 | json_dumper_begin_object(&dumper); // 4.layers
12176 | json_dumper_set_member_name(&dumper, "properties");
12177 | json_dumper_begin_object(&dumper); // 5.properties
12178 |
12179 | for (i = 0; i < gpa_hfinfo.len; i++) {
12180 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12181 | continue; /* This is a deregistered protocol or header field */
12182 |
12183 | 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", 12183 , __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", 12183 , "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", 12183, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12184 |
12185 | /*
12186 | * Skip the pseudo-field for "proto_tree_add_text()" since
12187 | * we don't want it in the list of filterable protocols.
12188 | */
12189 | if (hfinfo->id == hf_text_only)
12190 | continue;
12191 |
12192 | if (!proto_registrar_is_protocol(i)) {
12193 | 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", 12193 , __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", 12193 , "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", 12193 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12194 |
12195 | /*
12196 | * Skip the field if filter protocols have been set and this one's
12197 | * parent is not listed.
12198 | */
12199 | if (protos) {
12200 | found = false0;
12201 | j = 0;
12202 | proto = protos[0];
12203 | while(proto) {
12204 | if (!g_strcmp0(proto, parent_hfinfo->abbrev)) {
12205 | found = true1;
12206 | break;
12207 | }
12208 | j++;
12209 | proto = protos[j];
12210 | }
12211 | if (!found)
12212 | continue;
12213 | }
12214 |
12215 | if (prev_proto && g_strcmp0(parent_hfinfo->abbrev, prev_proto)) {
12216 | json_dumper_end_object(&dumper); // 7.properties
12217 | json_dumper_end_object(&dumper); // 8.parent_hfinfo->abbrev
12218 | open_object = true1;
12219 | }
12220 |
12221 | prev_proto = parent_hfinfo->abbrev;
12222 |
12223 | if (open_object) {
12224 | json_dumper_set_member_name(&dumper, parent_hfinfo->abbrev);
12225 | json_dumper_begin_object(&dumper); // 6.parent_hfinfo->abbrev
12226 | json_dumper_set_member_name(&dumper, "properties");
12227 | json_dumper_begin_object(&dumper); // 7.properties
12228 | open_object = false0;
12229 | }
12230 | /* Skip the fields that would map into string. This is the default in elasticsearch. */
12231 | type = ws_type_to_elastic(hfinfo->type);
12232 | /* when type is NULL, we have the default mapping: string */
12233 | if (type) {
12234 | str = ws_strdup_printf("%s_%s", prev_proto, hfinfo->abbrev)wmem_strdup_printf(((void*)0), "%s_%s", prev_proto, hfinfo-> abbrev);
12235 | dot_to_underscore(str);
12236 | if (g_strcmp0(prev_item, str)) {
12237 | json_dumper_set_member_name(&dumper, str);
12238 | json_dumper_begin_object(&dumper); // 8.hfinfo->abbrev
12239 | json_dumper_set_member_name(&dumper, "type");
12240 | json_dumper_value_string(&dumper, type);
12241 | json_dumper_end_object(&dumper); // 8.hfinfo->abbrev
12242 | }
12243 | g_free(prev_item);
12244 | prev_item = str;
12245 | }
12246 | }
12247 | }
12248 | g_free(prev_item);
12249 |
12250 | if (prev_proto) {
12251 | json_dumper_end_object(&dumper); // 7.properties
12252 | json_dumper_end_object(&dumper); // 6.parent_hfinfo->abbrev
12253 | }
12254 |
12255 | json_dumper_end_object(&dumper); // 5.properties
12256 | json_dumper_end_object(&dumper); // 4.layers
12257 | json_dumper_end_object(&dumper); // 3.properties
12258 | json_dumper_end_object(&dumper); // 2.mappings
12259 | json_dumper_end_object(&dumper); // 1.root
12260 | bool_Bool ret = json_dumper_finish(&dumper);
12261 | DISSECTOR_ASSERT(ret)((void) ((ret) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12261, "ret"))));
12262 |
12263 | g_strfreev(protos);
12264 | }
12265 |
12266 | /* Dumps the contents of the registration database to stdout. An independent
12267 | * program can take this output and format it into nice tables or HTML or
12268 | * whatever.
12269 | *
12270 | * There is one record per line. Each record is either a protocol or a header
12271 | * field, differentiated by the first field. The fields are tab-delimited.
12272 | *
12273 | * Protocols
12274 | * ---------
12275 | * Field 1 = 'P'
12276 | * Field 2 = descriptive protocol name
12277 | * Field 3 = protocol abbreviation
12278 | *
12279 | * Header Fields
12280 | * -------------
12281 | * Field 1 = 'F'
12282 | * Field 2 = descriptive field name
12283 | * Field 3 = field abbreviation
12284 | * Field 4 = type ( textual representation of the ftenum type )
12285 | * Field 5 = parent protocol abbreviation
12286 | * Field 6 = base for display (for integer types); "parent bitfield width" for FT_BOOLEAN
12287 | * Field 7 = bitmask: format: hex: 0x....
12288 | * Field 8 = blurb describing field
12289 | */
12290 | void
12291 | proto_registrar_dump_fields(void)
12292 | {
12293 | header_field_info *hfinfo, *parent_hfinfo;
12294 | int i, len;
12295 | const char *enum_name;
12296 | const char *base_name;
12297 | const char *blurb;
12298 | char width[5];
12299 |
12300 | len = gpa_hfinfo.len;
12301 | for (i = 0; i < len ; i++) {
12302 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12303 | continue; /* This is a deregistered protocol or header field */
12304 |
12305 | 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", 12305 , __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", 12305 , "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", 12305, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12306 |
12307 | /*
12308 | * Skip the pseudo-field for "proto_tree_add_text()" since
12309 | * we don't want it in the list of filterable fields.
12310 | */
12311 | if (hfinfo->id == hf_text_only)
12312 | continue;
12313 |
12314 | /* format for protocols */
12315 | if (proto_registrar_is_protocol(i)) {
12316 | printf("P\t%s\t%s\n", hfinfo->name, hfinfo->abbrev);
12317 | }
12318 | /* format for header fields */
12319 | else {
12320 | /*
12321 | * If this field isn't at the head of the list of
12322 | * fields with this name, skip this field - all
12323 | * fields with the same name are really just versions
12324 | * of the same field stored in different bits, and
12325 | * should have the same type/radix/value list, and
12326 | * just differ in their bit masks. (If a field isn't
12327 | * a bitfield, but can be, say, 1 or 2 bytes long,
12328 | * it can just be made FT_UINT16, meaning the
12329 | * *maximum* length is 2 bytes, and be used
12330 | * for all lengths.)
12331 | */
12332 | if (hfinfo->same_name_prev_id != -1)
12333 | continue;
12334 |
12335 | 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", 12335 , __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", 12335 , "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", 12335 , "gpa_hfinfo.hfi[hfinfo->parent] != ((void*)0)", "Unregistered hf!" )))) ; parent_hfinfo = gpa_hfinfo.hfi[hfinfo->parent];;
12336 |
12337 | enum_name = ftype_name(hfinfo->type);
12338 | base_name = "";
12339 |
12340 | if (hfinfo->type == FT_CHAR ||
12341 | hfinfo->type == FT_UINT8 ||
12342 | hfinfo->type == FT_UINT16 ||
12343 | hfinfo->type == FT_UINT24 ||
12344 | hfinfo->type == FT_UINT32 ||
12345 | hfinfo->type == FT_UINT40 ||
12346 | hfinfo->type == FT_UINT48 ||
12347 | hfinfo->type == FT_UINT56 ||
12348 | hfinfo->type == FT_UINT64 ||
12349 | hfinfo->type == FT_INT8 ||
12350 | hfinfo->type == FT_INT16 ||
12351 | hfinfo->type == FT_INT24 ||
12352 | hfinfo->type == FT_INT32 ||
12353 | hfinfo->type == FT_INT40 ||
12354 | hfinfo->type == FT_INT48 ||
12355 | hfinfo->type == FT_INT56 ||
12356 | hfinfo->type == FT_INT64) {
12357 |
12358 | switch (FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF)) {
12359 | case BASE_NONE:
12360 | case BASE_DEC:
12361 | case BASE_HEX:
12362 | case BASE_OCT:
12363 | case BASE_DEC_HEX:
12364 | case BASE_HEX_DEC:
12365 | case BASE_CUSTOM:
12366 | case BASE_PT_UDP:
12367 | case BASE_PT_TCP:
12368 | case BASE_PT_DCCP:
12369 | case BASE_PT_SCTP:
12370 | case BASE_OUI:
12371 | base_name = val_to_str_const(FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF), hf_display, "????");
12372 | break;
12373 | default:
12374 | base_name = "????";
12375 | break;
12376 | }
12377 | } else if (hfinfo->type == FT_BOOLEAN) {
12378 | /* For FT_BOOLEAN: 'display' can be "parent bitfield width" */
12379 | snprintf(width, sizeof(width), "%d", hfinfo->display);
12380 | base_name = width;
12381 | }
12382 |
12383 | blurb = hfinfo->blurb;
12384 | if (blurb == NULL((void*)0))
12385 | blurb = "";
12386 | else if (strlen(blurb) == 0)
12387 | blurb = "\"\"";
12388 |
12389 | printf("F\t%s\t%s\t%s\t%s\t%s\t0x%" PRIx64"l" "x" "\t%s\n",
12390 | hfinfo->name, hfinfo->abbrev, enum_name,
12391 | parent_hfinfo->abbrev, base_name,
12392 | hfinfo->bitmask, blurb);
12393 | }
12394 | }
12395 | }
12396 |
12397 | /* Dumps all abbreviated field and protocol completions of the given string to
12398 | * stdout. An independent program may use this for command-line tab completion
12399 | * of fields.
12400 | */
12401 | bool_Bool
12402 | proto_registrar_dump_field_completions(const char *prefix)
12403 | {
12404 | header_field_info *hfinfo;
12405 | int i, len;
12406 | size_t prefix_len;
12407 | bool_Bool matched = false0;
12408 |
12409 | prefix_len = strlen(prefix);
12410 | len = gpa_hfinfo.len;
12411 | for (i = 0; i < len ; i++) {
12412 | if (gpa_hfinfo.hfi[i] == NULL((void*)0))
12413 | continue; /* This is a deregistered protocol or header field */
12414 |
12415 | 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", 12415 , __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", 12415 , "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", 12415, "gpa_hfinfo.hfi[i] != ((void*)0)", "Unregistered hf!" )))) ; hfinfo = gpa_hfinfo.hfi[i];;
12416 |
12417 | /*
12418 | * Skip the pseudo-field for "proto_tree_add_text()" since
12419 | * we don't want it in the list of filterable fields.
12420 | */
12421 | if (hfinfo->id == hf_text_only)
12422 | continue;
12423 |
12424 | /* format for protocols */
12425 | if (proto_registrar_is_protocol(i)) {
12426 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12427 | matched = true1;
12428 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12429 | }
12430 | }
12431 | /* format for header fields */
12432 | else {
12433 | /*
12434 | * If this field isn't at the head of the list of
12435 | * fields with this name, skip this field - all
12436 | * fields with the same name are really just versions
12437 | * of the same field stored in different bits, and
12438 | * should have the same type/radix/value list, and
12439 | * just differ in their bit masks. (If a field isn't
12440 | * a bitfield, but can be, say, 1 or 2 bytes long,
12441 | * it can just be made FT_UINT16, meaning the
12442 | * *maximum* length is 2 bytes, and be used
12443 | * for all lengths.)
12444 | */
12445 | if (hfinfo->same_name_prev_id != -1)
12446 | continue;
12447 |
12448 | if(0 == strncmp(hfinfo->abbrev, prefix, prefix_len)) {
12449 | matched = true1;
12450 | printf("%s\t%s\n", hfinfo->abbrev, hfinfo->name);
12451 | }
12452 | }
12453 | }
12454 | return matched;
12455 | }
12456 |
12457 | /* Dumps field types and descriptive names to stdout. An independent
12458 | * program can take this output and format it into nice tables or HTML or
12459 | * whatever.
12460 | *
12461 | * There is one record per line. The fields are tab-delimited.
12462 | *
12463 | * Field 1 = field type name, e.g. FT_UINT8
12464 | * Field 2 = descriptive name, e.g. "Unsigned, 1 byte"
12465 | */
12466 | void
12467 | proto_registrar_dump_ftypes(void)
12468 | {
12469 | int fte;
12470 |
12471 | for (fte = 0; fte < FT_NUM_TYPES; fte++) {
12472 | printf("%s\t%s\n", ftype_name((ftenum_t)fte), ftype_pretty_name((ftenum_t)fte));
12473 | }
12474 | }
12475 |
12476 | /* This function indicates whether it's possible to construct a
12477 | * "match selected" display filter string for the specified field,
12478 | * returns an indication of whether it's possible, and, if it's
12479 | * possible and "filter" is non-null, constructs the filter and
12480 | * sets "*filter" to point to it.
12481 | * You do not need to [g_]free() this string since it will be automatically
12482 | * freed once the next packet is dissected.
12483 | */
12484 | static bool_Bool
12485 | construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt,
12486 | char **filter)
12487 | {
12488 | const header_field_info *hfinfo;
12489 | int start, length, length_remaining;
12490 |
12491 | if (!finfo)
12492 | return false0;
12493 |
12494 | hfinfo = finfo->hfinfo;
12495 | DISSECTOR_ASSERT(hfinfo)((void) ((hfinfo) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12495, "hfinfo"))));
12496 |
12497 | /* If we have BASE_NONE and strings (a non-NULL FIELDCONVERT),
12498 | * then "the numeric value ... is not used when preparing
12499 | * filters for the field in question." If it's any other
12500 | * base, we'll generate the filter normally (which will
12501 | * be numeric, even though the human-readable string does
12502 | * work for filtering.)
12503 | *
12504 | * XXX - It might be nice to use fvalue_to_string_repr() in
12505 | * "proto_item_fill_label()" as well, although, there, you'd
12506 | * have to deal with the base *and* with resolved values for
12507 | * addresses.
12508 | *
12509 | * Perhaps in addition to taking the repr type (DISPLAY
12510 | * or DFILTER) and the display (base), fvalue_to_string_repr()
12511 | * should have the the "strings" values in the header_field_info
12512 | * structure for the field as a parameter, so it can have
12513 | * if the field is Boolean or an enumerated integer type,
12514 | * the tables used to generate human-readable values.
12515 | */
12516 | if (hfinfo->strings && FIELD_DISPLAY(hfinfo->display)((hfinfo->display) & 0xFF) == BASE_NONE) {
12517 | const char *str = NULL((void*)0);
12518 |
12519 | switch (hfinfo->type) {
12520 |
12521 | case FT_INT8:
12522 | case FT_INT16:
12523 | case FT_INT24:
12524 | case FT_INT32:
12525 | str = hf_try_val_to_str(fvalue_get_sinteger(finfo->value), hfinfo);
12526 | break;
12527 |
12528 | case FT_CHAR:
12529 | case FT_UINT8:
12530 | case FT_UINT16:
12531 | case FT_UINT24:
12532 | case FT_UINT32:
12533 | str = hf_try_val_to_str(fvalue_get_uinteger(finfo->value), hfinfo);
12534 | break;
12535 |
12536 | default:
12537 | break;
12538 | }
12539 |
12540 | if (str != NULL((void*)0) && filter != NULL((void*)0)) {
12541 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == \"%s\"", hfinfo->abbrev, str);
12542 | return true1;
12543 | }
12544 | }
12545 |
12546 | switch (hfinfo->type) {
12547 |
12548 | case FT_PROTOCOL:
12549 | if (filter != NULL((void*)0))
12550 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12551 | break;
12552 |
12553 | case FT_NONE:
12554 | /*
12555 | * If the length is 0, just match the name of the
12556 | * field.
12557 | *
12558 | * (Also check for negative values, just in case,
12559 | * as we'll cast it to an unsigned value later.)
12560 | */
12561 | length = finfo->length;
12562 | if (length == 0) {
12563 | if (filter != NULL((void*)0))
12564 | *filter = wmem_strdup(NULL((void*)0), finfo->hfinfo->abbrev);
12565 | break;
12566 | }
12567 | if (length < 0)
12568 | return false0;
12569 |
12570 | /*
12571 | * This doesn't have a value, so we'd match
12572 | * on the raw bytes at this address.
12573 | *
12574 | * Should we be allowed to access to the raw bytes?
12575 | * If "edt" is NULL, the answer is "no".
12576 | */
12577 | if (edt == NULL((void*)0))
12578 | return false0;
12579 |
12580 | /*
12581 | * Is this field part of the raw frame tvbuff?
12582 | * If not, we can't use "frame[N:M]" to match
12583 | * it.
12584 | *
12585 | * XXX - should this be frame-relative, or
12586 | * protocol-relative?
12587 | *
12588 | * XXX - does this fallback for non-registered
12589 | * fields even make sense?
12590 | */
12591 | if (finfo->ds_tvb != edt->tvb)
12592 | return false0; /* you lose */
12593 |
12594 | /*
12595 | * Don't go past the end of that tvbuff.
12596 | */
12597 | length_remaining = tvb_captured_length_remaining(finfo->ds_tvb, finfo->start);
12598 | if (length > length_remaining)
12599 | length = length_remaining;
12600 | if (length <= 0)
12601 | return false0;
12602 |
12603 | if (filter != NULL((void*)0)) {
12604 | start = finfo->start;
12605 | char *str = bytes_to_dfilter_repr(NULL((void*)0), tvb_get_ptr(finfo->ds_tvb, start, length), length);
12606 | *filter = wmem_strdup_printf(NULL((void*)0), "frame[%d:%d] == %s", finfo->start, length, str);
12607 | wmem_free(NULL((void*)0), str);
12608 | }
12609 | break;
12610 |
12611 | /* By default, use the fvalue's "to_string_repr" method. */
12612 | default:
12613 | if (filter != NULL((void*)0)) {
12614 | char *str = fvalue_to_string_repr(NULL((void*)0), finfo->value, FTREPR_DFILTER, finfo->hfinfo->display);
12615 | *filter = wmem_strdup_printf(NULL((void*)0), "%s == %s", hfinfo->abbrev, str);
12616 | wmem_free(NULL((void*)0), str);
12617 | }
12618 | break;
12619 | }
12620 |
12621 | return true1;
12622 | }
12623 |
12624 | /*
12625 | * Returns true if we can do a "match selected" on the field, false
12626 | * otherwise.
12627 | */
12628 | bool_Bool
12629 | proto_can_match_selected(const field_info *finfo, epan_dissect_t *edt)
12630 | {
12631 | return construct_match_selected_string(finfo, edt, NULL((void*)0));
12632 | }
12633 |
12634 | /* This function attempts to construct a "match selected" display filter
12635 | * string for the specified field; if it can do so, it returns a pointer
12636 | * to the string, otherwise it returns NULL.
12637 | *
12638 | * The string is wmem allocated and must be freed with "wmem_free(NULL, ...)".
12639 | */
12640 | char *
12641 | proto_construct_match_selected_string(const field_info *finfo, epan_dissect_t *edt)
12642 | {
12643 | char *filter = NULL((void*)0);
12644 |
12645 | if (!construct_match_selected_string(finfo, edt, &filter))
12646 | {
12647 | wmem_free(NULL((void*)0), filter);
12648 | return NULL((void*)0);
12649 | }
12650 | return filter;
12651 | }
12652 |
12653 | /* This function is common code for all proto_tree_add_bitmask... functions.
12654 | */
12655 |
12656 | static bool_Bool
12657 | proto_item_add_bitmask_tree(proto_item *item, tvbuff_t *tvb, const int offset,
12658 | const int len, const int ett, int * const *fields,
12659 | const int flags, bool_Bool first,
12660 | bool_Bool use_parent_tree,
12661 | proto_tree* tree, uint64_t value)
12662 | {
12663 | uint64_t available_bits = UINT64_MAX(18446744073709551615UL);
12664 | uint64_t bitmask = 0;
12665 | uint64_t tmpval;
12666 | header_field_info *hf;
12667 | uint32_t integer32;
12668 | int bit_offset;
12669 | int no_of_bits;
12670 |
12671 | if (!*fields)
12672 | 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" );
12673 |
12674 | if (len < 0 || len > 8)
12675 | REPORT_DISSECTOR_BUG("Invalid len: %d", len)proto_report_dissector_bug("Invalid len: %d", len);
12676 | /**
12677 | * packet-frame.c uses len=0 since the value is taken from the packet
12678 | * metadata, not the packet bytes. In that case, assume that all bits
12679 | * in the provided value are valid.
12680 | */
12681 | if (len > 0) {
12682 | available_bits >>= (8 - (unsigned)len)*8;
12683 | }
12684 |
12685 | if (use_parent_tree == false0)
12686 | tree = proto_item_add_subtree(item, ett);
12687 |
12688 | while (*fields) {
12689 | uint64_t present_bits;
12690 | 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", 12690, __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", 12690 , "**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", 12690, "gpa_hfinfo.hfi[**fields] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[**fields];;
12691 | 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", 12691 , "hf->bitmask != 0", hf->abbrev))));
12692 |
12693 | bitmask |= hf->bitmask;
12694 |
12695 | /* Skip fields that aren't fully present */
12696 | present_bits = available_bits & hf->bitmask;
12697 | if (present_bits != hf->bitmask) {
12698 | fields++;
12699 | continue;
12700 | }
12701 |
12702 | switch (hf->type) {
12703 | case FT_CHAR:
12704 | case FT_UINT8:
12705 | case FT_UINT16:
12706 | case FT_UINT24:
12707 | case FT_UINT32:
12708 | proto_tree_add_uint(tree, **fields, tvb, offset, len, (uint32_t)value);
12709 | break;
12710 |
12711 | case FT_INT8:
12712 | case FT_INT16:
12713 | case FT_INT24:
12714 | case FT_INT32:
12715 | proto_tree_add_int(tree, **fields, tvb, offset, len, (int32_t)value);
12716 | break;
12717 |
12718 | case FT_UINT40:
12719 | case FT_UINT48:
12720 | case FT_UINT56:
12721 | case FT_UINT64:
12722 | proto_tree_add_uint64(tree, **fields, tvb, offset, len, value);
12723 | break;
12724 |
12725 | case FT_INT40:
12726 | case FT_INT48:
12727 | case FT_INT56:
12728 | case FT_INT64:
12729 | proto_tree_add_int64(tree, **fields, tvb, offset, len, (int64_t)value);
12730 | break;
12731 |
12732 | case FT_BOOLEAN:
12733 | proto_tree_add_boolean(tree, **fields, tvb, offset, len, value);
12734 | break;
12735 |
12736 | default:
12737 | 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))
12738 | 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))
12739 | 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))
12740 | 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));
12741 | break;
12742 | }
12743 | if (flags & BMT_NO_APPEND0x01) {
12744 | fields++;
12745 | continue;
12746 | }
12747 | tmpval = (value & hf->bitmask) >> hfinfo_bitshift(hf);
12748 |
12749 | /* XXX: README.developer and the comments have always defined
12750 | * BMT_NO_INT as "only boolean flags are added to the title /
12751 | * don't add non-boolean (integral) fields", but the
12752 | * implementation has always added BASE_CUSTOM and fields with
12753 | * value_strings, though not fields with unit_strings.
12754 | * Possibly this is because some dissectors use a FT_UINT8
12755 | * with a value_string for fields that should be a FT_BOOLEAN.
12756 | */
12757 | switch (hf->type) {
12758 | case FT_CHAR:
12759 | if (hf->display == BASE_CUSTOM) {
12760 | char lbl[ITEM_LABEL_LENGTH240];
12761 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12762 |
12763 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12763, "fmtfunc"))));
12764 | fmtfunc(lbl, (uint32_t) tmpval);
12765 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12766 | hf->name, lbl);
12767 | first = false0;
12768 | }
12769 | else if (hf->strings) {
12770 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12771 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12772 | first = false0;
12773 | }
12774 | else if (!(flags & BMT_NO_INT0x02)) {
12775 | char buf[32];
12776 | const char *out;
12777 |
12778 | if (!first) {
12779 | proto_item_append_text(item, ", ");
12780 | }
12781 |
12782 | out = hfinfo_char_value_format(hf, buf, (uint32_t) tmpval);
12783 | proto_item_append_text(item, "%s: %s", hf->name, out);
12784 | first = false0;
12785 | }
12786 |
12787 | break;
12788 |
12789 | case FT_UINT8:
12790 | case FT_UINT16:
12791 | case FT_UINT24:
12792 | case FT_UINT32:
12793 | if (hf->display == BASE_CUSTOM) {
12794 | char lbl[ITEM_LABEL_LENGTH240];
12795 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12796 |
12797 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12797, "fmtfunc"))));
12798 | fmtfunc(lbl, (uint32_t) tmpval);
12799 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12800 | hf->name, lbl);
12801 | first = false0;
12802 | }
12803 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12804 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12805 | hf->name, hf_try_val_to_str_const((uint32_t) tmpval, hf, "Unknown"));
12806 | first = false0;
12807 | }
12808 | else if (!(flags & BMT_NO_INT0x02)) {
12809 | char buf[NUMBER_LABEL_LENGTH80];
12810 | const char *out = NULL((void*)0);
12811 |
12812 | if (!first) {
12813 | proto_item_append_text(item, ", ");
12814 | }
12815 |
12816 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12817 | out = hf_try_val_to_str((uint32_t) tmpval, hf);
12818 | }
12819 | if (out == NULL((void*)0)) {
12820 | out = hfinfo_number_value_format(hf, buf, (uint32_t) tmpval);
12821 | }
12822 | proto_item_append_text(item, "%s: %s", hf->name, out);
12823 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12824 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12825 | }
12826 | first = false0;
12827 | }
12828 |
12829 | break;
12830 |
12831 | case FT_INT8:
12832 | case FT_INT16:
12833 | case FT_INT24:
12834 | case FT_INT32:
12835 | integer32 = (uint32_t) tmpval;
12836 | if (hf->bitmask) {
12837 | no_of_bits = ws_count_ones(hf->bitmask);
12838 | integer32 = ws_sign_ext32(integer32, no_of_bits);
12839 | }
12840 | if (hf->display == BASE_CUSTOM) {
12841 | char lbl[ITEM_LABEL_LENGTH240];
12842 | const custom_fmt_func_t fmtfunc = (const custom_fmt_func_t)hf->strings;
12843 |
12844 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12844, "fmtfunc"))));
12845 | fmtfunc(lbl, (int32_t) integer32);
12846 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12847 | hf->name, lbl);
12848 | first = false0;
12849 | }
12850 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12851 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12852 | hf->name, hf_try_val_to_str_const((int32_t) integer32, hf, "Unknown"));
12853 | first = false0;
12854 | }
12855 | else if (!(flags & BMT_NO_INT0x02)) {
12856 | char buf[NUMBER_LABEL_LENGTH80];
12857 | const char *out = NULL((void*)0);
12858 |
12859 | if (!first) {
12860 | proto_item_append_text(item, ", ");
12861 | }
12862 |
12863 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12864 | out = hf_try_val_to_str((int32_t) integer32, hf);
12865 | }
12866 | if (out == NULL((void*)0)) {
12867 | out = hfinfo_number_value_format(hf, buf, (int32_t) integer32);
12868 | }
12869 | proto_item_append_text(item, "%s: %s", hf->name, out);
12870 | if (hf->display & BASE_UNIT_STRING0x00001000) {
12871 | proto_item_append_text(item, "%s", unit_name_string_get_value((uint32_t) tmpval, (const unit_name_string*)hf->strings));
12872 | }
12873 | first = false0;
12874 | }
12875 |
12876 | break;
12877 |
12878 | case FT_UINT40:
12879 | case FT_UINT48:
12880 | case FT_UINT56:
12881 | case FT_UINT64:
12882 | if (hf->display == BASE_CUSTOM) {
12883 | char lbl[ITEM_LABEL_LENGTH240];
12884 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12885 |
12886 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12886, "fmtfunc"))));
12887 | fmtfunc(lbl, tmpval);
12888 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12889 | hf->name, lbl);
12890 | first = false0;
12891 | }
12892 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12893 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12894 | hf->name, hf_try_val64_to_str_const(tmpval, hf, "Unknown"));
12895 | first = false0;
12896 | }
12897 | else if (!(flags & BMT_NO_INT0x02)) {
12898 | char buf[NUMBER_LABEL_LENGTH80];
12899 | const char *out = NULL((void*)0);
12900 |
12901 | if (!first) {
12902 | proto_item_append_text(item, ", ");
12903 | }
12904 |
12905 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12906 | out = hf_try_val64_to_str(tmpval, hf);
12907 | }
12908 | if (out == NULL((void*)0)) {
12909 | out = hfinfo_number_value_format64(hf, buf, tmpval);
12910 | }
12911 | proto_item_append_text(item, "%s: %s", hf->name, out);
12912 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12913 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12914 | }
12915 | first = false0;
12916 | }
12917 |
12918 | break;
12919 |
12920 | case FT_INT40:
12921 | case FT_INT48:
12922 | case FT_INT56:
12923 | case FT_INT64:
12924 | if (hf->bitmask) {
12925 | no_of_bits = ws_count_ones(hf->bitmask);
12926 | tmpval = ws_sign_ext64(tmpval, no_of_bits);
12927 | }
12928 | if (hf->display == BASE_CUSTOM) {
12929 | char lbl[ITEM_LABEL_LENGTH240];
12930 | const custom_fmt_func_64_t fmtfunc = (const custom_fmt_func_64_t)hf->strings;
12931 |
12932 | DISSECTOR_ASSERT(fmtfunc)((void) ((fmtfunc) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\"" , "epan/proto.c", 12932, "fmtfunc"))));
12933 | fmtfunc(lbl, (int64_t) tmpval);
12934 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12935 | hf->name, lbl);
12936 | first = false0;
12937 | }
12938 | else if ((hf->strings) &&(!(hf->display & (BASE_UNIT_STRING0x00001000|BASE_SPECIAL_VALS0x00008000)))) {
12939 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12940 | hf->name, hf_try_val64_to_str_const((int64_t) tmpval, hf, "Unknown"));
12941 | first = false0;
12942 | }
12943 | else if (!(flags & BMT_NO_INT0x02)) {
12944 | char buf[NUMBER_LABEL_LENGTH80];
12945 | const char *out = NULL((void*)0);
12946 |
12947 | if (!first) {
12948 | proto_item_append_text(item, ", ");
12949 | }
12950 |
12951 | if (hf->strings && hf->display & BASE_SPECIAL_VALS0x00008000) {
12952 | out = hf_try_val64_to_str((int64_t) tmpval, hf);
12953 | }
12954 | if (out == NULL((void*)0)) {
12955 | out = hfinfo_number_value_format64(hf, buf, (int64_t) tmpval);
12956 | }
12957 | proto_item_append_text(item, "%s: %s", hf->name, out);
12958 | if (hf->strings && hf->display & BASE_UNIT_STRING0x00001000) {
12959 | proto_item_append_text(item, "%s", unit_name_string_get_value64(tmpval, (const unit_name_string*)hf->strings));
12960 | }
12961 | first = false0;
12962 | }
12963 |
12964 | break;
12965 |
12966 | case FT_BOOLEAN:
12967 | if (hf->strings && !(flags & BMT_NO_TFS0x08)) {
12968 | /* If we have true/false strings, emit full - otherwise messages
12969 | might look weird */
12970 | const struct true_false_string *tfs =
12971 | (const struct true_false_string *)hf->strings;
12972 |
12973 | if (tmpval) {
12974 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12975 | hf->name, tfs->true_string);
12976 | first = false0;
12977 | } else if (!(flags & BMT_NO_FALSE0x04)) {
12978 | proto_item_append_text(item, "%s%s: %s", first ? "" : ", ",
12979 | hf->name, tfs->false_string);
12980 | first = false0;
12981 | }
12982 | } else if (hf->bitmask & value) {
12983 | /* If the flag is set, show the name */
12984 | proto_item_append_text(item, "%s%s", first ? "" : ", ", hf->name);
12985 | first = false0;
12986 | }
12987 | break;
12988 | default:
12989 | 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))
12990 | 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))
12991 | 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))
12992 | 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));
12993 | break;
12994 | }
12995 |
12996 | fields++;
12997 | }
12998 |
12999 | /* XXX: We don't pass the hfi into this function. Perhaps we should,
13000 | * but then again most dissectors don't set the bitmask field for
13001 | * the higher level bitmask hfi, so calculate the bitmask from the
13002 | * fields present. */
13003 | if (item) {
13004 | bit_offset = len*8 - 1 - ws_ilog2(bitmask);
13005 | no_of_bits = ws_ilog2(bitmask) - ws_ctz(bitmask) + 1;
13006 | 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);
13007 | 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);
13008 | }
13009 | return first;
13010 | }
13011 |
13012 | /* This function will dissect a sequence of bytes that describe a
13013 | * bitmask and supply the value of that sequence through a pointer.
13014 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13015 | * to be dissected.
13016 | * This field will form an expansion under which the individual fields of the
13017 | * bitmask is dissected and displayed.
13018 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13019 | *
13020 | * fields is an array of pointers to int that lists all the fields of the
13021 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13022 | * or another integer of the same type/size as hf_hdr with a mask specified.
13023 | * This array is terminated by a NULL entry.
13024 | *
13025 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13026 | * FT_integer fields that have a value_string attached will have the
13027 | * matched string displayed on the expansion line.
13028 | */
13029 | proto_item *
13030 | proto_tree_add_bitmask_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb,
13031 | const unsigned offset, const int hf_hdr,
13032 | const int ett, int * const *fields,
13033 | const unsigned encoding, uint64_t *retval)
13034 | {
13035 | 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);
13036 | }
13037 |
13038 | /* This function will dissect a sequence of bytes that describe a
13039 | * bitmask.
13040 | * hf_hdr is a 8/16/24/32/40/48/56/64 bit integer that describes the bitmask
13041 | * to be dissected.
13042 | * This field will form an expansion under which the individual fields of the
13043 | * bitmask is dissected and displayed.
13044 | * This field must be of the type FT_[U]INT{8|16|24|32|40|48|56|64}.
13045 | *
13046 | * fields is an array of pointers to int that lists all the fields of the
13047 | * bitmask. These fields can be either of the type FT_BOOLEAN for flags
13048 | * or another integer of the same type/size as hf_hdr with a mask specified.
13049 | * This array is terminated by a NULL entry.
13050 | *
13051 | * FT_BOOLEAN bits that are set to 1 will have the name added to the expansion.
13052 | * FT_integer fields that have a value_string attached will have the
13053 | * matched string displayed on the expansion line.
13054 | */
13055 | proto_item *
13056 | proto_tree_add_bitmask(proto_tree *parent_tree, tvbuff_t *tvb,
13057 | const unsigned offset, const int hf_hdr,
13058 | const int ett, int * const *fields,
13059 | const unsigned encoding)
13060 | {
13061 | return proto_tree_add_bitmask_with_flags(parent_tree, tvb, offset, hf_hdr, ett, fields, encoding, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13062 | }
13063 |
13064 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13065 | * what data is appended to the header.
13066 | */
13067 | proto_item *
13068 | proto_tree_add_bitmask_with_flags_ret_uint64(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13069 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags,
13070 | uint64_t *retval)
13071 | {
13072 | proto_item *item = NULL((void*)0);
13073 | header_field_info *hf;
13074 | int len;
13075 | uint64_t value;
13076 |
13077 | 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", 13077, __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", 13077 , "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", 13077, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13078 | 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", 13078, (hf)->abbrev)));
13079 | len = ftype_wire_size(hf->type);
13080 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13081 |
13082 | if (parent_tree) {
13083 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13084 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13085 | flags, false0, false0, NULL((void*)0), value);
13086 | }
13087 |
13088 | *retval = value;
13089 | if (hf->bitmask) {
13090 | /* Mask out irrelevant portions */
13091 | *retval &= hf->bitmask;
13092 | /* Shift bits */
13093 | *retval >>= hfinfo_bitshift(hf);
13094 | }
13095 |
13096 | return item;
13097 | }
13098 |
13099 | /* The same as proto_tree_add_bitmask_ret_uint64(), but uses user-supplied flags to determine
13100 | * what data is appended to the header.
13101 | */
13102 | proto_item *
13103 | proto_tree_add_bitmask_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13104 | const int hf_hdr, const int ett, int * const *fields, const unsigned encoding, const int flags)
13105 | {
13106 | proto_item *item = NULL((void*)0);
13107 | header_field_info *hf;
13108 | int len;
13109 | uint64_t value;
13110 |
13111 | 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", 13111, __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", 13111 , "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", 13111, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13112 | 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", 13112, (hf)->abbrev)));
13113 |
13114 | if (parent_tree) {
13115 | len = ftype_wire_size(hf->type);
13116 | item = proto_tree_add_item(parent_tree, hf_hdr, tvb, offset, len, encoding);
13117 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13118 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13119 | flags, false0, false0, NULL((void*)0), value);
13120 | }
13121 |
13122 | return item;
13123 | }
13124 |
13125 | /* Similar to proto_tree_add_bitmask(), but with a passed in value (presumably because it
13126 | can't be retrieved directly from tvb) */
13127 | proto_item *
13128 | proto_tree_add_bitmask_value(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13129 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value)
13130 | {
13131 | return proto_tree_add_bitmask_value_with_flags(parent_tree, tvb, offset,
13132 | hf_hdr, ett, fields, value, BMT_NO_INT0x02|BMT_NO_TFS0x08);
13133 | }
13134 |
13135 | /* Similar to proto_tree_add_bitmask_value(), but with control of flag values */
13136 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern proto_item *
13137 | proto_tree_add_bitmask_value_with_flags(proto_tree *parent_tree, tvbuff_t *tvb, const unsigned offset,
13138 | const int hf_hdr, const int ett, int * const *fields, const uint64_t value, const int flags)
13139 | {
13140 | proto_item *item = NULL((void*)0);
13141 | header_field_info *hf;
13142 | int len;
13143 |
13144 | 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", 13144, __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", 13144 , "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", 13144, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13145 | 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", 13145, (hf)->abbrev)));
13146 | /* the proto_tree_add_uint/_uint64() calls below
13147 | will fail if tvb==NULL and len!=0 */
13148 | len = tvb ? ftype_wire_size(hf->type) : 0;
13149 |
13150 | if (parent_tree) {
13151 | if (len <= 4)
13152 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len, (uint32_t)value);
13153 | else
13154 | item = proto_tree_add_uint64(parent_tree, hf_hdr, tvb, offset, len, value);
13155 |
13156 | proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13157 | flags, false0, false0, NULL((void*)0), value);
13158 | }
13159 |
13160 | return item;
13161 | }
13162 |
13163 | /* Similar to proto_tree_add_bitmask(), but with no "header" item to group all of the fields */
13164 | void
13165 | proto_tree_add_bitmask_list(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13166 | const int len, int * const *fields, const unsigned encoding)
13167 | {
13168 | uint64_t value;
13169 |
13170 | if (tree) {
13171 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13172 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13173 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13174 | }
13175 | }
13176 |
13177 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13178 | proto_tree_add_bitmask_list_ret_uint64(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13179 | const int len, int * const *fields, const unsigned encoding, uint64_t *retval)
13180 | {
13181 | uint64_t value;
13182 |
13183 | value = get_uint64_value(tree, tvb, offset, len, encoding);
13184 | if (tree) {
13185 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13186 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13187 | }
13188 | if (retval) {
13189 | *retval = value;
13190 | }
13191 | }
13192 |
13193 | WS_DLL_PUBLIC__attribute__ ((visibility ("default"))) extern void
13194 | proto_tree_add_bitmask_list_value(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
13195 | const int len, int * const *fields, const uint64_t value)
13196 | {
13197 | if (tree) {
13198 | proto_item_add_bitmask_tree(NULL((void*)0), tvb, offset, len, -1, fields,
13199 | BMT_NO_APPEND0x01, false0, true1, tree, value);
13200 | }
13201 | }
13202 |
13203 |
13204 | /* The same as proto_tree_add_bitmask(), but using a caller-supplied length.
13205 | * This is intended to support bitmask fields whose lengths can vary, perhaps
13206 | * as the underlying standard evolves over time.
13207 | * With this API there is the possibility of being called to display more or
13208 | * less data than the dissector was coded to support.
13209 | * In such cases, it is assumed that bitmasks are extended on the MSb end.
13210 | * Thus when presented with "too much" or "too little" data, MSbits will be
13211 | * ignored or MSfields sacrificed.
13212 | *
13213 | * Only fields for which all defined bits are available are displayed.
13214 | */
13215 | proto_item *
13216 | proto_tree_add_bitmask_len(proto_tree *parent_tree, tvbuff_t *tvb,
13217 | const unsigned offset, const unsigned len, const int hf_hdr,
13218 | const int ett, int * const *fields, struct expert_field* exp,
13219 | const unsigned encoding)
13220 | {
13221 | proto_item *item = NULL((void*)0);
13222 | header_field_info *hf;
13223 | unsigned decodable_len;
13224 | unsigned decodable_offset;
13225 | uint32_t decodable_value;
13226 | uint64_t value;
13227 |
13228 | 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", 13228, __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", 13228 , "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", 13228, "gpa_hfinfo.hfi[hf_hdr] != ((void*)0)" , "Unregistered hf!")))) ; hf = gpa_hfinfo.hfi[hf_hdr];;
13229 | 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", 13229, (hf)->abbrev)));
13230 |
13231 | decodable_offset = offset;
13232 | decodable_len = MIN(len, (unsigned) ftype_wire_size(hf->type))(((len) < ((unsigned) ftype_wire_size(hf->type))) ? (len ) : ((unsigned) ftype_wire_size(hf->type)));
13233 |
13234 | /* If we are ftype_wire_size-limited,
13235 | * make sure we decode as many LSBs as possible.
13236 | */
13237 | if (encoding == ENC_BIG_ENDIAN0x00000000) {
13238 | decodable_offset += (len - decodable_len);
13239 | }
13240 |
13241 | if (parent_tree) {
13242 | decodable_value = get_uint_value(parent_tree, tvb, decodable_offset,
13243 | decodable_len, encoding);
13244 |
13245 | /* The root item covers all the bytes even if we can't decode them all */
13246 | item = proto_tree_add_uint(parent_tree, hf_hdr, tvb, offset, len,
13247 | decodable_value);
13248 | }
13249 |
13250 | if (decodable_len < len) {
13251 | /* Dissector likely requires updating for new protocol revision */
13252 | expert_add_info_format(NULL((void*)0), item, exp,
13253 | "Only least-significant %d of %d bytes decoded",
13254 | decodable_len, len);
13255 | }
13256 |
13257 | if (item) {
13258 | value = get_uint64_value(parent_tree, tvb, decodable_offset, decodable_len, encoding);
13259 | proto_item_add_bitmask_tree(item, tvb, decodable_offset, decodable_len,
13260 | ett, fields, BMT_NO_INT0x02|BMT_NO_TFS0x08, false0, false0, NULL((void*)0), value);
13261 | }
13262 |
13263 | return item;
13264 | }
13265 |
13266 | /* The same as proto_tree_add_bitmask(), but using an arbitrary text as a top-level item */
13267 | proto_item *
13268 | proto_tree_add_bitmask_text(proto_tree *parent_tree, tvbuff_t *tvb,
13269 | const unsigned offset, const unsigned len,
13270 | const char *name, const char *fallback,
13271 | const int ett, int * const *fields,
13272 | const unsigned encoding, const int flags)
13273 | {
13274 | proto_item *item = NULL((void*)0);
13275 | uint64_t value;
13276 |
13277 | if (parent_tree) {
13278 | item = proto_tree_add_text_internal(parent_tree, tvb, offset, len, "%s", name ? name : "");
13279 | value = get_uint64_value(parent_tree, tvb, offset, len, encoding);
13280 | if (proto_item_add_bitmask_tree(item, tvb, offset, len, ett, fields,
13281 | flags, true1, false0, NULL((void*)0), value) && fallback) {
13282 | /* Still at first item - append 'fallback' text if any */
13283 | proto_item_append_text(item, "%s", fallback);
13284 | }
13285 | }
13286 |
13287 | return item;
13288 | }
13289 |
13290 | proto_item *
13291 | proto_tree_add_bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13292 | const unsigned bit_offset, const int no_of_bits,
13293 | const unsigned encoding)
13294 | {
13295 | header_field_info *hfinfo;
13296 | int octet_length;
13297 | int octet_offset;
13298 |
13299 | 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", 13299, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13299 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13299, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13300 |
13301 | if (no_of_bits < 0) {
13302 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13303 | }
13304 | octet_length = (no_of_bits + 7) >> 3;
13305 | octet_offset = bit_offset >> 3;
13306 | test_length(hfinfo, tvb, octet_offset, octet_length, encoding);
13307 |
13308 | /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val()
13309 | * but only after doing a bunch more work (which we can, in the common
13310 | * case, shortcut here).
13311 | */
13312 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13313 | 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", 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];; if (((tree)->tree_data)->count > prefs.gui_max_tree_items ) { ((void)0); if (wireshark_abort_on_too_many_items) ws_log_fatal_full ("Epan", LOG_LEVEL_ERROR, "epan/proto.c", 13313, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
13314 |
13315 | return proto_tree_add_bits_ret_val(tree, hfindex, tvb, bit_offset, no_of_bits, NULL((void*)0), encoding);
13316 | }
13317 |
13318 | /*
13319 | * This function will dissect a sequence of bits that does not need to be byte aligned; the bits
13320 | * set will be shown in the tree as ..10 10.. and the integer value returned if return_value is set.
13321 | * Offset should be given in bits from the start of the tvb.
13322 | */
13323 |
13324 | static proto_item *
13325 | _proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13326 | const unsigned bit_offset, const int no_of_bits,
13327 | uint64_t *return_value, const unsigned encoding)
13328 | {
13329 | int offset;
13330 | unsigned length;
13331 | uint8_t tot_no_bits;
13332 | char *bf_str;
13333 | char lbl_str[ITEM_LABEL_LENGTH240];
13334 | uint64_t value = 0;
13335 | uint8_t *bytes = NULL((void*)0);
13336 | size_t bytes_length = 0;
13337 |
13338 | proto_item *pi;
13339 | header_field_info *hf_field;
13340 |
13341 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13342 | 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", 13342, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13342 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13342, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hf_field = gpa_hfinfo.hfi[hfindex] ;;
13343 |
13344 | if (hf_field->bitmask != 0) {
13345 | 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)
13346 | " 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)
13347 | 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);
13348 | }
13349 |
13350 | if (no_of_bits < 0) {
13351 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13352 | } else if (no_of_bits == 0) {
13353 | 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)
13354 | 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);
13355 | }
13356 |
13357 | /* Byte align offset */
13358 | offset = bit_offset>>3;
13359 |
13360 | /*
13361 | * Calculate the number of octets used to hold the bits
13362 | */
13363 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13364 | length = (tot_no_bits + 7) >> 3;
13365 |
13366 | if (no_of_bits < 65) {
13367 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13368 | } else if (hf_field->type != FT_BYTES) {
13369 | 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)
13370 | 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);
13371 | return NULL((void*)0);
13372 | }
13373 |
13374 | /* Sign extend for signed types */
13375 | switch (hf_field->type) {
13376 | case FT_INT8:
13377 | case FT_INT16:
13378 | case FT_INT24:
13379 | case FT_INT32:
13380 | case FT_INT40:
13381 | case FT_INT48:
13382 | case FT_INT56:
13383 | case FT_INT64:
13384 | value = ws_sign_ext64(value, no_of_bits);
13385 | break;
13386 |
13387 | default:
13388 | break;
13389 | }
13390 |
13391 | if (return_value) {
13392 | *return_value = value;
13393 | }
13394 |
13395 | /* Coast clear. Try and fake it */
13396 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13397 | 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", 13397 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13397, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13397, "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", 13397, __func__, "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); } } };
13398 |
13399 | bf_str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13400 |
13401 | switch (hf_field->type) {
13402 | case FT_BOOLEAN:
13403 | /* Boolean field */
13404 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, value,
13405 | "%s = %s: %s",
13406 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13407 | break;
13408 |
13409 | case FT_CHAR:
13410 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13411 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13412 | break;
13413 |
13414 | case FT_UINT8:
13415 | case FT_UINT16:
13416 | case FT_UINT24:
13417 | case FT_UINT32:
13418 | pi = proto_tree_add_uint(tree, hfindex, tvb, offset, length, (uint32_t)value);
13419 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13420 | break;
13421 |
13422 | case FT_INT8:
13423 | case FT_INT16:
13424 | case FT_INT24:
13425 | case FT_INT32:
13426 | pi = proto_tree_add_int(tree, hfindex, tvb, offset, length, (int32_t)value);
13427 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13428 | break;
13429 |
13430 | case FT_UINT40:
13431 | case FT_UINT48:
13432 | case FT_UINT56:
13433 | case FT_UINT64:
13434 | pi = proto_tree_add_uint64(tree, hfindex, tvb, offset, length, value);
13435 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13436 | break;
13437 |
13438 | case FT_INT40:
13439 | case FT_INT48:
13440 | case FT_INT56:
13441 | case FT_INT64:
13442 | pi = proto_tree_add_int64(tree, hfindex, tvb, offset, length, (int64_t)value);
13443 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13444 | break;
13445 |
13446 | case FT_BYTES:
13447 | bytes = tvb_get_bits_array(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_bits, &bytes_length, encoding);
13448 | pi = proto_tree_add_bytes_with_length(tree, hfindex, tvb, offset, length, bytes, (int) bytes_length);
13449 | proto_item_fill_label(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13450 | proto_item_set_text(pi, "%s", lbl_str);
13451 | return pi;
13452 |
13453 | /* TODO: should handle FT_UINT_BYTES ? */
13454 |
13455 | default:
13456 | 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))
13457 | 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))
13458 | 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))
13459 | 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));
13460 | return NULL((void*)0);
13461 | }
13462 |
13463 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13464 | return pi;
13465 | }
13466 |
13467 | proto_item *
13468 | proto_tree_add_split_bits_item_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13469 | const unsigned bit_offset, const crumb_spec_t *crumb_spec,
13470 | uint64_t *return_value)
13471 | {
13472 | proto_item *pi;
13473 | int no_of_bits;
13474 | int octet_offset;
13475 | unsigned mask_initial_bit_offset;
13476 | unsigned mask_greatest_bit_offset;
13477 | unsigned octet_length;
13478 | uint8_t i;
13479 | char bf_str[256];
13480 | char lbl_str[ITEM_LABEL_LENGTH240];
13481 | uint64_t value;
13482 | uint64_t composite_bitmask;
13483 | uint64_t composite_bitmap;
13484 |
13485 | header_field_info *hf_field;
13486 |
13487 | /* We can't fake it just yet. We have to fill in the 'return_value' parameter */
13488 | 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", 13488, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13488 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13488, "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 | →
13489 |
13490 | if (hf_field->bitmask != 0) {
8 | ← | Assuming field 'bitmask' is equal to 0 | →
9 | ← | Taking false branch | →
13491 | 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)
13492 | " 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)
13493 | 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);
13494 | }
13495 |
13496 | mask_initial_bit_offset = bit_offset % 8;
13497 |
13498 | no_of_bits = 0;
13499 | value = 0;
13500 | i = 0;
13501 | mask_greatest_bit_offset = 0;
13502 | composite_bitmask = 0;
13503 | composite_bitmap = 0;
13504 |
13505 | 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 | →
13506 | uint64_t crumb_mask, crumb_value;
13507 | uint8_t crumb_end_bit_offset;
13508 |
13509 | crumb_value = tvb_get_bits64(tvb,
13510 | bit_offset + crumb_spec[i].crumb_bit_offset,
13511 | crumb_spec[i].crumb_bit_length,
13512 | ENC_BIG_ENDIAN0x00000000);
13513 | value += crumb_value;
13514 | no_of_bits += crumb_spec[i].crumb_bit_length;
13515 | 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", 13515 , "no_of_bits <= 64", "a value larger than 64 bits cannot be represented" ))));
12 | ← | Assuming 'no_of_bits' is <= 64 | →
13 | ← | '?' condition is true | →
13516 |
13517 | /* The bitmask is 64 bit, left-aligned, starting at the first bit of the
13518 | octet containing the initial offset.
13519 | If the mask is beyond 32 bits, then give up on bit map display.
13520 | This could be improved in future, probably showing a table
13521 | of 32 or 64 bits per row */
13522 | if (mask_greatest_bit_offset
13.1 | 'mask_greatest_bit_offset' is < 32
< 32) {
14 | ← | Taking true branch | →
13523 | crumb_end_bit_offset = mask_initial_bit_offset
13524 | + crumb_spec[i].crumb_bit_offset
13525 | + crumb_spec[i].crumb_bit_length;
13526 | 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' | →
13527 |
13528 | if (crumb_end_bit_offset > mask_greatest_bit_offset) {
17 | ← | Assuming 'crumb_end_bit_offset' is <= 'mask_greatest_bit_offset' | →
18 | ← | Taking false branch | →
13529 | mask_greatest_bit_offset = crumb_end_bit_offset;
13530 | }
13531 | /* Currently the bitmap of the crumbs are only shown if
13532 | * smaller than 32 bits. Do not bother calculating the
13533 | * mask if it is larger than that. */
13534 | if (crumb_end_bit_offset
18.1 | 'crumb_end_bit_offset' is <= 32
<= 32) {
19 | ← | Taking true branch | →
13535 | 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'
13536 | composite_bitmap |= (crumb_value << (64 - crumb_end_bit_offset));
13537 | }
13538 | }
13539 | /* Shift left for the next segment */
13540 | value <<= crumb_spec[++i].crumb_bit_length;
13541 | }
13542 |
13543 | /* Sign extend for signed types */
13544 | switch (hf_field->type) {
13545 | case FT_INT8:
13546 | case FT_INT16:
13547 | case FT_INT24:
13548 | case FT_INT32:
13549 | case FT_INT40:
13550 | case FT_INT48:
13551 | case FT_INT56:
13552 | case FT_INT64:
13553 | value = ws_sign_ext64(value, no_of_bits);
13554 | break;
13555 | default:
13556 | break;
13557 | }
13558 |
13559 | if (return_value) {
13560 | *return_value = value;
13561 | }
13562 |
13563 | /* Coast clear. Try and fake it */
13564 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13565 | 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", 13565 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13565, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13565, "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", 13565, __func__, "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); } } };
13566 |
13567 | /* initialise the format string */
13568 | bf_str[0] = '\0';
13569 |
13570 | octet_offset = bit_offset >> 3;
13571 |
13572 | /* Round up mask length to nearest octet */
13573 | octet_length = ((mask_greatest_bit_offset + 7) >> 3);
13574 | mask_greatest_bit_offset = octet_length << 3;
13575 |
13576 | /* As noted above, we currently only produce a bitmap if the crumbs span less than 4 octets of the tvb.
13577 | It would be a useful enhancement to eliminate this restriction. */
13578 | if (mask_greatest_bit_offset > 0 && mask_greatest_bit_offset <= 32) {
13579 | other_decode_bitfield_value(bf_str,
13580 | (uint32_t)(composite_bitmap >> (64 - mask_greatest_bit_offset)),
13581 | (uint32_t)(composite_bitmask >> (64 - mask_greatest_bit_offset)),
13582 | mask_greatest_bit_offset);
13583 | } else {
13584 | /* If the bitmask is too large, try to describe its contents. */
13585 | snprintf(bf_str, sizeof(bf_str), "%d bits", no_of_bits);
13586 | }
13587 |
13588 | switch (hf_field->type) {
13589 | case FT_BOOLEAN: /* it is a bit odd to have a boolean encoded as split-bits, but possible, I suppose? */
13590 | /* Boolean field */
13591 | return proto_tree_add_boolean_format(tree, hfindex,
13592 | tvb, octet_offset, octet_length, value,
13593 | "%s = %s: %s",
13594 | bf_str, hf_field->name, tfs_get_string(!!value, hf_field->strings));
13595 | break;
13596 |
13597 | case FT_CHAR:
13598 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13599 | fill_label_char(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0));
13600 | break;
13601 |
13602 | case FT_UINT8:
13603 | case FT_UINT16:
13604 | case FT_UINT24:
13605 | case FT_UINT32:
13606 | pi = proto_tree_add_uint(tree, hfindex, tvb, octet_offset, octet_length, (uint32_t)value);
13607 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13608 | break;
13609 |
13610 | case FT_INT8:
13611 | case FT_INT16:
13612 | case FT_INT24:
13613 | case FT_INT32:
13614 | pi = proto_tree_add_int(tree, hfindex, tvb, octet_offset, octet_length, (int32_t)value);
13615 | fill_label_number(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13616 | break;
13617 |
13618 | case FT_UINT40:
13619 | case FT_UINT48:
13620 | case FT_UINT56:
13621 | case FT_UINT64:
13622 | pi = proto_tree_add_uint64(tree, hfindex, tvb, octet_offset, octet_length, value);
13623 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), false0);
13624 | break;
13625 |
13626 | case FT_INT40:
13627 | case FT_INT48:
13628 | case FT_INT56:
13629 | case FT_INT64:
13630 | pi = proto_tree_add_int64(tree, hfindex, tvb, octet_offset, octet_length, (int64_t)value);
13631 | fill_label_number64(PITEM_FINFO(pi)((pi)->finfo), lbl_str, NULL((void*)0), true1);
13632 | break;
13633 |
13634 | default:
13635 | 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))
13636 | 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))
13637 | 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))
13638 | 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));
13639 | return NULL((void*)0);
13640 | }
13641 | proto_item_set_text(pi, "%s = %s", bf_str, lbl_str);
13642 | return pi;
13643 | }
13644 |
13645 | void
13646 | proto_tree_add_split_bits_crumb(proto_tree *tree, const int hfindex, tvbuff_t *tvb, const unsigned bit_offset,
13647 | const crumb_spec_t *crumb_spec, uint16_t crumb_index)
13648 | {
13649 | header_field_info *hfinfo;
13650 | int start = bit_offset >> 3;
13651 | int length = ((bit_offset + crumb_spec[crumb_index].crumb_bit_length - 1) >> 3) - (bit_offset >> 3) + 1;
13652 |
13653 | /* We have to duplicate this length check from proto_tree_add_text_internal in order to check for a null tree
13654 | * so that we can use the tree's memory scope in calculating the string */
13655 | if (length == -1) {
13656 | tvb_captured_length(tvb) ? tvb_ensure_captured_length_remaining(tvb, start) : 0;
13657 | } else {
13658 | tvb_ensure_bytes_exist(tvb, start, length);
13659 | }
13660 | if (!tree) return;
13661 |
13662 | 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", 13662, __func__, "Unregistered hf! index=%d" , hfindex); ((void) ((hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\" (%s)", "epan/proto.c", 13662 , "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13662, "gpa_hfinfo.hfi[hfindex] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hfindex];;
13663 | proto_tree_add_text_internal(tree, tvb, start, length,
13664 | "%s crumb %d of %s (decoded above)",
13665 | decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, crumb_spec[crumb_index].crumb_bit_length,
13666 | tvb_get_bits32(tvb,
13667 | bit_offset,
13668 | crumb_spec[crumb_index].crumb_bit_length,
13669 | ENC_BIG_ENDIAN0x00000000),
13670 | ENC_BIG_ENDIAN0x00000000),
13671 | crumb_index,
13672 | hfinfo->name);
13673 | }
13674 |
13675 | proto_item *
13676 | proto_tree_add_bits_ret_val(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
13677 | const unsigned bit_offset, const int no_of_bits,
13678 | uint64_t *return_value, const unsigned encoding)
13679 | {
13680 | proto_item *item;
13681 |
13682 | if ((item = _proto_tree_add_bits_ret_val(tree, hfindex, tvb,
13683 | bit_offset, no_of_bits,
13684 | return_value, encoding))) {
13685 | FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7))do { if (((item)->finfo)) (((item)->finfo))->flags = (((item)->finfo))->flags | ((((bit_offset&0x7) & 63) << 5)); } while(0);
13686 | 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);
13687 | }
13688 | return item;
13689 | }
13690 |
13691 | static proto_item *
13692 | _proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13693 | tvbuff_t *tvb, const unsigned bit_offset,
13694 | const int no_of_bits, void *value_ptr,
13695 | const unsigned encoding, char *value_str)
13696 | {
13697 | int offset;
13698 | unsigned length;
13699 | uint8_t tot_no_bits;
13700 | char *str;
13701 | uint64_t value = 0;
13702 | header_field_info *hf_field;
13703 |
13704 | /* We do not have to return a value, try to fake it as soon as possible */
13705 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13706 | 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", 13706 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13706, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13706, "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", 13706, __func__, "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); } } };
13707 |
13708 | if (hf_field->bitmask != 0) {
13709 | 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)
13710 | " 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)
13711 | 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);
13712 | }
13713 |
13714 | if (no_of_bits < 0) {
13715 | THROW(ReportedBoundsError)except_throw(1, (3), ((void*)0));
13716 | } else if (no_of_bits == 0) {
13717 | 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)
13718 | 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);
13719 | }
13720 |
13721 | /* Byte align offset */
13722 | offset = bit_offset>>3;
13723 |
13724 | /*
13725 | * Calculate the number of octets used to hold the bits
13726 | */
13727 | tot_no_bits = ((bit_offset&0x7) + no_of_bits);
13728 | length = tot_no_bits>>3;
13729 | /* If we are using part of the next octet, increase length by 1 */
13730 | if (tot_no_bits & 0x07)
13731 | length++;
13732 |
13733 | if (no_of_bits < 65) {
13734 | value = tvb_get_bits64(tvb, bit_offset, no_of_bits, encoding);
13735 | } else {
13736 | 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)
13737 | 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);
13738 | return NULL((void*)0);
13739 | }
13740 |
13741 | str = decode_bits_in_field(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), bit_offset, no_of_bits, value, encoding);
13742 |
13743 | (void) g_strlcat(str, " = ", 256+64);
13744 | (void) g_strlcat(str, hf_field->name, 256+64);
13745 |
13746 | /*
13747 | * This function does not receive an actual value but a dimensionless pointer to that value.
13748 | * For this reason, the type of the header field is examined in order to determine
13749 | * what kind of value we should read from this address.
13750 | * The caller of this function must make sure that for the specific header field type the address of
13751 | * a compatible value is provided.
13752 | */
13753 | switch (hf_field->type) {
13754 | case FT_BOOLEAN:
13755 | return proto_tree_add_boolean_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13756 | "%s: %s", str, value_str);
13757 | break;
13758 |
13759 | case FT_CHAR:
13760 | case FT_UINT8:
13761 | case FT_UINT16:
13762 | case FT_UINT24:
13763 | case FT_UINT32:
13764 | return proto_tree_add_uint_format(tree, hfindex, tvb, offset, length, *(uint32_t *)value_ptr,
13765 | "%s: %s", str, value_str);
13766 | break;
13767 |
13768 | case FT_UINT40:
13769 | case FT_UINT48:
13770 | case FT_UINT56:
13771 | case FT_UINT64:
13772 | return proto_tree_add_uint64_format(tree, hfindex, tvb, offset, length, *(uint64_t *)value_ptr,
13773 | "%s: %s", str, value_str);
13774 | break;
13775 |
13776 | case FT_INT8:
13777 | case FT_INT16:
13778 | case FT_INT24:
13779 | case FT_INT32:
13780 | return proto_tree_add_int_format(tree, hfindex, tvb, offset, length, *(int32_t *)value_ptr,
13781 | "%s: %s", str, value_str);
13782 | break;
13783 |
13784 | case FT_INT40:
13785 | case FT_INT48:
13786 | case FT_INT56:
13787 | case FT_INT64:
13788 | return proto_tree_add_int64_format(tree, hfindex, tvb, offset, length, *(int64_t *)value_ptr,
13789 | "%s: %s", str, value_str);
13790 | break;
13791 |
13792 | case FT_FLOAT:
13793 | return proto_tree_add_float_format(tree, hfindex, tvb, offset, length, *(float *)value_ptr,
13794 | "%s: %s", str, value_str);
13795 | break;
13796 |
13797 | default:
13798 | 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))
13799 | 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))
13800 | 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))
13801 | 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));
13802 | return NULL((void*)0);
13803 | }
13804 | }
13805 |
13806 | static proto_item *
13807 | proto_tree_add_bits_format_value(proto_tree *tree, const int hfindex,
13808 | tvbuff_t *tvb, const unsigned bit_offset,
13809 | const int no_of_bits, void *value_ptr,
13810 | const unsigned encoding, char *value_str)
13811 | {
13812 | proto_item *item;
13813 |
13814 | if ((item = _proto_tree_add_bits_format_value(tree, hfindex,
13815 | tvb, bit_offset, no_of_bits,
13816 | value_ptr, encoding, value_str))) {
13817 | FI_SET_FLAG(PNODE_FINFO(item), FI_BITS_OFFSET(bit_offset&0x7))do { if (((item)->finfo)) (((item)->finfo))->flags = (((item)->finfo))->flags | ((((bit_offset&0x7) & 63) << 5)); } while(0);
13818 | 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);
13819 | }
13820 | return item;
13821 | }
13822 |
13823 | #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); \
13824 | va_start(ap, format)__builtin_va_start(ap, format); \
13825 | dst = wmem_strdup_vprintf(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), format, ap); \
13826 | va_end(ap)__builtin_va_end(ap);
13827 |
13828 | proto_item *
13829 | proto_tree_add_uint_bits_format_value(proto_tree *tree, const int hfindex,
13830 | tvbuff_t *tvb, const unsigned bit_offset,
13831 | const int no_of_bits, uint32_t value,
13832 | const unsigned encoding,
13833 | const char *format, ...)
13834 | {
13835 | va_list ap;
13836 | char *dst;
13837 | header_field_info *hf_field;
13838 |
13839 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13840 |
13841 | 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", 13841 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13841, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13841, "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", 13841, __func__, "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); } } };
13842 |
13843 | switch (hf_field->type) {
13844 | case FT_UINT8:
13845 | case FT_UINT16:
13846 | case FT_UINT24:
13847 | case FT_UINT32:
13848 | break;
13849 |
13850 | default:
13851 | 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)
13852 | 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);
13853 | return NULL((void*)0);
13854 | }
13855 |
13856 | 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);;
13857 |
13858 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13859 | }
13860 |
13861 | proto_item *
13862 | proto_tree_add_uint64_bits_format_value(proto_tree *tree, const int hfindex,
13863 | tvbuff_t *tvb, const unsigned bit_offset,
13864 | const int no_of_bits, uint64_t value,
13865 | const unsigned encoding,
13866 | const char *format, ...)
13867 | {
13868 | va_list ap;
13869 | char *dst;
13870 | header_field_info *hf_field;
13871 |
13872 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13873 |
13874 | 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", 13874 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13874, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13874, "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", 13874, __func__, "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); } } };
13875 |
13876 | switch (hf_field->type) {
13877 | case FT_UINT40:
13878 | case FT_UINT48:
13879 | case FT_UINT56:
13880 | case FT_UINT64:
13881 | break;
13882 |
13883 | default:
13884 | 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)
13885 | 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);
13886 | return NULL((void*)0);
13887 | }
13888 |
13889 | 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);;
13890 |
13891 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13892 | }
13893 |
13894 | proto_item *
13895 | proto_tree_add_float_bits_format_value(proto_tree *tree, const int hfindex,
13896 | tvbuff_t *tvb, const unsigned bit_offset,
13897 | const int no_of_bits, float value,
13898 | const unsigned encoding,
13899 | const char *format, ...)
13900 | {
13901 | va_list ap;
13902 | char *dst;
13903 | header_field_info *hf_field;
13904 |
13905 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13906 |
13907 | 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", 13907 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13907, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13907, "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", 13907, __func__, "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); } } };
13908 |
13909 | 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", 13909, ((hf_field))->abbrev))));
13910 |
13911 | 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);;
13912 |
13913 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13914 | }
13915 |
13916 | proto_item *
13917 | proto_tree_add_int_bits_format_value(proto_tree *tree, const int hfindex,
13918 | tvbuff_t *tvb, const unsigned bit_offset,
13919 | const int no_of_bits, int32_t value,
13920 | const unsigned encoding,
13921 | const char *format, ...)
13922 | {
13923 | va_list ap;
13924 | char *dst;
13925 | header_field_info *hf_field;
13926 |
13927 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13928 |
13929 | 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", 13929 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13929, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13929, "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", 13929, __func__, "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); } } };
13930 |
13931 | switch (hf_field->type) {
13932 | case FT_INT8:
13933 | case FT_INT16:
13934 | case FT_INT24:
13935 | case FT_INT32:
13936 | break;
13937 |
13938 | default:
13939 | 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)
13940 | 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);
13941 | return NULL((void*)0);
13942 | }
13943 |
13944 | 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);;
13945 |
13946 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13947 | }
13948 |
13949 | proto_item *
13950 | proto_tree_add_int64_bits_format_value(proto_tree *tree, const int hfindex,
13951 | tvbuff_t *tvb, const unsigned bit_offset,
13952 | const int no_of_bits, int64_t value,
13953 | const unsigned encoding,
13954 | const char *format, ...)
13955 | {
13956 | va_list ap;
13957 | char *dst;
13958 | header_field_info *hf_field;
13959 |
13960 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13961 |
13962 | 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", 13962 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13962, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13962, "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", 13962, __func__, "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); } } };
13963 |
13964 | switch (hf_field->type) {
13965 | case FT_INT40:
13966 | case FT_INT48:
13967 | case FT_INT56:
13968 | case FT_INT64:
13969 | break;
13970 |
13971 | default:
13972 | 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)
13973 | 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);
13974 | return NULL((void*)0);
13975 | }
13976 |
13977 | 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);;
13978 |
13979 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
13980 | }
13981 |
13982 | proto_item *
13983 | proto_tree_add_boolean_bits_format_value(proto_tree *tree, const int hfindex,
13984 | tvbuff_t *tvb, const unsigned bit_offset,
13985 | const int no_of_bits, uint64_t value,
13986 | const unsigned encoding,
13987 | const char *format, ...)
13988 | {
13989 | va_list ap;
13990 | char *dst;
13991 | header_field_info *hf_field;
13992 |
13993 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
13994 |
13995 | 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", 13995 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13995, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 13995, "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", 13995, __func__, "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); } } };
13996 |
13997 | 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" , 13997, ((hf_field))->abbrev))));
13998 |
13999 | 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);;
14000 |
14001 | return proto_tree_add_bits_format_value(tree, hfindex, tvb, bit_offset, no_of_bits, &value, encoding, dst);
14002 | }
14003 |
14004 | proto_item *
14005 | proto_tree_add_ts_23_038_7bits_packed_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14006 | const unsigned bit_offset, const int no_of_chars)
14007 | {
14008 | proto_item *pi;
14009 | header_field_info *hfinfo;
14010 | int byte_length;
14011 | int byte_offset;
14012 | char *string;
14013 |
14014 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14015 |
14016 | 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", 14016 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14016, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14016, "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", 14016, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14017 |
14018 | 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" , 14018, ((hfinfo))->abbrev))));
14019 |
14020 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14021 | byte_offset = bit_offset >> 3;
14022 |
14023 | string = tvb_get_ts_23_038_7bits_string_packed(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14024 |
14025 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14026 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14026, "byte_length >= 0" ))));
14027 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14028 |
14029 | return pi;
14030 | }
14031 |
14032 | proto_item *
14033 | proto_tree_add_ascii_7bits_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb,
14034 | const unsigned bit_offset, const int no_of_chars)
14035 | {
14036 | proto_item *pi;
14037 | header_field_info *hfinfo;
14038 | int byte_length;
14039 | int byte_offset;
14040 | char *string;
14041 |
14042 | CHECK_FOR_NULL_TREE(tree)if (!tree) { ((void)0); return ((void*)0); };
14043 |
14044 | 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", 14044 , __func__, "Unregistered hf! index=%d", hfindex); ((void) (( hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len ) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14044, "hfindex > 0 && (unsigned)hfindex < gpa_hfinfo.len" , "Unregistered hf!")))) ; ((void) ((gpa_hfinfo.hfi[hfindex] != ((void*)0)) ? (void)0 : (proto_report_dissector_bug("%s:%u: failed assertion \"%s\" (%s)" , "epan/proto.c", 14044, "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", 14044, __func__, "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items); ((tree)->tree_data )->count = 0; except_throw(1, (6), (wmem_strdup_printf(((tree )->tree_data->pinfo->pool), "Adding %s would put more than %d items in the tree -- possible infinite loop (max number of items can be increased in advanced preferences)" , hfinfo->abbrev, prefs.gui_max_tree_items))); } if (!(((tree )->tree_data)->visible)) { if (proto_item_is_hidden((tree ))) { 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) ; } } };
14045 |
14046 | 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" , 14046, ((hfinfo))->abbrev))));
14047 |
14048 | byte_length = (((no_of_chars + 1) * 7) + (bit_offset & 0x07)) >> 3;
14049 | byte_offset = bit_offset >> 3;
14050 |
14051 | string = tvb_get_ascii_7bits_string(PNODE_POOL(tree)((tree)->tree_data->pinfo->pool), tvb, bit_offset, no_of_chars);
14052 |
14053 | pi = proto_tree_add_pi(tree, hfinfo, tvb, byte_offset, &byte_length);
14054 | DISSECTOR_ASSERT(byte_length >= 0)((void) ((byte_length >= 0) ? (void)0 : (proto_report_dissector_bug ("%s:%u: failed assertion \"%s\"", "epan/proto.c", 14054, "byte_length >= 0" ))));
14055 | proto_tree_set_string(PNODE_FINFO(pi)((pi)->finfo), string);
14056 |
14057 | return pi;
14058 | }
14059 |
14060 | const value_string proto_checksum_vals[] = {
14061 | { PROTO_CHECKSUM_E_BAD, "Bad" },
14062 | { PROTO_CHECKSUM_E_GOOD, "Good" },
14063 | { PROTO_CHECKSUM_E_UNVERIFIED, "Unverified" },
14064 | { PROTO_CHECKSUM_E_NOT_PRESENT, "Not present" },
14065 | { PROTO_CHECKSUM_E_ILLEGAL, "Illegal" },
14066 |
14067 | { 0, NULL((void*)0) }
14068 | };
14069 |
14070 | proto_item *
14071 | proto_tree_add_checksum(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14072 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14073 | packet_info *pinfo, uint32_t computed_checksum, const unsigned encoding, const unsigned flags)
14074 | {
14075 | header_field_info *hfinfo;
14076 | uint32_t checksum;
14077 | uint32_t len;
14078 | proto_item* ti = NULL((void*)0);
14079 | proto_item* ti2;
14080 | bool_Bool incorrect_checksum = true1;
14081 |
14082 | 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", 14082, __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", 14082 , "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", 14082, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14083 |
14084 | switch (hfinfo->type) {
14085 | case FT_UINT8:
14086 | len = 1;
14087 | break;
14088 | case FT_UINT16:
14089 | len = 2;
14090 | break;
14091 | case FT_UINT24:
14092 | len = 3;
14093 | break;
14094 | case FT_UINT32:
14095 | len = 4;
14096 | break;
14097 | default:
14098 | 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)
14099 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_UINT8, FT_UINT16, FT_UINT24, or FT_UINT32" , hfinfo->abbrev);
14100 | }
14101 |
14102 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14103 | ti = proto_tree_add_uint_format_value(tree, hf_checksum, tvb, offset, len, 0, "[missing]");
14104 | proto_item_set_generated(ti);
14105 | if (hf_checksum_status != -1) {
14106 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, len, PROTO_CHECKSUM_E_NOT_PRESENT);
14107 | proto_item_set_generated(ti2);
14108 | }
14109 | return ti;
14110 | }
14111 |
14112 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14113 | ti = proto_tree_add_uint(tree, hf_checksum, tvb, offset, len, computed_checksum);
14114 | proto_item_set_generated(ti);
14115 | } else {
14116 | ti = proto_tree_add_item_ret_uint(tree, hf_checksum, tvb, offset, len, encoding, &checksum);
14117 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14118 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14119 | if (computed_checksum == 0) {
14120 | proto_item_append_text(ti, " [correct]");
14121 | if (hf_checksum_status != -1) {
14122 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14123 | proto_item_set_generated(ti2);
14124 | }
14125 | incorrect_checksum = false0;
14126 | } else if (flags & PROTO_CHECKSUM_IN_CKSUM0x04) {
14127 | computed_checksum = in_cksum_shouldbe(checksum, computed_checksum);
14128 | /* XXX - This can't distinguish between "shouldbe"
14129 | * 0x0000 and 0xFFFF unless we know whether there
14130 | * were any nonzero bits (other than the checksum).
14131 | * Protocols should not use this path if they might
14132 | * have an all zero packet.
14133 | * Some implementations put the wrong zero; maybe
14134 | * we should have a special expert info for that?
14135 | */
14136 | }
14137 | } else {
14138 | if (checksum == computed_checksum) {
14139 | proto_item_append_text(ti, " [correct]");
14140 | if (hf_checksum_status != -1) {
14141 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14142 | proto_item_set_generated(ti2);
14143 | }
14144 | incorrect_checksum = false0;
14145 | }
14146 | }
14147 |
14148 | if (incorrect_checksum) {
14149 | if (hf_checksum_status != -1) {
14150 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14151 | proto_item_set_generated(ti2);
14152 | }
14153 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14154 | proto_item_append_text(ti, " [incorrect]");
14155 | if (bad_checksum_expert != NULL((void*)0))
14156 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14157 | } else {
14158 | proto_item_append_text(ti, " incorrect, should be 0x%0*x", len*2, computed_checksum);
14159 | if (bad_checksum_expert != NULL((void*)0))
14160 | 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);
14161 | }
14162 | }
14163 | } else {
14164 | if (hf_checksum_status != -1) {
14165 | proto_item_append_text(ti, " [unverified]");
14166 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14167 | proto_item_set_generated(ti2);
14168 | }
14169 | }
14170 | }
14171 |
14172 | return ti;
14173 | }
14174 |
14175 | proto_item *
14176 | proto_tree_add_checksum_bytes(proto_tree *tree, tvbuff_t *tvb, const unsigned offset,
14177 | const int hf_checksum, const int hf_checksum_status, struct expert_field* bad_checksum_expert,
14178 | packet_info *pinfo, const uint8_t *computed_checksum, size_t checksum_len, const unsigned flags)
14179 | {
14180 | header_field_info *hfinfo;
14181 | uint8_t *checksum = NULL((void*)0);
14182 | proto_item* ti = NULL((void*)0);
14183 | proto_item* ti2;
14184 | bool_Bool incorrect_checksum = true1;
14185 |
14186 | 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", 14186, __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", 14186 , "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", 14186, "gpa_hfinfo.hfi[hf_checksum] != ((void*)0)" , "Unregistered hf!")))) ; hfinfo = gpa_hfinfo.hfi[hf_checksum ];;
14187 |
14188 | if (hfinfo->type != FT_BYTES) {
14189 | 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)
14190 | hfinfo->abbrev)proto_report_dissector_bug("field %s is not of type FT_BYTES" , hfinfo->abbrev);
14191 | }
14192 |
14193 | if (flags & PROTO_CHECKSUM_NOT_PRESENT0x10) {
14194 | ti = proto_tree_add_bytes_format_value(tree, hf_checksum, tvb, offset, (int)checksum_len, 0, "[missing]");
14195 | proto_item_set_generated(ti);
14196 | if (hf_checksum_status != -1) {
14197 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, (int)checksum_len, PROTO_CHECKSUM_E_NOT_PRESENT);
14198 | proto_item_set_generated(ti2);
14199 | }
14200 | return ti;
14201 | }
14202 |
14203 | if (flags & PROTO_CHECKSUM_GENERATED0x02) {
14204 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, computed_checksum);
14205 | proto_item_set_generated(ti);
14206 | } else {
14207 | 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 ))))));
14208 | tvb_memcpy(tvb, checksum, offset, checksum_len);
14209 | ti = proto_tree_add_bytes(tree, hf_checksum, tvb, offset, (int)checksum_len, checksum);
14210 | if (flags & PROTO_CHECKSUM_VERIFY0x01) {
14211 | if (flags & (PROTO_CHECKSUM_IN_CKSUM0x04|PROTO_CHECKSUM_ZERO0x08)) {
14212 | if (computed_checksum == 0) {
14213 | proto_item_append_text(ti, " [correct]");
14214 | if (hf_checksum_status != -1) {
14215 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14216 | proto_item_set_generated(ti2);
14217 | }
14218 | incorrect_checksum = false0;
14219 | }
14220 | } else {
14221 | if (memcmp(computed_checksum, checksum, checksum_len) == 0) {
14222 | proto_item_append_text(ti, " [correct]");
14223 | if (hf_checksum_status != -1) {
14224 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_GOOD);
14225 | proto_item_set_generated(ti2);
14226 | }
14227 | incorrect_checksum = false0;
14228 | }
14229 | }
14230 |
14231 | if (incorrect_checksum) {
14232 | if (hf_checksum_status != -1) {
14233 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_BAD);
14234 | proto_item_set_generated(ti2);
14235 | }
14236 | if (flags & PROTO_CHECKSUM_ZERO0x08) {
14237 | proto_item_append_text(ti, " [incorrect]");
14238 | if (bad_checksum_expert != NULL((void*)0))
14239 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s", expert_get_summary(bad_checksum_expert));
14240 | } else {
14241 | size_t computed_checksum_str_len = (2 * checksum_len * sizeof(char)) + 1;
14242 | 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))))));
14243 | for (size_t counter = 0; counter < checksum_len; ++counter) {
14244 | snprintf(
14245 | /* On ecah iteration inserts two characters */
14246 | (char*)&computed_checksum_str[counter << 1],
14247 | computed_checksum_str_len - (counter << 1),
14248 | "%02x",
14249 | computed_checksum[counter]);
14250 | }
14251 | proto_item_append_text(ti, " incorrect, should be 0x%s", computed_checksum_str);
14252 | if (bad_checksum_expert != NULL((void*)0))
14253 | expert_add_info_format(pinfo, ti, bad_checksum_expert, "%s [should be 0x%s]", expert_get_summary(bad_checksum_expert), computed_checksum_str);
14254 | }
14255 | }
14256 | } else {
14257 | if (hf_checksum_status != -1) {
14258 | proto_item_append_text(ti, " [unverified]");
14259 | ti2 = proto_tree_add_uint(tree, hf_checksum_status, tvb, offset, 0, PROTO_CHECKSUM_E_UNVERIFIED);
14260 | proto_item_set_generated(ti2);
14261 | }
14262 | }
14263 | }
14264 |
14265 | return ti;
14266 | }
14267 |
14268 | unsigned char
14269 | proto_check_field_name(const char *field_name)
14270 | {
14271 | return module_check_valid_name(field_name, false0);
14272 | }
14273 |
14274 | unsigned char
14275 | proto_check_field_name_lower(const char *field_name)
14276 | {
14277 | return module_check_valid_name(field_name, true1);
14278 | }
14279 |
14280 | bool_Bool
14281 | tree_expanded(int tree_type)
14282 | {
14283 | if (tree_type <= 0) {
14284 | return false0;
14285 | }
14286 | 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", 14286, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14287 | return tree_is_expanded[tree_type >> 5] & (1U << (tree_type & 31));
14288 | }
14289 |
14290 | void
14291 | tree_expanded_set(int tree_type, bool_Bool value)
14292 | {
14293 | 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", 14293, __func__, "assertion failed: %s", "tree_type >= 0 && tree_type < num_tree_types" ); } while (0);
14294 |
14295 | if (value)
14296 | tree_is_expanded[tree_type >> 5] |= (1U << (tree_type & 31));
14297 | else
14298 | tree_is_expanded[tree_type >> 5] &= ~(1U << (tree_type & 31));
14299 | }
14300 |
14301 | /*
14302 | * Editor modelines - https://www.wireshark.org/tools/modelines.html
14303 | *
14304 | * Local variables:
14305 | * c-basic-offset: 8
14306 | * tab-width: 8
14307 | * indent-tabs-mode: t
14308 | * End:
14309 | *
14310 | * vi: set shiftwidth=8 tabstop=8 noexpandtab:
14311 | * :indentSize=8:tabSize=8:noTabs=false:
14312 | */